ED 303: Windows Stack Protection III: Limitations of ASLR (15 pts)

What You Need

Purpose

Examine ASLR on Windows in more detail.

Here's what Microsoft says about ASLR randomness:

It seems like there's a 1 in 256 chance of guessing correctly for many EXE files!

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 Studion 2017", and click "Developer Command Prompt for VS 2017", as shown below.

Making the esp3 Program in C++

In the Developer Command Prompt window, execute these commands:
mkdir c:\127a
cd c:\127a
notepad esp3.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 << hex << data << endl;
}

In Notepad, click File, Save.

Compiling the Program Normally

In the Developer Command Prompt window, execute these commands:
cl /EHsc esp3.cpp
esp3.exe
esp3.exe
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 esp3.cpp esp4.cpp
cl /EHsc /c esp4.cpp
link /DYNAMICBASE:NO esp4.obj
esp4.exe
esp4.exe
The ESP value remains the same each time the program runs, as shown below, because ASLR is turned off for this application.

Task 2: Testing the Randomness of ASLR

We'll make a simple Python script to see how often ASLR fails.

In the Developer Command Prompt window, execute these commands:

cd c:\127a
notepad test.py
A box pops up, asking "Do you want to create a new file?". Click Yes.

Enter this code, as shown below. It will run the esp3.exe program 5 times and print out the results.

import os
for i in range(5):
  os.system("esp3.exe")

In Notepad, click File, Save.

Running the Program

In the Developer Command Prompt window, execute this commands:
c:\python27\python test.py
The results are all different, as shown below.

Running the Program 10000 Times

In the Developer Command Prompt window, execute this command:
notepad test.py
Change the "5" to "10000", as shown below.

In Notepad, click File, Save.

Running the Program

In the Developer Command Prompt window, execute this command:
c:\python27\python test.py > 10k.txt
It will take about three minutes to run. There are no visible results, because they all go into the "10k.txt" file, as shown below.

How Random Are They?

In the Developer Command Prompt window, execute this command:
notepad 10k.txt
The numbers appear random, as shown below, but how random are they?

Finding Matching Lines

We'll use a simple Python script to find addresses near the address we got from "esp4.exe", the program without ASLR.

In the Developer Command Prompt window, execute this command:

notepad count.py
A box pops up, asking "Do you want to create a new file?". Click Yes.

Enter this code, as shown below. It will print all the lines starting with 19ff.

import re
f = open("10k.txt", "r")
for line in f:
   if re.match("^19ff", line):
      print(line)

In Notepad, click File, Save.

Running the Program

In the Developer Command Prompt window, execute this commands:
c:\python27\python count.py
As shown above, several lines match. These matches show cases in which an exploit with a 256-byte NOP sled would work despite ASLR.

As you can see, when I did it, the chance was 2 in 10,000.

ED 303.1: Analyze My File (5 pts)

In the Developer Command Prompt window, execute these commands:
bitsadmin /transfer debjob /download /priority normal https://www.samsclass.info/127/proj/ED303_10k.txt c:\127a\10k.txt

c:\python27\python count.py
The flag is covered by a green rectangle in the image below.

Task 3: Viewing Memory Sections

Running esp4.exe in Immunity

Launch Immunity.

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

Immunity loads the program.

From the Immunity menu bar, click Debug, Run.

From the Immunity menu bar, click View, Memory.

Notice the Address of these items, as shown below:

Reloading esp4.exe in Immunity

From the Immunity menu bar, click Debug, Restart.

From the Immunity menu bar, click Debug, Run.

From the Immunity menu bar, click View, Memory.

Notice that the esp4 memory addresses remain the same, as shown above, because ASLR is disabled for esp4.exe.

Viewing Memory Sections from C++

In the Developer Command Prompt window, execute these commands:
cd c:\127a
notepad mem.cpp
A box pops up, asking "Do you want to create a new file?". Click Yes.

Enter this code, as shown below.

#include <cstdio>  
#include <cstdlib>  
#include <iostream>  
using namespace std;  

int d;                        /* in .data section */

void main()
{
    int i=1, j;
    int * p;                 /* pointer */

    char buf[5];             /* Activate stack cookie protection */
    strcpy(buf, "HERE");     /* To help find code in IDA */	

    __asm {mov edx, LABEL
          mov d, edx
          LABEL: NOP};       /* in .text */

    char * heapbuf;
    heapbuf = (char*) malloc(1); 	/* on heap */

    printf("Address in .text: %08x\n", d);
    printf("Address in .data: %08p\n", (void *) &d);
    printf("Address in .heap: %08p\n", (void *) heapbuf);
    printf("Address in stack: %08p\n", (void *) &i);

    printf("\nStack:\n");
    p = &i;
    for (j=0; j<9; j++) {
        printf("%d %08p %08x\n", j, (void *) p, *p);
        p++;
    }
    __asm int 3
}

In Notepad, click File, Save.

Compiling the Program with All Protections

In the Developer Command Prompt window, execute these commands. This compiles the program with ASLR enabled, and with stack cookies.
cl /EHsc mem.cpp
mem.exe
The program runs, showing memory information, as shown below, and then crashes when it hits the "INT 3".

In the box showing "mem.exe has stopped working", click the "Close program" button.

Viewing Memory Usage for mem.exe in Immunity

Launch Immunity Debugger.

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

Immunity loads the program.

From the Immunity menu bar, click Debug, Run.

From the Immunity menu bar, click View, Memory.

Press Alt + Tab to make the Command Prompt running "mem.exe" visible, as shown below.

Notice these items:

Viewing the Stack

From the Immunity menu bar, click View, CPU.

Press Alt + Tab to make the Command Prompt running "mem.exe" visible, as shown below.

Notice these items, referred to by the word number that count from 0 to 8 in the Command Prompt window:

Close Immunity.

Removing the INT 3

In the Developer Command Prompt window, execute these command to make a "mem1.cpp" file and edit it.
copy mem.cpp mem1.cpp
notepad mem1.cpp
Delete the "__asm int3" line, highlighted in the image below:

Save the file and close Notepad.

Execute these commands to compile the mem1 program with ASLR enabled, and with stack cookies.

cl /EHsc mem1.cpp
mem1.exe
The program runs, showing memory information, as shown below.

Animating the Display

In the Developer Command Prompt window, execute this command line:
cls && mem1.exe
By pressing Up-Arrow and then Enter, you can repeat the command several times to see what values change.

You should see the values outlined in yellow in the image below changing, while the other values stay the same.

Note these items:

Compiling the Program with No Protections

In the Developer Command Prompt window, execute these commands. This compiles the program with ASLR enabled, and with stack cookies.
copy mem1.cpp mem0.cpp
cl /EHsc /c /GS- mem0.cpp
link /DYNAMICBASE:NO mem0.obj
mem0.exe
The program runs, showing memory addresses, as shown below.

Notice that the .text section is near the classical value of 400000, which we've seen before.

Animating the Display

In the Developer Command Prompt window, execute this command line:
cls && mem0.exe
By pressing Up-Arrow and then Enter, you can repeat the command several times to see what values change.

You should see the values outlined in yellow in the image below changing, while the other values stay the same.

Note these items:

ED 303.2 Word 2 (10 pts)

Find the value of word 2 on the stack, covered by a green box in the image above. That's the flag.

References

Disable Program Has Stopped Working Error Dialog in Windows
Software defense: mitigating common exploitation techniques

Posted: 11-9-18
Typo in C code: i -> j 12-11-18
Updated extensively 4-25-2020
Updated for Windows 10 3-14-22