upx脱壳

梦应逍遥  金牌会员 | 2024-10-8 16:03:25 | 来自手机 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 576|帖子 576|积分 1728

参考链接:手动去upx特性_upx -d-CSDN博客
参考链接:linux 下 upx 脱壳笔记
参考链接:三叶草二进制招新培训
参考链接:怎样用x64dbg UPX手动脱壳(64位)
  upx壳简介

upx壳是一种压缩壳,在CTF比赛中比力常见。
针对upx壳有专业的脱壳工具。
当然我们也可以直接手脱,手动脱壳我们就需要找到加壳步伐的OEP然后dump文件内存。
   OEP原始步伐入口点。EP(Entry Point),意即步伐的入口点。而OEP是步伐的原始入口点,一个正常的步伐只有EP,只有入口点被修改的步伐(加壳等),才会拥有OEP。
  工具脱壳

UPX(Ultimate Packer for eXecutables)是一个开源的可执行文件压缩器,用于减小可执行文件的巨细,同时保持其功能。UPX 支持多种操纵系统,包罗 Linux、Windows 和 macOS。
upx工具使用请参考这篇文章。
   upx工具使用:【逆向】UPX工具使用及加壳_upx.exe-CSDN博客
  常规upx工具脱壳

直接使用 upx -d 进行脱壳
  1. #exe文件
  2. upx -d demo.exe
  3. #elf文件
  4. upx -d demo
复制代码
例题

   [SWPUCTF 2023 秋季新生赛]UPX
  分析

exeinfo查察发现upx加壳。

脱壳

直接使用upx -d进行脱壳。
可以看到脱壳成功。

exeinfo查察确认一下
确认脱壳成功

ida打开查察反编译代码,发现flag

upx魔改壳

常规upx壳只要利用upx工具直接执行upx -d下令即可脱壳。
不外只要做一些简单的修改就可以让upx工具失效。
这种魔改壳在CTF中很常见。
1.修改区段名

​ 我们先来查察一下未修改前的文件信息。

​ 可以看到图中显示了upx1和3.91 upx这两个特性标识。

​ 然后查察一下加壳后的区段窗口,发现只有三个区段。最明显的特性upx0和upx1.
​ 我们只需要修改它,就可以让upx工具无法脱壳。
​ 我们利用二进制编辑工具将upx改成rpx


尝试脱壳
​效果:

​可以看到失败了。
​只要改回原样就可以进行脱壳。
2.修改标识


​可以看到3.96.UPX!特性码。我们可以修改3.96版本号开始24个字节的内容。都不会对步伐运行产生影响。
​修改标识之后,upx工具就无法脱壳。不外可以利用UPX Unpacker for Dummies工具进行脱壳也可以直接手脱。
反面我们会讲怎样手动脱壳。
例题

   [LitCTF 2024]hello_upx
  分析

exe文件,查壳发现存在upx壳。

直接使用脱壳机,脱壳失败。

提示信息文件被修改,用010_Editor打开
发现有四处地方被修改

这里我们列出正常upx加壳文件的区段信息进行对比

   UPX0和UPX1是加UPX壳后的两个区段名。此中UPX1区段包罗了需要解压的数据块。
.rsrc是步伐资源信息区段名,这个区段含有原资源段的完整头部以及图标、Manifest、版本等未被压缩的资源,当然另有UPX自身需要的导入信息等(假如步伐自身不含资源段,加壳后就是UPX2)
  分析修改
  1. 1. upx0被改成了小写
  2. 2. upx1被改成了小写
  3. 3. upx2被改成了小写
  4. 4. upx!被改成了小写
复制代码
恢复

将upx0、upx1、upx2和upx!全部修改为大写

脱壳


可以看到脱壳成功。
分析代码逻辑

exp

根据代码逻辑构造exp
  1. data=[0x4C, 0x68, 0x72, 0x40, 0x50, 0x41, 0x75, 0x70, 0x2B, 0x63, 0x59, 0x25, 0x61, 0x58, 0x51, 0x65, 0x20, 0x4E, 0x5A, 0x1E, 0x60, 0x4E, 0x5E, 0x4F, 0x65]
  2. flag=""
  3. for i in range(len(data)):
  4.         flag+=chr((data[i]+i))
  5. print(flag)
  6. #LitCTF{w3lc0me_t0_l1tctf}
复制代码
手脱

exe

自己写的步伐加壳,手脱。

入口不是pushad,只能一步一步单步步过。
   pushad意味着upx壳解压缩代码的入口。
64位步伐中没有puahad,而是用几个push汇编代码替代。32位步伐中存在pushad。
  遵照单步定律,向下跳转答应实现,向上跳转不答应实现。
   向下的红色小箭头就是向下的跳转,线为红色即是跳转建立,线为白色就是跳转不建立。
同理向上的红色小箭头就是向上的跳转。
  

一直单步步过,直到发现这样的多个push指令为止。

   根据esp定律下断点探求OEP
  f8单步执行一下,让rsp发送厘革。

查察寄存器窗口,发现rsp产生厘革

右击rsp,选中在栈中转到。
右击栈顶,选制止点,选择硬件访问断点,选择4字节。

设置硬件断点后f9运行。
之后发现下面有一个比力大幅度的jmp跳转,而且已经显示文件特性。
判断这个特性会跳转到OEP。
选中jmp指令,然后f4。

之后直接f8跳到oep


接下来dump文件
点击dump之后将文件生存。
但是这样dump后的文件是无法执行的,所以我们要修复文件。

修复文件
先点击 IAT Autosearch,再点击 Get Imports ,在 Imports 列表中右键delete删掉带有红叉的。
之后点击 Fix Dump 选中之前的Dump文件,修复成功。


选中之前dump的文件修复既可。

脱壳之后运行步伐测试。
成功执行步伐,dump文件成功。

exeinfo确认脱壳
发现仍然保留特性信息

ida打开确认
确认已脱壳

elf

elf脱壳的过程

探求OEP

目标:找到原始步伐入口地址(OEP)
​从启动函数start开始设置断点,一步一步单步步过。
​发现ret指令直接F4然后F7,直到发现endbr64指令(即源步伐代码开头)。
​endbr64是elf步伐开头的汇编指令,即是OEP
​然后查察步伐代码,发现将函数地址送入rdi
判断函数地址为main函数地址
判断这是源步伐代码,进入
c将数据解释为代码,p创建函数
f5反编译,得到main函数伪代码
dump内存

根据OEP利用脚本dump内存到文件,并修复运行。
例题

自己写一段代码编译加壳。
  1. #include<stdio.h>
  2. int main()                                                                                                            1 {
  3.     char buf[10]={0};
  4.     puts("input:");
  5.     read(0,buf,10);
  6.     printf("%s",buf);
  7.     return 0;
  8. }
复制代码
编译,这里需要静态编译,要不然文件太小加不了壳。

加壳,可以看到加壳成功

exeinfo扫一下,可以看到显示upx壳

探求oep

ida打开文件
直接在启动函数位置下断点,然后动态调试。


下翻,翻到ret指令直接f4运行到这里,然后f8。
重复以上过程,假如没找到ret指令就执行最近的jmp跳转。
当看到下面这个汇编制止代码时我们就快到OEP了。
之后f4运行到ret位置,之后f8单步。

跳转到OEP
看起来都是数据,按快捷键c将数据解释为代码。

之后看到汇编代码endbr64,elf64位步伐的入口。
是由它来调用初始化步伐,进而调用main函数。
这里被传地址给rdi的byte_401775就是原步伐main函数。

进入main函数查察
按c解释为代码,然后在endbr64处按快捷键p创建函数。

之后就可以f5反编译了。

main函数反编译代码
CTF中一般就可以在这里分析步伐代码解题了。
不外接下来我们要学习怎样dump文件。

dump内存到文件

先回到OEP这里。
确保eip执向endbr64汇编代码。

然后,alt+f7快捷键打开并运行脚本。
dump64位步伐选用64位文件(idc脚本代码下面有)。

执行,期待执行完毕。

执行完毕

dump文件的存放路径在脚本中设置。
执行文件
可执行,则dump文件成功。

exeinfo扫一下,确认是否脱壳。
显示无壳,则脱壳成功。

idc dump内存文件代码

