Linux | UPX变形壳脱壳Tips

UPX是一种古老的压缩壳,因为高压缩比使用方便,常被各个黑产组织使用,为了防止恶意程序被UPX程序正常解压,分析程序本体。因此UPX压缩壳的变形方法层出不穷,被花式修改。

这篇文章主要总结Linux平台下,遇到过的UPX变形壳类型以及对应脱壳技巧Tips,方便以后快速脱壳。

UPX压缩原理与文件结构,可参考以下文章,不再赘述:

https://bbs.kanxue.com/thread-275753.htm

1. UPX变形手法

变形手法包括不限于以下方式:

  1. 修改UPX两个区段名称

  2. 修改三个UPX特征码

  3. 修改或去除UPX!相关字符串

  4. 修改或去除p_info结构信息

  5. 添加冗余数据至文件尾部

2. UPX脱壳Tips

2.1 快速识别变形类型

利用UPX原生程序直接尝试脱壳,根据报错信息快速识别变形类型。

大致分为三种告警:

  • need a newer version of UPX

  • p_info corrupted

  • not packed by UPX

提示 need a newer version of UPX ,使用新版本的UPX程序即可。

提示 p_info corrupted,p_info结构被破坏需要修复后脱壳。

提示 not packed by UPX,推测是否修改了UPX节区信息/l_magic结构/增加冗余数据,需要进一步确认后修复。

2.2 修复UPX特征码

Winhex中发现UPX被修改。

全局替换为UPX!。

即可利用UPX原生程序成功脱壳。

2.3 修复p_info结构信息

p_info头部结构体成员p_blocksize信息被抹去。

p_filesize与p_blocksize值相同,p_filesize记录在文件末尾偏移8字节的位置。

复制p_blocksize值到p_info中。

即可利用UPX原生程序成功脱壳。

2.4 删除冗余数据

winhex中发现最后一个UPX!节区超过32字节。

删除此节区超过32字节后面的冗余数据。

其余部分利用UPX原生程序即可修复,并成功脱壳。

2.5 使用IDA脱壳

开启IDA调试,F7步入第一个Call。

F8跳过三个循环。

IDA识别到ELF头部信息,即将跳转值ELF程序入口点。

跳转找到ELF入口点。

dump脱壳后的文件。

dumpfile.idc

#include #define PT_LOAD              1#define PT_DYNAMIC           2static main(void){  auto ImageBase,StartImg,EndImg;  auto e_phoff;  auto e_phnum,p_offset;  auto i,dumpfile;  ImageBase=0x400000;  StartImg=0x400000;  EndImg=0x0;  if (Dword(ImageBase)==0x7f454c46 || Dword(ImageBase)==0x464c457f )  {    if(dumpfile = fopen("C:\\Users\\admin\\Desktop\\infected\\20240327\\DumpFile","wb"))    {      e_phoff=ImageBase+Qword(ImageBase+0x20);      Message("e_phoff = 0x%x\n", e_phoff);      e_phnum=Word(ImageBase+0x38);      Message("e_phnum = 0x%x\n", e_phnum);      for(i=0;i      {        if (Dword(e_phoff)==PT_LOAD || Dword(e_phoff)==PT_DYNAMIC)        {           p_offset=Qword(e_phoff+0x8);          StartImg=Qword(e_phoff+0x10);          EndImg=StartImg+Qword(e_phoff+0x28);          Message("start = 0x%x, end = 0x%x, offset = 0x%x\n", StartImg, EndImg, p_offset);          dump(dumpfile,StartImg,EndImg,p_offset);          Message("dump segment %d ok.\n",i);        }            e_phoff=e_phoff+0x38;      }
fseek(dumpfile,0x3c,0); fputc(0x00,dumpfile); fputc(0x00,dumpfile); fputc(0x00,dumpfile); fputc(0x00,dumpfile);
fseek(dumpfile,0x28,0); fputc(0x00,dumpfile); fputc(0x00,dumpfile); fputc(0x00,dumpfile); fputc(0x00,dumpfile); fputc(0x00,dumpfile); fputc(0x00,dumpfile); fputc(0x00,dumpfile); fputc(0x00,dumpfile);
fclose(dumpfile); } else Message("dump err."); }}static dump(dumpfile,startimg,endimg,offset) { auto i; auto size; size = endimg-startimg; fseek(dumpfile,offset,0); for ( i=0; i < size; i=i+1 ) { fputc(Byte(startimg+i),dumpfile); }}

2.6 使用修复工具

upx-recovery-tool使用方法参考Github。

https://github.com/NozomiNetworks/upx-recovery-tool

upxfix使用方法参考Github。

https://github.com/srozb/upxfix

请使用浏览器的分享功能分享到微信等