首页
社区
课程
招聘
[原创][HUBUCTF 2022 新生赛]simple_RE
发表于: 2023-7-15 19:02 5639

[原创][HUBUCTF 2022 新生赛]simple_RE

2023-7-15 19:02
5639

题目地址
https://wwvc.lanzouk.com/iPtGM13wncna

查壳,64位
图片描述
找main函数,F5查看伪代码,简单分析一下
图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v4; // [rsp+24h] [rbp-44h] BYREF
  void *Buf1; // [rsp+28h] [rbp-40h] BYREF
  char v6[56]; // [rsp+30h] [rbp-38h] BYREF
 
  sub_401770(argc, argv, envp);
  printf("please input the flag:");
  scanf("%s", v6);                              // v6是flag
  Buf1 = 0i64;                                  // 初始化Buf1
  sub_401570(v6, &Buf1, &v4);                   // v6进行base64编码,但是不是根据A-Z,...,而是根据这串字符编码qvEJAfHmUYjBac+u8Ph5n9Od17FrICL/X0gVtM4Qk6T2z3wNSsyoebilxWKGZpRD
  if ( !memcmp(Buf1, a5mc58bphliax7j, v4) )     // 对这串字符串"5Mc58bPHLiAx7J8ocJIlaVUxaJvMcoYMaoPMaOfg15c475tscHfM/8=="进行微改变的base64解码,即得flag
    printf("\nsuccess!");
  else
    printf("\nfailed!");
  if ( Buf1 )
    free(Buf1);
  return 0;
}

v6是flag,经过sub_401570函数加密,得到a5mc58bphliax7j对应的加密后的值,即加密后的flag值

这里的重点就是sub_401570函数,我们需要了解经过怎么样的加密,接下来我们点进去看看
图片描述
sub_401570函数

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
59
60
61
62
63
64
65
__int64 __fastcall sub_401570(const char *a1, _QWORD *a2, int *a3)
{
  int v6; // r15d
  int v7; // r12d
  int v8; // r13d
  __int64 v9; // r14
  _BYTE *v10; // rax
  _BYTE *v11; // r9
  __int64 v12; // r8
  char v13; // cl
  char v14; // r11
  char v15; // r10
  __int64 result; // rax
 
  v6 = strlen(a1);
  v7 = v6 % 3;
  if ( v6 % 3 )
  {
    v8 = 4 * (v6 / 3) + 4;
    v9 = v8;
    v10 = malloc(v8 + 1i64);
    v10[v8] = 0;
    if ( v6 <= 0 )
      goto LABEL_5;
  }
  else
  {
    v8 = 4 * (v6 / 3);
    v9 = v8;
    v10 = malloc(v8 + 1i64);
    v10[v8] = 0;
    if ( v6 <= 0 )
      goto LABEL_8;
  }
  v11 = v10;
  v12 = 0i64;
  do
  {
    v11 += 4;
    v13 = a1[v12];
    *(v11 - 4) = aQvejafhmuyjbac[v13 >> 2];
    v14 = a1[v12 + 1];
    *(v11 - 3) = aQvejafhmuyjbac[(v14 >> 4) | (16 * v13) & 0x30];
    v15 = a1[v12 + 2];
    v12 += 3i64;
    *(v11 - 2) = aQvejafhmuyjbac[(v15 >> 6) | (4 * v14) & 0x3C];
    *(v11 - 1) = aQvejafhmuyjbac[v15 & 0x3F];
  }
  while ( v6 > (int)v12 );
LABEL_5:
  if ( v7 == 1 )
  {
    v10[v9 - 2] = 61;
    v10[v9 - 1] = 61;
  }
  else if ( v7 == 2 )
  {
    v10[v9 - 1] = 61;
  }
LABEL_8:
  *a2 = v10;
  result = 0i64;
  *a3 = v8;
  return result;
}

