2017 SCTF Buildingblocks
by St1tchProb
- Score : 250
Challenge
- 이 문제는 문제설명에도 적혀있다시피 base64로 encode된 x64 machine code를 11개 정도 준다. 이 machine code를 1개를 실행시키던, 전부 실행시키던, 순서를 뒤죽박죽 시키던 정상적으로 실행이 되는 순서조합의 machine code를 보내면 stage를 통과하는 그런 류의 문제이다.(실제로는 주어진 machine code를 모두 사용하는 경우밖에 보지 못한 것 같다.)
Solution
- 11개라고 가정했을 때, 모든 permutation을 검증을 하기에는 stage한개에 대한 최적의 실행순서를 찾는데도 오랜 시간이 걸린다.
- 따라서 해당 순서에 실행이 되는 machine code가 있으면, 재귀적으로 다음 machine code를 실행해서, 유효한 machine code만 우선 실행시키는 방법을 사용하여, 트리순회와 같은 느낌으로 machine code의 실행결과를 검증하면 된다.
- 예를들어, 6 번 째의 machine code가 첫 번째 순서에 있을 때 실행이 된다면, 이 machine code가 첫 번째에 올 때의 모든 경우를 생각한다. 재귀적으로 두 번째 순서에 나머지 machine code를 넣어보고 유효한 machine 코드의 목록들에 대해서 다시 재귀적으로 탐색한다. 즉, 해당 순서에 대해 유효한 machine code에 대해 dfs탐색을 한다고 생각하면 된다.
- x64 machine code가 segment fault 없이 제대로 실행이 되는지 확인하는 방법으로는 python 모듈중에 unicorn 모듈을 사용하여 확인을 했다. 사실 여러가지 방법이 있겠지만 unicorn모듈을 통해 가상 emulate를 간단하게 할 수 있기 때문에 이 방법을 사용했다.
Solve
from __future__ import print_function
from unicorn import *
from unicorn.x86_const import *
from pwn import *
from base64 import b64encode, b64decode
def emulator(OPCODE):
ADDRESS = 0x1000000
try:
mu = Uc(UC_ARCH_X86, UC_MODE_64)
mu.mem_map(ADDRESS, 2 * 1024 * 1024)
mu.mem_write(ADDRESS, OPCODE)
mu.emu_start(ADDRESS, ADDRESS + len(OPCODE))
return True
except UcError as e:
return False
def recursion(opcode, cur, depth, dict_):
if depth > len(opcode):
return
opcodes = []
for op in opcode:
if op not in cur:
opcodes.append(op)
for op in opcodes:
exec_op = ''.join(cur) + op
if emulator(exec_op):
dict_[len(exec_op)] = cur+[op]
recursion(opcode, cur + [op], depth+1, dict_)
def solver():
p = log.progress('start...')
cnt = 1
while True:
try:
dat = s.recvuntil(':', drop=True)
block = eval(dat[dat.index('['):dat.index(']')+1])
dict_ = {}
recursion(map(b64decode, block), [], 0, dict_)
s.sendline(sha256sumhex(''.join(sorted(dict_.items())[::-1][0][1])))
p.status('stage{}'.format(cnt))
cnt += 1
except:
log.success('get flag!')
s.interactive()
break
if __name__ == '__main__':
s = remote('buildingblocks.eatpwnnosleep.com', 46115)
solver()
Result
블로그의 정보
튜기's blogg(st1tch)
St1tch