Skip to content

Instantly share code, notes, and snippets.

@dikim33
Last active May 28, 2017 02:38
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 dikim33/68dfeb4fa8c020fb84fefd7b172118f2 to your computer and use it in GitHub Desktop.
Save dikim33/68dfeb4fa8c020fb84fefd7b172118f2 to your computer and use it in GitHub Desktop.
RETriforce Files
push rbp
mov rbp,rsp
sub rsp,0x40
mov DWORD PTR [rbp-0x34],edi
mov QWORD PTR [rbp-0x40],rsi
mov QWORD PTR [rbp-0x30],0x0
mov QWORD PTR [rbp-0x28],0x0
mov QWORD PTR [rbp-0x20],0x0
mov QWORD PTR [rbp-0x18],0x0
mov BYTE PTR [rbp-0x30],0x66
mov BYTE PTR [rbp-0x2f],0x6c
mov BYTE PTR [rbp-0x2e],0x61
mov BYTE PTR [rbp-0x2d],0x67
mov BYTE PTR [rbp-0x2c],0x7b
mov BYTE PTR [rbp-0x2b],0x14
movzx eax,BYTE PTR [rbp-0x2b]
mov edx,eax
mov eax,edx
shl eax,0x2
add eax,edx
mov BYTE PTR [rbp-0x2b],al
movzx eax,BYTE PTR [rbp-0x2b]
sub eax,0x1
mov BYTE PTR [rbp-0x2b],al
mov BYTE PTR [rbp-0x2a],0x6e
movzx eax,BYTE PTR [rbp-0x2a]
xor eax,0x17
mov BYTE PTR [rbp-0x2a],al
mov BYTE PTR [rbp-0x29],0x62
movzx eax,BYTE PTR [rbp-0x29]
sar al,0x2
mov BYTE PTR [rbp-0x29],al
movzx eax,BYTE PTR [rbp-0x29]
shl eax,0x2
mov BYTE PTR [rbp-0x29],al
movzx eax,BYTE PTR [rbp-0x29]
add eax,0x2
mov BYTE PTR [rbp-0x29],al
mov BYTE PTR [rbp-0x28],0x30
movzx eax,BYTE PTR [rbp-0x28]
movsx eax,al
shl eax,0x2
mov BYTE PTR [rbp-0x28],al
movzx eax,BYTE PTR [rbp-0x28]
or eax,0xf
mov BYTE PTR [rbp-0x28],al
movzx eax,BYTE PTR [rbp-0x28]
add eax,0x64
mov BYTE PTR [rbp-0x28],al
mov BYTE PTR [rbp-0x27],0xe
mov DWORD PTR [rbp-0x4],0x0
jmp 0x4005f7
movzx eax,BYTE PTR [rbp-0x27]
add eax,0x1
mov BYTE PTR [rbp-0x27],al
add DWORD PTR [rbp-0x4],0x1
cmp DWORD PTR [rbp-0x4],0x63
jle 0x4005e9
mov BYTE PTR [rbp-0x26],0xff
movzx eax,BYTE PTR [rbp-0x26]
lea edx,[rax+0x3]
test al,al
cmovs eax,edx
sar al,0x2
mov BYTE PTR [rbp-0x26],al
movzx eax,BYTE PTR [rbp-0x26]
sar al,0x2
mov BYTE PTR [rbp-0x26],al
movzx eax,BYTE PTR [rbp-0x26]
add eax,0x73
mov BYTE PTR [rbp-0x26],al
mov BYTE PTR [rbp-0x25],0xff
movzx eax,BYTE PTR [rbp-0x25]
add eax,0x4
mov BYTE PTR [rbp-0x25],al
movzx eax,BYTE PTR [rbp-0x25]
mov edx,eax
mov eax,edx
shl eax,0x3
add eax,edx
shl eax,0x2
add eax,edx
mov BYTE PTR [rbp-0x25],al
movzx eax,BYTE PTR [rbp-0x25]
add eax,0xa
mov BYTE PTR [rbp-0x25],al
movzx eax,BYTE PTR [rbp-0x25]
sub eax,0x9
mov BYTE PTR [rbp-0x25],al
mov BYTE PTR [rbp-0x24],0x3
movzx eax,BYTE PTR [rbp-0x24]
movsx eax,al
shl eax,0x4
mov BYTE PTR [rbp-0x24],al
movzx eax,BYTE PTR [rbp-0x24]
or eax,0x4
mov BYTE PTR [rbp-0x24],al
mov BYTE PTR [rbp-0x23],0x14
movzx eax,BYTE PTR [rbp-0x23]
mov edx,eax
mov eax,edx
shl eax,0x2
add eax,edx
mov BYTE PTR [rbp-0x23],al
movzx eax,BYTE PTR [rbp-0x23]
sub eax,0x1
mov BYTE PTR [rbp-0x23],al
mov BYTE PTR [rbp-0x22],0x30
movzx eax,BYTE PTR [rbp-0x22]
movsx eax,al
shl eax,0x2
mov BYTE PTR [rbp-0x22],al
movzx eax,BYTE PTR [rbp-0x22]
or eax,0xf
mov BYTE PTR [rbp-0x22],al
movzx eax,BYTE PTR [rbp-0x22]
add eax,0x64
mov BYTE PTR [rbp-0x22],al
movzx eax,BYTE PTR [rbp-0x23]
mov BYTE PTR [rbp-0x21],al
movzx eax,BYTE PTR [rbp-0x21]
sub eax,0x4
mov BYTE PTR [rbp-0x21],al
mov BYTE PTR [rbp-0x20],0x14
movzx eax,BYTE PTR [rbp-0x20]
mov edx,eax
mov eax,edx
shl eax,0x2
add eax,edx
mov BYTE PTR [rbp-0x20],al
movzx eax,BYTE PTR [rbp-0x20]
sub eax,0x1
mov BYTE PTR [rbp-0x20],al
mov BYTE PTR [rbp-0x1f],0x3
movzx eax,BYTE PTR [rbp-0x1f]
movsx eax,al
shl eax,0x4
mov BYTE PTR [rbp-0x1f],al
movzx eax,BYTE PTR [rbp-0x1f]
or eax,0x4
mov BYTE PTR [rbp-0x1f],al
mov BYTE PTR [rbp-0x1e],0x64
movzx eax,BYTE PTR [rbp-0x1e]
add eax,0xa
mov BYTE PTR [rbp-0x1e],al
movzx eax,BYTE PTR [rbp-0x1e]
sub eax,0x1
mov BYTE PTR [rbp-0x1e],al
mov BYTE PTR [rbp-0x1d],0xff
movzx eax,BYTE PTR [rbp-0x1d]
add eax,0x4
mov BYTE PTR [rbp-0x1d],al
movzx eax,BYTE PTR [rbp-0x1d]
mov edx,eax
mov eax,edx
shl eax,0x3
add eax,edx
shl eax,0x2
add eax,edx
mov BYTE PTR [rbp-0x1d],al
movzx eax,BYTE PTR [rbp-0x1d]
add eax,0xa
mov BYTE PTR [rbp-0x1d],al
movzx eax,BYTE PTR [rbp-0x1d]
sub eax,0x9
mov BYTE PTR [rbp-0x1d],al
mov BYTE PTR [rbp-0x1c],0x7d
lea rax,[rbp-0x30]
mov rdi,rax
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from keystone import *
from capstone import *
from capstone.x86 import *
from unicorn import *
from unicorn.x86_const import *
from struct import pack
from binascii import hexlify, unhexlify
import argparse
def read_file(fileName):
f = open(fileName, "r")
code = f.read()
f.close()
return code
def print_registers(emu):
rax = emu.reg_read(UC_X86_REG_RAX)
rbx = emu.reg_read(UC_X86_REG_RBX)
rcx = emu.reg_read(UC_X86_REG_RCX)
rdx = emu.reg_read(UC_X86_REG_RDX)
rsi = emu.reg_read(UC_X86_REG_RSI)
rdi = emu.reg_read(UC_X86_REG_RDI)
rsp = emu.reg_read(UC_X86_REG_RSP)
rbp = emu.reg_read(UC_X86_REG_RBP)
rip = emu.reg_read(UC_X86_REG_RIP)
r8 = emu.reg_read(UC_X86_REG_R8)
r9 = emu.reg_read(UC_X86_REG_R9)
r10 = emu.reg_read(UC_X86_REG_R10)
r11 = emu.reg_read(UC_X86_REG_R11)
r12 = emu.reg_read(UC_X86_REG_R12)
r13 = emu.reg_read(UC_X86_REG_R13)
r14 = emu.reg_read(UC_X86_REG_R14)
r15 = emu.reg_read(UC_X86_REG_R15)
print("--------------------------------------------------------------------------------")
print("/////////////////////////////// REGISTER STATE /////////////////////////////////")
print("--------------------------------------------------------------------------------")
print("rax = 0x%016x rdx = 0x%016x rsp = 0x%016x" % (rax, rdx, rsp))
print("rbx = 0x%016x rsi = 0x%016x rbp = 0x%016x" % (rbx, rsi, rbp))
print("rcx = 0x%016x rdi = 0x%016x rip = 0x%016x" % (rax, rdi, rip))
print("r8 = 0x%016x r9 = 0x%016x r10 = 0x%016x" % (r8, r9, r10))
print("r11 = 0x%016x r12 = 0x%016x r13 = 0x%016x" % (r11, r12, r13))
print("r14 = 0x%016x r15 = 0x%016x" % (r14, r15))
print("--------------------------------------------------------------------------------")
def hook_code(emu, address, size, user_data):
# user_data contains optional data specified by the caller
# I've included the capstone instance (cap) in a list
cap = user_data[0]
# read the opcodes for this instruction
ocbytes = emu.mem_read(address, size)
opcodes = hexlify(ocbytes)
try:
if cap.detail:
for inst in cap.disasm(bytes(ocbytes), size):
print("0x%08x: %s\t%s\t%s" % (address, opcodes.ljust(15), inst.mnemonic, inst.op_str))
# get and print some detailed information about this instruction
sm_operlen = len(inst.operands)
print(" Operands: %d" % sm_operlen)
# if instructions has operands, get more details
if sm_operlen > 0:
c = -1
for i in inst.operands:
c += 1
if i.type == X86_OP_MEM:
print(" Type: Memory Operation")
# see if the memory operation has a base
if i.mem.base != 0:
print(" Operand %d mem.base: REG = %s" % (c, inst.reg_name(i.mem.base)))
# get memory access type
# Note: if you are not on the Capstone "NEXT BRANCH" i.access will fail!
# See this: https://github.com/aquynh/capstone/wiki/Next-branch
if i.access == CS_AC_READ:
print(" Operand %d Access: READ\n" % (c))
elif i.access == CS_AC_WRITE:
print(" Operand %d Access: WRITE\n" % (c))
elif i.access == CS_AC_READ | CS_AC_WRITE:
print(" Operand %d Access: READ | WRITE\n" % (c))
else:
print(" Operand %d Access: UNKNOWN\n" % (c))
print("")
else:
for (cs_address, cs_size, cs_mnemonic, cs_opstr) in cap.disasm_lite(str(ocbytes), address):
print("0x%08x:\t%s\t%s" % (cs_address, cs_mnemonic, cs_opstr))
except CsError as e:
print("CAPSTONE ERROR: %s" % e)
def main():
BASE_ADDRESS = 0x0000000000400526
try:
# Initialize Keystone, Capstone, and Unicorn
kst = Ks(KS_ARCH_X86, KS_MODE_64)
cap = Cs(CS_ARCH_X86, CS_MODE_64)
emu = Uc(UC_ARCH_X86, UC_MODE_64)
# Emable detailed disassembly if requested by user
# Allows us to get semantics about each instruction
if args.detail:
cap.detail = True
# Read the assembly code from the user specified file
ASM_CODE = read_file(args.assembly_file)
# Assemble our challenge assembly to machine code with Keystone
try:
encoding, count = kst.asm(ASM_CODE, BASE_ADDRESS)
MACHINE_CODE = ""
for opcode in encoding:
MACHINE_CODE += pack("B", opcode)
except KsError as e:
# ruh-roh, we cannot recover from an assembly error, bail out
print("KEYSTONE ERROR: %s" % e)
exit()
# Hook each instruction so we can print them with Capstone
emu.hook_add(UC_HOOK_CODE, hook_code, [cap])
# Create 2MB of memory at the closest page boundary for the code
emu.mem_map((BASE_ADDRESS/0x1000)*0x1000, 2 * 1024 * 1024)
# Write our challenge code to the base address
emu.mem_write(BASE_ADDRESS, MACHINE_CODE)
# create stack space for the code to use
# location is completely arbitrary, size depends on code being emulated
# do not "collide" with your executable code (MACHINE_CODE) space!
STACK_START = 0x0000000000200000
STACK_SIZE = 0x0000000000010000
emu.mem_map(STACK_START - STACK_SIZE, STACK_SIZE)
# set stack pointer and base pointer to the location of our stack
emu.reg_write(UC_X86_REG_RSP, STACK_START)
emu.reg_write(UC_X86_REG_RBP, STACK_START)
# setting RIP is not required, we do it so the regitser print isn't misleading
# emu_start sets RIP for us
emu.reg_write(UC_X86_REG_RIP, BASE_ADDRESS)
# Print the starting register state
print_registers(emu)
# Run emulation from the start of code to the end
# Registers and memory initialize to ZERO (0x0000000000000000)
emu.emu_start(BASE_ADDRESS, BASE_ADDRESS + len(MACHINE_CODE))
# Print the flag. We know RAX and RDI contain a pointer to the flag on the stack
rax = emu.reg_read(UC_X86_REG_RAX)
# read 40 bytes from the flag pointer (size is arbitrarily chosen, flag ends up being 21 bytes)
flag = emu.mem_read(rax, 40)
# print the final register state
print_registers(emu)
# print the flag
print("Flag: %s" % flag)
except UcError as e:
print("UNICORN ERROR: %s" % e)
if __name__ == "__main__":
# argument parsing
parser = argparse.ArgumentParser(description="RETriforce: Keystone, Capstone, Unicorn Example")
# required arguments
parser.add_argument('assembly_file', action='store', help='x86_64 assembly file')
# optional arguments
parser.add_argument('--detail', action='store_true', help='print semantic information about instructions')
args = parser.parse_args()
main()
FROM ubuntu:16.04
## Helpful commands
# >> Build the docker container
# docker build -t retriforce .
# >> Run the docker container, mapping a directory into the container
# docker run --rm -it -v "<HOST_SHARE>:<GUEST_DIR>" retriforce
## Tunables
ENV UNICORNVER 0.9
#ENV CAPSTONEVER 3.0.4
ENV CAPSTONEVER next
ENV KEYSTONEVER 0.9.1
## Checkout new versions if you're interested:
# http://www.unicorn-engine.org/download/
# http://www.capstone-engine.org/download.html
# http://www.keystone-engine.org/download/
## Prepare dependencies
RUN apt-get update -y
RUN apt-get install -y python-dev libglib2.0-dev wget less vim sed cmake time python-pip
RUN apt-get install -y lib32stdc++-4.8-dev libc6-dev-i386
RUN apt-get install -y git unzip
RUN pip install --upgrade pip
###########################################################
## Install the Unicorn Engine
# Get the Unicorn-Engine sources
WORKDIR /usr/src
RUN wget https://github.com/unicorn-engine/unicorn/archive/$UNICORNVER.tar.gz && tar -xzf $UNICORNVER.tar.gz
# Build the Unicorn-Engine
WORKDIR /usr/src/unicorn-$UNICORNVER
RUN ./make.sh && ./make.sh install
# Build the Python bindings
WORKDIR /usr/src/unicorn-$UNICORNVER/bindings/python
RUN make install
###########################################################
## Install the Captsone Engine
# Get the Capstone-Engine sources
WORKDIR /usr/src
RUN wget https://github.com/aquynh/capstone/archive/$CAPSTONEVER.tar.gz && tar -xzf $CAPSTONEVER.tar.gz
# Build the Unicorn-Engine
WORKDIR /usr/src/capstone-$CAPSTONEVER
RUN ./make.sh && ./make.sh install
# Build the Python bindings
WORKDIR /usr/src/capstone-$CAPSTONEVER/bindings/python
RUN make install
###########################################################
## Install the Keystone Engine
# Get the Keystone-Engine sources
WORKDIR /usr/src
RUN wget https://github.com/keystone-engine/keystone/archive/$KEYSTONEVER.tar.gz && tar -xzf $KEYSTONEVER.tar.gz
# Build the Keystone-Engine
WORKDIR /usr/src/keystone-$KEYSTONEVER
RUN mkdir build
WORKDIR /usr/src/keystone-$KEYSTONEVER/build
RUN ../make-share.sh
RUN make install
# Build the Python bindings
WORKDIR /usr/src/keystone-$KEYSTONEVER/bindings/python
RUN make install
# Very important for Ubuntu! Otherwise keystone python scripts will not run
RUN sed -i '1i /usr/local/lib/' /etc/ld.so.conf
RUN ldconfig
###########################################################
# Cleanup
RUN rm -rf /usr/src/*
WORKDIR /root
RUN git clone https://github.com/dikim33/unicorn.git uck
RUN chmod +x uck/challenge.py
from capstone import *
from binascii import unhexlify
# Machine code x86 32-bit
CODE = unhexlify("414A") # => "\x41\x4A"
BASE_ADDRESS = 0x00400526
def main():
try:
# Initialize engine in X86 32-bit mode
cap = Cs(CS_ARCH_X86, CS_MODE_32)
for i in cap.disasm(CODE, BASE_ADDRESS):
print("0x%08x:\t%s\t%s" %(i.address, i.mnemonic, i.op_str))
except CsError as e:
print("ERROR: %s" %e)
if __name__ == "__main__":
main()
from keystone import *
from struct import pack
from binascii import hexlify
# Separate assembly instructions by ; or \n
CODE = "INC ECX\n" \
"DEC EDX\n"
def main():
try:
# Initialize engine in X86 32-bit mode
ks = Ks(KS_ARCH_X86, KS_MODE_32)
encoding, count = ks.asm(CODE)
machine_code = ""
for opcode in encoding:
machine_code += pack("B", opcode)
print("Machine Code:\n%s\n" %(hexlify(machine_code)))
except KsError as e:
print("ERROR: %s" %e)
if __name__ == "__main__":
main()
from unicorn import *
from unicorn.x86_const import *
from binascii import hexlify, unhexlify
X86_CODE32 = unhexlify("414A")
BASE_ADDRESS = 0x0040059d
def main():
try:
emu = Uc(UC_ARCH_X86, UC_MODE_32)
emu.mem_map((BASE_ADDRESS/0x1000)*0x1000, 2 * 1024 * 1024)
emu.mem_write(BASE_ADDRESS, X86_CODE32)
emu.reg_write(UC_X86_REG_ECX, 0x9)
emu.reg_write(UC_X86_REG_EDX, 0x5)
emu.emu_start(BASE_ADDRESS, BASE_ADDRESS + len(X86_CODE32))
print("Emulation done.")
print(">>> ECX = 0x%08x" % emu.reg_read(UC_X86_REG_ECX))
print(">>> EDX = 0x%08x" % emu.reg_read(UC_X86_REG_EDX))
except UcError as e:
print("ERROR: %s" % e)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment