当前位置: 首页 > news >正文

ctf逆向常见算法----base64

ctf逆向常见算法----base64

base64顾名思义,即为使用A-Z,a-z,0-9,+,/,64个字符进行编码的一种方式,当然在日常的使用中还会出现=用作填充字符。

作为在ctf竞赛中最常用的一种编码形式,本篇文章将对其原理及代码实现进行详解

原理

base64算法首先运用到的是一张包含有64个字符的索引表

0 1 2 3 4 5 6 7 8 9
A B C D E F G H I J
10 11 12 13 14 15 16 17 18 19
K L M N O P Q R S T
20 21 22 23 24 25 26 27 28 29
U V W X Y Z a b c d
30 31 32 33 34 35 36 37 38 39
e f g h i j k l m n
40 41 42 43 44 45 46 47 48 49
o p q r s t u v w x
50 51 52 53 54 55 56 57 58 59
y z 0 1 2 3 4 5 6 7
60 61 62 63
8 9 + /

如表中所示每一个字符都相对应这一个索引,共64个,由此便引申出base64中的要点,2的6次方等于64,即每个索引用6位二进制来表示,而在计算机中一个字符使用8位二进制来表示,二者的转化关系如图所示

image-20250917002147941

由图中的关系可以看出,三位文本字符则对应四位base64字符,而在实际运用中由于每次进行编码的文本并非都为3的倍数,故而在base64编码中加入=号进行填充

如果最后剩下一个字符,则在二进制编码中中加入4个0位,在base编码中加入==

image-20250917002208320

如果最后剩下两个字符,则在二进制编码中中加入2个0位,在base编码中加入=

image-20250917002224487

代码

c语言实现

编码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>// Base64编码表
static const char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";/*** Base64编码函数* @param data 要编码的原始数据* @param input_length 原始数据长度* @param output_length 编码后数据长度(输出参数)* @return Base64编码字符串,需要调用者释放内存*/
char *base64_encode(const unsigned char *data, size_t input_length, size_t *output_length) {if (data == NULL || input_length == 0) {return NULL;}// 计算输出缓冲区大小(每3字节输入转换为4字节输出)size_t output_size = 4 * ((input_length + 2) / 3);char *encoded_data = malloc(output_size + 1); // +1用于字符串结束符if (encoded_data == NULL) {return NULL;}size_t i, j;for (i = 0, j = 0; i < input_length;) {uint32_t octet_a = i < input_length ? data[i++] : 0;uint32_t octet_b = i < input_length ? data[i++] : 0;uint32_t octet_c = i < input_length ? data[i++] : 0;uint32_t triple = (octet_a << 16) | (octet_b << 8) | octet_c;encoded_data[j++] = base64_table[(triple >> 18) & 0x3F];encoded_data[j++] = base64_table[(triple >> 12) & 0x3F];encoded_data[j++] = base64_table[(triple >> 6) & 0x3F];encoded_data[j++] = base64_table[triple & 0x3F];}// 处理填充if (input_length % 3 != 0) {size_t padding_count = 3 - (input_length % 3);for (size_t k = 0; k < padding_count; k++) {encoded_data[output_size - 1 - k] = '=';}}encoded_data[output_size] = '\0'; // 添加字符串结束符if (output_length != NULL) {*output_length = output_size;}return encoded_data;
}int main() {const char *test_string = "Hello, World!";size_t input_len = strlen(test_string);size_t output_len;char *encoded = base64_encode((const unsigned char *)test_string, input_len, &output_len);if (encoded != NULL) {printf("Original: %s\n", test_string);printf("Base64: %s\n", encoded);printf("Output length: %zu\n", output_len);free(encoded);} else {printf("Encoding failed!\n");}return 0;
}

