[LitCTF 2023]enbase64

WriteUp 6个月前 admin
39 0 0

这是一个将flag换base64表之后加密的代码。


附件下载


https://wwvc.lanzouj.com/iwZuF1bmzehg


查壳


无壳,32位。


[LitCTF 2023]enbase64


分析


丢入ida32,找到main函数F5。


int __cdecl main(int argc, const char **argv, const char **envp)
{
char Source[61]; // [esp+1Fh] [ebp-81Dh] BYREF
char v5[4]; // [esp+5Ch] [ebp-7E0h] BYREF
char Str1[1000]; // [esp+60h] [ebp-7DCh] BYREF
char Str[1012]; // [esp+448h] [ebp-3F4h] BYREF

__main();
memset(Str, 0, 1000);
memset(Str1, 0, sizeof(Str1));
*(_DWORD *)Source = *(_DWORD *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
strcpy(v5, "9+/");
qmemcpy(&Source[1], &aAbcdefghijklmn[-(Source - &Source[1])], 4 * (((Source - &Source[1] + 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函数里面看看。


[LitCTF 2023]enbase64

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


[LitCTF 2023]enbase64


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


[LitCTF 2023]enbase64

脚本


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


换后的表


[LitCTF 2023]enbase64

gJ1BRjQie/FIWhEslq7GxbnL26M4+HXUtcpmVTKaydOP38of5v90ZSwrkYzCAuND


接下来就好办了,把之前写过的base64解密代码的base64表替换一下,找到加密后的值。


也就是basecheck函数。


[LitCTF 2023]enbase64


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


[LitCTF 2023]enbase64

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[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] = '';

printf("Decoded string: %sn", decodedStr);

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

int main() {
char str[100]="GQTZlSqQXZ/ghxxwhju3hbuZ4wufWjujWrhYe7Rce7ju"; // Example base64 encoded string
base64decode(str);
return 0;
}


运行即得flag:LitCTF{B@5E64_l5_tooo0_E3sy!!!!!}


[LitCTF 2023]enbase64




[LitCTF 2023]enbase64


看雪ID:Zer0_0

https://bbs.kanxue.com/user-home-945402.htm

*本文为看雪论坛优秀文章,由 Zer0_0 原创,转载请注明来自看雪社区

[LitCTF 2023]enbase64

# 往期推荐

1、IOFILE exploit入门

2、入门编译原理之前端体验

3、如何用纯猜的方式逆向喜马拉雅xm文件加密(wasm部分)

4、反恶意软件扫描接口(AMSI)如何帮助您防御恶意软件

5、sRDI — Shellcode反射式DLL注入技术

6、对APP的检测以及参数计算分析


[LitCTF 2023]enbase64


[LitCTF 2023]enbase64

球分享

[LitCTF 2023]enbase64

球点赞

[LitCTF 2023]enbase64

球在看

原文始发于微信公众号(看雪学苑):[LitCTF 2023]enbase64

版权声明:admin 发表于 2023年10月25日 下午6:04。
转载请注明:[LitCTF 2023]enbase64 | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...