IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    实战逆向RUST语言程序

    dingjiacan@antvsion.com发表于 2024-12-23 08:26:46
    love 0

    实战为主,近日2024年羊城杯出了一道Rust编写的题目,这里将会以此题目为例,演示Rust逆向该如何去做。

    题目名称:sedRust_happyVm

    题目内容:unhappy rust, happy vm

    关于Rust逆向,其实就是看汇编,考验选手的基础逆向能力。在汇编代码面前,任何干扰都会成为摆设。

    1、初步分析

    64为程序,使用IDA 64打开

    image

    通过字符串定位分析点

    image

    image

    现在我们知道 inputflag的长度大于 0x15

    image

    接下来在汇编层面下一个断点,输入假flag,去观察相关寄存器的值

    image

    image

    image

    好像并没有什么内容

    image

    继续单步 步过,直到发现下一个要注意的地方!

    image

    image

    字符串长度:0x28



    我们继续单步步过跟踪

    image

    开辟空间的时候,说明快到真正函数处理过程了。

    image

    image

    image

    image

    2、分析加密流程

    2.1 base64分割模块

    这里简单将 3 字节变成4字节的操作,称之为 base64分割模块

    这里举个例子

    输入的:"111"
    ->二进制字符串 001100010011000100110001
    经过base64分割模块
    ->001100 010011 000100 110001

    image

    发现程序执行完后正好是这样的结果

    image

    2.2 组合

    image

    举个例子:

    假如分割之后的4字节为:

    0xC、0x13、0x4、0x31

    那么组合后的字符串

    rax = 0xC
    rcx = 0x1300
    edx = 0xB1130C18

    image

    2.3 VM处理模块

    image

    发现func3 非常乱

    并且频繁调用sub_40A800()

    image

    发现这是一道VM类型的题,那么VM的题加密应该会很简单,基本是异或之类。

    image

    在 sub_40A800 里面找到 异或,下断点

    image

    image

    image

    image

    这个al每经过两次就是秘钥

    image

    image

    解题脚本

    int main() {
       //提取的密文
       unsigned char s1[] = { 0x00,0x82,0x11,0x92,0xa8,0x39,0x82,0x28,0x9a,0x61,0x58,0x8b,0xa2,0x43,0x68,0x89,0x4,0x8f,0xb0,0x43,0x49,0x3a,0x18,0x39,0x72,0xc,0xba,0x76,0x98,0x13,0x8b,0x46,0x33,0x2b,0x25,0xa2,0x8b,0x27,0xb7,0x61,0x7c,0x3f,0x58 };
       //提取的秘钥
       unsigned char s2[] = { 0x18,0xb1,0x9,0xa4,0xa6,0x2a,0x9e,0x1b,0x96,0x57,0x5d,0xad,0xae,0x75,0x65,0xac,0x9,0x8c,0xa0,0x76,0x47,0x2c,0x10,0x1,0x7c,0xf,0xba,0x47,0x95,0x30,0x9b,0x74,0x3f,0x2d,0x2d,0x9a,0x87,0x31,0xba,0x43,0x70,0x2c,0x4c };

       unsigned char s3[128] = { 0 };

       for (int i = 0; i < 43; i++) {
           s3[i] = s1[i] ^ s2[i];
       }
       //还原base64分割模块
       char s4[128] = { 0 };
       int j = 0;
       for (int i = 0; i < 44; i += 4, j += 3) {
           s4[j] = (s3[i] << 2) | (s3[i + 1] >> 4);
           s4[j+1] = (s3[i+1] << 4) | (s3[i + 2] >> 2);
           s4[j+2] = (s3[i+2] << 6) | s3[i + 3];

       }

       printf("%s", s4);
     
       return 0;
    }

    ‍  




沪ICP备19023445号-2号
友情链接