64位步伐dump内存代码

  1. #include <idc.idc>
  2. #define PT_LOAD              1
  3. #define PT_DYNAMIC           2
  4. static main(void)
  5. {
  6.          auto ImageBase,StartImg,EndImg;
  7.          auto e_phoff;
  8.          auto e_phnum,p_offset;
  9.          auto i,dumpfile;
  10.          ImageBase=0x400000;
  11.          StartImg=0x400000;
  12.          EndImg=0x0;
  13.          if (Dword(ImageBase)==0x7f454c46 || Dword(ImageBase)==0x464c457f )
  14.   {
  15.     if(dumpfile=fopen("G:\\dumpfile","wb")) //这里可以更改路径
  16.     {
  17.       e_phoff=ImageBase+Qword(ImageBase+0x20);
  18.       Message("e_phoff = 0x%x\n", e_phoff);
  19.       e_phnum=Word(ImageBase+0x38);
  20.       Message("e_phnum = 0x%x\n", e_phnum);
  21.       for(i=0;i<e_phnum;i++)
  22.       {
  23.          if (Dword(e_phoff)==PT_LOAD || Dword(e_phoff)==PT_DYNAMIC)
  24.                          {
  25.                                  p_offset=Qword(e_phoff+0x8);
  26.                                  StartImg=Qword(e_phoff+0x10);
  27.                                  EndImg=StartImg+Qword(e_phoff+0x28);
  28.                                  Message("start = 0x%x, end = 0x%x, offset = 0x%x\n", StartImg, EndImg, p_offset);
  29.                                  dump(dumpfile,StartImg,EndImg,p_offset);
  30.                                  Message("dump segment %d ok.\n",i);
  31.                          }   
  32.          e_phoff=e_phoff+0x38;
  33.       }
  34.       fseek(dumpfile,0x3c,0);
  35.       fputc(0x00,dumpfile);
  36.       fputc(0x00,dumpfile);
  37.       fputc(0x00,dumpfile);
  38.       fputc(0x00,dumpfile);
  39.       fseek(dumpfile,0x28,0);
  40.       fputc(0x00,dumpfile);
  41.       fputc(0x00,dumpfile);
  42.       fputc(0x00,dumpfile);
  43.       fputc(0x00,dumpfile);
  44.       fputc(0x00,dumpfile);
  45.       fputc(0x00,dumpfile);
  46.       fputc(0x00,dumpfile);
  47.       fputc(0x00,dumpfile);
  48.       fclose(dumpfile);
  49.         }else Message("dump err.");
  50. }
  51. }
  52. static dump(dumpfile,startimg,endimg,offset)
  53. {
  54.         auto i;
  55.         auto size;
  56.         size=endimg-startimg;
  57.         fseek(dumpfile,offset,0);
  58.         for ( i=0; i < size; i=i+1 )
  59.         {
  60.         fputc(Byte(startimg+i),dumpfile);
  61.         }
  62. }
复制代码
32位步伐dump内存代码

  1. #include <idc.idc>
  2. #define PT_LOAD              1
  3. #define PT_DYNAMIC           2
  4. static main(void)
  5. {
  6.     auto ImageBase,StartImg,EndImg;        //基址 08048000
  7.     auto e_phoff;
  8.     auto e_phnum,p_offset;        //paddr 0xc 地址,pmemsz ox14大小,p_offset 0x4
  9.     auto i,dumpfile;
  10.     ImageBase=0x08048000;
  11.     StartImg=0x08048000;
  12.     EndImg=0x0;
  13.     Message("%8x\n",Dword(ImageBase));
  14.     if (Dword(ImageBase)==0x7f454c46 || Dword(ImageBase)==0x464c457f )
  15.     {
  16.         if(dumpfile=fopen("G:\\dumpfile","wb"))//这里可以更改路径
  17.         {
  18.             e_phoff=ImageBase+Word(ImageBase+0x1c);
  19.             e_phnum=Word(ImageBase+0x2c);
  20.             for(i=0;i<e_phnum;i++)
  21.             {
  22.                  if (Dword(e_phoff)==PT_LOAD || Dword(e_phoff)==PT_DYNAMIC)
  23.                      
  24.                     {   p_offset=Dword(e_phoff+0x4);               
  25.                         StartImg=Dword(e_phoff+0xc);
  26.                         EndImg=Dword(e_phoff+0xc)+Dword(e_phoff+0x14);
  27.                              
  28.                                 dump(dumpfile,StartImg,EndImg,p_offset);
  29.                                 Message("dump LOAD%d ok.\n",i);
  30.                     }      
  31.                      
  32.                 e_phoff=e_phoff+0x20;
  33.             }
  34.             fseek(dumpfile,0x30,0);
  35.             fputc(0x00,dumpfile);      
  36.             fputc(0x00,dumpfile);      
  37.             fputc(0x00,dumpfile);      
  38.             fputc(0x00,dumpfile);
  39.             fclose(dumpfile);
  40.         }else Message("dump err.");
  41.     }
  42. }
  43. static dump(dumpfile,startimg,endimg,offset)
  44. {
  45.     auto i;
  46.     auto size;
  47.     size=endimg-startimg;
  48.     fseek(dumpfile,offset,0);
  49.     for ( i=0; i < size; i=i+1 )
  50.     {
  51.             fputc(Byte(startimg+i),dumpfile);
  52.         }
  53. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

梦应逍遥

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表