2024CBCTF招新赛复盘
inside
根据 hint,去https://github.com/ergrelet/unlicense下载脱壳机,直接拖拽文件脱壳.
里面一看,是个被魔改的 base64,把 key 和密文 dump 出来,扔给 gpt 一把梭写脚本,即得到 flag.
def custom_base64_decrypt(encoded_bytes):
# 映射表
v11 = "BACDEFGHIJKLMNOPQRSTUVWXZYabcdefghijklmnopqrstuvwxyz01234567+/89"
# 解密的逆向 XOR 操作值
xor_values = [21, 0x55, 69, 51]
# 逆向映射表
reverse_v11 = {v: i for i, v in enumerate(v11)}
decoded_bytes = []
for i in range(0, len(encoded_bytes), 4):
chunk = encoded_bytes[i:i+4]
# 解密:先 XOR,然后通过映射表逆向查找
indices = []
for j, c in enumerate(chunk):
decoded_char = chr(c ^ xor_values[j])
if decoded_char in reverse_v11:
indices.append(reverse_v11[decoded_char])
else:
indices.append(0) # 防止异常字符
# 将索引恢复为原始的三个字节
if len(indices) == 4:
b1 = (indices[0] << 2) | (indices[1] >> 4)
b2 = ((indices[1] & 0xF) << 4) | (indices[2] >> 2)
b3 = ((indices[2] & 0x3) << 6) | indices[3]
decoded_bytes.extend([b1, b2, b3])
# 移除填充的多余字节
return bytes(decoded_bytes)
# 被加密的密文
encrypted_data = [
0x44, 0x65, 0x0F, 0x77, 0x43, 0x10, 0x1C, 0x04, 0x71, 0x11, 0x29, 0x58, 0x4D, 0x66, 0x22, 0x01,
0x76, 0x39, 0x6A, 0x5A, 0x58, 0x38, 0x03, 0x49, 0x58, 0x39, 0x6A, 0x40, 0x5B, 0x66, 0x17, 0x55,
0x4C, 0x3F, 0x03, 0x55, 0x4C, 0x67, 0x6A, 0x1C
]
# 解密结果
plaintext = custom_base64_decrypt(encrypted_data)
print(plaintext.decode('utf-8', errors='ignore'))
in_inside
这题与其说是我自己做的,不如说早就被学长透完了.
不会用 dbg,也看不懂壳,没有工具.学长说这是 vmp,是强壳,不能脱,直接动调.于是就用着笨办法,一步一步调,看出了逻辑,本质上就是两个字节的四位互换,然后再异或 0x11,0x22(这里我把他们当成了十进制 😓).那么就可以写脚本了.
我自己的脚本不知道为什么出问题了,还是让 ai 修改了好久才成功.
void decrypt(unsigned char *data, size_t length)
{
for (size_t i = 0; i < length; i += 2)
{
unsigned char x1 = data[i];
unsigned char x2 = data[i + 1];
// 反向异或操作
x1 ^= 0x11; // 对应原始加密中使用的 22
x2 ^= 0x22; // 对应原始加密中使用的 11
// 反向移位
unsigned char temp1 = (x1 >> 4) | (x2 << 4); // 交换两个字节的高低四位
unsigned char temp2 = (x2 >> 4) | (x1 << 4); // 交换两个字节的高低四位
// 反向位移
x1 = temp1;
x2 = temp2;
// 更新数据
data[i] = x1;
data[i + 1] = x2;
}
}
int main()
{
size_t data_length = sizeof(encrypted_data);
decrypt(encrypted_data, data_length);
printf("Decrypted data:\n%s\n", encrypted_data);
return 0;
}
让我康康
也基本是学长教的.
首先一眼平坦化,用 D-810 结果搞不出来,想了半天.去搜索到另一个工具 angr,利用符号执行(D-810 也是啊,用什么不同呢 🤔).然后去平坦化,但还是依托诗.
后面姑且看出了是个流加密,写了脚本,但由于不熟悉 RC4 和平坦化的依托诗.在学长提醒下才知道这是个魔改的 RC4,抄网上脚本,加上了魔改的随机数.(这是个考点,windows 下和 linux 下的rand()
是不同的)
结果还是出不来,这时学长非常贱地说了一句话:"写不出来就对啦."这里 key 值被修改了(如果脚本发现无问题,应该想到这点,要么密文,要么 key,但我脑子太昏了,没想到),通过交叉应用看到main
之前的修改函数,是根据有无调试而修改 key 值,利用学长教的方法,打断点,修改 ZF 值,手动 hook 过去,可以看到 key 值被修改成了"showmeyourpower!!"
然后修改 key 值,即可得 flag.
#include<stdio.h>
/*
RC4初始化函数
*/
void rc4_init(unsigned char* s, unsigned char* key, unsigned long Len_k)
{
int i = 0, j = 0;
char k[256] = { 0 };
unsigned char tmp = 0;
for (i = 0; i < 256; i++) {
s[i] = i;
k[i] = key[i % Len_k];
}
for (i = 0; i < 256; i++) {
j = (j + s[i] + k[i]) % 256;
tmp = s[i];
s[i] = s[j];
s[j] = tmp;
}
}
/*
RC4加解密函数
unsigned char* Data 加解密的数据
unsigned long Len_D 加解密数据的长度
unsigned char* key 密钥
unsigned long Len_k 密钥长度
*/
void rc4_crypt(unsigned char* Data, unsigned long Len_D, unsigned char* key, unsigned long Len_k) //加解密
{
unsigned char s[256];
rc4_init(s, key, Len_k);
int i = 0, j = 0, t = 0;
unsigned long k = 0;
unsigned char tmp;
for (k = 0; k < Len_D; k++) {
i = (i + 1) % 256;
j = (j + s[i]) % 256;
tmp = s[i];
s[i] = s[j];
s[j] = tmp;
t = (s[i] + s[j]) % 256;
s[t] ^= rand();
Data[k] = Data[k] ^ s[t];
}
}
int main()
{
srand(0x1BF52);
//字符串密钥
unsigned char key[] = 0x73, 0x68, 0x6F, 0x77, 0x5F, 0x6D, 0x65, 0x5F, 0x79, 0x6F,
0x75, 0x72, 0x5F, 0x70, 0x6F, 0x77, 0x65, 0x72, 0x21, 0x21;
unsigned long key_len = sizeof(key);
//数组密钥
//unsigned char key[] = {};
//unsigned long key_len = sizeof(key);
//加解密数据
unsigned char data[] = {0x21, 0xEE, 0x74, 0xF0, 0x2C, 0x76, 0xC4, 0x29, 0x33, 0x8F, 0xA2, 0xC2, 0x25, 0x18, 0x57, 0xA0, 0xAB, 0x42, 0x94, 0x76, 0x4F, 0x57, 0x47, 0x1B, 0x58, 0xE4, 0xD9, 0xE3, 0x1D, 0x35, 0x4E, 0xA4};
//加解密
rc4_crypt(data, sizeof(data), key, key_len);
printf("%s",data);
return;
}
合集:
各类CTF比赛
分类:
Cyber / 各类比赛WP
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)