REVERSE-COMPETITION-CISCN-2025
- rand0m
- ezCsky
- dump
- cython
rand0m
3.12版本的pyd逆向
读16进制,分成4个4字节的int,每个int做两步运算
第一步,右移28bit,左移4bit,然后拼接
注意左移4bit后又&0x3a3affff,会丢失8bit,需要爆破
第二步,输入还是原本的4字节
右移11bit后做类似rsa的幂模运算
两步依次验证,第一步验证成功后才会进行第二步验证
对于每个int,先claripy求解的范围,然后爆破验证第二步
import claripy
inp = claripy.BVS("inp",32)
def func(inp):
a = inp>>5
a &= 0xffffffff
b = inp<<4
b &= 0xffffffff
b &= 0x3a3affff
b &= 0xffffffff
a >>= 23
a &= 0xffffffff
c = a + b
c &= 0xffffffff
return c
s=claripy.Solver()
s.add(func(inp)&0xfffffff==0x8108807)
print(s.check_satisfiability())
print(s.constraints)
arr = []
for i in s.eval(inp,2000):
arr.append(i)
print(len(arr))
def enc2(inp):
a = inp ^ 0x9e3779b9
a &= 0xffffffff
a >>= 11
a &= 0xffffffff
a **= 65537
a %= 0xfffffffd
return hex(a).endswith("8499BB6".lower())
for i in arr:
if enc2(i):
print(hex(i))
最终得到flag{813a97f3d4b34f74802ba12678950880}
ezCsky
IDA插件
分析完大概是
rc4是标准的,密钥是”testkey”
check是个从前往后循环异或
解密
from Crypto.Cipher import ARC4
enc = [0x96, 0x8F, 0xB8, 0x08, 0x5D, 0xA7, 0x68, 0x44, 0xF2, 0x64,
0x92, 0x64, 0x42, 0x7A, 0x78, 0xE6, 0xEA, 0xC2, 0x78, 0xB8,
0x63, 0x9E, 0x5B, 0x3D, 0xD9, 0x28, 0x3F, 0xC8, 0x73, 0x06,
0xEE, 0x6B, 0x8D, 0x0C, 0x4B, 0xA3, 0x23, 0xAE, 0xCA, 0x40,
0xED, 0xD1]
rc4 = ARC4.new(b"testkey")
enc = rc4.decrypt(bytes(enc))
enc = list(enc)
for i in range(len(enc)-2, -1, -1):
enc[i] ^= enc[i+1]
print(bytes(enc))
# flag{d0f5b330-9a74-11ef-9afd-acde48001122}
dump
单字节变换,找映射逆回去即可
import string
tb = string.printable
print(tb)
tb_res = list(bytes.fromhex("001c1d000000000000001e1f202122232425262728292a2b2c2d2e2f303132333435363702030405060708090a0b0c0d0e0f101112131415161718191a1b00000000000000000000000000000000000100000000000000000038003900"))
enc = list(bytes.fromhex("23 29 1E 24 38 0E 15 20 37 0E 05 20 00 0E 37 12 1D 0F 24 01 01 39"))
for i in enc:
if i in tb_res:
print(tb[tb_res.index(i)],end="")
# flag`MTczMDc0MzQ2Ng<<|
# flag{MTczMDc4MzQ2Ng==}
cython
魔改的xtea,改了左移右移位数,delta,轮数
#include <stdio.h>
#include <stdint.h>
//加密函数
void encrypt(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4])
{
unsigned int i;
uint32_t v0 = v[0], v1 = v[1], sum = 0, delta = 0x54646454;
for (i = 0; i < num_rounds; i++)
{
v0 += (((v1 << 3) ^ (v1 >> 6)) + v1) ^ (sum + key[sum & 3]);
sum += delta;
v1 += (((v0 << 3) ^ (v0 >> 6)) + v0) ^ (sum + key[(sum >> 11) & 3]);
}
v[0] = v0;
v[1] = v1;
printf("sum==0x%x\n", sum);
}
//解密函数
void decrypt(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4])
{
unsigned int i;
uint32_t v0 = v[0], v1 = v[1], delta = 0x54646454, sum = 0x19191500;
for (i = 0; i < num_rounds; i++)
{
v1 -= (((v0 << 3) ^ (v0 >> 6)) + v0) ^ (sum + key[(sum >> 11) & 3]);
sum -= delta;
v0 -= (((v1 << 3) ^ (v1 >> 6)) + v1) ^ (sum + key[sum & 3]);
}
v[0] = v0;
v[1] = v1;
printf("sum==0x%x\n", sum);
}
//打印数据 hex_or_chr: 1-hex 0-chr
void dump_data(uint32_t *v, int n, bool hex_or_chr)
{
if (hex_or_chr)
{
for (int i = 0; i < n; i++)
{
printf("0x%x,", v[i]);
}
}
else
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < sizeof(uint32_t) / sizeof(uint8_t); j++)
{
printf("%c", (v[n - i - 1] >> (j * 8)) & 0xFF);
}
}
}
printf("\n");
return;
}
int main()
{
// v为要加解密的数据
uint32_t v[] = {0x481f56c9, 0xc7ee5ef4, 0xa00a5b72, 0x7648f086, 0x0307f948, 0x29b379b0};
// k为加解密密钥,4个32位无符号整数,密钥长度为128位
uint32_t k[4] = {102, 108, 97, 103};
// num_rounds,建议取值为32
unsigned int r = 64;
int n = sizeof(v) / sizeof(uint32_t);
/*
printf("加密前明文数据:");
dump_data(v, n, 1);
for (int i = 0; i < n / 2; i++)
{
encrypt(r, &v[i * 2], k);
}
*/
printf("加密后密文数据:");
dump_data(v, n, 1);
for (int i = 0; i < n / 2; i++)
{
decrypt(r, &v[i * 2], k);
}
printf("解密后明文数据:");
dump_data(v, n, 1);
printf("解密后明文字符:");
dump_data(v, n, 0);
return 0;
}
// flag{w9bFoVlQ5M67vfDngH}