1#!/usr/bin/env python
2## -*- coding: utf-8 -*-
3##
4##  Jonathan Salwan - 2018-11-03
5##
6##  To solve the challenge we have to execute (in a concrete way) the function
7##  fnhowtouse(int) in the howtouse.dll. Calling this function with an index
8##  input returns a part of the flag. Calling this function from the index 0
9##  to 44 returns the complet flag.
10##
11##  Output:
12##
13##  $ time python solve.py
14##  [+] Loading 0x10001000 - 0x10001b10
15##  [+] Loading 0x10002000 - 0x10002573
16##  [+] Loading 0x10003000 - 0x10003364
17##  [+] Loading 0x10004000 - 0x100042b0
18##  [+] Loading 0x10005000 - 0x1000517e
19##  [+] Starting emulation of the function howtouse(0)
20##  [+] Starting emulation of the function howtouse(1)
21##  [+] Starting emulation of the function howtouse(2)
22##  [+] Starting emulation of the function howtouse(3)
23##  [+] Starting emulation of the function howtouse(4)
24##  [+] Starting emulation of the function howtouse(5)
25##  [+] Starting emulation of the function howtouse(6)
26##  [+] Starting emulation of the function howtouse(7)
27##  [+] Starting emulation of the function howtouse(8)
28##  [+] Starting emulation of the function howtouse(9)
29##  [+] Starting emulation of the function howtouse(10)
30##  [+] Starting emulation of the function howtouse(11)
31##  [+] Starting emulation of the function howtouse(12)
32##  [+] Starting emulation of the function howtouse(13)
33##  [+] Starting emulation of the function howtouse(14)
34##  [+] Starting emulation of the function howtouse(15)
35##  [+] Starting emulation of the function howtouse(16)
36##  [+] Starting emulation of the function howtouse(17)
37##  [+] Starting emulation of the function howtouse(18)
38##  [+] Starting emulation of the function howtouse(19)
39##  [+] Starting emulation of the function howtouse(20)
40##  [+] Starting emulation of the function howtouse(21)
41##  [+] Starting emulation of the function howtouse(22)
42##  [+] Starting emulation of the function howtouse(23)
43##  [+] Starting emulation of the function howtouse(24)
44##  [+] Starting emulation of the function howtouse(25)
45##  [+] Starting emulation of the function howtouse(26)
46##  [+] Starting emulation of the function howtouse(27)
47##  [+] Starting emulation of the function howtouse(28)
48##  [+] Starting emulation of the function howtouse(29)
49##  [+] Starting emulation of the function howtouse(30)
50##  [+] Starting emulation of the function howtouse(31)
51##  [+] Starting emulation of the function howtouse(32)
52##  [+] Starting emulation of the function howtouse(33)
53##  [+] Starting emulation of the function howtouse(34)
54##  [+] Starting emulation of the function howtouse(35)
55##  [+] Starting emulation of the function howtouse(36)
56##  [+] Starting emulation of the function howtouse(37)
57##  [+] Starting emulation of the function howtouse(38)
58##  [+] Starting emulation of the function howtouse(39)
59##  [+] Starting emulation of the function howtouse(40)
60##  [+] Starting emulation of the function howtouse(41)
61##  [+] Starting emulation of the function howtouse(42)
62##  [+] Starting emulation of the function howtouse(43)
63##  [+] Starting emulation of the function howtouse(44)
64##  Flag is: MMA{fc7d90ca001fc8712497d88d9ee7efa9e9b32ed8}
65##  python solve.py  0.18s user 0.02s system 99% cpu 0.200 total
66##
67
68from __future__ import print_function
69from triton     import *
70
71import random
72import string
73import sys
74import lief
75import os
76
77TARGET = os.path.join(os.path.dirname(__file__), 'howtouse.dll')
78DEBUG  = True
79
80# The debug function
81def debug(s):
82    if DEBUG: print(s)
83
84# Memory mapping
85BASE_STACK = 0x9fffffff
86
87
88# Emulate the binary.
89def emulate(ctx, pc):
90    while pc:
91        # Fetch opcodes
92        opcodes = ctx.getConcreteMemoryAreaValue(pc, 16)
93
94        # Create the Triton instruction
95        instruction = Instruction()
96        instruction.setOpcode(opcodes)
97        instruction.setAddress(pc)
98
99        # Process
100        if ctx.processing(instruction) == False:
101            debug('[-] Instruction not supported: %s' %(str(instruction)))
102            break
103
104        #print instruction
105
106        # Next
107        pc = ctx.getConcreteRegisterValue(ctx.registers.eip)
108    return
109
110
111def loadBinary(ctx, binary):
112    # Map the binary into the memory
113    sections = binary.sections
114    for sec in sections:
115        size   = sec.virtual_size
116        vaddr  = sec.virtual_address + 0x10000000
117        debug('[+] Loading 0x%06x - 0x%06x' %(vaddr, vaddr+size))
118        ctx.setConcreteMemoryAreaValue(vaddr, sec.content)
119    return
120
121
122def run(ctx, binary, arg):
123    # Concretize previous context
124    ctx.concretizeAllMemory()
125    ctx.concretizeAllRegister()
126
127    # Define a fake stack
128    ctx.setConcreteRegisterValue(ctx.registers.ebp, BASE_STACK)
129    ctx.setConcreteRegisterValue(ctx.registers.esp, BASE_STACK)
130
131    ctx.setConcreteMemoryValue(MemoryAccess(BASE_STACK+4, CPUSIZE.DWORD), arg)
132
133    # Let's emulate the binary from the entry point
134    debug('[+] Starting emulation of the function howtouse(%d)' %(arg))
135    emulate(ctx, 0x10001130)
136    return ctx.getConcreteRegisterValue(ctx.registers.eax)
137
138
139def main():
140    # Get a Triton context
141    ctx = TritonContext()
142
143    # Set the architecture
144    ctx.setArchitecture(ARCH.X86)
145
146    # Parse the binary
147    binary = lief.parse(TARGET)
148
149    # Load the binary
150    loadBinary(ctx, binary)
151
152    # Init and emulate
153    flag = str()
154    for i in range(45):
155        flag += chr(run(ctx, binary, i))
156
157    print('Flag is: %s' %(flag))
158    return not (flag == 'MMA{fc7d90ca001fc8712497d88d9ee7efa9e9b32ed8}')
159
160
161if __name__ == '__main__':
162    retValue = main()
163    sys.exit(retValue)
164