吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 28760|回复: 73
收起左侧

[原创] ELF64手脱UPX壳实战

  [复制链接]
一米丶阳光 发表于 2019-11-4 22:01
本帖最后由 一米丶阳光 于 2019-11-4 22:12 编辑

最近在做CTF逆向习题时,遇到一个带有UPX壳的ELF CrackMe,题目的目标是找到flag。
由于此前只对PE做过UPX脱壳,本来使用UPX的脱壳工具,用命令就能脱壳,但是出于研究的目的,看看ELF文件的UPX如何手动脱壳,话不多说,进入正题~

0x1 工具和环境

  • IDA
  • Ubuntu18.04

0x2 寻找OEP

  • 首先在Ubuntu上运行程序,观察程序的运行情况
    1.png
    2.png
  • Ubuntu上打开终端使用命令查看当前IP
    6.png
  • 将IDA文件夹内的linux_server64拷贝到Ubuntu系统中,给与运行权限并运行
    3.png
    4.png
  • 将ELF文件拖入Win上的IDA内,选择Linux远程调试器,填入Ubuntu的IP地址启动调试,弹框点击确定
    5.png
    7.png
  • 开始单步调试,单步调试遵循两个原则:1.除非F8跑飞,否则不用F7。2.循环直接跳过。
    8.png
    9.png
    10.png
    11.png
    12.png
    13.png
    14.png

0x3 Dump内存文件

  • 顺利找到OEP,准备dump内存
    15.png
  • dump文件执行结束,在对应目录生成dump文件
    16.png
    17.png
  • 将dump文件拖入Ubuntu系统给与权限,并运行查看结果
    18.png

0x4 Dump文件代码

#include <idc.idc>
#define PT_LOAD              1
#define PT_DYNAMIC           2
static 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("G:\\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<e_phnum;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);
        }
}

0x5 总结

  • 样本来源于CTF的逆向题,各位可放心下载练习,如果有兴趣,可以继续找出目标flag,好啦,附件拿走,免费评分留下 ~
  • 链接: https://pan.baidu.com/s/1v_uL26C6FooLhHHSbPUhmQ 提取码: ubmc
  • 解压密码:52pojie.cn

免费评分

参与人数 37吾爱币 +32 热心值 +32 收起 理由
beiwjk + 1 + 1 我很赞同!
七个涨停一倍 + 1 鼓励转贴优秀软件安全工具和文档!
gink + 1 + 1 谢谢@Thanks!
薛定谔消失的弦 + 1 + 1 谢谢@Thanks!
wuwutian + 1 + 1 热心回复!
THook + 1 用心讨论,共获提升!
aywl47 + 1 用心讨论,共获提升!
11987GENIUS + 1 我很赞同!
Damon尼 + 1 我很赞同!
cpj1203 + 1 谢谢@Thanks!
zhangchang + 1 用心讨论,共获提升!
jmnzhlx + 1 + 1 用心讨论,共获提升!
Spwpun + 1 + 1 学习了linux调试的方法、ELF脱壳没了解过,最近在看IDA Pro脚本编写的部分.
chencg + 1 我很赞同!
jnez112358 + 1 + 1 谢谢@Thanks!
对影三人 + 1 + 1 热心回复!
macsun + 1 + 1 谢谢@Thanks!
guojinhao + 1 用心讨论,共获提升!
yixi + 1 + 1 谢谢@Thanks!
zhengyg + 1 + 1 谢谢@Thanks!
gaosld + 1 + 1 用心讨论,共获提升!
1390794904 + 1 + 1 请勿灌水,提高回帖质量是每位会员应尽的义务!
LOLQAQ + 1 + 1 我很赞同!
40m41h42t + 1 + 1 谢谢@Thanks!
run_boy + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
aileki + 1 + 1 谢谢@Thanks!
sunnylds7 + 1 + 1 热心回复!
hszt + 1 + 1 谢谢@Thanks!
凉米饭 + 1 谢谢@Thanks!
GenW + 3 + 1 支持技术帖!
yaoyao7 + 1 + 1 我很赞同!
hjm666 + 1 热心回复!
为海尔而战 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
itmaple + 1 我很赞同!
sumile + 1 + 1 用心讨论,共获提升!
陈世界 + 1 + 1 热心回复!
笙若 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

