Zer0o 发表于 2023-10-12 22:52

[LitCTF 2023]enbase64

本帖最后由 Zer0o 于 2023-10-12 22:56 编辑

这是一个将flag换base64表之后加密的代码
附件下载

https://wwvc.lanzouj.com/iwZuF1bmzehg
查壳
无壳,32位

分析
丢入ida32,找到main函数F5
```
int __cdecl main(int argc, const char **argv, const char **envp)
{
    char Source; // BYREF
    char v5; // BYREF
    char Str1; // BYREF
    char Str; // BYREF

    __main();
    memset(Str, 0, 1000);
    memset(Str1, 0, sizeof(Str1));
    *(_DWORD *)Source = *(_DWORD *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    strcpy(v5, "9+/");
    qmemcpy(&Source, &aAbcdefghijklmn[-(Source - &Source)], 4 * (((Source - &Source + 65) & 0xFFFFFFFC) >> 2));
    puts("Please input flag:");
    gets(Str);
    if ( strlen(Str) == 33 )
{
    base64(Source, Str, Str1);
    basecheck(Str1);
}
    return 0;
}
```
第12和第13没有用,Source是base64表,也就是ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/,Str是输入的flag,先经过base64这个函数加密,我们先点入base64函数里面看看

发现basechange(Source),怀疑将base64表换了,我们继续跟进basechange函数

将Source的表换成Destination,可以直接跑出来换后的表,即Destination值

脚本
```
#include<stdio.h>
#include<string.h>
int main()
{
char *result; // eax
char Destination; // BYREF
int v3; // BYREF
int j; //
int i; //
char Source[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
memset(v3, 0, sizeof(v3));
v3 = 16;
v3 = 34;
v3 = 56;
v3 = 7;
v3 = 46;
v3 = 2;
v3 = 10;
v3 = 44;
v3 = 20;
v3 = 41;
v3 = 59;
v3 = 31;
v3 = 51;
v3 = 60;
v3 = 61;
v3 = 26;
v3 = 5;
v3 = 40;
v3 = 21;
v3 = 38;
v3 = 4;
v3 = 54;
v3 = 52;
v3 = 47;
v3 = 3;
v3 = 11;
v3 = 58;
v3 = 48;
v3 = 32;
v3 = 15;
v3 = 49;
v3 = 14;
v3 = 37;
v3 = 55;
v3 = 53;
v3 = 24;
v3 = 35;
v3 = 18;
v3 = 25;
v3 = 33;
v3 = 43;
v3 = 50;
v3 = 39;
v3 = 12;
v3 = 19;
v3 = 13;
v3 = 42;
v3 = 9;
v3 = 17;
v3 = 28;
v3 = 30;
v3 = 23;
v3 = 36;
v3 = 1;
v3 = 22;
v3 = 57;
v3 = 63;
v3 = 8;
v3 = 27;
v3 = 6;
v3 = 62;
v3 = 45;
v3 = 29;
result = strcpy(Destination, Source);
for ( i = 0; i <= 47; ++i )
{
    for ( j = 0; j <= 63; ++j )
      Source = Destination];
    result = strcpy(Destination, Source);
}
printf("%s",Destination);
return 0;
}
```
换后的表

gJ1BRjQie/FIWhEslq7GxbnL26M4+HXUtcpmVTKaydOP38of5v90ZSwrkYzCAuND
接下来就好办了,把之前写过的base64解密代码的base64表替换一下,找到加密后的值
也就是basecheck函数

双击跟进,找到加密后的值

GQTZlSqQXZ/ghxxwhju3hbuZ4wufWjujWrhYe7Rce7ju
现在换的表和加密后的值都找到了,可以得到flag值了,直接上脚本
```
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char base64CharsArr[] = "gJ1BRjQie/FIWhEslq7GxbnL26M4+HXUtcpmVTKaydOP38of5v90ZSwrkYzCAuND";

void base64decode(char str[]) {
    int length = strlen(str);
    int padding = 0;

    // 计算填充字符数量
    if (str == '=') {
      padding++;
      if (str == '=')
            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 == str) {
                char1 = j;
                break;
            }
      }

      for (int j = 0; j < 64; j++) {
            if (base64CharsArr == str) {
                                char2 = j;
                break;
            }
      }

      for (int j = 0; j < 64; j++) {
            if (base64CharsArr == str) {
                                char3 = j;
                break;
            }
      }

      for (int j = 0; j < 64; j++) {
            if (base64CharsArr == str) {
                                char4 = j;
                break;
            }
      }

      // 解码并存储结果
      decodedStr = (char1 << 2) | ((char2 & 0x30) >> 4);
      if (char3 != -1)
            decodedStr = ((char2 & 0xf) << 4) | ((char3 & 0x3c) >> 2);
      if (char4 != -1)
            decodedStr = ((char3 & 0x3) << 6) | char4;
    }

    // 添加字符串结束符
    decodedStr = '\0';

    printf("Decoded string: %s\n", decodedStr);

    // 释放内存
    free(decodedStr);
}

int main() {
    char str="GQTZlSqQXZ/ghxxwhju3hbuZ4wufWjujWrhYe7Rce7ju"; // Example base64 encoded string
        base64decode(str);
    return 0;
}
```
运行即得flag:LitCTF{B@5E64_l5_tooo0_E3sy!!!!!}

页: [1]
查看完整版本: [LitCTF 2023]enbase64