第六届金盾信安RE 题解

admin 2024年12月2日23:03:30评论15 views字数 4925阅读16分25秒阅读模式

babyre

使用工具

DIE

IDApro

分析过程

第六届金盾信安RE 题解

DIE查壳发现是PE32文件,IDApro32分析。

第六届金盾信安RE 题解

v26保存前十六个字符,v24保存后十六个字符。

sub_401130函数v26的字符赋值给v21,是大端序复制。

第六届金盾信安RE 题解

sub_401100调试检测

第六届金盾信安RE 题解
第六届金盾信安RE 题解

直接NOP掉。

在 sub_401100处下断点运行后观察v20的值

第六届金盾信安RE 题解

可以发现真正的密钥是这些。这4个就是TEA的密钥。

在 (loc_4011A0)(v21, v20); 处下断点,F7跟进

第六届金盾信安RE 题解

遇到这样的提示就选择 YES

分析汇编

第六届金盾信安RE 题解
第六届金盾信安RE 题解
第六届金盾信安RE 题解

就是一个标准的TEA加密。

sub_2812F0后十六个字符就是凯撒加密,偏移为3.

第六届金盾信安RE 题解
第六届金盾信安RE 题解

对v6进行解密

解密

void decrypt(uint32_t *v, uint32_t *k)
{
    uint32_t v0 = v[0], v1 = v[1], sum = 0xC6EF3720, i;  /* set up */
    uint32_t delta = 0x9e3779b9;                         /* a key schedule constant */
    uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3]; /* cache key */
    for (i = 0; i < 32; i++)
    { /* basic cycle start */
        v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
        v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
        sum -= delta;
    } /* end cycle */
    v[0] = v0;
    v[1] = v1;
}

int main()
{
    uint32_t plaintext[]={0x369A15830x009A9E6D0xBE761C600x3ED644A00x64716A510x6C49686C0x546C4F640x6C21217D};
    uint32_t key[] = { 0x1266,0x3404,0x562A,0x78C2 };
    for (size_t i = 0; i < 4; i+=2)
    {
        decrypt(&plaintext[i],key);
    }
    

    for (size_t i = 0; i < 8; i++)
    {
       printf("%08x",plaintext[i]);
       
    }
    
    // 666c61677b5a6875616e674269576f5264716a516c49686c546c4f646c21217d
    // flag{ZhuangBiWoRdqjQlIhlTlOdl!!}

    return 0;
}

在对后十六字节进行凯撒解密

Shift = 3: angNiFeiQiLai!!}

flag就是

flag{ZhuangBiWoRangNiFeiQiLai!!}

easyre

分析工具

IDApro

DIE

分析过程

第六届金盾信安RE 题解

DIE查壳发现是PE32文件。 

第六届金盾信安RE 题解

在Main函数发现两个无用的跳转,直接NOP掉,在函数PUSH处按P识别为函数。

第六届金盾信安RE 题解

分析伪代码

loc_401410处有花指令

第六届金盾信安RE 题解

按U在把第一个字节NOP掉

第六届金盾信安RE 题解

发现是RC4密钥流的生成,同时也发现sub_401100函数是调试检测。

第六届金盾信安RE 题解
第六届金盾信安RE 题解

直接在汇编中把这个调用调试检测的函数给NOP掉。

sub_4014D0函数

第六届金盾信安RE 题解

RC4加密实现,标准的。sub_401100同样是调试检测,直接NOP。

sub_401130函数

通过观察byte_404060异或后的值发现就是标准BASE64的码表。

sub_401640函数

第六届金盾信安RE 题解

直接NOP,修改一下函数结束地址。

第六届金盾信安RE 题解

发现是验证函数。

做完以上操作后要应用修改,在Edit->patch program处。

解密

结合以上分析,程序加密逻辑为RC4加密-->Base64加密。RC4加密密钥疑似为

第六届金盾信安RE 题解

但实际测试下来发现不是,这里不在追踪密钥,直接动调获取到生成S盒的数据。

第六届金盾信安RE 题解

这些就是S盒子,一共256个。

第六届金盾信安RE 题解

标准Base64码表。

第六届金盾信安RE 题解
#include <iostream>
#include <string.h>
#include <string.h>
#include <Windows.h>

using namespace std;


