Mas0n
mailto:MasonShi@88.com
翻车鱼

Dragon CTF 2021

Dragon CTF 2021

有幸跟着主队打比赛,逆向就出了一题。虽说比较简单,但是还是写了很久,记录一下吧。

还是得感谢队友的帮助…

Run of the Mill

一大堆位操作

https://cdn.shi1011.cn/2021/11/0bea2102d3b392b63520cfd377a599ee.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5

首先是想到了符号执行,会发现路径爆炸。

换个思路:逆序运行。

Method 1

直接使用IDA的伪码会有异代码,如下

v4 = _m_pxor((__m64)0x82A766A24751FB61ui64, _m_pxor((__m64)0x9823CC120C3B05F0ui64, *(__m64 *)flag));
*(__m64 *)flag = v4;
*(_WORD *)&flag[4] = __ROR2__(WORD2(v4.m64_u64), 3);

等同于

*(__m64 *)flag = _m_pxor((__m64)0x82A766A24751FB61ui64, _m_pxor((__m64)0x9823CC120C3B05F0ui64, *(__m64 *)flag));
*(_WORD *)&flag[4] = __ROR2__(*(_WORD *)&flag[4], 3);

如下

*(_WORD *)&flag[27] = (*(_DWORD *)&flag[26] >> 8) ^ 0x2F6E;

等同于

*(_WORD *)&flag[27] = (*(_WORD *)&flag[27] ^ 0x2F6E;

还有一些其他的语句需要修改。

脚本进行初步逆序,手动修改部分代码后,g++编译运行

这里文件过大就不展示了,上一个附件

Method 2

ida python脚本分析指令(队伍里其他师傅写的,不要脸的拿来抄了)

import re
import idautils

enc_ins = []

def match_offset(asm_text):
    r1 = re.search(r"flag\+([0-9A-F]*)h", asm_text)
    r2 = re.search(r"flag\+([0-9A-F])", asm_text)
    r3 = re.search(r"flag", asm_text)
    if r1:
        return r1.groups(0)[0]
    elif r2:
        return r2.groups(0)[0]
    elif r3:
        return "offset_is_zero"
    else:
        return 0
    
def match_imm(asm_text):
    re2 = re.search(r", (([0-9A-F]*)h|[0-9A-F])", asm_text)
    if re2:
        return re2.groups(0)[0]

for ins in idautils.FuncItems(0x401000):
    asm_text = GetDisasm(ins)
    if 'flag' in asm_text:
        flag = ""
        for s in ['add', 'sub', 'pxor', 'xor', 'rol', 'ror']:
            if s in asm_text:
                flag = s
                break
        if flag == 'pxor':
            offset = match_offset(asm_text)
            if offset == "offset_is_zero":
                enc_ins.append((hex(ins), "pxor", '0'))
                continue
            if offset:
                enc_ins.append((hex(ins), "pxor", offset))
                continue
        if flag in ['add', 'sub', 'xor', 'rol', 'ror']:
            offset = match_offset(asm_text)
            if offset == "offset_is_zero":
                imm = match_imm(asm_text)
                if imm:
                    if 'dword' in asm_text:
                        l = 4
                        enc_ins.append((hex(ins), flag, '0', imm, l))
                        continue
                    elif 'word' in asm_text:
                        l = 2
                        enc_ins.append((hex(ins), flag, '0', imm, l))
                        continue
                    else:
                        l = 1
                        enc_ins.append((hex(ins), flag, '0', imm, l))
                        continue
            if offset:
                imm = match_imm(asm_text)
                if imm:
                    if 'dword' in asm_text:
                        l = 4
                        enc_ins.append((hex(ins), flag, offset, imm, l))
                        continue
                    elif 'word' in asm_text:
                        l = 2
                        enc_ins.append((hex(ins), flag, offset, imm, l))
                        continue
                    else:
                        l = 1
                        enc_ins.append((hex(ins), flag, offset, imm, l))
                        continue
        print("!!", hex(ins), asm_text)
print("*" * 999)
for i in enc_ins:
    print(i, end=', ')

获取pxor key

import re
import idautils
import binascii
import struct


def read_xmm_reg(name):
    rv = idaapi.regval_t()
    idaapi.get_reg_val(name, rv)
    return (struct.unpack('Q', rv.bytes())[0])



rmap = {}
while ida_dbg.step_over():
    wait_for_next_event(WFNE_ANY, -1)
    rip = idc.get_reg_value("rip")
    if rip > 0x411810:
        break
    asm_text = GetDisasm(rip)
    if 'pxor' in asm_text:
        rmap[rip] = read_xmm_reg('mm0')
        print(hex(rip), hex(rmap[rip]))
print(rmap)

写个脚本逆出代码后,相同办法g++编译运行

脚本及代码参下附件

https://cdn.shi1011.cn/2021/11/d3a0d56f12ad6ea2d6858519604efc69.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5
本文链接:https://blog.shi1011.cn/ctf/1878
本文采用 CC BY-NC-SA 3.0 Unported 协议进行许可

Mas0n

文章作者

发表评论

textsms
account_circle
email

翻车鱼

Dragon CTF 2021
有幸跟着主队打比赛,逆向就出了一题。虽说比较简单,但是还是写了很久,记录一下吧。 还是得感谢队友的帮助… Run of the Mill 一大堆位操作 首先是想到了符号执行,会发…
扫描二维码继续阅读
2021-11-28