ED 302: Windows Stack Protection II: Exploit Without ASLR (15 pts)

What You Need

Purpose

Examine stack defenses on Windows in more detail.

Task 1: Observing ASLR on Windows

ASLR (Address Space Layout Randomization) prevents many buffer overflow exploits by making the location of the stack difficult to predict.

Launching a Developer Command Prompt

You must already have Visual C++ Build Tools installed.

Click the Start button, scroll to the V secton, expand "Visual Studio 2019", and click "Developer Command Prompt for VS 2019", as shown below.

Making the esp Program in C++

In the Developer Command Prompt window, execute these commands
(Skip the first command if you already did this in Project 301):
mkdir c:\127 
cd c:\127
notepad esp.cpp
A box pops up, asking "Do you want to create a new file?". Click Yes.

Enter this code, as shown below:

#include <iostream>  
using namespace std;  

void main() {
	int data = 0;   
	__asm {
	    mov data, esp
	}
   cout << "$esp = ";
   cout << hex << data;
   cout << "\n";

   cout << "Press Enter to continue\n";
   cin.ignore();
}

In Notepad, click File, Save.

Compiling the Program Normally

In the Developer Command Prompt window, execute these commands:
cl /EHsc esp.cpp
esp.exe
Press Enter. Execute esp.exe twice more.

The ESP value changes each time the program runs, as shown below. This happens because ASLR is activated by default in Windows.

Compiling the Program Without ASLR

In the Developer Command Prompt window, execute these commands:
copy esp.cpp esp2.cpp
cl /EHsc /c esp2.cpp
link /DYNAMICBASE:NO esp2.obj
esp2.exe
Press Enter. Execute esp2.exe twice more.

The ESP value remains the same each time the program runs, as shown below, because ASLR is turned off for this application.


Task 2: Making the Pwd3.exe Program

In the Developer Command Prompt window, execute these commands:
(skip first command if you are still in 127 folder)
cd c:\127
notepad pwd3.cpp
A box pops up, asking "Do you want to create a new file?". Click Yes.

Enter this code, as shown below.

This is a program we used in the early Linux projects, which has a simple buffer overflow vulnerability. It also discloses information about the stack address.

#include <iostream>  
using namespace std;  

int test_pw()
{
   char pin[10];
   int x=15, i, data = 0;   

   __asm {
      mov data, esp
   }
   cout << "$esp = ";
   cout << hex << data;
   cout << "\n";

   cout << "Enter password: ";
   cin >> pin; 
   for (i=0; i<10; i+=2) x = (x & pin[i]) | pin[i+1];
   if (x == 48) return 0;
   else return 1;
}

void main()
{
   if (test_pw()) cout << "Fail!\n";
   else cout << "You win!\n";
}

In Notepad, click File, Save.

Compiling the Program Without ASLR

In the Developer Command Prompt window, execute these commands, to compile and link the program without a stack cookie, and with ASLR disabled:
cl /EHsc /c /GS- pwd3.cpp
link /DYNAMICBASE:NO pwd3.obj
pwd3.exe
The program asks for a password. Enter any value and press Enter. The program says "Fail!", as shown below.


Task 3: Install Immunity and Mona

Uninstall Python

Click Start and type CONTROL

Open Control Panel. In the "Programs" section, click "Uninstall a program". If any versions of Python are installed, especially 64-bit versions, uninstall them.

This is necessary because Immunity needs to find the correct version of Python on your system and other versions cause Immunity to fail when running Mona.

Get Immunity

On your Windows machine, in a browser, go to

https://www.immunityinc.com/products/debugger/

Click the "Download Immunity Debugger Here" link, as shown below.

If that link is not working, use this alternate download link:

ImmunityDebugger_1_85_setup.exe

Install it with the default options. It will install Immunity and then install Python.

Installing MONA

MONA is a python module which gives Immunity the ability to list modules and search through them.

On your Windows machine, open a Web browser, and open this page:

https://github.com/corelan/mona

A Github page opens, as shown below.

On the left side, near the bottom, click mona.py.

On the right side of the page, right-click Raw, and click "Save Target As". Save the file in your Downloads folder.

Alternate Download Link

mona.7z

On the taskbar, click the yellow folder icon to open Windows Explorer. Navigate to your Downloads folder. Right-click mona and click Copy, as shown below.

In Windows Explorer, in the left pane, expand the Computer container.

Navigate to:

C:\Program Files (x86)\Immunity Inc\Immunity Debugger\PyCommands

In the right pane of Windows Explorer, right-click and click Paste.

A box pops up saying "You'll need to provide administrator permission...". Click Continue.

Mona appears in the window, as shown below.


Task 4: Debugging Pwd3.exe

Running pwd3.exe in Immunity

Launch Immunity.

From the Immunity menu bar, click File, Open. Navigate to C:\127\pwd3.exe and double-click it.

Immunity loads the program.

If the font is hard to read, on the top menu click Options and Appearance

Click Fonts. If no fonts are listed, click Colours, then click Fonts again.
Choose OEM Fixed Font, click Change. Type in a font size of 14, click Ok, and Ok

Right click in any of the black in the boxes, and choose Appearance, Font (all), OEM fixed font

Note that eip, in the top right pane, is in "ntdll", and that the program is "Paused", as indicated in the lower right corner, as shown below.

