CTF Reverse逆向学习之SMC动态代码加密技术,题目复现(NSSCTF)([网鼎杯 2020 青龙组]jocker)

SMC简介

SMC,即Self Modifying Code,动态代码加密技术,指通过修改代码或数据,阻止别人直接静态分析,然后在动态运行程序时对代码进行解密,达到程序正常运行的效果。

SMC的实现方式有很多种,可以通过修改PE文件的Section Header、使用API Hook实现代码加密和解密、使用VMProtect等第三方加密工具等。关于具体的实现方式可以参考合天的文章:探究SMC局部代码加密技术以及在CTF中的运用 - SecPulse.COM | 安全脉搏

CTF中的SMC

SMC一般有俩种破解方法,第一种是找到对代码或数据加密的函数后通过idapython写解密脚本。第二种是动态调试到SMC解密结束的地方dump出来。

SMC的实现是需要对目标内存进行修改的,.text一般是没有写权限的。那么就需要拥有修改目标内存的权限:

  • 在linux系统中,可以通过mprotect函数修改目标内存的权限
  • 在Windows系统中,VirtualProtect函数实现内存权限的修改

因此也可以观察是否有这俩个函数来判断是否进行了SMC。 

CTF 题目复现

[网鼎杯 2020 青龙组]jocker

CTF Reverse逆向学习之SMC动态代码加密技术,题目复现(NSSCTF)([网鼎杯 2020 青龙组]jocker)_第1张图片

文件先查壳,无壳,32bit文件,一打开就可以发现VitualProtect函数,这里对内存权限进行了修改,大概率是SMC。

这里的逻辑大致看下,通过scanf让我们输入一个长度为24的flag,再wrong函数和omg。

CTF Reverse逆向学习之SMC动态代码加密技术,题目复现(NSSCTF)([网鼎杯 2020 青龙组]jocker)_第2张图片

CTF Reverse逆向学习之SMC动态代码加密技术,题目复现(NSSCTF)([网鼎杯 2020 青龙组]jocker)_第3张图片


key = 0x66, 0x6B, 0x63, 0x64, 0x7F, 0x61, 0x67, 0x64, 0x3B, 0x56, 0x6B, 0x61, 0x7B, 0x26, 0x3B, 0x50, 0x63, 0x5F, 0x4D, 0x5A, 0x71, 0x0C, 0x37, 0x66
flag = ''
 
 
for i in range(24):
    if i % 2 == 1:
        flag += chr(key[i] + i)
    else:
        flag += chr(key[i] ^ i)
 
 
print(flag)

这里解出一个flag{fak3_alw35_sp_me!!} 是个假flag。

接着往下看,可以看到encrypt,并且encrypt函数打开出错了。

CTF Reverse逆向学习之SMC动态代码加密技术,题目复现(NSSCTF)([网鼎杯 2020 青龙组]jocker)_第4张图片

可以判断是在encrypt处进行了SMC加密,随便下个断点,用 Local windows debugger调试

CTF Reverse逆向学习之SMC动态代码加密技术,题目复现(NSSCTF)([网鼎杯 2020 青龙组]jocker)_第5张图片

CTF Reverse逆向学习之SMC动态代码加密技术,题目复现(NSSCTF)([网鼎杯 2020 青龙组]jocker)_第6张图片

根据前面得判断,输入长度为24得flag 123456789123456789123456

CTF Reverse逆向学习之SMC动态代码加密技术,题目复现(NSSCTF)([网鼎杯 2020 青龙组]jocker)_第7张图片

这里,F7单步走到00401833的call处,单步进入_Z7函数内

CTF Reverse逆向学习之SMC动态代码加密技术,题目复现(NSSCTF)([网鼎杯 2020 青龙组]jocker)_第8张图片

点击__Z7encryptPc 先用U将其设为无定义

CTF Reverse逆向学习之SMC动态代码加密技术,题目复现(NSSCTF)([网鼎杯 2020 青龙组]jocker)_第9张图片

接着选中下面所有数据内容,按C转换为代码。