lishua 发表于 2021-2-23 16:59
本帖最后由 lishua 于 2021-3-25 15:47 编辑
一米丶阳光 发表于 2021-1-7 14:59
因为只有LOAD和DYNAMIC段才是运行时真正用到的

网上找了一篇文章(ELF文件的加载过程 https://blog.csdn.net/gatieme/article/details/51628257 其实只是大致看了elf加载的流程)。ELF加载后内存中只有标识为PT_LOAD或PT_DYNAMIC的segment,所以如果想要还原原始的程序信息,是不是也只有PT_LOAD或PT_DYNAMIC的segment可以下手,这样让自己理解感觉又很牵强
今天使用楼主提供的idc脚本成功将一个找到OEP的64 bits程序给dump脱壳了。
我仿照楼主代码写的32位的脱壳脚本不知道为啥脱了一个32位程序,运行后是segment fault,楼主大大看到帖子能否抽空帮忙看一下? 解答一下困惑
[C] 纯文本查看 复制代码
#include <idc.idc>
#define PT_LOAD              1

#define PT_DYNAMIC           2

static main(void)
{
  auto ImageBase,StartImg,EndImg;
  auto e_phoff;
  auto e_phnum,p_offset;
  auto i,dumpfile;
  ImageBase=0x08048000;
  StartImg=0x08048000;
  EndImg=0x0;
  if (Dword(ImageBase)==0x7f454c46 || Dword(ImageBase)==0x464c457f )
  {
    if(dumpfile=fopen("d:\\dumpfile","wb"))
    {
      e_phoff=ImageBase+Dword(ImageBase+0x1c);
      Message("e_phoff = 0x%x\n", e_phoff);
      e_phnum=Word(ImageBase+0x2c);
      Message("e_phnum = 0x%x\n", e_phnum);
      for(i=0;i<e_phnum;i++)
      {
         if (Dword(e_phoff)==PT_LOAD || Dword(e_phoff)==PT_DYNAMIC)
         { 
                        p_offset=Dword(e_phoff+0x4);
            StartImg=Dword(e_phoff+0x8);//p_vaddr
            EndImg=StartImg+Dword(e_phoff+0x14);//p_memsz
            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+0x20;
      }

      fseek(dumpfile,0x30,0);//e_shnum e_shstrndx
      fputc(0x00,dumpfile);
      fputc(0x00,dumpfile);
      fputc(0x00,dumpfile);
      fputc(0x00,dumpfile);

      fseek(dumpfile,0x20,0);//e_shoff
      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);
  }
}
 楼主| 一米丶阳光 发表于 2019-11-6 19:38
zhengyg 发表于 2019-11-6 19:34
按照您的教程我也弄出来了,好厉害,谢谢您,那个脚本怎么写的呀,只能看懂一点点,想学的话从哪里入手好呢 ...

嘿嘿 恭喜你,要想写那个脚本,你得先去了解一下ELF64的头部结构,然后结合脚本代码你就明白啦
wl960612 发表于 2019-11-4 22:47
夜步城 发表于 2019-11-4 23:30
支持楼主
头像被屏蔽
xiao135140 发表于 2019-11-5 05:58
谢谢分享啊啊
Hmily 发表于 2019-11-5 08:09
elf程序脱壳资料不多,加精鼓励,期待更多分享。
GJH588 发表于 2019-11-5 08:25
这类教程很少,期待更多的教学,支持一下
 楼主| 一米丶阳光 发表于 2019-11-5 09:08
Hmily 发表于 2019-11-5 08:09
elf程序脱壳资料不多,加精鼓励,期待更多分享。

谢H大,我会继续努力
yaoyao7 发表于 2019-11-5 09:37
elf脱壳的少见啊,多分享一下
A-new 发表于 2019-11-5 10:20
为什么不直接用edb呢
daymissed 发表于 2019-11-5 10:21
视频学习起来更好点。感谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-22 15:47

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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