DASCTF十月挑战赛 EZRE
本文最后更新于 26 天前,其中的信息可能已经有所发展或是发生改变。

文件信息

脱壳部分

这里查到一个Themida3.X的壳,通过搜索,github有一个开源项目用于脱掉这种壳

项目地址:https://github.com/ergrelet/unlicense

我们下载该项目的release就可以了,之后使用对应的exe去打开题目附件

去除花指令

这样就脱好了,我们使用IDA打开

这main函数一样经典花指令,先把上面的jz/jnz原地跳转nop了,再把下面的call去D一下,然后把0E8hnop掉,剩下的C将字节码转成汇编,选中全部的main函数p一下定义就可以了

修好主函数的花指令之后应该是这样:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char v4[44]; // [esp+14h] [ebp-90h]
  int i; // [esp+40h] [ebp-64h]
  int j; // [esp+44h] [ebp-60h]
  char v7[44]; // [esp+48h] [ebp-5Ch] BYREF
  char v8[44]; // [esp+74h] [ebp-30h] BYREF

  v4[0] = 0x50;
  v4[1] = 0xD4;
  v4[2] = 0xC8;
  v4[3] = 0xC4;
  v4[4] = 0x8F;
  v4[5] = 0x84;
  v4[6] = 0x40;
  v4[7] = 0xEB;
  v4[8] = 0x32;
  v4[9] = 0x81;
  v4[10] = 0x8F;
  v4[11] = 0x85;
  v4[12] = 0x6C;
  v4[13] = 0xB2;
  v4[14] = 0x2B;
  v4[15] = 6;
  v4[16] = 0xBF;
  v4[17] = 5;
  v4[18] = 0x35;
  v4[19] = 0x5D;
  v4[20] = 0x2E;
  v4[21] = 0xE3;
  v4[22] = 0x7D;
  v4[23] = 0x46;
  v4[24] = 0x8D;
  v4[25] = 0x35;
  v4[26] = 1;
  v4[27] = 0x70;
  v4[28] = 0x3A;
  v4[29] = 0x80;
  v4[30] = 0x81;
  v4[31] = 0xC5;
  v4[32] = 0xE6;
  v4[33] = 0x71;
  v4[34] = 0xD3;
  v4[35] = 0xD6;
  v4[36] = 0x50;
  v4[37] = 0x69;
  v4[38] = 0x6F;
  v4[39] = 0xE2;
  v4[40] = 0x6E;
  v4[41] = 0x78;
  v4[42] = 0x14;
  v4[43] = 0xD8;
  sub_F61020(Format, aPleaseEnterYou);
  sub_F61050("%s", v7);
  (loc_F61290)(v7, v8);
  for ( i = 0; i <= 36; ++i )
    (loc_F613C0)(&v8[i]);
  for ( j = 0; j < 44; ++j )
  {
    if ( v4[j] != v8[j] )
    {
      sub_F61020(Format, aWrong);
      break;
    }
  }
  if ( j == 44 )
    sub_F61020(Format, aCongratulation);
  return 0;
}

逻辑还是很清晰的,v4就是我们的密文,然后printf和scanf就不过多讲述了,发现了两个函数loc_F61290loc_F613C0都对我们的输入进行了操作,最后跟密文进行比较

双击进入这两个函数之后发现直接跳到汇编了,说明是无法F5的,然后又看见了经典的jz/jnz call near ptr,我们继续nop去花

将几处花全部去掉之后就能够看见函数的具体实现了,我技术有限,也就只能修成这样了

RC4加密

sub_1290:

char __cdecl sub_F61290(char *a1, int a2)
{
  char result; // al
  unsigned int i; // [esp+18h] [ebp-10h]
  char *v4; // [esp+1Ch] [ebp-Ch]
  unsigned __int8 v6; // [esp+26h] [ebp-2h]
  unsigned __int8 v7; // [esp+27h] [ebp-1h]

  v7 = 0;
  v6 = 0;
  sub_F610C0();
  v4 = a1;
  do
    result = *v4;
  while ( *v4++ );
  for ( i = 0; i < v4 - (a1 + 1); ++i )
  {
    v6 += byte_F643B0[++v7];
    sub_F61080(&byte_F643B0[v7], &byte_F643B0[v6]);
    *(i + a2) = (byte_F643B0[(byte_F643B0[v6] + byte_F643B0[v7])] ^ 0x33) + a1[i];
    result = i + 1;
  }
  return result;
}

其中的sub_F610C0函数是这样的

