This file is indexed.

/usr/share/doc/python-impacket/examples/spoolss.py is in python-impacket 0.9.10-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/python
# Copyright (c) 2003-2012 CORE Security Technologies
#
# This software is provided under under a slightly modified version
# of the Apache Software License. See the accompanying LICENSE file
# for more information.
#
# $Id: spoolss.py 600 2012-07-11 19:39:46Z bethus@gmail.com $
#
# SPOOLSS example for some functions implemented
#
# Author:
#  Alberto Solino (bethus@gmail.com)
#
# Reference for:
#  DCE/RPC for SPOOLSS

import socket
import string
import sys
import types

from impacket import uuid, ntlm, version
from impacket.dcerpc import dcerpc_v4, dcerpc, transport, printer
from struct import unpack

import argparse

class SPOOLSS:
    KNOWN_PROTOCOLS = {
        '139/SMB': (r'ncacn_np:%s[\pipe\spoolss]', 139),
        '445/SMB': (r'ncacn_np:%s[\pipe\spoolss]', 445),
        }


    def __init__(self, username, password, domain, hashes, protocols):
        if not protocols:
            protocols = SPOOLSS.KNOWN_PROTOCOLS.keys()

        self.__username = username
        self.__password = password
        self.__protocols = [protocols]
        self.__domain = domain
        self.__lmhash = ''
        self.__nthash = ''
        if hashes is not None:
            self.__lmhash, self.__nthash = hashes.split(':')

    def play(self, addr):

        # Try all requested protocols until one works.
        entries = []
        for protocol in self.__protocols:
            protodef = SPOOLSS.KNOWN_PROTOCOLS[protocol]
            port = protodef[1]

            print "Trying protocol %s..." % protocol
            stringbinding = protodef[0] % addr

            rpctransport = transport.DCERPCTransportFactory(stringbinding)
            rpctransport.set_dport(port)
            if hasattr(rpctransport, 'set_credentials'):
                # This method exists only for selected protocol sequences.
                rpctransport.set_credentials(self.__username, self.__password, self.__domain, self.__lmhash, self.__nthash)

            try:
                entries = self.doStuff(rpctransport)
            except Exception, e:
                print 'Protocol failed: %s' % e
            else:
                # Got a response. No need for further iterations.
                break


    def doStuff(self, rpctransport):
        dce = dcerpc.DCERPC_v5(rpctransport)

        dce.connect()
        dce.set_auth_level(ntlm.NTLM_AUTH_PKT_PRIVACY)
        #dce.set_max_fragment_size(16)
        dce.bind(printer.MSRPC_UUID_SPOOLSS)
        rpcspool = printer.PrintSpooler(dce)
        resp = rpcspool.enumPrinters('\x00',0x2, level=1)
        data = resp['PrinterEnum']
        index = 0 
        for i in range(resp['cReturned']):
            # skip the flags
            flags = unpack('<L',data[index:index+4])[0]
            index += 4
            description = unpack('<L',data[index:index+4])[0]
            index += 4
            name = unpack('<L',data[index:index+4])[0]
            index += 4
            comment = unpack('<L',data[index:index+4])[0]
            index += 4
            # Yes.. still don't know why.. offsets are 0x10*i away from the actual data
            description = data[(description+16*i):].split('\x00\x00')[0]
            name = data[(name+16*i):].split('\x00\x00')[0]
            comment = data[(comment+16*i):].split('\x00\x00')[0]
            print "flags: 0x%x\nname:[%s]\ndescription:[%s]\ncomment:[%s]\n" %(flags,name,description,comment)
            
        #resp = rpcspool.enumPorts()
        #resp.dump()

        dce.disconnect()


# Process command-line arguments.
if __name__ == '__main__':
    print version.BANNER

    parser = argparse.ArgumentParser()

    parser.add_argument('target', action='store', help='[domain/][username[:password]@]<address>')
    parser.add_argument('protocol', choices=SPOOLSS.KNOWN_PROTOCOLS.keys(), nargs='?', default='445/SMB', help='transport protocol (default 445/SMB)')

    group = parser.add_argument_group('authentication')

    group.add_argument('-hashes', action="store", metavar = "LMHASH:NTHASH", help='NTLM hashes, format is LMHASH:NTHASH')
 
    if len(sys.argv)==1:
        parser.print_help()
        sys.exit(1)

    options = parser.parse_args()

    import re
    domain, username, password, address = re.compile('(?:(?:([^/@:]*)/)?([^@:]*)(?::([^@]*))?@)?(.*)').match(options.target).groups('')

    if domain is None:
        domain = ''

    dumper = SPOOLSS(username, password, domain, options.hashes, options.protocol)
    dumper.play(address)