byt3bl33d3r / CrackMapExec

A swiss army knife for pentesting networks
BSD 2-Clause "Simplified" License
8.29k stars 1.64k forks source link

Current master: Indexing SMB shares triggers stacktrace on exit and on export to CSV #775

Open sandervandegeijn opened 1 year ago

sandervandegeijn commented 1 year ago

Describe the bug Indexed 2500+ hosts successfully, then it gives the stack trace below. This happens after the last host in the list. Command executed:

crackmapexec smb hosts.up -u user -p pass --shares

hosts.up contains one ip per line.

Traceback (most recent call last):
  File "/usr/local/bin/crackmapexec", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/usr/local/lib/python3.11/site-packages/cme/crackmapexec.py", line 257, in main
    asyncio.run(
  File "/usr/local/lib/python3.11/asyncio/runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/cme/crackmapexec.py", line 105, in start_threadpool
    await asyncio.gather(*jobs)
  File "/usr/local/lib/python3.11/site-packages/cme/crackmapexec.py", line 69, in run_protocol
    await asyncio.wait_for(
  File "/usr/local/lib/python3.11/asyncio/tasks.py", line 442, in wait_for
    return await fut
           ^^^^^^^^^
  File "/usr/local/lib/python3.11/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/cme/protocols/smb.py", line 143, in __init__
    connection.__init__(self, args, db, host)
  File "/usr/local/lib/python3.11/site-packages/cme/connection.py", line 65, in __init__
    self.proto_flow()
  File "/usr/local/lib/python3.11/site-packages/cme/connection.py", line 101, in proto_flow
    if self.login() or (self.username == '' and self.password == ''):
       ^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/cme/connection.py", line 300, in login
    elif self.plaintext_login(self.domain, user, password): return True
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/cme/protocols/smb.py", line 450, in plaintext_login
    self.conn.login(self.username, self.password, domain)
  File "/usr/local/lib/python3.11/site-packages/impacket/smbconnection.py", line 276, in login
    return self._SMBConnection.login(user, password, domain, lmhash, nthash, ntlmFallback)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/impacket/smb.py", line 3494, in login
    self.login_extended(user, password, domain, lmhash, nthash, use_ntlmv2 = True)
  File "/usr/local/lib/python3.11/site-packages/impacket/smb.py", line 3402, in login_extended
    type3, exportedSessionKey = ntlm.getNTLMSSPType3(auth, respToken['ResponseToken'], user, password, domain, lmhash, nthash, use_ntlmv2 = use_ntlmv2)
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/impacket/ntlm.py", line 634, in getNTLMSSPType3
    ntResponse, lmResponse, sessionBaseKey = computeResponse(ntlmChallenge['flags'], ntlmChallenge['challenge'],
                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/impacket/ntlm.py", line 42, in computeResponse
    return computeResponseNTLMv2(flags, serverChallenge, clientChallenge, serverName, domain, user, password,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/impacket/ntlm.py", line 907, in computeResponseNTLMv2
    av_pairs = AV_PAIRS(serverName)
               ^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/impacket/ntlm.py", line 210, in __init__
    self.fromString(data)
  File "/usr/local/lib/python3.11/site-packages/impacket/ntlm.py", line 233, in fromString
    fType = struct.unpack('<H',tInfo[:struct.calcsize('<H')])[0]
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The shares seem to be in the database, so I tried to export it:

cmedb (default)(smb) > export shares detailed shares.csv

Traceback (most recent call last):
  File "/usr/local/bin/cmedb", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/usr/local/lib/python3.11/site-packages/cme/cmedb.py", line 400, in main
    cmedbnav = CMEDBMenu(config_path)
               ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/cme/cmedb.py", line 300, in __init__
    self.do_proto(self.db)
  File "/usr/local/lib/python3.11/site-packages/cme/cmedb.py", line 326, in do_proto
    proto_menu.cmdloop()
  File "/usr/local/lib/python3.11/cmd.py", line 138, in cmdloop
    stop = self.onecmd(line)
           ^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/cmd.py", line 217, in onecmd
    return func(arg)
           ^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/cme/cmedb.py", line 137, in do_export
    entry.append(self.db.get_computers(share[1])[0][2])
                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^
IndexError: list index out of range

To Reproduce Steps to reproduce the behavior: see above

Expected behavior Don't trigger the error

Screenshots If applicable, add screenshots to help explain your problem.

Crackmapexec info Master [d2ea13f] Built a docker container from the Docker file on RHEL7.

Additional context

sandervandegeijn commented 1 year ago

Don't know if this is the same error:

SMB         10.1.1.1      445    SERVER        [-] Connection Error: The NETBIOS connection with the remote host timed out.
Traceback (most recent call last):
  File "/usr/local/bin/cme", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/usr/local/lib/python3.11/site-packages/cme/crackmapexec.py", line 257, in main
    asyncio.run(
  File "/usr/local/lib/python3.11/asyncio/runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/cme/crackmapexec.py", line 105, in start_threadpool
    await asyncio.gather(*jobs)
  File "/usr/local/lib/python3.11/site-packages/cme/crackmapexec.py", line 69, in run_protocol
    await asyncio.wait_for(
  File "/usr/local/lib/python3.11/asyncio/tasks.py", line 442, in wait_for
    return await fut
           ^^^^^^^^^
  File "/usr/local/lib/python3.11/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/cme/protocols/smb.py", line 143, in __init__
    connection.__init__(self, args, db, host)
  File "/usr/local/lib/python3.11/site-packages/cme/connection.py", line 65, in __init__
    self.proto_flow()
  File "/usr/local/lib/python3.11/site-packages/cme/connection.py", line 101, in proto_flow
    if self.login() or (self.username == '' and self.password == ''):
       ^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/cme/connection.py", line 300, in login
    elif self.plaintext_login(self.domain, user, password): return True
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/cme/protocols/smb.py", line 450, in plaintext_login
    self.conn.login(self.username, self.password, domain)
  File "/usr/local/lib/python3.11/site-packages/impacket/smbconnection.py", line 278, in login
    return self._SMBConnection.login(user, password, domain, lmhash, nthash)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/impacket/smb3.py", line 952, in login
    packetID = self.sendSMB(packet)
               ^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/impacket/smb3.py", line 455, in sendSMB
    self._NetBIOSSession.send_packet(data)
  File "/usr/local/lib/python3.11/site-packages/impacket/nmb.py", line 912, in send_packet
    self._sock.sendall(p.rawData())
BrokenPipeError: [Errno 32] Broken pipe
Marshall-Hallenbeck commented 1 year ago

@ict-one-nl is there anyway you can share the data of the last share line? I can guess what the issue is, but without the actual data (or a representation of the data, filtered to protect sensitive information) it's hard to be exact.

sandervandegeijn commented 1 year ago

Sorry for the slow response - been on holiday and forgot afterwards. What data would you need? I'll see if I can make it happen.

Marshall-Hallenbeck commented 1 year ago

@ict-one-nl that's alright. Would it be possible for you to run cmedb and check if the host it is trying to print a share for actually exists in the CME DB?

sandervandegeijn commented 1 year ago

I'm having difficulty to pinpoint the data where it hurts, to diagnose I need to do this locally but that would alert the SOC. I'll try to have another go next week during business hours if I find the time. Did come across another stack trace.

ERROR:asyncio:Exception in callback BaseSelectorEventLoop._add_reader(0, <bound method...rt fd=0 idle>>)
handle: <Handle BaseSelectorEventLoop._add_reader(0, <bound method...rt fd=0 idle>>)>
Traceback (most recent call last):
  File "/usr/local/lib/python3.11/asyncio/selector_events.py", line 265, in _add_reader
    key = self._selector.get_key(fd)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/selectors.py", line 192, in get_key
    raise KeyError("{!r} is not registered".format(fileobj)) from None
KeyError: '0 is not registered'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.11/asyncio/events.py", line 80, in _run
    self._context.run(self._callback, *self._args)
  File "/usr/local/lib/python3.11/asyncio/selector_events.py", line 267, in _add_reader
    self._selector.register(fd, selectors.EVENT_READ,
  File "/usr/local/lib/python3.11/selectors.py", line 359, in register
    self._selector.register(key.fd, poller_events)
PermissionError: [Errno 1] Operation not permitted
NeffIsBack commented 1 year ago

Do you have access to the sponsored version? There will soon be a fix for the export. The crash is likely caused when an error occures while adding a host to the database. Therefore the export of the shares crashes when trying to access the corresponding (missing) host.

The new error seems to be caused by an external package, not sure if we can do something about it. But the sponsored version has better error handling over all, maybe that helps.

sandervandegeijn commented 1 year ago

Not yet... I'm considering it, need to get approval (working for a university). That's just a question of pressing the buy link on https://porchetta.industries/subscriptions?selected=year right? :)

mpgn commented 1 year ago

We will push the private version soon on the public repo if you want to wait

sandervandegeijn commented 1 year ago

Will the public and the private version merge? Not that we're not willing to pay, two separate things :)

mpgn commented 1 year ago

yes, it will be merged together

sandervandegeijn commented 1 year ago

Okay, will retest after the merge. :)