HWS计划2021硬件安全冬令营线上选拔赛


HWS计划2021硬件安全冬令营线上选拔赛逆向部分wp

没有参加比赛,赛后复现一波re,感觉题都还可以,别的师傅说难度不大,但是我感觉对我来说挺难的😵

babyre

一道hook题,ida打开代码还是比较清晰的,首先判断长度然后在加密,但是我没有搞清楚这个hook的流程,听别的师傅说的在CRT的时候,从r3到r0时候hook的😥(听的不是很懂),但是我瞎找找到这两个函数

资源解密

资源加载

可以看出程序加载了一个叫CIPHER_DLL的资源,这个资源其实就是经过加密的DLL,我用ResourceHacker(一个可以查看程序资源的工具)来查看程序中的资源

程序中确实有一个叫CIPHER_DLL的资源,且这个资源需要解密才能使用,图中 wow! 就是证明,把这个资源的二进制文件提出来,在解密回去,得到一个DLL

import struct
import os

//解密资源
def ResourceDecrypt():
    filepath = 'C:\\Users\\86180\\Desktop\\CIPHER_DLL101'
    dllpath = 'C:\\Users\\86180\\Desktop\\DLL.dll'
    key = 'wow!'
    size = os.path.getsize(filepath) # 获得文件大小
    with open(filepath, 'rb') as cipher_stream:
        with open(dllpath, 'wb') as dll_stream:
            for i in range(size):
                data = struct.unpack('B', cipher_stream.read(1))[0] ^ ord(key[i%4])
                dll_stream.write(struct.pack('B', data))

把DLL用ida打开,查看加密函数,字符串已经告诉我们是SM4加密,没有魔改.

SM4Github代码链接

from ida import ida_bytes
import pysm4

# 从ida中提取加密后的数据
def Dump_ida_data():
    addr = 0x00BFA808
    res = []
    for i in range(32):
        res.append(get_byte(addr + i))
    print(bytes(res).hex())

    
# 利用GitHub上找的sm4脚本,写的解密函数
 def Decrypt():
    string = b'Ez_5M4_C1pH@r!!!'.hex()
    key = 0x457a5f354d345f433170484072212121
    cipher1 = 0xea6358b78ce2a1e9c5298f53e8083259
    cipher2 = 0xaf1b67aed9dacfc472ffb1ec7673f306
    plain1 = hex(pysm4.decrypt(cipher1, key))[2:]
    plain2 = hex(pysm4.decrypt(cipher2, key))[2:]
    for i in range(0,len(plain1),2):
        print(chr(int(plain1[i:i+2],16)),end='')
    for i in range(0,len(plain1),2):
        print(chr(int(plain2[i:i+2],16)),end='')
    
# flag{42b061b4cb41cfa89ca78047bde1856e}

image-20210201191532668

child_protect

参考看雪的一篇文章:https://bbs.pediy.com/thread-95082.htm

这道题考的是双进程守护问题,上面的文章和这道题类似,但是难点在于调试。

ida打开后发现主函数无法正常反编译,而且看到了int3中断异常指令。由于是双进程守护,需要找到创建子进程的地方

通过搜索CreateProcess函数,确定子进程由函数sub_413670创建

继续跟踪,确定了两个函数调用子进程,分别是sub_413BE0和sub_413950

而函数sub_413950是一个关键函数,他对子进程做了修改。如果想让ida正确的反编译,我们需要nop掉所有的int3指令,且按照程序修改部分指令,这里我用010Editor进行修改。

首先找到所有的int3指令




上图就是需要我们首先nop掉的地方,用010Editor修改后再次用ida打开可以发现主函数已经可以正常反编译,但是还不能够动态调试,
因为所有的过程都是在子进程中进行,但是我们现在已经修改了父进程的数据和子进程一样,所以可以跳过调用子进程的步骤,这需要修改一部分数据。

经过多次下断点调试后,定位到函数sub_413D10,修改过后就可以进行调试,但是还有一个坑。。

每次调试到这里的时候都会闪退,无论怎么调都没有用,最后我选择的办法是直接patch掉调用这个函数的指令,因为这步比较简单,且不影响后面的数据。

在可以动调后,就可以分析算法了,算法有两处,一处异或,一处tea加密,异或函数我将他pach,直接看tea处
异或
tea

tea加密的key是在运行时生成的,但是如果不动态调试也可以直接复制整个函数跑一遍也可以,我喜欢动态调试(懒)

生成了8个数据,但是只用到了前四个,后面只需要找到加密后的数据就ok了,这里我用idapython

import idc 
from ida_bytes import *
import idaapi 

def DumpCipher():
    addr = []
    res = []
    start = 0x4122C8
    end = 0x4123AE
    curr_addr = start
    dword = ''
    while curr_addr <= end:
        addr.append(curr_addr)
        curr_addr = idc.next_head(curr_addr,end)
    
    for i in range(32):
        if i%4==0 and i != 0:
            print(dword)
            res.append(int(dword, 16))
            dword = ''
        data = idc.print_operand(addr[i], 1).replace('h', '')
        if len(data) == 1:
            data = '0' + data
        elif len(data) == 3:
            data = data[1:]
        dword = dword + data
    # print(dword)
    res.append(int(dword, 16))
    print(res)

#include <stdio.h>
#include <stdint.h>


void TEA_decrypt(uint32_t* v, uint32_t* k)
{
   
    uint32_t sum = 0xC6EF3720, delta = 0x9E3779B9;
    uint32_t v0 = v[0], v1 = v[1];
    for (int i = 0; i < 32; i++) {
   
        v1 -= ((v0 << 4) + k[2]) ^ (v0 + sum) ^ ((v0 >> 5) + k[3]);
        v0 -= ((v1 << 4) + k[0]) ^ (v1 + sum) 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值