Yk2eR0's Blog.

buuctf_re3(base64)

字数统计: 774阅读时长: 4 min
2020/02/12 Share

主函数逆出来是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
__int64 __usercall main_0@<edx:eax>(int a1@<ebx>, int a2@<edi>, int a3@<esi>)
{
void *v3; // ecx
int v4; // eax
const char *v5; // eax
size_t v6; // eax
int v7; // edx
__int64 v8; // ST08_8
signed int j; // [esp+DCh] [ebp-ACh]
unsigned int i; // [esp+E8h] [ebp-A0h]
signed int v12; // [esp+E8h] [ebp-A0h]
char Dest[108]; // [esp+F4h] [ebp-94h]
char Str; // [esp+160h] [ebp-28h]
char v15; // [esp+17Ch] [ebp-Ch]

for ( i = 0; (signed int)i < 0144; ++i ) // meiyong
//
{
if ( i >= 0144 )
j____report_rangecheckfailure(a1, a2, a3);
Dest[i] = 0;
}
sub_41132F("please enter the flag:");
sub_411375(v3, "%20s", &Str); // strlen
v4 = j_strlen(&Str);
v5 = (const char *)sub_4110BE((int)&Str, v4, (int)&v15);
strncpy(Dest, v5, 050u);
v12 = j_strlen(Dest);
for ( j = 0; j < v12; ++j )
Dest[j] += j;
v6 = j_strlen(Dest);
if ( !strncmp(Dest, Str2, v6) )
sub_41132F("rigth flag!\n");
else
sub_41132F("wrong flag!\n");
HIDWORD(v8) = v7;
LODWORD(v8) = 0;
return v8;
}

去掉没用的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  char Dest[108];
sub_41132F("please enter the flag:");
sub_411375(v3, "%20s", &Str); // 两句相当于input
v4 = strlen(&Str);
v5 = (const char *)sub_4110BE((int)&Str, v4, (int)&v15);
strncpy(Dest, v5, 050u);//v5赋值给Dest
for ( j = 0; j < trlen(Dest); ++j )//循环相当于每个数的ASCII加上它的下标
Dest[j] += j;
v6 = j_strlen(Dest);
if ( !strncmp(Dest, Str2, v6) )//Dest=Str2则正确
sub_41132F("rigth flag!\n");
else
sub_41132F("wrong flag!\n");
HIDWORD(v8) = v7;
LODWORD(v8) = 0;
return v8;
}
  • 可以看出重点在于sub_4110BE这个函数.
  • 先逆出v5:
    Str2=”e3nifIH9b_C@n@dH”;
    脚本跑出 v5=”e2lfbDB2ZV95b3V9”

    跟进,简化sub_4110BE:

    只展示函数逻辑:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    void *__cdecl sub_411AB0(char *a1, unsigned int a2, int *a3)//a1为明输入,a2为a1长度,a3为一块康健,用于存储Dst
    {
    v9 = a2 / 3;
    if ( (signed int)(a2 / 3) % 3 )//如果(a2/3)%3不为0则V9++,防止后续申请内存不够
    ++v9;
    v10 = 4 * v9;
    *a3 = v10;
    Dst = malloc(v10 + 1);//Dst的空间为a1的4/3
    if ( !Dst )
    return 0;
    j_memset(Dst, 0, v10 + 1);
    v13 = a1;
    v11 = a2;
    v7 = 0;
    while ( v11 > 0 )
    {
    byte_41A144[2] = 0;
    byte_41A144[1] = 0;
    byte_41A144[0] = 0;
    for ( i = 0; i < 3 && v11 >= 1; ++i )//读取三位
    {
    byte_41A144[i] = *v13;
    --v11;
    ++v13;
    }
    if ( !i )
    break;
    switch ( i )
    {
    case 1:
    *((_BYTE *)Dst + v7) = aAbcdefghijklmn[(signed int)(unsigned __int8)byte_41A144[0] >> 2];
    v4 = v7 + 1;
    *((_BYTE *)Dst + v4++) = aAbcdefghijklmn[((byte_41A144[1] & 0xF0) >> 4) | 16 * (byte_41A144[0] & 3)];
    *((_BYTE *)Dst + v4++) = aAbcdefghijklmn[64];
    *((_BYTE *)Dst + v4) = aAbcdefghijklmn[64];
    v7 = v4 + 1;
    break;
    case 2:
    *((_BYTE *)Dst + v7) = aAbcdefghijklmn[(signed int)(unsigned __int8)byte_41A144[0] >> 2];
    v5 = v7 + 1;
    *((_BYTE *)Dst + v5++) = aAbcdefghijklmn[((byte_41A144[1] & 0xF0) >> 4) | 16 * (byte_41A144[0] & 3)];
    *((_BYTE *)Dst + v5++) = aAbcdefghijklmn[((byte_41A144[2] & 0xC0) >> 6) | 4 * (byte_41A144[1] & 0xF)];
    *((_BYTE *)Dst + v5) = aAbcdefghijklmn[64];
    v7 = v5 + 1;
    break;
    case 3:
    *((_BYTE *)Dst + v7) = aAbcdefghijklmn[(signed int)(unsigned __int8)byte_41A144[0] >> 2];
    v6 = v7 + 1;
    *((_BYTE *)Dst + v6++) = aAbcdefghijklmn[((byte_41A144[1] & 0xF0) >> 4) | 16 * (byte_41A144[0] & 3)];
    *((_BYTE *)Dst + v6++) = aAbcdefghijklmn[((byte_41A144[2] & 0xC0) >> 6) | 4 * (byte_41A144[1] & 0xF)];
    *((_BYTE *)Dst + v6) = aAbcdefghijklmn[byte_41A144[2] & 0x3F];
    v7 = v6 + 1;
    break;
    }
    }
    *((_BYTE *)Dst + v7) = 0;
    return Dst;
    }
    Abcdefghijklmn=”ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=”
    base64替换表:”ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/“
    猜测为base64.解码即可得到

原文作者:Yk2eR0

原文链接:https://www.yk2er0.fun/2020/02/12/buuctf-re3/

发表日期:二月 12日 2020, 5:50:24 下午

更新日期:February 13th 2020, 12:06:22 pm

版权声明:非商业用允许转载

CATALOG
  1. 1. 主函数逆出来是这样的:
  2. 2. 去掉没用的:
  3. 3. 跟进,简化sub_4110BE: