CISCN 2023 RE WP

一、moveAside

对strcmp下断,通过黑盒测试,可以发现这里存在测信道攻击

直接pintools + python脚本 爆破

Pintools脚本如下:

#include <iostream>
#include <fstream>
#include "pin.H"

using std::cerr;
using std::endl;
using std::string;
static UINT64 icount = 0;

VOID docount(VOID* addr) {
    if (( int )addr == 0x8049010)
    {
        icount++;
    }
}

VOID Instruction(INS ins, VOID* v)
{
    INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)docount, IARG_INST_PTR, IARG_END);
}

KNOB< string > KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool", "o", "inscount.out", "specify output file name");

VOID Fini(INT32 code, VOID* v)
{
    std::cout << "Count " << icount << endl;
}


INT32 Usage()
{
    cerr << "This tool counts the number of dynamic instructions executed" << endl;
    cerr << endl << KNOB_BASE::StringKnobSummary() << endl;
    return -1;
}

int main(int argc, char* argv[])
{
    if (PIN_Init(argc, argv)) return Usage();

    INS_AddInstrumentFunction(Instruction, 0);

    PIN_AddFiniFunction(Fini, 0);

    PIN_StartProgram();
    return 0;
}

Python爆破脚本如下:

import subprocess
import time
import copy
import os
STR_LEN = 30
start_time = time.time()
out_file_path = r"ttext.txt"
exe_path = r"./moveAside"
dll_path = r"./MyPinTool.so"
record_ins_nums = {}        # 指令计数器 
except_str = "flag{"
except_inss = 0   
find_str = ""
s_map = "0123456789qwertyuiopasdfghjklzxcvbnm{}-"
# s_map = "0123456789"

def sub_intreaction(input_msg):
    global start_time
    sh = subprocess.Popen(['pin','-t',dll_path,'-o',out_file_path,'--',exe_path],
                            stdin=subprocess.PIPE,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE)
    sh.stdin.write(str.encode(input_msg.ljust(48,"0")))   # 必须补齐,不然后面的sh.stdout 会出错    # 即将缓冲区中的数据立刻写入文件,同时清空缓冲区,不需要是被动的等待输出缓冲区写入
    sh.stdin.flush()
    sh.stdout.flush()
    sh.stdin.write(str.encode(input_msg.ljust(48,"0")))
    sh.stdin.flush()
    sh.stdout.flush()
    sh.stdin.write(str.encode(input_msg.ljust(48,"0")))
    sh.stdin.flush()
    sh.stdout.flush()
    get_input = sh.stdout.readlines()
    # print(get_input)
    lenn = int(get_input[2][6:])

    if record_ins_nums and lenn > max(record_ins_nums.values()):
        record_ins_nums[input_msg] = lenn
        sh.kill()
        print(input_msg," : ",get_input)
        return 1
    record_ins_nums[input_msg] = lenn
    sh.kill()
    print(input_msg," : ",get_input)

    if b"success" in get_input[1]:
        print("Oh,my sir, you may got the flag:")
        print(input_msg)
        print(time.time() - start_time)
        exit()
    
    return 0

def intreaction():
    for i in range(len(s_map)):
        if sub_intreaction(except_str + s_map[i]) == 1:
            return 
        
def pintools():
    global except_str,v,record_ins_nums,except_inss
    intreaction()

    for k,v in record_ins_nums.items():
        if v >= except_inss:   # 出错原因,之前用的 '>' 号,发现input_msg 填充的数据 0 也是input的数据,导致 012345678901234567890 指令数一样,从而导致无线循环
            except_str = copy.deepcopy(k)
            except_inss = v
    print(except_str," ",except_inss)
    record_ins_nums = {}
    pintools()

if __name__ == '__main__':
    pintools()

爆破过程:

 

爆破得到flag:

flag{781dda4e-d910-4f06-8f5b-5c3755182337}

二、ezbyte

