easy_rc4
分析
一眼
key = FenKey!!
,提取出密文后直接在线网站解码
后面还有个xor 0x20的操作
exp
LitCTF{71bb2a06417a5306ba297ddcfce7b1b0}
pickle
分析
python的Pickle反序列化,用pickletools提取字节流反汇编
import pickletools
with open("challenge.pickle", "rb") as f:
data = f.read()
pickletools.dis(data)
翻译后大概是这样
def check(user_input):
raw = input("input your flag > ")
flag_bytes = raw.encode()
result = []
for i in range(len(encrypted_flag)):
b = flag_bytes[i] ^ key_ints[i % len(key_ints)]
result.append(b)
if tuple(result) == encrypted_flag:
print("Good job! You made it!")
return True
else:
print("Nah, don't give up!")
return False
提取出encrypted_flag
和key_ints
exp
#include <iostream>
#include <cstring>
#include <string>
void boom(const char *flag, int key)
{
char tmp[45] = "";
for(int i = 0;i < 45;i++)
{
tmp[i] = flag[i] + key;
}
if(strstr(tmp,"LitCTF") != NULL)
{
printf("%s\n",tmp);
}
}
int main()
{
int encrypted_flag[] = {
85, 84, 174, 227, 132, 190, 207, 142, 77, 24, 235, 236, 231,
213, 138, 153, 60, 29, 241, 241, 237, 208, 144, 222, 115, 16,
242, 239, 231, 165, 157, 224, 56, 104, 242, 128, 250, 211, 150,
225, 63, 29, 242, 169
};
short key[] = {
19, 55, 192, 222, 202, 254, 186, 190
};
char flag[45] = "";
for(int i = 0;i < 45;i++)
{
flag[i] = encrypted_flag[i] ^ key[i % 8];
}
for(int i = 0;i < 0xFF;i++)
{
boom(flag,i);
}
}
LitCTF{6d518316-5075-40ff-873a-d1e8d632e208}
参考
Python之Pickle反序列化 python pickle 反序列化
easy_tea
分析
看题目带有tea,猜测tea模板题,解压出来文件名为"花",猜测有花指令
IDA载入无法直接F5,直接分析反汇编大体内容
找到疑似key和密文的数据,再找找TEA算法在哪实现
进入call内部
去花,然后重构,长这样
TEA的delta值被魔改了,为0x114514
回到main函数,修复试试
NOP掉上图红框部分和上面的
db 0
,再nop掉jmp short loc_4150A9
还是有点问题,但没影响了,解密时记得小端序存储问题就行了
exp
#include <stdio.h>
#include <stdint.h>
// TEA 解密模板(delta=0x114514)
void tea_decrypt(uint32_t v[2], const uint32_t k[4]) {
uint32_t v0 = v[0];
uint32_t v1 = v[1];
const uint32_t delta = 0x114514;
uint32_t sum = delta * 32;
for (int i = 0; i < 32; i++) {
v1 -= ((v0 << 4) + k[2]) ^ (v0 + sum) ^ ((v0 >> 5) + k[3]);
v0 -= ((v1 << 4) + k[0]) ^ (v1 + sum) ^ ((v1 >> 5) + k[1]);
sum -= delta;
}
v[0] = v0;
v[1] = v1;
}
int main(void) {
uint32_t enc[] = {
0x977457FE,0x0DA3E1880,
0x0B8169108,0x1E95285C,
0x1FE7E6F2,0x2BC5FC57,
0x0B28F0FA8,0x8E0E0644,
0x68454425,0x0C57740D9
};
size_t n_enc = sizeof(enc)/sizeof(enc[0]);
size_t n_blocks = n_enc / 2;
const uint32_t key[4] = {
0x11223344, 0x55667788,
0x99AABBCC, 0xDDEEFF11,
};
uint8_t flag[n_blocks*8 + 1];
size_t pos = 0;
for (size_t i = 0; i < n_blocks; i++) {
uint32_t v[2] = { enc[2*i], enc[2*i + 1] };
tea_decrypt(v, key);
for (int b = 0; b < 4; b++) {
flag[pos++] = (v[0] >> (8 * b)) & 0xFF;
}
for (int b = 0; b < 4; b++) {
flag[pos++] = (v[1] >> (8 * b)) & 0xFF;
}
}
flag[pos] = '\0';
printf("%s\n", flag);
return 0;
}
LitCTF{590939df61690383a47ed1bc6ade9d51}
test_your_nc
没过滤Tab键,在shell中Tab键可以当作分隔符
利用python读取文件并打印就行了
python3<TAB>-c<TAB>"print(open('flag').read())"
FeatureExtraction(复现)
分析
uint32_t pre = 0;
for (uint32_t i = 0; i < 44; i++)
{
pre = 0;
for (uint32_t j = 0; j < 10; j++)
{
pre = szFlag[i] * key[j];
TestEncflag[i + j] += pre;
}
}
每次第i
轮确定一个TestEncflag[i]
TestEncflag[0] = szFlag[0] * key[0]
TestEncflag[1] = szFlag[0] * key[1] + szFlag[1] * key[0]
TestEncflag[2] = szFlag[0] * key[2] + szFlag[1] * key[1] + szFlag[2] * key[0]
以此类推
exp
#include <iostream>
uint32_t key[] = { 0x4C, 0x69, 0x74, 0x43, 0x54, 0x46, 0x32, 0x30, 0x32, 0x35 };
uint32_t encflag[53] = {
0x1690, 0x3E58, 0x6FF1, 0x86F0, 0x9D66, 0xAB30, 0xCA71, 0xCF29, 0xE335, 0xE492,
0xF1FD, 0xDE80, 0xD0C8, 0xC235, 0xB9B5, 0xB1CF, 0x9E9F, 0x9E86, 0x96B4, 0xA550,
0xA0D3, 0xA135, 0x99CA, 0xACC0, 0xBE78, 0xC196, 0xBC00, 0xB5C3, 0xB7F0, 0xB465,
0xB673, 0xB71F, 0xBBE2, 0xCB4F, 0xD2AD, 0xDE20, 0xEC94, 0xFC30, 0x104B8, 0xF6EE,
0xEDC9, 0xE385, 0xD78B, 0xDE19, 0xC94C, 0xAD14, 0x7E88, 0x6BB9, 0x4CC6, 0x3806,
0x2DC9, 0x2398, 0x19E1
};
int main()
{
uint32_t flag[100] = { 0 };
uint32_t pre = 0;
for (uint32_t i = 0; i < 44; i++)
{
pre = 0;
for (uint32_t j = 0; j < i; j++)
{
if (i - j < 10)
{
pre += flag[j] * key[i - j];
}
}
flag[i] = (encflag[i] - pre) / key[0];
}
for (uint32_t i = 0; i < 44; i++)
{
printf("%c", (char)flag[i]);
}
return 0;
}
附上对源码的猜测
void OriProcess()
{
char szFlag[] = "LitCTF{1e5a6230-308c-47cf-907c-4bfafdec8296}";
uint32_t TestEncflag[53] = { 0 };
uint32_t pre = 0;
for (uint32_t i = 0; i < 44; i++)
{
pre = 0;
for (uint32_t j = 0; j < 10; j++)
{
pre = szFlag[i] * key[j];
TestEncflag[i + j] += pre;
}
}
for (uint32_t i = 0; i < 53; i++)
{
printf("0x%x\t", TestEncflag[i]);
}
}
LitCTF{1e5a6230-308c-47cf-907c-4bfafdec8296}
Robbie_Wanna_Revenge(复现)
分析
Unity游戏逆向,一般可以开个无敌过去,但是先找找有没有捷径
用CE附加游戏,开启Mono
展开所有条目,保存为文件
有一个PlayerWon关键词,尝试调用
得到flag