void *sub_F610C0()
{
  void *result; // eax
  int v1; // [esp+18h] [ebp-128h]
  int j; // [esp+1Ch] [ebp-124h]
  char *v3; // [esp+20h] [ebp-120h]
  unsigned int i; // [esp+24h] [ebp-11Ch]
  int k; // [esp+28h] [ebp-118h]
  char v6[256]; // [esp+30h] [ebp-110h] BYREF
  char v7[12]; // [esp+130h] [ebp-10h] BYREF

  strcpy(v7, "th0s_i0_ke9");
  for ( i = 0; i < 0x100; ++i )
    byte_F643B0[i] = i;
  v3 = &v7[strlen(v7) + 1];
  result = memset(v6, 0, sizeof(v6));
  for ( j = 0; j < 256; ++j )
  {
    result = j;
    v6[j] = v7[j % (v3 - &v7[1])];
  }
  v1 = 0;
  for ( k = 0; k < 256; ++k )
  {
    v1 = (v6[k] + v1 + byte_F643B0[k]) % 256;
    result = sub_F61080(&byte_F643B0[k], &byte_F643B0[v1]);
  }
  return result;
}

不难看出这是一个RC4的加密,不过有些许魔改,循环了44和异或了0x33

52的佬还是讲得很好的

xTEA加密

sub_F613C0:

int *__cdecl sub_F613C0(int *a1)
{
  int *result; // eax
  int v2[4]; // [esp+Ch] [ebp-24h]
  int v3; // [esp+1Ch] [ebp-14h]
  int i; // [esp+20h] [ebp-10h]
  unsigned int v5; // [esp+24h] [ebp-Ch]
  unsigned int v6; // [esp+28h] [ebp-8h]
  unsigned int v7; // [esp+2Ch] [ebp-4h]

  v2[0] = 0x6E982837;
  v2[1] = 0x44332211;
  v2[2] = 0x11223344;
  v2[3] = 0x3728986E;
  v6 = *a1;
  v5 = a1[1];
  v7 = 0x66778899;
  v3 = 0x9E3779B8;
  for ( i = 0; i <= 32; ++i )
  {
    v6 += (v2[v7 & 3] + v7) ^ (v5 + ((v5 >> 6) ^ (32 * v5)));
    v7 += v3;
    v5 += (v2[(v7 >> 11) & 3] + v7) ^ (v6 + ((v6 >> 5) ^ (16 * v6)));
  }
  *a1 = v6;
  result = a1;
  a1[1] = v5;
  return result;
}

这个不用解释了,一眼xTEA,不过还是进行了一定的魔改,比如说轮次变成了33,在主函数中又循环了37次(头大

exp

既然如此每个步骤都分析完了写个解密脚本不是简简单单(bushi

#include <iostream>
#include <cstring>
#include <cstdint>

using namespace std;

unsigned char S[256];

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 j = 0;

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

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

void decrypt(const char* a1, char* a2, int length) {
    unsigned char v6 = 0;
    unsigned char v7 = 0;

    for (int i = 0; i < length; ++i) {
        v6 += S[++v7];
        swap(S[v7], S[v6]);
        a2[i] = a1[i] - (S[(unsigned char)(S[v6] + S[v7])] ^ 0x33);
    }
}

void xtea_decrypt(uint32_t* a1) {
    int v2[4] = { 1855465527, 1144201745, 287454020, 925407342 };
    uint32_t v6 = a1[0];
    uint32_t v5 = a1[1];

    uint32_t v7 = 1719109785 + (0x9E3779B8 * 33);
    int v3 = 0x9E3779B8;

    for (int i = 0; i <= 32; ++i) {
        v5 -= (v2[(v7 >> 11) & 3] + v7) ^ (v6 + ((v6 >> 5) ^ (16 * v6)));
        v7 -= v3;
        v6 -= (v2[v7 & 3] + v7) ^ (v5 + ((v5 >> 6) ^ (32 * v5)));
    }

    a1[0] = v6;
    a1[1] = v5;
}

int main() {
    unsigned char key[] = "th0s_i0_ke9";
    int key_length = strlen((const char*)key);

    // 初始化S盒
    rc4_key_setup(key, key_length, S);

    unsigned char encenc[] = {
        0x50, 0xD4, 0xC8, 0xC4, 0x8F, 0x84, 0x40, 0xEB, 0x32,
        0x81, 0x8F, 0x85, 0x6C, 0xB2, 0x2B, 0x06, 0xBF, 0x05,
        0x35, 0x5D, 0x2E, 0xE3, 0x7D, 0x46, 0x8D, 0x35, 0x01,
        0x70, 0x3A, 0x80, 0x81, 0xC5, 0xE6, 0x71, 0xD3, 0xD6,
        0x50, 0x69, 0x6F, 0xE2, 0x6E, 0x78, 0x14, 0xD8, 0x25
    };

    // XTEA解密
    for (int i = 36; i >= 0; i--) {
        xtea_decrypt((uint32_t*)&encenc[i]);
    }

    // RC4解密
    char encrypted_data[45]; // 注意这里需要 +1 以容纳结束符
    decrypt((char*)encenc, encrypted_data, 44);
    encrypted_data[44] = '\0'; // 添加结束符

    cout << encrypted_data << endl;
    return 0;
}
//DASCTF{Th1l_t8e1a_rc4_l8s_s8o_int9r3es4t1ng}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