ELF64手脱UPX壳实战

最近在做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);
}
}


### 0x4 总结
* 样本来源于CTF的逆向题,各位可放心下载练习,如果有兴趣,可以继续找出目标flag,好啦,附件拿走,评分留下:lol ~
* 链接: https://pan.baidu.com/s/1v_uL26C6FooLhHHSbPUhmQ 提取码: ubmc
* 解压密码:52pojie.cn
THE END
喜欢就支持以下吧
点赞0
分享
评论 抢沙发
  • 管埋员

    昵称

  • 取消
    昵称