Immunity has loaded the program and paused.

From the Immunity menu bar, click Debug, Run.

Immunity pauses again immediately. Click Debug, Run again.

At the bottom of the Windows screen, in the taskbar, click the rightmost button to bring the Command Prompt running "pwd3.exe" to the front, as shown below.

Enter a password consisting of 32 letters: the letters A through H four times each, as shown below, and then press the Enter key.

AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHH

The program crashes, and the message at the bottom of the Immunity window says "Access violation when executing 48484848", as shown below.

In the top right pane of Immunity, notice that EIP contains 48484848. This is a classic buffer overflow exploit, letting us control the EIP.


Task 5: Finding the Target Address

Finding the Overflow

The lower right pane of Immunity shows the Stack at the point of the crash, as shown in the image above.

Notice the second word, marked "RETURN to pwd3.00409DF6 from pwd3.00401250". This was the code preceding the crash, so we want to look there.

In the lower right pane of Immunity, right-click the second line, as shown below, and click "Follow in Disassembler", as shown below.

Assembly code appears in the top left pane, as shown below.

In the top left pane, scroll to the top. The code starts at address 00401000. Scroll down a few screens until you find the string "Enter Password", as shown below.
You may have to drag the column wider.

The PUSH instruction at address 004011E5, puts a pointer to the string "Enter password:" onto the stack.

Note: If you cannot view the full address, you can drag the column wider.
Hover in between columns until your mouse changes to a line with two arrows and drag right.

The CALL at address 004011EF prints out the prompt message to the user.

The next "CALL" instruction, at address 00401200, takes input from the user, and it's where the buffer overflow happens.

Placing Breakpoints

Click the second CALL instruction after the line containing "Enter password:". In the example 2 images above, it's at address 00401200, but it may be different on your system.

Press F2 to set a breakpoint. If you are using a Mac, press fn+F2.

Set a second breakpoint on the next instruction after the CALL. In the example 2 images above, its at 00401205 and both addresses are highlighed in aqua.

Finding the "You Win!" Message

In the top left pane, scroll down a few pages, and find the "You Win!" Message, as shown below.

Make a note of the address of this instruction. In the image below, it's 00401270. This is the address we want to inject into the EIP.

Restarting the Program

From the Immunity menu bar, click Debug, Restart.

A "Process still active" box pops up. Click Yes.

From the Immunity menu bar, click Debug, Run.

Viewing the Stack Before the Overflow

Immunity hits the breakpoint and stops, as shown below.

On the top right, find the values of ESP and EBP, which are the top and bottom of the current stack frame. When I did it, the values were 19FF10 and 19FF30.

In the lower right pane, highlight the stack frame, as shown in the image below.

The word after EBP contains a RETURN pointer, at address 19FF34 in the image below.

Performing the Buffer Overflow

From the Immunity menu bar, click Debug, Run. Click Debug, Run again.

At the bottom of the desktop, in the taskbar, click the rightmost icon to bring the command prompt to the front.

Enter a password consisting of 32 letters: the letters A through H four times each, as shown below, and then press the Enter key.

AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHH

Immunity hits the second breakpoint and stops, as shown above.

In the stack, the address of the RETURN pointer now contains 48484848, as shown above, which are the ASCII letters "HHHH".

Inserting the Target Address

In the lower right pane of Immunity, right-click the line containing 48484848 and click Edit, as shown below.

Find the adress of the "You Win!" instruction, which you determined earlier. When I did it, that address was 401270, but your value may be different.

In the "Edit stack" box, click in the HEX +00 field and enter the address of the "You Win!" instruction in little-endian byte order, as shown below.

70 12 40 00

In the "Edit stack" box, click OK. Verify that the address appears correctly in the stack, as shown below.


ED 302.1: "You win!" (15 pts)

From the Immunity menu bar, click Debug, Run.

The program runs and terminates.

At the bottom of the desktop, in the taskbar, click the rightmost icon to bring the command prompt to the front.

The "You Win!" message appears, as shown below.

Notice the message at the bottom left of the Immunity window, covered by a green box in the image above. That's the flag.


Task 6: Writing an Exploit in Python

Launch a Developer Command Prompt window as you did before, and execute these commands:
cd c:\127
notepad exploit1.py
A box pops up, asking "Do you want to create a new file?". Click Yes.

Enter this code, as shown below. Adjust the last four bytes to match the "You Win!" address on your system, which you determined previously.

print "AAAABBBBCCCCDDDDEEEEFFFFGGGG\x70\x12\x40\x00"

In Notepad, click File, Save.

In the Command Prompt window, execute these commands:

c:\python27\python exploit1.py
c:\python27\python exploit1.py | pwd3.exe
The first command shows you the exploit text, which ends in several strange characters, and the second command runs the exploit, which results in the "You win!" message, as shown below.

Troubleshooting

If python won't run, open a new Administrator Command Prompt and execute these commands:
cd c:\Windows
mklink /H python.exe c:\python27\python.exe

References

Disable Program Has Stopped Working Error Dialog in Windows

Ported to Google Cloud by Travis Knapp-Prasek
Minor edits 8-2-19
Minor formatting edits 10-16-19
Second "Run" command added 4-18-2020