unsigned char aaaaa[266] = {
    0x2D0x200xAE0x560x9B0x510x120x530x160x210x250x720x910xD50x0A0x4F,
    0xF70x870xA20x8A0x930x950xC80x610x1D0x300xDB0x660x840x230x490x9F,
    0x620x350x080x460x0E0x6F0xD70x260x220x820xF00xF10xC10xE70x650x18,
    0x6B0x010x0F0x8D0xBF0x430x790x2C0xB80x680xD90x280xB30xD40x940x34,
    0xE30x1B0x5C0x4D0xAC0x3D0xAA0xB20x550xB70xF80x810x920x410x890x47,
    0xA10x270x0B0x5A0x580x090xCC0xE60x5B0x8B0xCD0xD80x760x500xB10x1A,
    0x020x800xEA0x5E0xE50xBC0x6A0x030xE40xE20x190xC60xAF0x7E0xA50xA4,
    0x360x730xC70x140xEF0x770x320xA00x1E0xD30xF20xEE0x240x750x3B0xB6,
    0xAB0x4B0x3A0x850xFC0xBD0xFB0xB50xD00x150x450x2E0x970xCF0x4E0xCA,
    0xC30x860xC50x070x540x600xBE0xD60x390x400x050x4C0x2A0x690xC20xF4,
    0x700x570x990x290xD20x880x7B0x110x7D0x3C0xCE0xDD0x420x710x1F0x8F,
    0x060x3F0xA70x480xDE0xE10xE90x0C0xFD0xEC0x9E0x000xFA0x980xAD0x2F,
    0xA90xDA0xED0xC90x0D0xB40xDC0x3E0x100xFE0xDF0x780x7C0x630x900x5D,
    0xE80xB90x9C0x2B0x670xFF0xA60x740xBA0x1C0xC00x380x830x440x370xBB,
    0x9A0xF50x590x8E0x9D0x330x960x7A0xEB0xF90x310xF30xCB0xA30x6D0xB0,
    0x6E0x520x130x4A0xA80x640xE00x040x8C0xC40x7F0x6C0x5F0xD10x170xF6,
    0x3C0xA60x3B0x270xFE0xFF0xFF0xFF0xE80xF7
};

void swap(unsigned char* a, unsigned char* b) {
    unsigned char temp = *a;
    *a = *b;
    *b = temp;
}

void rc4_key_setup(unsigned char* key, int key_length, unsigned char S[256]) {
    unsigned char T[256];
    int i, j;

    for (i = 0; i < 256; i++) {
        S[i] = i;
        T[i] = key[i % key_length];
    }

    j = 0;
    for (i = 0; i < 256; i++) {
        j = (j + S[i] + T[i]) % 256;
        swap(&S[i], &S[j]);
    }
}

void rc4_crypt(unsigned char* input_data, int input_length, unsigned char* output_data, unsigned char S[256]) {
    int i, j, k;
    i = j = 0;

    for (k = 0; k < input_length; k++) {
        i = (i + 1) % 256;
        j = (j + S[i]) % 256;
        swap(&S[i], &S[j]);
        int t = (S[i] + S[j]) % 256;
        output_data[k] = input_data[k] ^ S[t];
    }
}


int main()
{
    unsigned char input_data[] = { 0x5c,0xf8,0x84,0xb8,0x2e,0xe9,0xbe,0xc9,0x3a,0x03,0xac,0xbb,0xb6,0x26,0xd9,0xea,0x87,0xec,0xf1,0x13,0x1a,0x4e,0x9f,0x03,0x2d,0xbe,0xa4,0x5d,0xa9,0x6c,0x98,0xb2,0xec,0xcb,0x94,0xf9,0xc6,0x9d,0xef,0xe3,0x51 };
    unsigned char decrypted_data[sizeof(input_data)];

    rc4_crypt(input_data, sizeof(input_data), decrypted_data, aaaaa);

    for (int i = 0; i < sizeof(decrypted_data); i++) {
        printf("%c", decrypted_data[i]);
    }
    return 0;
}
// flag{2aed4771-b75048e3-db87779b-a3811911}

文末

添加机器人wx,回复进群,即可获取进群链接。

第六届金盾信安RE 题解

原文始发于微信公众号(琴音安全):第六届金盾信安RE 题解

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年12月2日23:03:30
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   第六届金盾信安RE 题解https://cn-sec.com/archives/3459261.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息