CTF Reverse逆向学习之SMC动态代码加密技术,题目复现(NSSCTF)([网鼎杯 2020 青龙组]jocker)_第10张图片

CTF Reverse逆向学习之SMC动态代码加密技术,题目复现(NSSCTF)([网鼎杯 2020 青龙组]jocker)_第11张图片

选择Force,再点击yes

CTF Reverse逆向学习之SMC动态代码加密技术,题目复现(NSSCTF)([网鼎杯 2020 青龙组]jocker)_第12张图片

之后再点击_Z7进行P定义为函数,再用F5反编译。这里可以得到encrypt函数

CTF Reverse逆向学习之SMC动态代码加密技术,题目复现(NSSCTF)([网鼎杯 2020 青龙组]jocker)_第13张图片

下面还有一个函数不要忽略了,同样P定义为函数,再F5反编译。

CTF Reverse逆向学习之SMC动态代码加密技术,题目复现(NSSCTF)([网鼎杯 2020 青龙组]jocker)_第14张图片

CTF Reverse逆向学习之SMC动态代码加密技术,题目复现(NSSCTF)([网鼎杯 2020 青龙组]jocker)_第15张图片

通过第一个encrpyt函数 逆向一下,


hh = 'hahahaha_do_you_find_me?'
v2 = [0x0E, 0x0D, 0x9, 0x6, 0x13, 0x5, 0x58, 0x56, 0x3E, 0x6,
      0x0C, 0x3C, 0x1F, 0x57, 0x14, 0x6B, 0x57, 0x59, 0x0D]
flag = []
 
 
for i in range(19):
    flag.append(chr(v2[i] ^ ord(hh[i])))

解出flag{d07abccf8a410c   明显还有后半部分,看第二个函数,大致的意思就是%tp&:这五个字符和某个数字异或得到最后的flag,已知是flag的最后一位一定是},那么就很好求了。


v3 = [37, 116, 112, 38, 58]
key = ord('}') ^ 58
 
for i in range(5):
    flag.append(chr(v3[i] ^ key))
 
print(''.join(flag))

这样就可以解出flag{d07abccf8a410cb37a}

[羊城杯 2021]BabySmc

题目打开CTF Reverse逆向学习之SMC动态代码加密技术,题目复现(NSSCTF)([网鼎杯 2020 青龙组]jocker)_第16张图片

在导入表中看到VirtualProtect函数

CTF Reverse逆向学习之SMC动态代码加密技术,题目复现(NSSCTF)([网鼎杯 2020 青龙组]jocker)_第17张图片

CTF Reverse逆向学习之SMC动态代码加密技术,题目复现(NSSCTF)([网鼎杯 2020 青龙组]jocker)_第18张图片

CTF Reverse逆向学习之SMC动态代码加密技术,题目复现(NSSCTF)([网鼎杯 2020 青龙组]jocker)_第19张图片

在最下面可以看到一个错误地址。点进去 看汇编,

CTF Reverse逆向学习之SMC动态代码加密技术,题目复现(NSSCTF)([网鼎杯 2020 青龙组]jocker)_第20张图片

大量的数据,可以直接尝试下断点动态调试。用本地win就好

CTF Reverse逆向学习之SMC动态代码加密技术,题目复现(NSSCTF)([网鼎杯 2020 青龙组]jocker)_第21张图片

F8步过,进入数据处,这里会提示是否让IDA自己根据RIP生成代码,选no,因为这里IDA已经不能自主分辨主函数的结构了。

CTF Reverse逆向学习之SMC动态代码加密技术,题目复现(NSSCTF)([网鼎杯 2020 青龙组]jocker)_第22张图片

No了后,从上方的main头一直选到第一个retn处,按C后选择Force强制转换为代码,之后直接F5反编译就好了。 

CTF Reverse逆向学习之SMC动态代码加密技术,题目复现(NSSCTF)([网鼎杯 2020 青龙组]jocker)_第23张图片

你可能感兴趣的:(网络安全,密码学,安全)