看不懂不要紧,为了这个,我专门用一天时间消化base64编码与解码的原理,链接如下:https://www.cnblogs.com/Zer0o/p/17556660.html
看完,就能对base64原理了解的八九不离十了

这段代码一看移位运算,或运算,与运算,与base64编码一样,只不过base64是根据ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/编码,而这里修改为aQvejafhmuyjbac对应的字符串
图片描述
双击进入,知道这个base64是根据这串字符串编码的qvEJAfHmUYjBac+u8Ph5n9Od17FrICL/X0gVtM4Qk6T2z3wNSsyoebilxWKGZpRD,而不是ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
图片描述

知道原理了,返回main函数
图片描述
简单捋一下,就是将flag进行变异的base64编码,编码结果为a5mc58bphliax7j对应的数据,即5Mc58bPHLiAx7J8ocJIlaVUxaJvMcoYMaoPMaOfg15c475tscHfM/8==
图片描述
写出源码

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
char base64CharsArr[] = "qvEJAfHmUYjBac+u8Ph5n9Od17FrICL/X0gVtM4Qk6T2z3wNSsyoebilxWKGZpRD";
 
void base64decode(char str[]) {
    int length = strlen(str);
    int padding = 0;
 
    // 计算填充字符数量
    if (str[length - 1] == '=') {
        padding++;
        if (str[length - 2] == '=')
            padding++;
    }
 
    // 计算解码后的字符数量
    int decodedLength = (length * 3) / 4 - padding;
 
    // 分配存储解码结果的内存
    char* decodedStr = (char*)malloc(decodedLength + 1);
 
    int outIndex = 0;
    for (int i = 0; i < length; i += 4) {
        char char1 = -1, char2 = -1, char3 = -1, char4 = -1;
 
        // 查找每个字符在Base64字符集中的索引
        for (int j = 0; j < 64; j++) {
            if (base64CharsArr[j] == str[i]) {
                char1 = j;
                break;
            }
        }
 
        for (int j = 0; j < 64; j++) {
            if (base64CharsArr[j] == str[i + 1]) {
                char2 = j;
                break;
            }
        }
 
        for (int j = 0; j < 64; j++) {
            if (base64CharsArr[j] == str[i + 2]) {
                 char3 = j;
                break;
            }
        }
 
        for (int j = 0; j < 64; j++) {
            if (base64CharsArr[j] == str[i + 3]) {
                 char4 = j;
                break;
            }
        }
 
        // 解码并存储结果
        decodedStr[outIndex++] = (char1 << 2) | ((char2 & 0x30) >> 4);
        if (char3 != -1)
            decodedStr[outIndex++] = ((char2 & 0xf) << 4) | ((char3 & 0x3c) >> 2);
        if (char4 != -1)
            decodedStr[outIndex++] = ((char3 & 0x3) << 6) | char4;
    }
 
    // 添加字符串结束符
    decodedStr[decodedLength] = '\0';
 
    printf("Decoded string: %s\n", decodedStr);
 
    // 释放内存
    free(decodedStr);
}
 
int main() {
    char str[100]="5Mc58bPHLiAx7J8ocJIlaVUxaJvMcoYMaoPMaOfg15c475tscHfM/8=="; // Example base64 encoded string
    base64decode(str);
    return 0;
}

图片描述
flag:NSSCTF{a8d4347722800e72e34e1aba3fe914ae}


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2023-7-30 20:34 被Zer0_0编辑 ,原因:
收藏
免费 3
支持
分享
最新回复 (3)
雪    币: 27071
活跃值: (63057)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
2
程序方便上传论坛一份?以供其他人学习时直接操作练习
2023-7-15 19:08
0
雪    币: 2787
活跃值: (30801)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
感谢分享
2023-7-15 23:04
1
雪    币: 844
活跃值: (507)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
4
Editor 程序方便上传论坛一份?以供其他人学习时直接操作练习
多谢提醒,已上传
2023-7-30 20:34
0
游客
登录 | 注册 方可回帖
返回
//