问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
从2022 网鼎杯拾遗 UPX
前几天,参加了2022网鼎杯青龙组的比赛,第一道逆向考察点是upx脱壳,然而由于好久没有做过upx相关的题目了,有些生疏了,修了半天环境竟然都没有发现原来是特征值被篡改了,这提醒我,是时候该回头总结一下upx类题目了
0x00 前言 ======= 前几天,参加了2022网鼎杯青龙组的比赛,第一道逆向考察点是upx脱壳,然而由于好久没有做过upx相关的题目了,有些生疏了,修了半天环境竟然都没有发现原来是特征值被篡改了,这提醒我,是时候该回头总结一下upx类题目了 0x01 upx ctf normal题型 ===================== 能用upx -d直接脱掉的题目就不说了 目前比赛中流行的upx类题目解法主要包括两种,第一种、工具受阻直接采取手工脱壳的方法(压缩壳甚至可以直接带壳跑,不会损坏文件内容)第二种针对篡改特征值类防脱壳,可以使用二进制文本工具修复特征值。此外,我们再研究以下upx各种防脱壳的办法(以备以后出题 huohai 大家(雾)) 0x02 修复特征值类 =========== \[2022网鼎杯青龙组\]fakeshell ----------------------- 拿到exe,查壳发现UPX壳 使用upx -d脱壳失败。当时比赛想带壳跑,但是一直提示缺少两个dll文件(后来发现是vs2010没装全的原因)但是其实这个提示误导了我,导致我没有看到很明显的upx特征值被修改了 ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-492824183da1558ab73606854e9fe62f6c7aa592.png) 010 editor打开源文件,发现两处被篡改的特征值 将其修复为UPX0,UPX1 ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-f5b498b07450dba22d6e8e95fb9936d7b96db90a.png) 修复后就可以成功用upx -d脱壳了 ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-5ce51d1c6d270f73ecd9ade9471d912f04a90bd4.png) ida分析,发现了两个处理: ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-aa7a9dbd747f0a2dbe668ca33864ef5a1d564ed3.png) ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-7012d3c5492bcf16327c38ff5cf149f206290943.png) 很简单的逻辑加密,写脚本得到flag即可 ```python a= [0x4B,0x48,0x79,0x13,0x45,0x30,0x5C,0x49,0x5A,0x79,0x13,0x70,0x6D,0x78,0x13,0x6F,0x48,0x5D,0x64,0x64] flag="" for i in range(len(a)): a[i]=(a[i]^0x50)-10 for i in range(len(a)): flag+=chr(a[i]^0x66) print(flag) ``` \[HGAME2022 WEEK2\] upx magic ----------------------------- 再来趁热打铁回顾一道 2022 年初HGAME 的一道同类型的题目,,不过这题是改变了upx加壳后的magic 因此直接查壳会显示没有加壳,比网鼎杯这道题更加高明。 ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-eb681311650be7da38ce029d4308b0acf87af674.png) 程序放入010editor中打开 搜索upx,我们可以看到原本的特征值upx!被篡改成了upx? 因此我们把每一处修复回来就可以了(55 50 58 35 改为 55 50 58 21) ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-f689dc949a8c7f6acde019a7813fe063f880d6b3.png) ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-9bb0b8406d3332bf999994dd0b91bfc840932162.png) 成功脱壳 ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-fea0d2f2d3f7c54aa732c709ff942e898c479cc0.png) ida打开分析,发现是crc16加密 ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-5f1a5021915de22c0f31149c73791aabdce6b5c0.png) 写脚本爆破flag ```c #include <stdio.h> #include <string.h> #include <stdlib.h> using namespace std; int main() { int cipher[] = {0x8d68, 0x9d49, 0x2a12, 0xab1a, 0xcbdc, 0xb92b, 0x2e32, 0x9f59, 0xddcd, 0x9d49, 0xa90a, 0xe70, 0xf5cf, 0xa50, 0x5af5, 0xff9f, 0x9f59, 0xbd0b, 0x58e5, 0x3823, 0xbf1b, 0x78a7, 0xab1a, 0x48c4, 0xa90a, 0x2c22, 0x9f59, 0x5cc5, 0x5ed5, 0x78a7, 0x2672, 0x5695}; for(int k=0;k<32;k++) { for(int i=0x2e;i<0x7f;i++) { unsigned int crc =i; crc<<=8; for(int j=0;j<8;j++) { if((crc & 0x8000)!=0) { crc<<=1; crc=crc^0x1021; } else { crc<<=1; } } if(cipher[k] == (crc&0xffff)) { printf("%c",i); break; } } } system("pause"); return 0; } ``` 0x03 手动脱壳 ========= 这里介绍最常用的两种方法,足以应对ctf题目。采用的样例文件来自吾爱破解网站 方法一:单步跟踪法 --------- ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-006bf5e89304695ccccd5c5decb3ee0608a117c6.png) 接着用od载入程序,载入后进行调试。这里介绍 f8(快捷键) 为单步执行。单步跟踪的脱壳原则是允许向下的跳转不执行向上的跳转。 那当我们遇到向上的跳转时怎么办呢。有两种办法: 第一种,选中跳转命令下一行,右击->断点->运行到选定位置 第二种 选中跳转命令下一行,右击->断点->切换 运行。再点切换取消断点 一般采用第一种方法(快捷键f4) 向下的跳转如下图:红色线连接的箭头向下,这时候我们直接单步执行(f8)即可 ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-01a68cf5ca09069ec1260a0a0060a597ff8958af.png) 向上的跳转如下图,根据我们之前说的脱壳原则,不允许步入向上的跳转,选中该语句下一行 运行到此处即可(f4) ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-bb18342757a89562fb8e2f55b5f9587a9d2ff057.png) 就这样按部就班的进行动调即可,但是还有一些特殊情况需要规避,例如下图 ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-9ff4858abc715b8804597aaf15f7423ab428b8a9.png) 按照常理,面对向上的跳转,我们应该f4进跳转语句的下一行,但是我们发现下一行仍然是一个跳转语句,所以我们选择运行到再下一行也就是mov命令行。 遇到的下一个特殊情况如下图所示,jmp命令的下一行为call命令,采用同样的方法,执行到再下一行popad行 继续单步,步入到如下命令 目前的地址范围为0057开头,而该语句直接跳转到0047开头,如此大范围的跳转,一般预示着动调的结束,我们将要进入真正的入口点(OEP) ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-cf0b3ac42e75e72857be4f33ae108d9fee53504e.png) f8单步跳转进入真正的入口点 ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-475bccfe50f176c02bacdeaaa15143f308ea1e80.png) 右击该语句,使用olldump脱壳, 方法二:ESP定律法 ---------- **名词定义**: esp:一个寄存器 esp定律:ESP定律又称堆栈平衡定律,是应用频率最高的脱壳方法之一 ,不论是新手还是老手都经常用到。 **原理:堆栈平衡** 由于在程序自解密或者自解压过程中, 多数壳会先将当前寄存器状态压栈, 如使用`pushad`, 而在解压结束后, 会将之前的寄存器值出栈, 如使用`popad`. 因此在寄存器出栈时, 往往程序代码被恢复, 此时硬件断点触发(这就是我们要下硬件断点的原因),然后在程序当前位置, 只需要一些单步操作, 就会到达正确的OEP位置. **操作步骤** 在pushad处(程序打开处f8单步执行。发现只有esp的值发生变化)右击esp->在数据窗口中跟随。在esp地址处下硬件访问断点。 ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-70de2fae1050347ffa398dcfbb684ba69913cd64.png) 单步运行后也可以使用commend命令寻址下断点 dd XXXXX(esp地址) hr XXXXX 之后点击下图圈出部分运行停止到jmp语句。打开调试,删除硬件断点后,稍作跟进即可找到程序真正的oep ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-49684e134a96738278b0a74f0145305710e9165b.png) 找到真正入口点之后就可以愉快的脱壳了,该方法适用于几乎全部的压缩壳以及早期的加密壳 dump程序 ------ 在找到程序 OEP 后, 我们需要将程序 dump 出来, 并重建`IAT`. `IAT`全名是`Import Address Table`, 表项指向函数实际地址. 比如如下, 我们找到了 OEP, 到达了程序的真正入口点. 我们这时就需要将程序 dump 出来. 我们右键, 选择`"用OllyDump脱壳调试进程"`主要就是看看`入口点地址`有没有选对. 然后取消勾选`重建输入表`. ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-ae041b5f5bffc53adfebb60378b8c8769d927612.png) 尝试来运行一下脱壳出的文件dump1,发现运行错误,这是由于脱壳过程中程序的IAT出现了问题,接下来我们来重建`IAT` ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-98647cd1789e299e9a4808ee70812bd297c356c0.png) 打开`ImportREC`, 选择一个正在运行的进程`原版.exe`(`原版.exe`是我在 OD 中正在调试的进程, OD 中的`EIP`正处在`OEP`位置, 在用`Ollydump`之后不要关闭这个进程哦.) Ollydbg 里我们知道程序目前在的入口点是`004022CA2, 而镜像基址是`00400000` 因此我们这里需要填写`OEP`是`00022CA2`点击自动获取iat接下来可能会弹出提示框 "发现可能是原 IAT 地址"点击确定再点击获取输入表 ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-5bbb5a95a3cb4383da451db7504a7ec5a327cfae.png) IAT表修复完成后,最后点击转储到文件完成iat表的修复 ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-e8636f852dd433d1c24a23253be131fcb5e56be0.png) UPX 防脱壳进阶技术研究 ------------- 目前ctf 中大多数upx题型还是处在不能脱壳但是可以识别upx的阶段,接下来我们学习一些方法让查壳程序无法识别出upx壳的方法。 ### 去掉UPX特征码 查阅资料我们了解到upx的特征码是如下内容 ```php 特征码1:60 BE ?? ?? ?? 00 8D BE ?? ?? ?? FF 特征码2:60 BE ?? ?? ?? ?? 8D BE ?? ?? ?? ?? 57 EB 0B 90 8A 06 46 88 07 47 01 DB 75 ?? 8B 1E 83 ?? ?? 11 DB 72 ?? B8 01 00 00 00 01 DB 75 特征码3:55 FF 96 ?? ?? ?? ?? 09 C0 74 07 89 03 83 C3 04 EB ?? FF 96 ?? ?? ?? ?? 8B AE ?? ?? ?? ?? 8D BE 00 F0 FF FF BB 00 10 00 00 50 54 6A 04 53 57 FF D5 8D 87 ?? ?? 00 00 80 20 7F 80 60 28 7F 58 50 54 50 53 57 FF D5 58 61 8D 44 24 80 6A 00 39 C4 75 FA 83 EC 80 ``` 随便找了一个upx加密的文件 放到od中跑起来,来研究如何对抗这三段特征码 ### 对抗特征码1 ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-00aab36a16cb819ce1a46202af81fcb6bbec0f84.png) 010editor 找到对应位置 添加混淆代码 ```php 60 pushad 90 nop BE 00004100 mov esi,packed.00410000 8DBE 0010FFFF lea edi,dword ptr d[esi+FFFF1000] 57 push edi EB 01 jmp short packed.00418121 90 nop 8A06 mov al,byte ptr ds:[esi] ``` ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-2f8952ed9030d16f0fca4ac63bc96ea3eab8a448.png) ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-e113a9e71d46ac02da15210f791363d8e5052f64.png) 可以看到我们混淆特征码1之后查壳程序已经验证不出upx壳了,但是还是能看到特征值的,无法完全混淆。 ### 对抗特征码2 ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-38925bf196e56fe18972400fab1e0964c6e3f6e9.png) 修改前: ```php 00418131 72 ED jb short packed.00418120 00418133 B8 01000000 mov eax,1 00418138 01DB add ebx,ebx ``` 修改后: ```php 00418295 39C4 cmp esp,eax 00418297 ^ 0F85 F6FFFFFF jnz packed.00418293 0041829D 83EC 80 sub esp,-80 004182A0 - E9 7EDDFEFF jmp packed.00406023 ``` ### 对抗特征码3: 修改前: ```php 00418295 39C4 cmp esp,eax 00418297 ^ 75 FA jnz short packed.00418293 00418299 83EC 80 sub esp,-80 0041829C - E9 82DDFEFF jmp packed.00406023 ``` 修改后: ```php 00418295 39C4 cmp esp,eax 00418297 ^ 0F85 F6FFFFFF jnz packed.00418293 0041829D 83EC 80 sub esp,-80 004182A0 - E9 7EDDFEFF jmp packed.00406023 ``` ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-b205d17ac4737c52d51879437d1a106fa72e8933.png) 其实就是把jnz short XXX改成jnz long XXX 加垃圾区段 ----- 发现之前的混淆并不能使得exeinfo完全识别不出来 exeinfo牛逼 那我们再学习一些别的办法,比如再在文件末尾添加512个00的脏数据 ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-1e9585c864e596b4c2ee382d760f49046600ec9a.png) PE头移动 ----- 原来0xec、后来的0x54、0x55处是PE头大小,0x3c是PE头起始位置,所有地址反着写. ![image.png](https://shs3.b.qianxin.com/attack_forum/2022/08/attach-79f9712afa55a9d453f65532232339247ac19ee2.png) 修改后 ```php Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F 00000000 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 MZ?  00000010 B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 ? @ 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000030 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00 @ 00000040 50 45 00 00 4C 01 03 00 9A DA 22 4D 00 00 00 00 PE L 氌"M 00000050 00 00 00 00 78 01 0F 01 0B 01 06 00 00 90 00 00 x ? 00000060 00 20 00 00 00 F0 00 00 10 81 01 00 00 00 01 00 ? ? 00000070 00 90 01 00 00 00 40 00 00 10 00 00 00 02 00 00 ? @ 00000080 04 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 00000090 00 B0 01 00 00 10 00 00 00 00 00 00 02 00 00 00 ? 000000A0 00 00 10 00 00 10 00 00 00 00 10 00 00 10 00 00 000000B0 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 000000C0 D0 A5 01 00 04 02 00 00 00 90 01 00 D0 15 00 00 啸 ? ? 000000D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000000E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000000F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00000190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000001A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000001B0 00 00 00 00 00 00 00 00 ``` 0x04 后记 ======= 目前能够总结到的关于upx壳的内容就这么多,ctf中脱壳也不作为逆向的主要得分点,但是还是要尽量掌握全面常见的方式方法,系统梳理,比赛的时候才不容易失误,这次比赛的经历也算是给我长了一个教训,知己知彼才能百战不殆 0x05 参考链接 ========= [https://bbs.pediy.com/thread-258222.htm#msg\_header\_h1\_0](https://bbs.pediy.com/thread-258222.htm#msg_header_h1_0) <https://www.52pojie.cn/thread-326995-1-1.html>
发表于 2022-09-08 09:36:36
阅读 ( 7082 )
分类:
漏洞分析
0 推荐
收藏
0 条评论
请先
登录
后评论
绿冰壶
学生
18 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!