欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

Reversing.kr题目之SimpleVM详解

来源:本站整理 作者:佚名 时间:2018-03-30 TAG: 我要投稿

概述
Reversing.kr是一个韩国的逆向题练习网站,题目的质量还是比较好的,比较费时间去破解,这里给出我在刷到SimpleVM这道题目的时候的一些心得和体会。
SimpleVM
###0
拿到文件之后拖入ida分析,发现报错,illegal program entry point(C023DC)。我们继续打开文件,发现程序在00C023C7的时候就中断了,所以会报这个不合法的入口点,我们通过readelf命令可以清楚的查看到program header的信息(FileSize 为13C7):
Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x00c01000 0x00c01000 0x013c7 0x013c7 RWE 0x1000
  LOAD           0x00019c 0x0804b19c 0x0804b19c 0x00000 0x00000 RW  0x1000
但是有一点是这样的,Linux中文件/内存映射总是页面大小的倍数,在x86上通常是4k。此处的映射长度0x13c7将四舍五入为页面大小的倍数,这意味着0×2000字节将被映射。所以其实我们通过010editor去查看该文件是可以看到(c023dc-c01000) = 13dc是有数据的。我们去更改一下FileSize和MemSize,之后拖入ida发现是正确的。我们在C023DC出查看代码如下:
                          ; DATA XREF: LOAD:00C01018↑o
LOAD:00C023DC                 mov     dword_C01BF0, 252E8h
LOAD:00C023DC ; ---------------------------------------------------------------------------
LOAD:00C023E6                 db 0E9h
LOAD:00C023E7                 db    5
LOAD:00C023E8                 db 0F8h
LOAD:00C023E9                 db 0FFh
LOAD:00C023E9 LOAD            ends
后面的db没有被翻译出来,但是我们通过E9命令这是一个跳转的jmp命令,从而进入正常的程序流程。
###1
我们利用ida的linux_server进行虚拟机的远程调试,直接启动,ctrl+s查看段信息如下:

看LOAD段完全没有任何的突破口,但是观察到debug001和debug002这两个段。我们进去看一下,发现前面几个字节0x7f,0×45,0x4c,0×46,一个明显的elf文件我们得把他dump下来,基本的ida script模板如下:
static main(void)
{
  auto fp, begin, end, dexbyte;
  fp = fopen("D:\\dump.txt", "wb");
  begin = 0x8048000;
  end = 0x804c000;
  for ( dexbyte = begin; dexbyte dexbyte ++ )
      fputc((dexbyte), fp);
}
得到一个dump文件。
###2
我们将dump文件拖入ida分析,shift+f12查看字符串,好的“input”字符串没有被加密,直接出来,我们定位到该函数sub_8048556().我们发现所有的函数都被重新加密了,我们看input的这个函数,
 sub_8048460(1, (int)"Input : ", 8);
明显可以得出它是类似与printf()的一个函数,我这里采用了一个动态调试的方法去跟踪该函数。首先记录下该函数的位置为8048460,接着利用ida运行起来这个文件,定位到8048460这个点。快捷键c一下,code出来为jmp off_804B018,跟进可知off_804B018的值为F7E1D3C0,显然这是一个so文件的函数,我们ctrl+s发现这个函数存在libc_2.23.so中。去查看Modules窗口查看libc_2.23.so,好像并不能查看name,无妨,我们从虚拟机中拷贝一份libc_2.23.so拖入ida分析,通过F7E1D3C0与libc_2.23.so的首地址的偏移量去查找,发现这个函数就是libc中的write函数。利用这个方法,我们可以得出大部分的系统调用函数出来,大致如下:
sub_8048460 -- write()
sub_8048470 -- pipe()
sub_8048480 -- fork()
sub_8048400 -- read()
同时通过动态调试将类似与下方的代码分析称相应的字符串输出即可:
for ( i = 1; i 6; ++i )
{
      v8 = byte_804B074[i - 1] ^ i;
      write(1, (int)&v8, 1);
}
整个函数翻译如下:
unsigned int sub_8048556()
{
  v16 = __readgsdword(0x14u);
  if ( getuid() )
  {
    v9 = 0;
    for ( i = 1; i 14; ++i )
    {
      v8 = access_denyed[i - 1] ^ i;
      write(1, (int)&v8, 1);
    }
  }
  else
  {
    write(1, (int)"Input : ", 8);
    if ( pipe((int)&v3) != -1 && pipe((int)&v5) != -1 )
    {
      v7 = fork();
      if ( v7 == -1 )

[1] [2] [3] [4] [5] [6]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载