16 Oct 2019

控制流平坦化

控制流平坦化

控制流平坦化

通过一个主分发器来控制程序基本块的执行流程

正常执行流程

1

控制流平坦化后的执行流程

2

8

  • 各结构之间的关系

    1. 函数的开始地址为序言的地址
    2. 序言的后继为主分发器
    3. 后继为主分发器的块为预处理器
    4. 后继为预处理器的块为真实块
    5. 无后继的块为retn块
    6. 剩下的为无用块

符号执行去平坦化

  1. 获取真实块、序言、retn块和无用块
  2. 确定真实块、序言和retn块的前后关系
  3. Patch二进制程序

2019中关村CTF flat

3

5个check函数

check1检查flag长度

check2检查前五个字符是否为flag{

chekc3检查最后一个字节是否为}

check4检查-的位置

check5检查flag

分析check5

4

5

控制流平坦化

deflat.py去平坦化

$ python3 deflat.py flat 0x400af0
*******************relevant blocks************************
prologue: 0x400af0
main_dispatcher: 0x400b17
pre_dispatcher: 0x40102d
retn: 0x40101c
relevant_blocks: ['0x400e75', '0x400fe7', '0x400dba', '0x400e9f', '0x400e1f', '0x400e49', '0x400d90', '0x400fd8', '0x400f72', '0x400d71', '0x400de4', '0x400f31', '0x400f13', '0x400fc5', '0x400f91', '0x400f59', '0x401009', '0x400f04', '0x400f22', '0x400ec9', '0x400d67']
*******************symbolic execution*********************
-------------------dse 0x400e75---------------------
-------------------dse 0x400fe7---------------------
-------------------dse 0x400dba---------------------
-------------------dse 0x400e9f---------------------
-------------------dse 0x400e1f---------------------
-------------------dse 0x400e49---------------------
-------------------dse 0x400d90---------------------
-------------------dse 0x400fd8---------------------
-------------------dse 0x400f72---------------------
-------------------dse 0x400d71---------------------
-------------------dse 0x400de4---------------------
-------------------dse 0x400f31---------------------
-------------------dse 0x400f13---------------------
-------------------dse 0x400fc5---------------------
-------------------dse 0x400f91---------------------
-------------------dse 0x400f59---------------------
-------------------dse 0x401009---------------------
-------------------dse 0x400f04---------------------
-------------------dse 0x400f22---------------------
-------------------dse 0x400ec9---------------------
-------------------dse 0x400d67---------------------
-------------------dse 0x400af0---------------------
************************flow******************************
0x400e75:  ['0x400e9f', '0x400f04']
0x400fe7:  ['0x400f72']
0x400dba:  ['0x400de4', '0x400e1f']
0x400e9f:  ['0x400ec9', '0x400f04']
0x400e1f:  ['0x400e49', '0x400e75']
0x400e49:  ['0x400f13']
0x400d90:  ['0x400dba', '0x400e1f']
0x400fd8:  ['0x400fe7']
0x400f72:  ['0x400f91', '0x401009']
0x400d71:  ['0x400d90', '0x400f59']
0x400de4:  ['0x400f22']
0x400f31:  ['0x400d71']
0x400f13:  ['0x400f22']
0x400fc5:  ['0x40101c']
0x400f91:  ['0x400fc5', '0x400fd8']
0x400f59:  ['0x400f72']
0x401009:  ['0x40101c']
0x400f04:  ['0x400f13']
0x400f22:  ['0x400f31']
0x400ec9:  ['0x400f04']
0x400d67:  ['0x400e75']
0x400af0:  ['0x400d71']
0x40101c:  []
************************patch*****************************
Successful! The recovered file: flat_recovered

6

check5传入参数是flag和一个已知字符串dest

在main中,执行memcpy(&dest, "J", 0x90uLL)

7

J2261C63-3I2I-EGE4-IBCC-IE41A5I5F4HB

遍历输入的字符,若当前字节小于0或大于9,判断是否等于-,若相等则不变,若不相等,则判断是否大于a且小于z,若是则当前字节减去48。

若当前字节大于等于0且小于等于9,则当前字节加17.

正确的flag经过处理后应与J2261C63-3I2I-EGE4-IBCC-IE41A5I5F4HB相等

dest = 'J2261C63-3I2I-EGE4-IBCC-IE41A5I5F4HB'
flag = ''
for i in range(0,len(dest)):
    for j in range(0,255):
    	t = ''
        if j < ord('0') or j > ord('9'):
            if j == ord('-'):
                t = chr(j)
            elif j >= ord('a') and j <= ord('z'):
                t = chr(j-48)
        else:
            t = chr(j+17)
        if t == dest[i]:
            flag += chr(j)
            break
print(flag)
#flag{9bbfa2fc-c8b8-464d-8122-84da0e8e5d71}
# ./flat
please input string:
flag{9bbfa2fc-c8b8-464d-8122-84da0e8e5d71}
you got it !

参考

Obfuscating C++ programs via control flow flattening:http://ac.inf.elte.hu/Vol_030_2009/003.pdf

利用符号执行去除控制流平坦化:https://security.tencent.com/index.php/blog/msg/112

基于目前angr版本的deflat:https://github.com/cq674350529/deflat


Tags:
0 comments



本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议CC BY-NC-ND 4.0)进行许可。

This work is licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License (CC BY-NC-ND 4.0).