解码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>// Base64解码表
static const unsigned char base64_decode_table[256] = {['A'] = 0, ['B'] = 1, ['C'] = 2, ['D'] = 3, ['E'] = 4, ['F'] = 5, ['G'] = 6, ['H'] = 7,['I'] = 8, ['J'] = 9, ['K'] = 10, ['L'] = 11, ['M'] = 12, ['N'] = 13, ['O'] = 14, ['P'] = 15,['Q'] = 16, ['R'] = 17, ['S'] = 18, ['T'] = 19, ['U'] = 20, ['V'] = 21, ['W'] = 22, ['X'] = 23,['Y'] = 24, ['Z'] = 25, ['a'] = 26, ['b'] = 27, ['c'] = 28, ['d'] = 29, ['e'] = 30, ['f'] = 31,['g'] = 32, ['h'] = 33, ['i'] = 34, ['j'] = 35, ['k'] = 36, ['l'] = 37, ['m'] = 38, ['n'] = 39,['o'] = 40, ['p'] = 41, ['q'] = 42, ['r'] = 43, ['s'] = 44, ['t'] = 45, ['u'] = 46, ['v'] = 47,['w'] = 48, ['x'] = 49, ['y'] = 50, ['z'] = 51, ['0'] = 52, ['1'] = 53, ['2'] = 54, ['3'] = 55,['4'] = 56, ['5'] = 57, ['6'] = 58, ['7'] = 59, ['8'] = 60, ['9'] = 61, ['+'] = 62, ['/'] = 63,['='] = 0 // 填充字符视为0
};// Base64解码函数
unsigned char *base64_decode(const char *data) {if (!data || !*data) return NULL;size_t len = strlen(data);size_t padding = (data[len-1] == '=') + (data[len-2] == '=');size_t out_size = (len * 3) / 4 - padding;unsigned char *decoded = malloc(out_size + 1);if (!decoded) return NULL;uint32_t buf = 0;int bits = 0, count = 0;for (size_t i = 0; i < len; i++) {unsigned char c = data[i];if (c == '=') break; // 遇到填充字符停止uint8_t value = base64_decode_table[c];if (value == 0 && c != 'A') continue; // 跳过无效字符('A'的值为0)buf = (buf << 6) | value;bits += 6;if (bits >= 8) {bits -= 8;decoded[count++] = (buf >> bits) & 0xFF;}}decoded[count] = '\0';return decoded;
}int main(int argc, char *argv[]) {if (argc != 2) {printf("Usage: %s <base64_string>\n", argv[0]);return 1;}unsigned char *decoded = base64_decode(argv[1]);if (decoded) {printf("%s\n", decoded);free(decoded);return 0;} else {printf("Error: Invalid Base64 input\n");return 1;}
}

python实现

编码:

import base64text =  input("请输入文本")
encoded = base64.b64encode(text.encode('utf-8')).decode('utf-8')
print(encoded)

解码:

import base64encoded_text = input("请输入要解码的 Base64 字符串: ")
decoded = base64.b64decode(encoded_text).decode()
print(decoded)

实战

image-20250916233545577

下载附件后先使用die进行查壳

image-20250916233847644

使用ida打开后,

使用shift+F12,查看字符串后可以看到base64索引表,在部分题目中会对此字符串进行变化

image-20250916234635056

进入encode_one,可以看到base64加密过程

image-20250916234220502

encode_two相当于将加密后的字符串以13为单位重新排列

image-20250916235501284

encode_three使用到了凯撒变换

image-20250916235643148

加密逻辑就是

首先将输入的字符串进行base64编码,再进行移位,最后再使用凯撒

本博客只介绍base64编码,具体解题过程我放在下面了

参考文章

https://zhuanlan.zhihu.com/p/111700349
https://blog.csdn.net/m0_73644864/article/details/128792247
http://www.hskmm.com/?act=detail&tid=25353

相关文章:

  • 02020409 EF Core基础09-一对一、多对多、EF Core基于关系的复杂查询
  • 02020503 EF Core高级03-分页查询、IQuerable底层的实现形式、DataReader、DataTable、EF Core中的异步方法
  • 02020502 EF Core高级02-IQuerable会延迟执行、分部和动态构建IQuerable、IQuerable的复用
  • 在 PyCharm 中,环境:bert_env , 执行 import wandb 报错。但是,在CMD窗口,环境:bert_env , 执行 import wandb 正常。
  • Linux_T(Sticky Bit)粘滞位详解 - 详解
  • P2831 [NOIP 2016 提高组] 愤怒的小鸟 题解
  • 库存中心(三层库存模型)
  • Valley靶机渗透实战:从凭证复用到Python库劫持
  • 10.05模拟赛反思
  • MariaDB收购SkySQL增强AI与无服务器能力
  • 单片机寄存器的四种主要类型! - 实践
  • TDengine 高级特性——读缓存
  • 非合作博弈之软性均衡:东方智慧与西方理论的融合框架
  • 如何快速搭建spring-boot工程 - murphy
  • Ai元人文:东谈西论——非合作博弈之软性均衡
  • 反向传播与梯度下降:神经网络如何真正学会分类
  • Spring Cloud Alibaba微服务开发
  • OI 各种东西的板子
  • 价值弥漫:AI元人文的场域革命与共生之路
  • 做题记录 #1
  • 阿爸阿爸
  • 深度学习优化器算法巧思速览
  • 完整教程:LangChain完全指南:从入门到精通,打造AI应用开发新范式
  • NDK开发与实践(入门篇微课视频版)
  • 调了很久的代码总结
  • CF700E
  • 价值弥漫:“AI元人文”的场域革命与共生之路
  • k8s之pod概念
  • CF 1055 Div.1+Div.2
  • 2026 NOI 做题记录(五)