NSSCTF题包(脱壳类和SMC)
题包里的这些类型的题这些已经接触了很长时间但是仍然需要进行巩固在这里先感谢师傅们还有胡楚昊大佬对我的帮助和支持这套题还有去花类的前面文章讲过了脱壳类主要应用的是自动脱壳以及ESP定律法手动脱壳ESP定律法ESP 定律法堆栈平衡定律是 Windows x86 程序脱壳中快速定位 OEP原始程序入口点的核心手法基于壳的堆栈保护与恢复机制对 UPX 、Aspack等压缩壳及部分加密壳高效适用。E是Entry入口我们要找到壳真正把控制权交给原程序的地方也就是我们常说的OEPOriginal Entry Point原始入口点那么需要我们让程序跑起来穿过壳的初始化、自解密、自校验在“壳 → 原程序”交接点停住S是搜索和还原让程序看起来像个正常程序。在OEP附近但是程序结构还不完整。就是要在OEP处Dump内存这个时候壳已经解除P是修复程序让dump出来的程序可以独立、稳定运行。像修复IAT、修复OEP、去壳残留等这些需要工具或者更多的操作核心原理壳执行流程通常为pushad压入所有通用寄存器→ 解压 / 解密原程序 → popad恢复寄存器→ jmp OEP。ESP 定律利用 “堆栈访问断点” 在壳恢复堆栈时触发中断快速接近 OEP本质是堆栈平衡与硬件断点的结合。工具X64/32dbgOllydbg我用的是X64/32dbg步骤看核心原理其实可能不太能明白先梳理一下用手动工具脱壳的步骤1. 用X64/32dbg载入加壳程序入口常见pushad。F8 单步一次观察 ESP 变红值变化。2. 右键地址ESP→在内存窗口中转到内存1。在左下数据窗口选中该地址→右键→断点→硬件访问→DWORD或 Byte/Word。3. F9 运行程序会在popad/jmp前触发硬件断点这里下方或者断点处有提示。先按F8再按F8 单步跳过popad与jmp最终停在 OEP常见call或push ebp开头。4. 取消硬件断点可做可不做用插件Scylla脱壳并修复 IAT。例题程序2这里先以NSSCTF的题包的例题为例子NSSCTF需要购买官方也用一个文档例子说了这个脱壳方法这里我就实操一下先查壳32位。用X32dbg打开初始位置在pushad处这个指令的意思是压入所有的通用寄存器F8单步执行一次这里会发现右侧ESP的地址是红色的此时在ESP的地址处下一次断点在下方此处继续下断点F9直接跳转到断点处此时就是程序的入口处F8单步执行到ret再点一次到push ebp这里就到了程序的入口点就可以在这dump上面有插件点击ScyllaIAT Autosearch继续依次Get ImportsdumpFix Dump选择dump出来文件的地址即可程序3这题直接upx -d即可我尝试了一下ESP定律发现单步执行太慢了但是我连续两次F9找到了入口我同学说他dump不出来但是这里可以dump出来但是不知道为啥程序432位可以用UPX直接脱也可以用dbg跟第三题一样思路程序5OEP定律直接脱到retn后直接dump即可SMC首先解释一下什么是SMC。SMC就是自修改代码。在一些程序中用ida打开后解析的是乱码而通过SMC程序在运行时自己修改自己的代码段原本只读的指令区把加密 / 混淆的指令还原成能正常执行的指令。这时候就需要用到动调查看解密后的代码具体操作会以例题来讲解程序6查壳进入ida。分析代码发现是有SMC那么就在SMC运行后的函数下断点开始动调输入数据找到对应函数这时已经解密但还不是代码。按U是将代码转换为数据解除定义按C是将数据转换为代码按P定义函数一定要记住到retn再定义看加密代码跟进byte_40A000[i]看数据一个简单的逆向写代码str[0x9f, 0x91, 0xa7, 0xa5, 0x94, 0xa6, 0x8d, 0xb5, 0xa7, 0x9c, 0xa6, 0xa1, 0xbf, 0x91, 0xa4, 0x53, 0xa6, 0x53, 0xa5, 0xa3, 0x94, 0x9b, 0x91, 0x9e, 0x8f, 0x0, 0x0, 0x0] flag for i in str: flag chr((i^0x39)-57) print(flag)程序7查壳进入main函数在GetNextNumber函数里介绍了SMC值得看看。下面有count之类的这段代码的作用相当于一直自增1可以通过动调查看这里选择动调在strcpy前的if语句下断点。这个程序要用Linux动调。需要把ida的一个文件linux_server64放入Linux还有程序也放进去动调前的选项动调输入之后在函数发现报错以为是花指令但是仔细查看之后发现是函数类型搞错了是int不是void。按y修改转换重新定义函数即可看到正常逻辑这是GetNextNumber的数值后面是算法很简单写代码flag v2[0]*64 v2[0] 78 v2[1] 82 v2[2] 81 v2[3] 64 v2[4] 80 v2[5] 65 v2[6] 117 v2[7] 97 v2[8] 43 v2[9] 44 v2[10] 79 v2[11] 37 v2[12] 106 v2[13] 92 v2[14] 52 v2[15] 93 v2[16] 49 v2[17] 101 v2[18] 58 v2[19] 34 v2[20] 75 v2[21] 28 v2[22] 88 v2[23] 93 v2[24] 27 v2[25] 89 v2[26] 75 v2[27] 26 v2[28] 88 v2[29] 76 v2[30] 80 v2[31] 72 v2[32] 63 v2[33] 82 v2[34] 17 v2[35] 14 v2[36] 66 v2[37] 58 v2[38] 71 v2[39] 9 v2[40] 60 v2[41] 8 v2[42] 60 v2[43] 78 v2[44] 51 v2[45] 54 v2[46] 2 v2[47] 53 v2[48] 3 v2[49] 46 v2[50] -1 v2[51] 5 v2[52] 35 v2[53] 30 v2[54] 18 v2[55] 13 v2[56] 30 v2[57] -6 v2[58] 59 v2[59] -4 v2[60] 51 v2[61] 6 v2[62] 22 v2[63] 62 for i in range(64): flagchr(v2[i]i) print(flag)运行即可反调试程序12这里存在反调试如果存在调试就闪退没有就输出IS herejnz此函数触发了闪退需要把jnz改为jz此时应用一下就可以调试成功但是你打开程序发现闪退这是因为此时的命令和原始命令不同可以把原始的retn给nop掉这道题后续会补充讲解
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2449879.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!