飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 3731|回复: 2

[原创] XCTF高校战“疫”一道VM逆向题目详解

[复制链接]
  • TA的每日心情
    开心
    2021-7-27 17:21
  • 签到天数: 9 天

    [LV.3]偶尔看看II

    发表于 2020-3-10 14:33:21 | 显示全部楼层 |阅读模式
    飘云阁全网首发,未经许可,禁止转载
    前两天在打xctf的一场比赛,其中一道题目使用了模拟化虚拟机的保护技术,对新手认识与分析VM有很好的学习意义。题目为64位ELF文件,本文将采用IDA远程调试Linux程序的方式,具体调试步骤不再赘述。
    1.png
    如上图所示,程序要求输入flag,如果验证正确则成功。由于核心的指令都是虚拟化处理的,所以在本题是无法通过字符串定位到关键代码的。因此从main函数开始分析。
    [C++] 纯文本查看 复制代码
    __int64 __fastcall main(__int64 a1, char **a2, char **a3)
    {
      sub_40DB60();
      return 0LL;
    }
    void sub_40DB60()
    {
      sub_40BD40(&dword_484358, 0x25uLL);
    }
    
    其中sub_40BD40则为VM的解码执行组件,而参数一为虚拟字节码的内存首地址,参数二为虚拟字节码的总长度。sub_40BD40函数有多处调用,在实际调试中发现该处只是为了打印字符串,因此不需要浪费时间分析这里的字节码执行逻辑,直接给出验证flag的函数如下。
    [C++] 纯文本查看 复制代码
    void sub_40DB80()
    {
      sub_40BD40(&dword_4846D0, 0x4BuLL);
    }
    
    因此dword_4846D0指向核心的虚拟字节码,sub_40BD40函数解码动作如下:
    2.png
    很明显Qword为单位存储字节码,字节码在内存中的部分视图如下:
    3.png
    因此首先执行的操作码为06,操作数都为0,该操作码对应的处理分支如下图,很明显是将输入的字符串的一个字符存入到tmp[0]中,而调试发现此时inputPtr指向输入字符串的末尾,最后将inputPtr前移。
    4.png
    下一条虚拟字节码为 00 7D 1A,该操作码对应的处理分支如下图,实际就是比如tmp[0]与0x7D的大小。
    5.png
    下一条虚拟字节码为 12 00 1C,为一条跳转操作,刚好与上一条的比较构成一个完整的判断。换句话说,如果我们输入字节串的最后一个字符等于0x7D(对应ASCII码‘}’,在ctf中flag的格式为flag{****})则跳转到第0x12条虚拟字节码执行。
    6.png
    而此时我们的输入不满足,所以不会触发跳转,故继续分析下一条 00 62 01,翻译过来就是tmp[0]=0x62(对应ASCII码‘b’)
    7.png
    后面紧着的几条操作码都是01,直接出给翻译结果,正好对应文章开头截图中的失败提示“bye~~~”
    [AppleScript] 纯文本查看 复制代码
    00 62 01 tmp[0]=0x62   //label:失败    以下输出失败
    01 79 01 tmp[1]=0x79
    02 65 01 tmp[2]=0x65
    03 7E 01 tmp[3]=0x7e
    06 7E 01 tmp[6]=0x7e
    07 7E 01 tmp[7]=0x7e
    
    因此在后续的分析中,我们需要构造满足的字符串继续分析,篇幅关系不能每一条都翻译给大家看,我直接给出我翻译好的字节码与其对应的操作。
    [Plain Text] 纯文本查看 复制代码
    00 00 06 读最后一个字节
    00 7D 1A 是否等于}
    12 00 1C 相等则跳转cur = 0x12
    00 62 01 tmp[0]=0x62   //label:失败    以下输出失败
    01 79 01 tmp[1]=0x79
    02 65 01 tmp[2]=0x65
    03 7E 01 tmp[3]=0x7e
    06 7E 01 tmp[6]=0x7e
    07 7E 01 tmp[7]=0x7e
    00 00 18 
    01 00 18 
    02 00 18 
    03 00 18 
    06 00 18 
    07 00 18 
    00 0A 01 
    00 00 18 
    00 00 19 
    08 100 01 tmp[8]=0x100      //label: 0x12
    08 E1 1A  比较是否tmp[8]<0xE1
    19 00 1E 如果小于则跳转0x19(表示赋值完毕)
    00 00 06 tmp[0]=倒取输入的字符
    08 00 04 data[tmp[8]]=tmp[0]
    08 01 09 tmp[8] = tmp[8]-1
    13 00 1D cur = 0x13(无条件跳转)
    00 00 06 //以下比较开头是否为flag{  //label: 0x19
    00 7B 1A 
    03 00 1F 
    00 00 06 
    00 67 1A 
    03 00 1F 
    00 00 06 
    00 61 1A 
    03 00 1F 
    00 00 06 
    00 6C 1A 
    03 00 1F 
    00 00 06 
    00 66 1A 
    03 00 1F 
    09 09 12 tmp[9]=0  		
    0A E1 01 tmp[A]=0xe1
    07 09 03 tmp[7]=data[tmp[9]]  //label: 0x2A
    06 0A 03 tmp[6]=data[tmp[A]]
    06 63 11 tmp[6]^=0x63
    06 02 0D tmp[6]=tmp[6]<<2
    06 07 1B tmp[6]==tmp[7]
    03 00 1F 不等于跳转失败
    09 01 07 tmp[9]+=1
    0A 01 07 tmp[A]+=1
    09 20 1A tmp[9]<0x20
    2A 00 1E 小于则跳转0x2A (继续运算)
    00 63 01 //以下输出成功
    01 6F 01 
    02 72 01 
    03 72 01 
    06 65 01 
    07 63 01 
    00 00 18 
    01 00 18 
    02 00 18 
    03 00 18 
    06 00 18 
    07 00 18 
    00 74 01 
    01 6C 01 
    02 79 01 
    03 21 01 
    06 0A 01 
    00 00 18 
    01 00 18 
    02 00 18 
    03 00 18 
    06 00 18 
    逻辑很简单,逐字符对输入进行运算并比较,暴力破解即可,脚本如下:
    [Python] 纯文本查看 复制代码
    flag=''
    data=[0x90,0x14C,0x1C,0x0F0,0x84,0x3C,0x18,0x40,0x40,0x0F0,0x0D0,0x58,0x2C,0x8,0x34,0x0F0,0x114,0x0F0,0x80,0x2C,0x28,0x34,0x8,0x0F0,0x90,0x44,0x30,0x50,0x5C,0x2C,0x108,0x0F0]
    for i in range(len(data)):
        for j in range(33,126):
            if((j^0x63)<<2 == data[i]):
                flag += chr(j)
    print flag
    

    题目附件下载:
    提取码:j79t



    评分

    参与人数 1威望 +10 飘云币 +10 收起 理由
    PYG官方论坛 + 10 + 10 感谢发布原创作品,PYG有你更精彩!

    查看全部评分

    PYG19周年生日快乐!
  • TA的每日心情

    2020-6-14 14:52
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2020-3-12 01:07:50 | 显示全部楼层
    XCTF高校战“疫”一道VM逆向题目详解
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    2020-3-23 01:09
  • 签到天数: 7 天

    [LV.3]偶尔看看II

    发表于 2020-3-13 12:05:07 | 显示全部楼层
    不明觉厉,支持大佬
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

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