byt3bl33d3r / CrackMapExec

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

Using literal password '/dev/random' hangs or brute-forces instead of login (unique case) #272

Closed rewardone closed 4 years ago

rewardone commented 6 years ago

Steps to reproduce

  1. Attempt to login, list shares, etc while using an account whose password is '/dev/random' causes cme to hang (brute-force?).

Command string used

cme smb 127.0.0.1 -u user -p "/dev/random"

CME verbose output (using the --verbose flag)

(CrackMapExec-yAfY2G20) ➜ CrackMapExec git:(master) cme --verbose smb 127.0.0.1 -u user -p "/dev/random" DEBUG Passed args: {'clear_obfscripts': False, 'content': False, 'continue_on_success': False, 'cred_id': [], 'darrell': False, 'depth': None, 'disks': False, 'domain': None, 'exclude_dirs': '', 'exec_method': None, 'execute': None, 'fail_limit': None, 'force_ps32': False, 'gen_relay_list': None, 'gfail_limit': None, 'groups': None, 'hash': [], 'jitter': None, 'list_modules': False, 'local_auth': False, 'local_groups': None, 'loggedon_users': False, 'lsa': False, 'module': None, 'module_options': [], 'no_output': False, 'ntds': None, 'obfs': False, 'only_files': False, 'pass_pol': False, 'password': ['/dev/random'], 'pattern': None, 'port': 445, 'protocol': 'smb', 'ps_execute': None, 'regex': None, 'rid_brute': None, 'sam': False, 'server': 'https', 'server_host': '0.0.0.0', 'server_port': None, 'sessions': False, 'share': 'C$', 'shares': False, 'show_module_options': False, 'spider': None, 'spider_folder': '.', 'target': ['127.0.0.1'], 'threads': 100, 'timeout': None, 'ufail_limit': None, 'username': ['tim'], 'users': None, 'verbose': True, 'wmi': None, 'wmi_namespace': 'root\cimv2'} DEBUG Error retrieving os arch of 127.0.0.1: Could not connect: [Errno 111] Connection refused SMB 127.0.0.1 445 INTERNAL [*] Windows Server (R) 2008 Standard 6001 Service Pack 1 (name:INTERNAL) (domain:INTERNAL) (signing:False) (SMBv1:True)

<hangs here until CTRL+C>

CME Version (cme --version)

4.0.1dev - Bug Pr0n

OS

PRETTY_NAME="Kali GNU/Linux Rolling" NAME="Kali GNU/Linux" ID=kali VERSION="2018.4" VERSION_ID="2018.4"

Target OS

Windows Server 2008

Detailed issue explanation

It seems there is a unique use case where the password for a user is "/dev/random". Upon passing the password, CrackMapExec (v4.0.1dev) hangs. Upon CTRL+C, it looks like it hangs attempting to use /dev/random like a file, and brute force through a list of passwords (unless 'for f_pass in password' is normal for single password logon).

(CrackMapExec-yAfY2G20) ➜  CrackMapExec git:(master) cme smb 127.0.0.1 -u user -p "/dev/random"                                                                                        
SMB         127.0.0.1       445    INTERNAL         [*] Windows Server (R) 2008 Standard 6001 Service Pack 1 (name:INTERNAL) (domain:INTERNAL) (signing:False) (SMBv1:True)           
^C^C^CTraceback (most recent call last):
  File "src/gevent/greenlet.py", line 716, in gevent._greenlet.Greenlet.run
  File "/root/.local/share/virtualenvs/CrackMapExec-yAfY2G20/local/lib/python2.7/site-packages/crackmapexec-4.0.1.dev0-py2.7.egg/cme/protocols/smb.py", line 110, in __init__         
    connection.__init__(self, args, db, host)
  File "/root/.local/share/virtualenvs/CrackMapExec-yAfY2G20/local/lib/python2.7/site-packages/crackmapexec-4.0.1.dev0-py2.7.egg/cme/connection.py", line 41, in __init__             
    self.proto_flow()
  File "/root/.local/share/virtualenvs/CrackMapExec-yAfY2G20/local/lib/python2.7/site-packages/crackmapexec-4.0.1.dev0-py2.7.egg/cme/connection.py", line 73, in proto_flow           
    self.login()
  File "/root/.local/share/virtualenvs/CrackMapExec-yAfY2G20/local/lib/python2.7/site-packages/crackmapexec-4.0.1.dev0-py2.7.egg/cme/connection.py", line 219, in login               
    for f_pass in password:
KeyboardInterrupt
2018-10-20T16:31:52Z <Greenlet "Greenlet-0" at 0x7f4415bc6ba8: smb(Namespace(clear_obfscripts=False, content=False, c, <protocol.database instance at 0x7f4417f1e7a0>, '127.0.0.1')> failed with KeyboardInterrupt

Using --verbose flag shows that "/dev/random" is indeed being used as the password.

Attempting to escape the password results in an incorrect login

(CrackMapExec-yAfY2G20) ➜  CrackMapExec git:(master) cme smb 127.0.0.1 -u user -p "\/dev\/random"                                                                                      
SMB         127.0.0.1       445    INTERNAL         [*] Windows Server (R) 2008 Standard 6001 Service Pack 1 (name:INTERNAL) (domain:INTERNAL) (signing:False) (SMBv1:True)           
SMB         127.0.0.1       445    INTERNAL         [-] INTERNAL\tim:\/dev\/random STATUS_LOGON_FAILURE   

Attempting to escape the password without quotes causes CrackMapExec to reproduce the error as well (CrackMapExec-yAfY2G20) ➜ CrackMapExec git:(master) cme --verbose smb 127.0.0.1 -u user -p \/dev\/random

Interestingly, it seems to be a unique edge case with just /dev/random, as using /dev/something correctly attempts to login (and correctly results in logon failure).

(CrackMapExec-yAfY2G20) ➜  CrackMapExec git:(master) cme smb 127.0.0.1 -u user -p "/dev/something" 
SMB         127.0.0.1       445    INTERNAL         [*] Windows Server (R) 2008 Standard 6001 Service Pack 1 (name:INTERNAL) (domain:INTERNAL) (signing:False) (SMBv1:True)           
SMB         127.0.0.1       445    INTERNAL         [-] INTERNAL\tim:/dev/something STATUS_LOGON_FAILURE 

A workaround for this is to use a password file containing /dev/random. This will process the login correctly.

(CrackMapExec-yAfY2G20) ➜  CrackMapExec git:(master) cat /file/user_password                                                                                                                
/dev/random# 
(CrackMapExec-yAfY2G20) ➜  CrackMapExec git:(master) cme --verbose smb 127.0.0.1 -u user -p /file/user_password
DEBUG Passed args:
{'clear_obfscripts': False,
 'content': False,
 'continue_on_success': False,
 'cred_id': [],
 'darrell': False,
 'depth': None,
 'disks': False,
 'domain': None,
 'exclude_dirs': '',
 'exec_method': None,
 'execute': None,
 'fail_limit': None,
 'force_ps32': False,
 'gen_relay_list': None,
 'gfail_limit': None,
 'groups': None,
 'hash': [],
 'jitter': None,
 'list_modules': False,
 'local_auth': False,
 'local_groups': None,
 'loggedon_users': False,
 'lsa': False,
 'module': None,
 'module_options': [],
 'no_output': False,
 'ntds': None,
 'obfs': False,
 'only_files': False,
 'pass_pol': False,
 'password': ['/file/user_password'],
 'pattern': None,
 'port': 445,
 'protocol': 'smb',
 'ps_execute': None,
 'regex': None,
 'rid_brute': None,
 'sam': False,
 'server': 'https',
 'server_host': '0.0.0.0',
 'server_port': None,
 'sessions': False,
 'share': 'C$',
 'shares': False,
 'show_module_options': False,
 'spider': None,
 'spider_folder': '.',
 'target': ['127.0.0.1'],
 'threads': 100,
 'timeout': None,
 'ufail_limit': None,
 'username': ['tim'],
 'users': None,
 'verbose': True,
 'wmi': None,
 'wmi_namespace': 'root\\cimv2'}
DEBUG Error retrieving os arch of 127.0.0.1: Could not connect: [Errno 111] Connection refused
SMB         127.0.0.1       445    INTERNAL         [*] Windows Server (R) 2008 Standard 6001 Service Pack 1 (name:INTERNAL) (domain:INTERNAL) (signing:False) (SMBv1:True)
DEBUG add_credential(credtype=plaintext, domain=INTERNAL, username=user, password=/dev/random, groupid=None, pillaged_from=None) => None
SMB         127.0.0.1       445    INTERNAL         [+] INTERNAL\user:/dev/random
byt3bl33d3r commented 6 years ago

Can you try enclosing the password in single quotes instead of double? e.g. '/dev/random'

Adding the dafuq tag cause this is weird.

rewardone commented 6 years ago

sure, sorry it wasn't one of my previous test cases.

(CrackMapExec-yAfY2G20) ➜  CrackMapExec git:(master) cme --verbose smb 127.0.0.1 -u user -p '/dev/random'
DEBUG Passed args:
{'clear_obfscripts': False,
 'content': False,
 'continue_on_success': False,
 'cred_id': [],
 'darrell': False,
 'depth': None,
 'disks': False,
 'domain': None,
 'exclude_dirs': '',
 'exec_method': None,
 'execute': None,
 'fail_limit': None,
 'force_ps32': False,
 'gen_relay_list': None,
 'gfail_limit': None,
 'groups': None,
 'hash': [],
 'jitter': None,
 'list_modules': False,
 'local_auth': False,
 'local_groups': None,
 'loggedon_users': False,
 'lsa': False,
 'module': None,
 'module_options': [],
 'no_output': False,
 'ntds': None,
 'obfs': False,
 'only_files': False,
 'pass_pol': False,
 'password': ['/dev/random'],
 'pattern': None,
 'port': 445,
 'protocol': 'smb',
 'ps_execute': None,
 'regex': None,
 'rid_brute': None,
 'sam': False,
 'server': 'https',
 'server_host': '0.0.0.0',
 'server_port': None,
 'sessions': False,
 'share': 'C$',
 'shares': False,
 'show_module_options': False,
 'spider': None,
 'spider_folder': '.',
 'target': ['127.0.0.1'],
 'threads': 100,
 'timeout': None,
 'ufail_limit': None,
 'username': ['tim'],
 'users': None,
 'verbose': True,
 'wmi': None,
 'wmi_namespace': 'root\\cimv2'}
DEBUG Error retrieving os arch of 127.0.0.1: Could not connect: [Errno 111] Connection refused
SMB         127.0.0.1       445    INTERNAL         [*] Windows Server (R) 2008 Standard 6001 Service Pack 1 (name:INTERNAL) (domain:INTERNAL) (signing:False) (SMBv1:True)
^C^CTraceback (most recent call last):
  File "src/gevent/greenlet.py", line 716, in gevent._greenlet.Greenlet.run
  File "/root/.local/share/virtualenvs/CrackMapExec-yAfY2G20/local/lib/python2.7/site-packages/crackmapexec-4.0.1.dev0-py2.7.egg/cme/protocols/smb.py", line 110, in __init__
    connection.__init__(self, args, db, host)
  File "/root/.local/share/virtualenvs/CrackMapExec-yAfY2G20/local/lib/python2.7/site-packages/crackmapexec-4.0.1.dev0-py2.7.egg/cme/connection.py", line 41, in __init__
    self.proto_flow()
  File "/root/.local/share/virtualenvs/CrackMapExec-yAfY2G20/local/lib/python2.7/site-packages/crackmapexec-4.0.1.dev0-py2.7.egg/cme/connection.py", line 73, in proto_flow
    self.login()
  File "/root/.local/share/virtualenvs/CrackMapExec-yAfY2G20/local/lib/python2.7/site-packages/crackmapexec-4.0.1.dev0-py2.7.egg/cme/connection.py", line 219, in login
    for f_pass in password:
KeyboardInterrupt
2018-10-20T19:34:38Z <Greenlet "Greenlet-0" at 0x7f10b5d18ba8: smb(Namespace(clear_obfscripts=False, content=False, c, <protocol.database instance at 0x7f10b80757a0>, '127.0.0.1')> failed with KeyboardInterrupt

Same issue.

I honestly don't think it's worth putting a lot of time/effort into a fix since this is more of a "CTF" problem and this particular password will be found if it's put in a brute-force list, but I wanted to make mention of it somewhere in case someone somewhere else happened into the same thing.

I think I may also be behind the Github master branch in terms of versions?

rewardone commented 6 years ago

Another thought for troubleshooting, here's a packet dump. I can provide the raw data if needed, but the traffic simply stops.

listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
14:40:51.455142 IP 127.0.0.1.60860 > 127.0.0.1.445: Flags [S], seq 778855716, win 43690, options [mss 65495,sackOK,TS val 3287433564 ecr 0,nop,wscale 7], length 0                    
14:40:51.455156 IP 127.0.0.1.445 > 127.0.0.1.60860: Flags [S.], seq 1365980003, ack 778855717, win 43690, options [mss 65495,sackOK,TS val 3287433564 ecr 3287433564,nop,wscale 7], length 0
14:40:51.455166 IP 127.0.0.1.60860 > 127.0.0.1.445: Flags [.], ack 1, win 342, options [nop,nop,TS val 3287433564 ecr 3287433564], length 0                                           
14:40:51.455567 IP 127.0.0.1.60860 > 127.0.0.1.445: Flags [P.], seq 1:52, ack 1, win 342, options [nop,nop,TS val 3287433565 ecr 3287433564], length 51 SMB PACKET: SMBnegprot (REQUEST)

14:40:51.607190 IP 127.0.0.1.445 > 127.0.0.1.60860: Flags [P.], seq 1:120, ack 52, win 342, options [nop,nop,TS val 3287433716 ecr 3287433565], length 119 SMB PACKET: SMBnegprot (REPLY)

14:40:51.607210 IP 127.0.0.1.60860 > 127.0.0.1.445: Flags [.], ack 120, win 342, options [nop,nop,TS val 3287433716 ecr 3287433716], length 0                                         
14:40:51.608958 IP 127.0.0.1.60860 > 127.0.0.1.445: Flags [P.], seq 52:192, ack 120, win 342, options [nop,nop,TS val 3287433718 ecr 3287433716], length 140 SMB PACKET: SMBsesssetupX
(REQUEST)

14:40:51.608980 IP 127.0.0.1.445 > 127.0.0.1.60860: Flags [.], ack 192, win 350, options [nop,nop,TS val 3287433718 ecr 3287433718], length 0                                         
14:40:51.659384 IP 127.0.0.1.445 > 127.0.0.1.60860: Flags [P.], seq 120:456, ack 192, win 350, options [nop,nop,TS val 3287433768 ecr 3287433718], length 336 SMB PACKET: SMBsesssetupX (REPLY)

14:40:51.661629 IP 127.0.0.1.60860 > 127.0.0.1.445: Flags [P.], seq 192:339, ack 456, win 350, options [nop,nop,TS val 3287433771 ecr 3287433768], length 147 SMB PACKET: SMBsesssetupX (REQUEST)

14:40:51.661655 IP 127.0.0.1.445 > 127.0.0.1.60860: Flags [.], ack 339, win 359, options [nop,nop,TS val 3287433771 ecr 3287433771], length 0                                         
14:40:51.711278 IP 127.0.0.1.445 > 127.0.0.1.60860: Flags [P.], seq 456:602, ack 339, win 359, options [nop,nop,TS val 3287433820 ecr 3287433771], length 146 SMB PACKET: SMBsesssetupX (REPLY)

14:40:51.713419 IP 127.0.0.1.60860 > 127.0.0.1.445: Flags [P.], seq 339:382, ack 602, win 359, options [nop,nop,TS val 3287433822 ecr 3287433820], length 43 SMB PACKET: SMBulogoffX (REQUEST)

14:40:51.713440 IP 127.0.0.1.445 > 127.0.0.1.60860: Flags [.], ack 382, win 359, options [nop,nop,TS val 3287433822 ecr 3287433822], length 0                                         
14:40:51.768692 IP 127.0.0.1.445 > 127.0.0.1.60860: Flags [P.], seq 602:645, ack 382, win 359, options [nop,nop,TS val 3287433878 ecr 3287433822], length 43 SMB PACKET: SMBulogoffX (REPLY)

14:40:51.769602 IP 127.0.0.1.60864 > 127.0.0.1.445: Flags [S], seq 833526310, win 43690, options [mss 65495,sackOK,TS val 3287433879 ecr 0,nop,wscale 7], length 0                    
14:40:51.769611 IP 127.0.0.1.445 > 127.0.0.1.60864: Flags [S.], seq 3336422803, ack 833526311, win 43690, options [mss 65495,sackOK,TS val 3287433879 ecr 3287433879,nop,wscale 7], length 0
14:40:51.769619 IP 127.0.0.1.60864 > 127.0.0.1.445: Flags [.], ack 1, win 342, options [nop,nop,TS val 3287433879 ecr 3287433879], length 0                                           
14:40:51.769928 IP 127.0.0.1.60864 > 127.0.0.1.445: Flags [P.], seq 1:52, ack 1, win 342, options [nop,nop,TS val 3287433879 ecr 3287433879], length 51 SMB PACKET: SMBnegprot (REQUEST)

14:40:51.769933 IP 127.0.0.1.445 > 127.0.0.1.60864: Flags [.], ack 52, win 342, options [nop,nop,TS val 3287433879 ecr 3287433879], length 0                                          
14:40:51.811190 IP 127.0.0.1.60860 > 127.0.0.1.445: Flags [.], ack 645, win 359, options [nop,nop,TS val 3287433920 ecr 3287433878], length 0                                         
14:40:51.873516 IP 127.0.0.1.445 > 127.0.0.1.60864: Flags [P.], seq 1:120, ack 52, win 342, options [nop,nop,TS val 3287433982 ecr 3287433879], length 119 SMB PACKET: SMBnegprot (REPLY)

14:40:51.873537 IP 127.0.0.1.60864 > 127.0.0.1.445: Flags [.], ack 120, win 342, options [nop,nop,TS val 3287433982 ecr 3287433982], length 0 
14:42:54.795004 IP 127.0.0.1.445 > 127.0.0.1.60860: Flags [F.], seq 645, ack 382, win 359, options [nop,nop,TS val 3287556905 ecr 3287433920], length 0                               
14:42:54.795023 IP 127.0.0.1.445 > 127.0.0.1.60864: Flags [F.], seq 120, ack 52, win 342, options [nop,nop,TS val 3287556906 ecr 3287433982], length 0                                
14:42:54.835098 IP 127.0.0.1.60864 > 127.0.0.1.445: Flags [.], ack 121, win 342, options [nop,nop,TS val 3287556946 ecr 3287556906], length 0                                         
14:42:54.835171 IP 127.0.0.1.60860 > 127.0.0.1.445: Flags [.], ack 646, win 359, options [nop,nop,TS val 3287556946 ecr 3287556905], length 0 
awsmhacks commented 6 years ago

I'm pretty sure i figured this out. The -p switch was designed to take either a file or string. std_parser.add_argument("-p", metavar="PASSWORD", dest='password', nargs='+', default=[], help="password(s) or file(s) containing passwords") Doing it this way argparse has no way of knowing that you want to reference the literal string. Will need to either add another switch to tell it how to interpret the input (gross), or change it to be something close to: -p will define a type=string and add new switch option -P will take a password file.

awsmhacks commented 6 years ago

I can work on a quick fix as long as someone i know doesnt get to it first 😄

byt3bl33d3r commented 5 years ago

@awsmhacks as much as i'd like -p to accept everything, I'm probably going to be doing exactly that in the re-write as it simplifies the code and removes weird edgecases like this.

offsecginger commented 4 years ago

I Lol'd thinking about the logs this probably generated. Great CTF idea though!

mpgn commented 4 years ago

TLDR: put the username into a file 👍