finger+连点器恢复一些符号(

通过调试发现

程序通过异常处理进入到这个了函数

这里实现了小型虚拟机

经过调试,可以发现虚拟机工作如下:

inp[3] += 0x8b3778
inp[3] ^= 0x1a3dbfb3bbdaeefb
inp[3] ^= 0x790b86d78a647422
inp[2] +=  0x171378
inp[2] ^= 0xf3fb14121b8606d
inp[2] ^= 0x2206872240fc27dc
inp[1] += 0x88e3e5
inp[1] ^= 0x10ca3d978ad743e3
inp[1] ^= 0x75fe10f2ba170af1
inp[0] += 0x1ce183
inp[0] ^= 0x112ddf8e50094ca7
inp[0] ^= 0x244fb9eb69445b4f
inp[0] += inp[1]
inp[0] += inp[2] 
inp[0] += inp[3] 
assert inp[0] == 0

exp即为:

from struct import pack , unpack

def pt(p):
    print(p)
def pth(p):
    print(hex(p))

def Q2b(m):
    return pack("<Q",m)
def b2Q(m):
    return unpack("<Q",m)[0]

t1 = (0 ^ 0x112ddf8e50094ca7 ^ 0x244fb9eb69445b4f) - 0x1ce183
t2 = (0 ^ 0x10ca3d978ad743e3 ^ 0x75fe10f2ba170af1)   - 0x88e3e5
t3 = (0x2206872240fc27dc ^ 0 ^ 0xf3fb14121b8606d) - 0x171378
t4 = (0x790b86d78a647422 ^ 0 ^ 0x1a3dbfb3bbdaeefb   ) - 0x8b3778
pt(Q2b(t1) + Q2b(t2) + Q2b(t3) + Q2b(t4))

# flag{e609efb5-e70e-4e94-ac69-ac31d96c3861}

Flag即为:

flag{e609efb5-e70e-4e94-ac69-ac31d96c3861}

三、BabyRE

Snap! 语言逆向

https://snap.berkeley.edu/snap/snap.html

网址打开后开启js扩展

 

在这里下断点并显示变量

 

动态运行,即可拿到密文

 

加密流程如下:

 

 

Exp为:

t1 = [102,10,13,6,28,74,3,1,3,7,85,0,4,75,20,92,92,8,28,25,81,83,7,28,76,88,9,0,29,73,0,86,4,87,87,82,84,85,4,85,87,30]
print(len(t1))
for i in range(1,len(t1)):
    t1[i] = t1[i] ^ t1[i-1]

for i in range(len(t1)):    
    print(chr(t1[i]),end = "")

flag即为:

flag{12307bbf-9e91-4e61-a900-dd26a6d0ea4c}

待补充...

四、flutterror

思路一

参考群友的思路

 Alt+t搜索CMP ,再在CMP里面搜 #0x2a

即可定位到关键函数

exp:

t = [0, 10, 7, 1, 29, 95, 80, 3, 80, 83, 80, 95, 81, 75, 83, 3, 4, 4, 75, 82, 81, 82, 81, 75, 95, 80, 85, 80, 75, 7, 3, 0, 5, 2, 86, 82, 84, 5, 3, 94, 86, 27]
flag = bytearray([i ^ 0x66 for i in t])
print(flag)

flag{96e65697-5ebb-4747-9636-aefcd042ce80}

这个方法的思路是基于flag的长度是42位的(可以看前面的flag,都为42位),猜测.so文件会对输入进行长度比较,从而搜索长度比较汇编代码来找到关键函数

PS:

第二次打国赛,第一天的mov混淆是我没想到的,属实是没活了,第二天的snap!逆向导师眼前一亮,之后的安卓+web题和futter题没整明白,看到有大师傅通过Hook logcat函数来做的,属实是没想到,还是道行太浅

 

 

----------------------------------------------|追风赶月莫停留,平芜尽处是春山|----------------------------------------------

 

posted @ 2023-05-28 22:10  TLSN  阅读(751)  评论(0编辑  收藏  举报