SMC在CTF逆向中的应用

admin 2024年8月4日21:23:08评论32 views字数 2413阅读8分2秒阅读模式

SMC简介

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

方法

SMC一般有两种破解方法

第一种是找到对代码或数据加密的函数后通过idapython写解密脚本。

第二种是动态调试到SMC解密结束的地方dump出来。

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

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

  • 在Windows系统中,VirtualProtect函数实现内存权限的修改

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

这里主要对动态调试这一方法进行分析

实操

[网鼎杯 2020 青龙组]jocker

进入main函数

可以直接找到被smc的函数 VirtualProtect

SMC在CTF逆向中的应用

VitualProtect函数,这里对内存权限进行了修改,大概率是SMC

分析代码,通过scanf让我们输入一个长度为24的flag,又经过wrong函数和omg函数加密

打开encrypt函数时出错

SMC在CTF逆向中的应用

因为在前面VirtualProtect函数包含了encrypt函数,所以显然在encrypt处进行了SMC加密

动态调试

在这里下断点

SMC在CTF逆向中的应用

F7进入这个call

SMC在CTF逆向中的应用

点击__Z7encryptPc 先按U将其设为未定义

SMC在CTF逆向中的应用

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

SMC在CTF逆向中的应用

点击函数按p构造函数

按F5即可反编译

SMC在CTF逆向中的应用

同理,对__Z7finallyPc操作

SMC在CTF逆向中的应用

接下来直接分析伪代码解密即可

 buffer = 'hahahaha_do_you_find_me?'
 v3 = '%tp&:'
 v2 = [14, 13, 9, 6, 19, 5, 88, 86, 62, 6, 12, 60, 31, 87, 20, 107, 87, 89, 13]
 for i in range(len(v2)):
     a1=v2[i]^ord(buffer[i])
     print(chr(a1),end='')
 for j in range(5):
     a2 = ord(v3[j]) ^ ord(':') ^ ord('}')
     print(chr(a2),end='')
 
 # flag{d07abccf8a410cb37a}

idapython

 start = 0x401500
 for i in range(187):
 a = idc.get_wide_byte(start + i)
 ida_bytes.patch_byte(start + i,a ^ 0x55 ^ 0x14)

[H&NCTF2024]I_LOVE_SWDD

进入main函数

SMC在CTF逆向中的应用

进入sub_411186函数时,发现无法识别,只有一堆数据

SMC在CTF逆向中的应用

SMC在CTF逆向中的应用

可以猜测是SMC(当然仅仅是猜测)

再看导入表

SMC在CTF逆向中的应用

存在VirtualProtect函数,这下更确定了

动态调试

在这里下断点

SMC在CTF逆向中的应用

点击loc_417000,按u转未定义,再按c分析函数,再按p构造函数

完美

SMC在CTF逆向中的应用

F5反编译成功

SMC在CTF逆向中的应用

之后就是简单的凯撒密码

 str2 = 'S_VYFO_CGNN_GRKD_KLYED_IYE'
 str1 = ''
 for i in str2:
     if 'A' < i < 'Z':
         str1 += chr((ord(i) - 10 - 65) % 26 + 65)
     else:
         str1 += i
 print(str1)
 # I_LOVE_SWDD_WHAT_ABOUT_YOU

[羊城杯 2021]BabySmc

进入main函数

这里发现无法分析,可以猜测是SMC,但是需要确定一下

SMC在CTF逆向中的应用

查看导入表,发现VirtualProtect函数

SMC在CTF逆向中的应用

xref 追到 sub_7FF6EB171E30 函数

动态调试

在这里下断点动调

SMC在CTF逆向中的应用

SMC在CTF逆向中的应用

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

SMC在CTF逆向中的应用

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

这里开始

SMC在CTF逆向中的应用

这里结束(return)

SMC在CTF逆向中的应用

然后按F5反编译即可

idapython

脚本一

 start = 0x140001085
 end = 0x140001D00
 
 import idc
 import ida_bytes
 
 def change_byte(uint8):
     return (((uint8 & 7) << 5) | (uint8 >> 3)) ^ 0x5a
 
 size = end - start + 1
 b = idc.get_bytes(start, size)
 b2 = bytes([change_byte(x) for x in b])
 ida_bytes.patch_bytes(start, b2)

脚本二

 from idc_bc695 import *
 def ROR(i,index):
 tmp bin(i)[2:].rjust(8,"0")
 for _ in range(index):
 tmp = tmp[-1] + tmp[:-1]
 return int(tmp, 2)
 def ROL(i,index):#循环左移
 tmp bin(i)[2:].rjust(8,"0")
 for _ in range(index):
 tmp = tmp[1:] + tmp[0]
 return int(tmp, 2)
 addr1=0x140001085
 addr2=0x140001d00
 for i in range(addr2-addr1):
 PatchByte(addr1+i,ROR(Byte(addr1+i),3)^90)
 print('successful')

网上抄的,暂时不清楚原理,只能猜测是根据VirtualProtect函数来的

SMC在CTF逆向中的应用

总结

  1. 重点在于找到被SMC的函数的起始地址和结束地址,这样才能针对性的对被改变的数据进行还原

  2. 可以使用动调让程序自动解密,然后重新构造被SMC的函数

  3. 也可以使用ida脚本直接对数据修改,得到原来的函数

原文始发于微信公众号(火炬木攻防实验室):SMC在CTF逆向中的应用

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年8月4日21:23:08
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   SMC在CTF逆向中的应用https://cn-sec.com/archives/3034266.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息