no one is safe ...

fixing samrdump.py

Um möglichst alle Informationen des SMB Protokolls auszulesen bringt Backtrack das sehr nützliche Tool samrdump.py mit. In gewissen Konstellationen bricht dieses Tool allerdings mit folgender unschönen Fehlermeldung ab:

root@bt:~# /pentest/python/impacket-examples/samrdump.py 10.8.28.240
Retrieving endpoint list from 10.8.28.240
Trying protocol 445/SMB...
Found domain(s):
. WIN2K-ENG-SP0
. Builtin
Looking up users in domain WIN2K-ENG-SP0
Found user: Administrator, uid = 500
Found user: Guest, uid = 501
Found user: IUSR_WIN2K-ENG, uid = 1001
Found user: IWAM_WIN2K-ENG, uid = 1002
Found user: TsInternetUser, uid = 1000
Administrator (500)/Enabled: true
Administrator (500)/Kickoff: Wed, 16 Dec 2009 11:39:20
Administrator (500)/PWD Can Change: Wed, 16 Dec 2009 11:39:20
Administrator (500)/PWD Must Change: Infinity
Administrator (500)/Group id: 513
Administrator (500)/Bad pwd count: 0
Administrator (500)/Logon count: 4
Administrator (500)/Profile:
Administrator (500)/Comment:
Administrator (500)/Logon hours: Unlimited
Administrator (500)/Workstations:
Administrator (500)/Description: Built-in account for administering the computer/domain
Administrator (500)/Parameters:
Administrator (500)/Script:
Administrator (500)/Home Drive:
Administrator (500)/Account Name: Administrator
Administrator (500)/Home:
Administrator (500)/Full Name:
Guest (501)/Enabled: false
Guest (501)/Kickoff:
Traceback (most recent call last):
  File "/pentest/python/impacket-examples/samrdump.py", line 182, in <module>
    dumper.dump(address)
  File "/pentest/python/impacket-examples/samrdump.py", line 83, in dump
    print base + '/Kickoff:', user.get_kickoff_time()
  File "/var/lib/python-support/python2.5/impacket/dcerpc/samr.py", line 134, in get_kickoff_time
    return display_time(self._kickoff_time_high, self._kickoff_time_low)
  File "/var/lib/python-support/python2.5/impacket/dcerpc/samr.py", line 35, in display_time
    r = (strftime("%a, %d %b %Y %H:%M:%S",gmtime(d)), minutes_utc/60)[0]
ValueError: timestamp out of range for platform time_t

Ein einfacher Fix dafür ist folgender:

In der Datei "/var/lib/python-support/python2.5/impacket/dcerpc/samr.py" wird unter gewissen Umständen ein falsche (negatives) Datum berechnet. Dies lässt sich einfach korrigieren in dem das Datum in solchen Konstellationen auf 0 gesetzt wird (ab Zeile 33):

27 def display_time(filetime_high, filetime_low, minutes_utc=0):
28     d = filetime_high*4.0*1.0*(1<<30)
29     d += filetime_low
30     d *= 1.0e-7
31     d -= (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
32     if minutes_utc == 0:
33         try:    #dirty fix</b></em>
34                 r = (strftime("%a, %d %b %Y %H:%M:%S",gmtime(d)), minutes_utc/60)[0]
35         except: #dirty fix
36                 r = 0   #dirty fix
37     else:
38         try:    #dirty fix
39                 r = "%s GMT %d " % (strftime("%a, %d %b %Y %H:%M:%S",gmtime(d)), minutes_utc/60)
40         except: #dirty fix
41                 r = 0   #dirty fix
42     return r

Als nächstes finde ich es sehr nervig, dass das Script bei Verbindungsfehlern immer einen riesen Traceback ausgibt!

Traceback (most recent call last):
  File "/pentest/python/impacket-examples/samrdump.py", line 184, in <module>
    dumper.dump(address)
  File "/pentest/python/impacket-examples/samrdump.py", line 67, in dump
    entries = self.__fetchList(rpctransport)
  File "/pentest/python/impacket-examples/samrdump.py", line 114, in __fetchList
    dce.connect()
  File "/var/lib/python-support/python2.5/impacket/dcerpc/dcerpc.py", line 627, in connect
    return self._transport.connect()
  File "/var/lib/python-support/python2.5/impacket/dcerpc/transport.py", line 301, in connect
    self.__handle = self.__smb_server.nt_create_andx(self.__tid, self.__filename)
  File "/var/lib/python-support/python2.5/impacket/smb.py", line 2033, in nt_create_andx
    if smb.isValidAnswer(SMB.SMB_COM_NT_CREATE_ANDX):
  File "/var/lib/python-support/python2.5/impacket/smb.py", line 611, in isValidAnswer
    raise SessionError, ("SMB Library Error", self['ErrorClass'], self['ErrorCode'])
impacket.smb.SessionError: SessionError: ('S', 'M', 'B', ' ', 'L', 'i', 'b', 'r', 'a', 'r', 'y', ' ', 'E', 'r', 'r', 'o', 'r'), class: ERRDOS, code: ERRnoaccess(Access denied.)

Um dem auch zu begegnen lässt sich in der Datei samrdump.py eine neue Variable debug einführen worüber sich steuern lässt ob ein Traceback angezeigt werden soll oder nicht.

25
26 debug = 0       #new debug variable for traceback controlling
27
...
68             except Exception, e:
69                 print 'Protocol failed: %s' % e
70                 if debug == 1:
71                         raise
72             else:

So schnell wird man "sinnlose" Fehlermeldungen los ;)

Zu guter Letzt finde ich es immer sinnvoll wenn man nicht nur einzelne IP Adressen angeben kann, sondern ganze Files mit IP Listen laden kann. Folgende Ergänzungen ermöglichen in Zukunft die Angabe eines Files an Stelle der Adresse:

22 import os
...
175         print "address could also be a file with one IP per line"
176         sys.exit(1)
177
178     import re
179
180     username, password, address = re.compile('(?:([^@:]*)(?::([^@]*))?@)?(.*)').match(sys.argv[1]).    groups('')
181
182     if len(sys.argv) > 2:
183         dumper = SAMRDump(sys.argv[2:], username, password)
184     else:
185         dumper = SAMRDump(username = username, password = password)
186
187     if os.path.isfile(address):
188         addressfile = open(address, "r")
189         for address in addressfile.readlines():
190                 dumper.dump(address)
191     else:
192         dumper.dump(address)

Attached findet ihr die geänderten Files.

mIke

AttachmentSize
samr-v1.8.py_.txt23.48 KB
samrdump-v1.3.py_.txt6.33 KB