-
-
[原创] WMCTF2021 Re 部分复现
-
发表于: 2021-9-3 22:31 11976
-
开局flutter,直呼内行
咕咕咕(bushi) 另外两题实在肝不动,等官方wp了
题目开局花指令[常见花指令识别与处理方案 | 我的CTF学习笔记 ]
去掉花指令后,正常F5,发现虚假控制流
对输入进行了条件约束
将起始下标定位到输入的WMCTF{
后一位Str[6]
,而后进入控制流顺序执行。
首先开辟了一块大小为576的内存空间,给地址为首先将Block
指针转为DOWRD*
,而后*(Block + 273) = 0xdead
进入case 0
,取了前四位字符,循环写入了四段数据
而后运行至case 1
,取四字符之后的16位,写入Block + 530
对应的地址空间
而后就是运行case 2
了,此时index已经是6 + 4 + 16
,而分析case 2
发现其对之后的每五位进行处理,最大能够处理三组数据。
五位中,第一位被拿来作为不同函数调用的标志,再分别将后四位十六进制字符转换成int类型,而后调用相关函数
理解不了,先放一放,看后面
分析后,发现,cond开头的四个参数可以通过z3求出,而且,其值源自boxXor
,虽然它不可逆,但我们在分析case 0
的时候就知道,Block
,Block + 257
……四段正好是由四个字符处理而来。
考虑爆破出4字符
爆破得到Hah4
而后在上图也可以看到,我分析后标注了xteaEncrypt
函数,key
和src
,但同时我也注释了两个unknown
,为什么?后面再讲。
第一时间,当我们看到
很快能够想到之前case 0
似乎有出现给Block + 273
这一地址空间赋值0xdead
于是我们尝试解密,发现并不是可见字符——key是错误的。
0~0xffff
尝试爆破出真正的值
看到明文
尝试解密
得到_D0_yOu_L1kE_It!
现在我们拿到了前半段flag,下面就是考虑如何拿到后半段flag
切入点:Block + 273
既然Block + 273
被修改了,猜测是在case 2
执行过程中修改了它
分析各个函数,想办法能够修改到Block + 273
这里就需要试着套流程 ,依靠脑洞了- -
最后得到@FFFE#0F20-11B7
tips: 这里的@,用到了一个0xff的溢出(-1)
android题,主逻辑一如既往在ndk
动态注册的函数调用。
先瞟一眼.init_array
看起来是加了混淆
再看JNI_OnLoad
发现一个出题者挖的坑,检测了调试机的root
试了试frida直接hook,结果hook不住……(有知道为啥的大佬教一下我)那就直接patch so吧
打包回去,安装
尴尬,改一下AndroidManifest.xml里的android:extractNativeLibs
再来
调试环境整好,下面先静态分析一下。
程序的正常流程是在这里注册
注册的函数为sub_10134
分析出来,先进行了AES加密而后进行RC4,这里的算法都是经过一定的魔改,并不是标准算法。
最后与stru_46000[0].n128_u8[v11]
比对
KeyExpansion
是标准的密钥扩展算法,AES主要的修改点在于Sbox和ShiftRows部分
而RC4的修改,在于最后异或时多异或了0x50
算法是分析完了,那么如何拿到AES Key,IV和RC4Key?
我们前面看到.init_array
是对一些数据的解密,静态提取是不可取了,那就动态跑起来取,Frida Hook(动态调试So也是可以的)
下面继续取RC4的Key
拿到RC4Key:Hello from C++
再去Hook比对的加密文本
撸脚本解密了
拿出Sbox,跑出InvBox,修改ShiftRows
aes.cpp
AES.h
main.cpp
解出flag:wmctf{e78ce1a3ac4be37a96e27e98c}
v7 = index++;
str_7 = Str[v7];
// Str[27]
if
( str_7 ==
'_'
&& index + 4 <= length )
{
if
( (Str[index] <
'0'
|| Str[index] >
'9'
) && (Str[index] <
'A'
|| Str[index] >
'F'
)
|| (Str[index + 1] <
'0'
|| Str[index + 1] >
'9'
) && (Str[index + 1] < 65 || Str[index + 1] > 70)
|| (Str[index + 2] <
'0'
|| Str[index + 2] >
'9'
) && (Str[index + 2] < 65 || Str[index + 2] > 70)
|| (Str[index + 3] <
'0'
|| Str[index + 3] >
'9'
) && (Str[index + 3] < 65 || Str[index + 3] > 70) )
{
vars9A = 1;
}
else
{
v8 = index++;
str_8 = Str[v8];
v9 = index++;
str_9 = Str[v9];
str_10 = hex2int(str_8, str_9);
// 十六进制转十进制
v10 = index++;
str_8 = Str[v10];
v11 = index++;
str_9 = Str[v11];
vars9B = hex2int(str_8, str_9);
sub_140003320((
__int64
)Block, str_10, vars9B);
}
}
else
if
( str_7 ==
'@'
&& index + 4 <= length )
{
if
( (Str[index] < 48 || Str[index] > 57) && (Str[index] < 65 || Str[index] > 70)
|| (Str[index + 1] < 48 || Str[index + 1] > 57) && (Str[index + 1] < 65 || Str[index + 1] > 70)
|| (Str[index + 2] < 48 || Str[index + 2] > 57) && (Str[index + 2] < 65 || Str[index + 2] > 70)
|| (Str[index + 3] < 48 || Str[index + 3] > 57) && (Str[index + 3] < 65 || Str[index + 3] > 70) )
{
vars9A = 1;
}
else
{
v12 = index++;
str_8 = Str[v12];
v13 = index++;
str_9 = Str[v13];
str_10 = hex2int(str_8, str_9);
v14 = index++;
str_8 = Str[v14];
v15 = index++;
str_9 = Str[v15];
vars9B = hex2int(str_8, str_9);
sub_140003390((
__int64
)Block, str_10, vars9B);
}
}
else
if
( str_7 ==
'#'
&& index + 4 <= length )
{
if
( (Str[index] < 48 || Str[index] > 57) && (Str[index] < 65 || Str[index] > 70)
|| (Str[index + 1] < 48 || Str[index + 1] > 57) && (Str[index + 1] < 65 || Str[index + 1] > 70)
|| (Str[index + 2] < 48 || Str[index + 2] > 57) && (Str[index + 2] < 65 || Str[index + 2] > 70)
|| (Str[index + 3] < 48 || Str[index + 3] > 57) && (Str[index + 3] < 65 || Str[index + 3] > 70) )
{
vars9A = 1;
}
else
{
v16 = index++;
str_8 = Str[v16];
v17 = index++;
str_9 = Str[v17];
str_10 = hex2int(str_8, str_9);
v18 = index++;
str_8 = Str[v18];
v19 = index++;
str_9 = Str[v19];
vars9B = hex2int(str_8, str_9);
sub_1400033F0(Block, str_10, vars9B);
}
}
else
if
( str_7 ==
'?'
&& index + 4 <= length )
{
if
( (Str[index] < 48 || Str[index] > 57) && (Str[index] < 65 || Str[index] > 70)
|| (Str[index + 1] < 48 || Str[index + 1] > 57) && (Str[index + 1] < 65 || Str[index + 1] > 70)
|| (Str[index + 2] < 48 || Str[index + 2] > 57) && (Str[index + 2] < 65 || Str[index + 2] > 70)
|| (Str[index + 3] < 48 || Str[index + 3] > 57) && (Str[index + 3] < 65 || Str[index + 3] > 70) )
{
vars9A = 1;
}
else
{
v20 = index++;
str_8 = Str[v20];
v21 = index++;
str_9 = Str[v21];
str_10 = hex2int(str_8, str_9);
v22 = index++;
str_8 = Str[v22];
v23 = index++;
str_9 = Str[v23];
vars9B = hex2int(str_8, str_9);
sub_140003470((
__int64
)Block, str_10, vars9B);
}
}
else
if
( str_7 ==
'!'
&& index + 4 <= length )
{
if
( (Str[index] < 48 || Str[index] > 57) && (Str[index] < 65 || Str[index] > 70)
|| (Str[index + 1] < 48 || Str[index + 1] > 57) && (Str[index + 1] < 65 || Str[index + 1] > 70)
|| (Str[index + 2] < 48 || Str[index + 2] > 57) && (Str[index + 2] < 65 || Str[index + 2] > 70)
|| (Str[index + 3] < 48 || Str[index + 3] > 57) && (Str[index + 3] < 65 || Str[index + 3] > 70) )
{
vars9A = 1;
}
else
{
v24 = index++;
str_8 = Str[v24];
v25 = index++;
str_9 = Str[v25];
str_10 = hex2int(str_8, str_9);
v26 = index++;
str_8 = Str[v26];
v27 = index++;
str_9 = Str[v27];
vars9B = hex2int(str_8, str_9);
sub_140003500(Block, str_10, vars9B);
}
}
else
if
( str_7 ==
'&'
&& index + 4 <= length )
{
if
( (Str[index] < 48 || Str[index] > 57) && (Str[index] < 65 || Str[index] > 70)
|| (Str[index + 1] < 48 || Str[index + 1] > 57) && (Str[index + 1] < 65 || Str[index + 1] > 70)
|| (Str[index + 2] < 48 || Str[index + 2] > 57) && (Str[index + 2] < 65 || Str[index + 2] > 70)
|| (Str[index + 3] < 48 || Str[index + 3] > 57) && (Str[index + 3] < 65 || Str[index + 3] > 70) )
{
vars9A = 1;
}
else
{
v28 = index++;
str_8 = Str[v28];
v29 = index++;
str_9 = Str[v29];
str_10 = hex2int(str_8, str_9);
v30 = index++;
str_8 = Str[v30];
v31 = index++;
str_9 = Str[v31];
vars9B = hex2int(str_8, str_9);
sub_140003580(Block, str_10, vars9B);
}
}
else
if
( str_7 ==
'-'
&& index + 4 <= length )
{
if
( (Str[index] < 48 || Str[index] > 57) && (Str[index] < 65 || Str[index] > 70)
|| (Str[index + 1] < 48 || Str[index + 1] > 57) && (Str[index + 1] < 65 || Str[index + 1] > 70)
|| (Str[index + 2] < 48 || Str[index + 2] > 57) && (Str[index + 2] < 65 || Str[index + 2] > 70)
|| (Str[index + 3] < 48 || Str[index + 3] > 57) && (Str[index + 3] < 65 || Str[index + 3] > 70) )
{
vars9A = 1;
}
else
{
v32 = index++;
str_8 = Str[v32];
v33 = index++;
str_9 = Str[v33];
str_10 = hex2int(str_8, str_9);
v34 = index++;
str_8 = Str[v34];
v35 = index++;
str_9 = Str[v35];
vars9B = hex2int(str_8, str_9);
sub_1400035E0(Block, str_10, vars9B);
}
}
else
if
( str_7 ==
'$'
&& index + 4 <= length )
{
if
( (Str[index] < 48 || Str[index] > 57) && (Str[index] < 65 || Str[index] > 70)
|| (Str[index + 1] < 48 || Str[index + 1] > 57) && (Str[index + 1] < 65 || Str[index + 1] > 70)
|| (Str[index + 2] < 48 || Str[index + 2] > 57) && (Str[index + 2] < 65 || Str[index + 2] > 70)
|| (Str[index + 3] < 48 || Str[index + 3] > 57) && (Str[index + 3] < 65 || Str[index + 3] > 70) )
{
vars9A = 1;
}
else
{
v36 = index++;
str_8 = Str[v36];
v37 = index++;
str_9 = Str[v37];
str_10 = hex2int(str_8, str_9);
v38 = index++;
str_8 = Str[v38];
v39 = index++;
str_9 = Str[v39];
vars9B = hex2int(str_8, str_9);
sub_1400036A0(Block, str_10, vars9B);
}
}
else
if
( str_7 ==
'+'
&& index + 4 <= length )
{
if
( (Str[index] < 48 || Str[index] > 57) && (Str[index] < 65 || Str[index] > 70)
|| (Str[index + 1] < 48 || Str[index + 1] > 57) && (Str[index + 1] < 65 || Str[index + 1] > 70)
|| (Str[index + 2] < 48 || Str[index + 2] > 57) && (Str[index + 2] < 65 || Str[index + 2] > 70)
|| (Str[index + 3] < 48 || Str[index + 3] > 57) && (Str[index + 3] < 65 || Str[index + 3] > 70) )
{
vars9A = 1;
}
else
{
v40 = index++;
str_8 = Str[v40];
v41 = index++;
str_9 = Str[v41];
str_10 = hex2int(str_8, str_9);
v42 = index++;
str_8 = Str[v42];
v43 = index++;
str_9 = Str[v43];
vars9B = hex2int(str_8, str_9);
sub_140003730((
__int64
)Block, str_10, vars9B);
}
}
else
{
Block[str_7 + 257] += str_7;
vars9A = 1;
}
break
;
v7 = index++;
str_7 = Str[v7];
// Str[27]
if
( str_7 ==
'_'
&& index + 4 <= length )
{
if
( (Str[index] <
'0'
|| Str[index] >
'9'
) && (Str[index] <
'A'
|| Str[index] >
'F'
)
|| (Str[index + 1] <
'0'
|| Str[index + 1] >
'9'
) && (Str[index + 1] < 65 || Str[index + 1] > 70)
|| (Str[index + 2] <
'0'
|| Str[index + 2] >
'9'
) && (Str[index + 2] < 65 || Str[index + 2] > 70)
|| (Str[index + 3] <
'0'
|| Str[index + 3] >
'9'
) && (Str[index + 3] < 65 || Str[index + 3] > 70) )
{
vars9A = 1;
}
else
{
v8 = index++;
str_8 = Str[v8];
v9 = index++;
str_9 = Str[v9];
str_10 = hex2int(str_8, str_9);
// 十六进制转十进制
v10 = index++;
str_8 = Str[v10];
v11 = index++;
str_9 = Str[v11];
vars9B = hex2int(str_8, str_9);
sub_140003320((
__int64
)Block, str_10, vars9B);
}
}
else
if
( str_7 ==
'@'
&& index + 4 <= length )
{
if
( (Str[index] < 48 || Str[index] > 57) && (Str[index] < 65 || Str[index] > 70)
|| (Str[index + 1] < 48 || Str[index + 1] > 57) && (Str[index + 1] < 65 || Str[index + 1] > 70)
|| (Str[index + 2] < 48 || Str[index + 2] > 57) && (Str[index + 2] < 65 || Str[index + 2] > 70)
|| (Str[index + 3] < 48 || Str[index + 3] > 57) && (Str[index + 3] < 65 || Str[index + 3] > 70) )
{
vars9A = 1;
}
else
{
v12 = index++;
str_8 = Str[v12];
v13 = index++;
str_9 = Str[v13];
str_10 = hex2int(str_8, str_9);
v14 = index++;
str_8 = Str[v14];
v15 = index++;
str_9 = Str[v15];
vars9B = hex2int(str_8, str_9);
sub_140003390((
__int64
)Block, str_10, vars9B);
}
}
else
if
( str_7 ==
'#'
&& index + 4 <= length )
{
if
( (Str[index] < 48 || Str[index] > 57) && (Str[index] < 65 || Str[index] > 70)
|| (Str[index + 1] < 48 || Str[index + 1] > 57) && (Str[index + 1] < 65 || Str[index + 1] > 70)
|| (Str[index + 2] < 48 || Str[index + 2] > 57) && (Str[index + 2] < 65 || Str[index + 2] > 70)
|| (Str[index + 3] < 48 || Str[index + 3] > 57) && (Str[index + 3] < 65 || Str[index + 3] > 70) )
{
vars9A = 1;
}
else
{
v16 = index++;
str_8 = Str[v16];
v17 = index++;
str_9 = Str[v17];
str_10 = hex2int(str_8, str_9);
v18 = index++;
str_8 = Str[v18];
v19 = index++;
str_9 = Str[v19];
vars9B = hex2int(str_8, str_9);
sub_1400033F0(Block, str_10, vars9B);
}
}
else
if
( str_7 ==
'?'
&& index + 4 <= length )
{
if
( (Str[index] < 48 || Str[index] > 57) && (Str[index] < 65 || Str[index] > 70)
|| (Str[index + 1] < 48 || Str[index + 1] > 57) && (Str[index + 1] < 65 || Str[index + 1] > 70)
|| (Str[index + 2] < 48 || Str[index + 2] > 57) && (Str[index + 2] < 65 || Str[index + 2] > 70)
|| (Str[index + 3] < 48 || Str[index + 3] > 57) && (Str[index + 3] < 65 || Str[index + 3] > 70) )
{
vars9A = 1;
}
else
{
v20 = index++;
str_8 = Str[v20];
v21 = index++;
str_9 = Str[v21];
str_10 = hex2int(str_8, str_9);
v22 = index++;
str_8 = Str[v22];
v23 = index++;
str_9 = Str[v23];
vars9B = hex2int(str_8, str_9);
sub_140003470((
__int64
)Block, str_10, vars9B);
}
}
else
if
( str_7 ==
'!'
&& index + 4 <= length )
{
if
( (Str[index] < 48 || Str[index] > 57) && (Str[index] < 65 || Str[index] > 70)
|| (Str[index + 1] < 48 || Str[index + 1] > 57) && (Str[index + 1] < 65 || Str[index + 1] > 70)
|| (Str[index + 2] < 48 || Str[index + 2] > 57) && (Str[index + 2] < 65 || Str[index + 2] > 70)
|| (Str[index + 3] < 48 || Str[index + 3] > 57) && (Str[index + 3] < 65 || Str[index + 3] > 70) )
{
vars9A = 1;
}
else
{
v24 = index++;
str_8 = Str[v24];
v25 = index++;
str_9 = Str[v25];
str_10 = hex2int(str_8, str_9);
v26 = index++;
str_8 = Str[v26];
v27 = index++;
str_9 = Str[v27];
vars9B = hex2int(str_8, str_9);
sub_140003500(Block, str_10, vars9B);
}
}
else
if
( str_7 ==
'&'
&& index + 4 <= length )
{
if
( (Str[index] < 48 || Str[index] > 57) && (Str[index] < 65 || Str[index] > 70)
|| (Str[index + 1] < 48 || Str[index + 1] > 57) && (Str[index + 1] < 65 || Str[index + 1] > 70)
|| (Str[index + 2] < 48 || Str[index + 2] > 57) && (Str[index + 2] < 65 || Str[index + 2] > 70)
|| (Str[index + 3] < 48 || Str[index + 3] > 57) && (Str[index + 3] < 65 || Str[index + 3] > 70) )
{
vars9A = 1;
}
else
{
v28 = index++;
str_8 = Str[v28];
v29 = index++;
str_9 = Str[v29];
str_10 = hex2int(str_8, str_9);
v30 = index++;
str_8 = Str[v30];
v31 = index++;
str_9 = Str[v31];
vars9B = hex2int(str_8, str_9);
sub_140003580(Block, str_10, vars9B);
}
}
else
if
( str_7 ==
'-'
&& index + 4 <= length )
{
if
( (Str[index] < 48 || Str[index] > 57) && (Str[index] < 65 || Str[index] > 70)
|| (Str[index + 1] < 48 || Str[index + 1] > 57) && (Str[index + 1] < 65 || Str[index + 1] > 70)
|| (Str[index + 2] < 48 || Str[index + 2] > 57) && (Str[index + 2] < 65 || Str[index + 2] > 70)
|| (Str[index + 3] < 48 || Str[index + 3] > 57) && (Str[index + 3] < 65 || Str[index + 3] > 70) )
{
vars9A = 1;
}
else
{
v32 = index++;
str_8 = Str[v32];
v33 = index++;
str_9 = Str[v33];
str_10 = hex2int(str_8, str_9);
v34 = index++;
str_8 = Str[v34];
v35 = index++;
str_9 = Str[v35];
vars9B = hex2int(str_8, str_9);
sub_1400035E0(Block, str_10, vars9B);
}
}
else
if
( str_7 ==
'$'
&& index + 4 <= length )
{
if
( (Str[index] < 48 || Str[index] > 57) && (Str[index] < 65 || Str[index] > 70)
|| (Str[index + 1] < 48 || Str[index + 1] > 57) && (Str[index + 1] < 65 || Str[index + 1] > 70)
|| (Str[index + 2] < 48 || Str[index + 2] > 57) && (Str[index + 2] < 65 || Str[index + 2] > 70)
|| (Str[index + 3] < 48 || Str[index + 3] > 57) && (Str[index + 3] < 65 || Str[index + 3] > 70) )
{
vars9A = 1;
}
else
{
v36 = index++;
str_8 = Str[v36];
v37 = index++;
str_9 = Str[v37];
str_10 = hex2int(str_8, str_9);
v38 = index++;
str_8 = Str[v38];
v39 = index++;
str_9 = Str[v39];
vars9B = hex2int(str_8, str_9);
sub_1400036A0(Block, str_10, vars9B);
}
}
else
if
( str_7 ==
'+'
&& index + 4 <= length )
{
if
( (Str[index] < 48 || Str[index] > 57) && (Str[index] < 65 || Str[index] > 70)
|| (Str[index + 1] < 48 || Str[index + 1] > 57) && (Str[index + 1] < 65 || Str[index + 1] > 70)
|| (Str[index + 2] < 48 || Str[index + 2] > 57) && (Str[index + 2] < 65 || Str[index + 2] > 70)
|| (Str[index + 3] < 48 || Str[index + 3] > 57) && (Str[index + 3] < 65 || Str[index + 3] > 70) )
{
vars9A = 1;
}
else
{
v40 = index++;
str_8 = Str[v40];
v41 = index++;
str_9 = Str[v41];
str_10 = hex2int(str_8, str_9);
v42 = index++;
str_8 = Str[v42];
v43 = index++;
str_9 = Str[v43];
vars9B = hex2int(str_8, str_9);
sub_140003730((
__int64
)Block, str_10, vars9B);
}
}
else
{
Block[str_7 + 257] += str_7;
vars9A = 1;
}
break
;
import
z3
cond1
=
z3.BitVec(
"cond1"
,
32
)
cond2
=
z3.BitVec(
"cond2"
,
32
)
cond3
=
z3.BitVec(
"cond3"
,
32
)
cond4
=
z3.BitVec(
"cond4"
,
32
)
result1
=
cond2
+
cond1
=
=
0x11AB7A7A
result2
=
cond2
-
cond3
=
=
0x1CD4F222
result3
=
cond4
+
cond3
=
=
0xC940F021
result4
=
cond3
+
cond1
-
cond4
=
=
0x7C7D68D1
solve
=
z3.Solver()
solve.add(result1)
solve.add(result2)
solve.add(result3)
solve.add(result4)
if
solve.check()
=
=
z3.sat:
m
=
solve.model()
cond1
=
m.
eval
(cond1).as_long()
cond2
=
m.
eval
(cond2).as_long()
cond3
=
m.
eval
(cond3).as_long()
cond4
=
m.
eval
(cond4).as_long()
print
(
hex
(cond1),
hex
(cond2),
hex
(cond3),
hex
(cond4))
import
string
box
=
[
0x00000000
,
0x703A11DE
,
0xE07423BC
,
0x904E3262
,
0xC6A99C09
,
0xB6938DD7
,
0x26DDBFB5
,
0x56E7AE6B
,
0x8B12E363
,
0xFB28F2BD
,
0x6B66C0DF
,
0x1B5CD101
,
0x4DBB7F6A
,
0x3D816EB4
,
0xADCF5CD6
,
0xDDF54D08
,
0x10641DB7
,
0x605E0C69
,
0xF0103E0B
,
0x802A2FD5
,
0xD6CD81BE
,
0xA6F79060
,
0x36B9A202
,
0x4683B3DC
,
0x9B76FED4
,
0xEB4CEF0A
,
0x7B02DD68
,
0x0B38CCB6
,
0x5DDF62DD
,
0x2DE57303
,
0xBDAB4161
,
0xCD9150BF
,
0x20C83B6E
,
0x50F22AB0
,
0xC0BC18D2
,
0xB086090C
,
0xE661A767
,
0x965BB6B9
,
0x061584DB
,
0x762F9505
,
0xABDAD80D
,
0xDBE0C9D3
,
0x4BAEFBB1
,
0x3B94EA6F
,
0x6D734404
,
0x1D4955DA
,
0x8D0767B8
,
0xFD3D7666
,
0x30AC26D9
,
0x40963707
,
0xD0D80565
,
0xA0E214BB
,
0xF605BAD0
,
0x863FAB0E
,
0x1671996C
,
0x664B88B2
,
0xBBBEC5BA
,
0xCB84D464
,
0x5BCAE606
,
0x2BF0F7D8
,
0x7D1759B3
,
0x0D2D486D
,
0x9D637A0F
,
0xED596BD1
,
0x419076DC
,
0x31AA6702
,
0xA1E45560
,
0xD1DE44BE
,
0x8739EAD5
,
0xF703FB0B
,
0x674DC969
,
0x1777D8B7
,
0xCA8295BF
,
0xBAB88461
,
0x2AF6B603
,
0x5ACCA7DD
,
0x0C2B09B6
,
0x7C111868
,
0xEC5F2A0A
,
0x9C653BD4
,
0x51F46B6B
,
0x21CE7AB5
,
0xB18048D7
,
0xC1BA5909
,
0x975DF762
,
0xE767E6BC
,
0x7729D4DE
,
0x0713C500
,
0xDAE68808
,
0xAADC99D6
,
0x3A92ABB4
,
0x4AA8BA6A
,
0x1C4F1401
,
0x6C7505DF
,
0xFC3B37BD
,
0x8C012663
,
0x61584DB2
,
0x11625C6C
,
0x812C6E0E
,
0xF1167FD0
,
0xA7F1D1BB
,
0xD7CBC065
,
0x4785F207
,
0x37BFE3D9
,
0xEA4AAED1
,
0x9A70BF0F
,
0x0A3E8D6D
,
0x7A049CB3
,
0x2CE332D8
,
0x5CD92306
,
0xCC971164
,
0xBCAD00BA
,
0x713C5005
,
0x010641DB
,
0x914873B9
,
0xE1726267
,
0xB795CC0C
,
0xC7AFDDD2
,
0x57E1EFB0
,
0x27DBFE6E
,
0xFA2EB366
,
0x8A14A2B8
,
0x1A5A90DA
,
0x6A608104
,
0x3C872F6F
,
0x4CBD3EB1
,
0xDCF30CD3
,
0xACC91D0D
,
0x8320EDB8
,
0xF31AFC66
,
0x6354CE04
,
0x136EDFDA
,
0x458971B1
,
0x35B3606F
,
0xA5FD520D
,
0xD5C743D3
,
0x08320EDB
,
0x78081F05
,
0xE8462D67
,
0x987C3CB9
,
0xCE9B92D2
,
0xBEA1830C
,
0x2EEFB16E
,
0x5ED5A0B0
,
0x9344F00F
,
0xE37EE1D1
,
0x7330D3B3
,
0x030AC26D
,
0x55ED6C06
,
0x25D77DD8
,
0xB5994FBA
,
0xC5A35E64
,
0x1856136C
,
0x686C02B2
,
0xF82230D0
,
0x8818210E
,
0xDEFF8F65
,
0xAEC59EBB
,
0x3E8BACD9
,
0x4EB1BD07
,
0xA3E8D6D6
,
0xD3D2C708
,
0x439CF56A
,
0x33A6E4B4
,
0x65414ADF
,
0x157B5B01
,
0x85356963
,
0xF50F78BD
,
0x28FA35B5
,
0x58C0246B
,
0xC88E1609
,
0xB8B407D7
,
0xEE53A9BC
,
0x9E69B862
,
0x0E278A00
,
0x7E1D9BDE
,
0xB38CCB61
,
0xC3B6DABF
,
0x53F8E8DD
,
0x23C2F903
,
0x75255768
,
0x051F46B6
,
0x955174D4
,
0xE56B650A
,
0x389E2802
,
0x48A439DC
,
0xD8EA0BBE
,
0xA8D01A60
,
0xFE37B40B
,
0x8E0DA5D5
,
0x1E4397B7
,
0x6E798669
,
0xC2B09B64
,
0xB28A8ABA
,
0x22C4B8D8
,
0x52FEA906
,
0x0419076D
,
0x742316B3
,
0xE46D24D1
,
0x9457350F
,
0x49A27807
,
0x399869D9
,
0xA9D65BBB
,
0xD9EC4A65
,
0x8F0BE40E
,
0xFF31F5D0
,
0x6F7FC7B2
,
0x1F45D66C
,
0xD2D486D3
,
0xA2EE970D
,
0x32A0A56F
,
0x429AB4B1
,
0x147D1ADA
,
0x64470B04
,
0xF4093966
,
0x843328B8
,
0x59C665B0
,
0x29FC746E
,
0xB9B2460C
,
0xC98857D2
,
0x9F6FF9B9
,
0xEF55E867
,
0x7F1BDA05
,
0x0F21CBDB
,
0xE278A00A
,
0x9242B1D4
,
0x020C83B6
,
0x72369268
,
0x24D13C03
,
0x54EB2DDD
,
0xC4A51FBF
,
0xB49F0E61
,
0x696A4369
,
0x195052B7
,
0x891E60D5
,
0xF924710B
,
0xAFC3DF60
,
0xDFF9CEBE
,
0x4FB7FCDC
,
0x3F8DED02
,
0xF21CBDBD
,
0x8226AC63
,
0x12689E01
,
0x62528FDF
,
0x34B521B4
,
0x448F306A
,
0xD4C10208
,
0xA4FB13D6
,
0x790E5EDE
,
0x09344F00
,
0x997A7D62
,
0xE9406CBC
,
0xBFA7C2D7
,
0xCF9DD309
,
0x5FD3E16B
,
0x2FE9F0B5
]
def
boxXor(a1, a2, a3):
v5
=
0
v4
=
a1
while
v5 < a3:
v4
=
(v4 >>
8
) ^ box[(a2[v5] ^ v4) &
0xff
]
v5
+
=
1
return
a1 ^ v4
def
genBlock(a1, a2, a3):
block
=
[]
for
i
in
range
(a3):
block.append(i
+
a1
+
a2)
return
block
cond0
=
0xFFFFFFFE
for
c
in
string.printable:
block
=
genBlock(
ord
(c),
0
,
256
)
cond
=
boxXor(cond0, block,
256
)
if
cond
=
=
cond1:
print
(
"find Str[7]: "
+
c)
for
c
in
string.printable:
block
=
genBlock(
ord
(c),
1
,
256
)
cond
=
boxXor(cond1, block,
256
)
if
cond
=
=
cond2:
print
(
"find Str[8]: "
+
c)
for
c
in
string.printable:
block
=
genBlock(
ord
(c),
2
,
0xf
)
cond
=
boxXor(cond2, block,
0xf
)
if
cond
=
=
cond3:
print
(
"find Str[9]: "
+
c)
for
c
in
string.printable:
block
=
genBlock(
ord
(c),
3
,
0x1c
)
cond
=
boxXor(cond3, block,
0x1c
)
if
cond
=
=
cond4:
print
(
"find Str[9]: "
+
c)
# Hah4
import
z3
cond1
=
z3.BitVec(
"cond1"
,
32
)
cond2
=
z3.BitVec(
"cond2"
,
32
)
cond3
=
z3.BitVec(
"cond3"
,
32
)
cond4
=
z3.BitVec(
"cond4"
,
32
)
result1
=
cond2
+
cond1
=
=
0x11AB7A7A
result2
=
cond2
-
cond3
=
=
0x1CD4F222
result3
=
cond4
+
cond3
=
=
0xC940F021
result4
=
cond3
+
cond1
-
cond4
=
=
0x7C7D68D1
solve
=
z3.Solver()
solve.add(result1)
solve.add(result2)
solve.add(result3)
solve.add(result4)
if
solve.check()
=
=
z3.sat:
m
=
solve.model()
cond1
=
m.
eval
(cond1).as_long()
cond2
=
m.
eval
(cond2).as_long()
cond3
=
m.
eval
(cond3).as_long()
cond4
=
m.
eval
(cond4).as_long()
print
(
hex
(cond1),
hex
(cond2),
hex
(cond3),
hex
(cond4))
import
string
box
=
[
0x00000000
,
0x703A11DE
,
0xE07423BC
,
0x904E3262
,
0xC6A99C09
,
0xB6938DD7
,
0x26DDBFB5
,
0x56E7AE6B
,
0x8B12E363
,
0xFB28F2BD
,
0x6B66C0DF
,
0x1B5CD101
,
0x4DBB7F6A
,
0x3D816EB4
,
0xADCF5CD6
,
0xDDF54D08
,
0x10641DB7
,
0x605E0C69
,
0xF0103E0B
,
0x802A2FD5
,
0xD6CD81BE
,
0xA6F79060
,
0x36B9A202
,
0x4683B3DC
,
0x9B76FED4
,
0xEB4CEF0A
,
0x7B02DD68
,
0x0B38CCB6
,
0x5DDF62DD
,
0x2DE57303
,
0xBDAB4161
,
0xCD9150BF
,
0x20C83B6E
,
0x50F22AB0
,
0xC0BC18D2
,
0xB086090C
,
0xE661A767
,
0x965BB6B9
,
0x061584DB
,
0x762F9505
,
0xABDAD80D
,
0xDBE0C9D3
,
0x4BAEFBB1
,
0x3B94EA6F
,
0x6D734404
,
0x1D4955DA
,
0x8D0767B8
,
0xFD3D7666
,
0x30AC26D9
,
0x40963707
,
0xD0D80565
,
0xA0E214BB
,
0xF605BAD0
,
0x863FAB0E
,
0x1671996C
,
0x664B88B2
,
0xBBBEC5BA
,
0xCB84D464
,
0x5BCAE606
,
0x2BF0F7D8
,
0x7D1759B3
,
0x0D2D486D
,
0x9D637A0F
,
0xED596BD1
,
0x419076DC
,
0x31AA6702
,
0xA1E45560
,
0xD1DE44BE
,
0x8739EAD5
,
0xF703FB0B
,
0x674DC969
,
0x1777D8B7
,
0xCA8295BF
,
0xBAB88461
,
0x2AF6B603
,
0x5ACCA7DD
,
0x0C2B09B6
,
0x7C111868
,
0xEC5F2A0A
,
0x9C653BD4
,
0x51F46B6B
,
0x21CE7AB5
,
0xB18048D7
,
0xC1BA5909
,
0x975DF762
,
0xE767E6BC
,
0x7729D4DE
,
0x0713C500
,
0xDAE68808
,
0xAADC99D6
,
0x3A92ABB4
,
0x4AA8BA6A
,
0x1C4F1401
,
0x6C7505DF
,
0xFC3B37BD
,
0x8C012663
,
0x61584DB2
,
0x11625C6C
,
0x812C6E0E
,
0xF1167FD0
,
0xA7F1D1BB
,
0xD7CBC065
,
0x4785F207
,
0x37BFE3D9
,
0xEA4AAED1
,
0x9A70BF0F
,
0x0A3E8D6D
,
0x7A049CB3
,
0x2CE332D8
,
0x5CD92306
,
0xCC971164
,
0xBCAD00BA
,
0x713C5005
,
0x010641DB
,
0x914873B9
,
0xE1726267
,
0xB795CC0C
,
0xC7AFDDD2
,
0x57E1EFB0
,
0x27DBFE6E
,
0xFA2EB366
,
0x8A14A2B8
,
0x1A5A90DA
,
0x6A608104
,
0x3C872F6F
,
0x4CBD3EB1
,
0xDCF30CD3
,
0xACC91D0D
,
0x8320EDB8
,
0xF31AFC66
,
0x6354CE04
,
0x136EDFDA
,
0x458971B1
,
0x35B3606F
,
0xA5FD520D
,
0xD5C743D3
,
0x08320EDB
,
0x78081F05
,
0xE8462D67
,
0x987C3CB9
,
0xCE9B92D2
,
0xBEA1830C
,
0x2EEFB16E
,
0x5ED5A0B0
,
0x9344F00F
,
0xE37EE1D1
,
0x7330D3B3
,
0x030AC26D
,
0x55ED6C06
,
0x25D77DD8
,
0xB5994FBA
,
0xC5A35E64
,
0x1856136C
,
0x686C02B2
,
0xF82230D0
,
0x8818210E
,
0xDEFF8F65
,
0xAEC59EBB
,
0x3E8BACD9
,
0x4EB1BD07
,
0xA3E8D6D6
,
0xD3D2C708
,
0x439CF56A
,
0x33A6E4B4
,
0x65414ADF
,
0x157B5B01
,
0x85356963
,
0xF50F78BD
,
0x28FA35B5
,
0x58C0246B
,
0xC88E1609
,
0xB8B407D7
,
0xEE53A9BC
,
0x9E69B862
,
0x0E278A00
,
0x7E1D9BDE
,
0xB38CCB61
,
0xC3B6DABF
,
0x53F8E8DD
,
0x23C2F903
,
0x75255768
,
0x051F46B6
,
0x955174D4
,
0xE56B650A
,
0x389E2802
,
0x48A439DC
,
0xD8EA0BBE
,
0xA8D01A60
,
0xFE37B40B
,
0x8E0DA5D5
,
0x1E4397B7
,
0x6E798669
,
0xC2B09B64
,
0xB28A8ABA
,
0x22C4B8D8
,
0x52FEA906
,
0x0419076D
,
0x742316B3
,
0xE46D24D1
,
0x9457350F
,
0x49A27807
,
0x399869D9
,
0xA9D65BBB
,
0xD9EC4A65
,
0x8F0BE40E
,
0xFF31F5D0
,
0x6F7FC7B2
,
0x1F45D66C
,
0xD2D486D3
,
0xA2EE970D
,
0x32A0A56F
,
0x429AB4B1
,
0x147D1ADA
,
0x64470B04
,
0xF4093966
,
0x843328B8
,
0x59C665B0
,
0x29FC746E
,
0xB9B2460C
,
0xC98857D2
,
0x9F6FF9B9
,
0xEF55E867
,
0x7F1BDA05
,
0x0F21CBDB
,
0xE278A00A
,
0x9242B1D4
,
0x020C83B6
,
0x72369268
,
0x24D13C03
,
0x54EB2DDD
,
0xC4A51FBF
,
0xB49F0E61
,
0x696A4369
,
0x195052B7
,
0x891E60D5
,
0xF924710B
,
0xAFC3DF60
,
0xDFF9CEBE
,
0x4FB7FCDC
,
0x3F8DED02
,
0xF21CBDBD
,
0x8226AC63
,
0x12689E01
,
0x62528FDF
,
0x34B521B4
,
0x448F306A
,
0xD4C10208
,
0xA4FB13D6
,
0x790E5EDE
,
0x09344F00
,
0x997A7D62
,
0xE9406CBC
,
0xBFA7C2D7
,
0xCF9DD309
,
0x5FD3E16B
,
0x2FE9F0B5
]
def
boxXor(a1, a2, a3):
v5
=
0
v4
=
a1
while
v5 < a3:
v4
=
(v4 >>
8
) ^ box[(a2[v5] ^ v4) &
0xff
]
v5
+
=
1
return
a1 ^ v4
def
genBlock(a1, a2, a3):
block
=
[]
for
i
in
range
(a3):
block.append(i
+
a1
+
a2)
return
block
cond0
=
0xFFFFFFFE
for
c
in
string.printable:
block
=
genBlock(
ord
(c),
0
,
256
)
cond
=
boxXor(cond0, block,
256
)
if
cond
=
=
cond1:
print
(
"find Str[7]: "
+
c)
for
c
in
string.printable:
block
=
genBlock(
ord
(c),
1
,
256
)
cond
=
boxXor(cond1, block,
256
)
if
cond
=
=
cond2:
print
(
"find Str[8]: "
+
c)
for
c
in
string.printable:
block
=
genBlock(
ord
(c),
2
,
0xf
)
cond
=
boxXor(cond2, block,
0xf
)
if
cond
=
=
cond3:
print
(
"find Str[9]: "
+
c)
for
c
in
string.printable:
block
=
genBlock(
ord
(c),
3
,
0x1c
)
cond
=
boxXor(cond3, block,
0x1c
)
if
cond
=
=
cond4:
print
(
"find Str[9]: "
+
c)
# Hah4
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <windows.h>
#include <iostream>
void
xteaEnc(
DWORD
*v,
DWORD
*kj,
DWORD
*a3)
{
unsigned
int
*result;
// rax
unsigned
int
v4;
// [rsp+0h] [rbp-30h]
unsigned
int
v5;
// [rsp+Ch] [rbp-24h]
unsigned
int
v6;
// [rsp+10h] [rbp-20h]
unsigned
int
i;
// [rsp+14h] [rbp-1Ch]
v6 = *v;
v5 = v[1];
v4 = 0;
for
( i = 0; i < 0x20; ++i )
{
v6 += (kj[v4 & 3] + v4) ^ (v5 + ((v5 >> 5) ^ (16 * v5)));
v4 -= 0x667E5433;
v5 += (kj[(v4 >> 11) & 3] + v4) ^ (v6 + ((v6 >> 5) ^ (16 * v6)));
}
*a3 = v6;
a3[1] = v5;
}
void
xteaDec(
DWORD
*v,
DWORD
*kj,
DWORD
*a3)
{
unsigned
int
*result;
// rax
unsigned
int
v4;
// [rsp+0h] [rbp-30h]
unsigned
int
v5;
// [rsp+Ch] [rbp-24h]
unsigned
int
v6;
// [rsp+10h] [rbp-20h]
unsigned
int
i;
// [rsp+14h] [rbp-1Ch]
v6 = *v;
v5 = v[1];
v4 = 0x303579a0;
for
( i = 0; i < 0x20; ++i )
{
v5 -= (kj[(v4 >> 11) & 3] + v4) ^ (v6 + ((v6 >> 5) ^ (16 * v6)));
v4 += 0x667E5433;
v6 -= (kj[v4 & 3] + v4) ^ (v5 + ((v5 >> 5) ^ (16 * v5)));
}
*a3 = v6;
a3[1] = v5;
}
void
DWORD2BYTE(uint8_t* Dst, uint64_t Value,
const
std::string& byteorder) {
/* ============================
* byteorder = "big" / "little"
* */
if
(byteorder ==
"big"
) {
// big
for
(
int
i = 0; i < 4; ++i) {
Dst[3 - i] = Value & 0xff;
Value >>= 8;
}
}
else
if
(byteorder ==
"little"
) {
// little
for
(
int
i = 0; i < 4; ++i) {
Dst[i] = Value & 0xff;
Value >>= 8;
}
}
else
{
perror
(
"plz check byteorder"
);
}
}
void
fuzzing() {
DWORD
P1 = 0xa3eeb7be,
P2 = 0x6dbcc2bc,
P3 = 0x50e7d09a,
P4 = 0x78591f87;
DWORD
plaintext[2] = {0x556E2853, 0x4393DF16};
for
(
int
fuz = 0; fuz < 0x10000; ++fuz) {
DWORD
vars7C = P4 & 0xFFFFFF00 | (unsigned
__int8
)fuz;
P3 &= 0xFFFF00FF;
P3 |= fuz & 0xFF00;
DWORD
key[4] = {P1, P3, P2, vars7C};
DWORD
result[2];
xteaDec(plaintext, key, result);
BYTE
flag[9] = {0};
DWORD2BYTE(flag, result[0],
"little"
);
DWORD2BYTE(&flag[4], result[1],
"little"
);
int
find = 1;
for
(
int
i = 0; i < 8; ++i) {
if
(flag[i] >
'z'
|| flag[i] <
' '
) {
find = 0;
break
;
}
}
if
(find) {
printf
(
"bytes: %x FLAG: %s\n"
, fuz, flag);
}
}
}
int
main()
{
fuzzing();
return
0;
}
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <windows.h>
#include <iostream>
void
xteaEnc(
DWORD
*v,
DWORD
*kj,
DWORD
*a3)
{
unsigned
int
*result;
// rax
unsigned
int
v4;
// [rsp+0h] [rbp-30h]
unsigned
int
v5;
// [rsp+Ch] [rbp-24h]
unsigned
int
v6;
// [rsp+10h] [rbp-20h]
unsigned
int
i;
// [rsp+14h] [rbp-1Ch]
v6 = *v;
v5 = v[1];
v4 = 0;
for
( i = 0; i < 0x20; ++i )
{
v6 += (kj[v4 & 3] + v4) ^ (v5 + ((v5 >> 5) ^ (16 * v5)));
v4 -= 0x667E5433;
v5 += (kj[(v4 >> 11) & 3] + v4) ^ (v6 + ((v6 >> 5) ^ (16 * v6)));
}
*a3 = v6;
a3[1] = v5;
}
void
xteaDec(
DWORD
*v,
DWORD
*kj,
DWORD
*a3)
{
unsigned
int
*result;
// rax
unsigned
int
v4;
// [rsp+0h] [rbp-30h]
unsigned
int
v5;
// [rsp+Ch] [rbp-24h]
unsigned
int
v6;
// [rsp+10h] [rbp-20h]
unsigned
int
i;
// [rsp+14h] [rbp-1Ch]
v6 = *v;
v5 = v[1];
v4 = 0x303579a0;
for
( i = 0; i < 0x20; ++i )
{
v5 -= (kj[(v4 >> 11) & 3] + v4) ^ (v6 + ((v6 >> 5) ^ (16 * v6)));
v4 += 0x667E5433;
v6 -= (kj[v4 & 3] + v4) ^ (v5 + ((v5 >> 5) ^ (16 * v5)));
}
*a3 = v6;
a3[1] = v5;
}
void
DWORD2BYTE(uint8_t* Dst, uint64_t Value,
const
std::string& byteorder) {
/* ============================
* byteorder = "big" / "little"
* */
if
(byteorder ==
"big"
) {
// big
for
(
int
i = 0; i < 4; ++i) {
Dst[3 - i] = Value & 0xff;
Value >>= 8;
}
}
else
if
(byteorder ==
"little"
) {
// little
for
(
int
i = 0; i < 4; ++i) {
Dst[i] = Value & 0xff;
Value >>= 8;
}
}
else
{
perror
(
"plz check byteorder"
);
}
}
void
fuzzing() {
DWORD
P1 = 0xa3eeb7be,
P2 = 0x6dbcc2bc,
P3 = 0x50e7d09a,
P4 = 0x78591f87;
DWORD
plaintext[2] = {0x556E2853, 0x4393DF16};
for
(
int
fuz = 0; fuz < 0x10000; ++fuz) {
DWORD
vars7C = P4 & 0xFFFFFF00 | (unsigned
__int8
)fuz;
P3 &= 0xFFFF00FF;
P3 |= fuz & 0xFF00;
DWORD
key[4] = {P1, P3, P2, vars7C};
DWORD
result[2];
xteaDec(plaintext, key, result);
BYTE
flag[9] = {0};
DWORD2BYTE(flag, result[0],
"little"
);
DWORD2BYTE(&flag[4], result[1],
"little"
);
int
find = 1;
for
(
int
i = 0; i < 8; ++i) {
if
(flag[i] >
'z'
|| flag[i] <
' '
) {
find = 0;
break
;
}
}
if
(find) {
printf
(
"bytes: %x FLAG: %s\n"
, fuz, flag);
}
}
}
int
main()
{
fuzzing();
return
0;
}
int
main()
{
DWORD
P1 = 0xa3eeb7be,
P2 = 0x6dbcc2bc,
P3 = 0x50e7d09a,
P4 = 0x78591f87;
DWORD
vars7C = P4 & 0xFFFFFF00 | (unsigned
__int8
)0xb7ad;
// 不知道对不对
P3 &= 0xFFFF00FF;
P3 |= 0xb7ad & 0xFF00;
// todo: unknown
DWORD
plaintext[2] = {0x556E2853, 0x4393DF16};
DWORD
key[4] = {P1, P3, P2, vars7C};
DWORD
result[2];
xteaDec(plaintext, key, result);
printf
(
"%lx %lx\n"
, result[0], result[1]);
DWORD
plaintext2[2] = {0x1989FB2B, 0x83F5A243};
DWORD
key2[4] = {vars7C, P2, P1, P3};
DWORD
result2[2];
xteaDec(plaintext2, key2, result2);
printf
(
"%lx %lx\n"
, result2[0], result2[1]);
BYTE
flag[17] = {0};
DWORD2BYTE(flag, result[0],
"little"
);
DWORD2BYTE(&flag[4], result2[0],
"little"
);
DWORD2BYTE(&flag[8], result2[1],
"little"
);
DWORD2BYTE(&flag[12], result[1],
"little"
);
printf
(
"%s\n"
, flag);
printf
(
"%08lx %08lx %08lx %08lx\n"
, result[0], result2[0], result2[1] ,result[1]);
return
0;
}
int
main()
{
DWORD
P1 = 0xa3eeb7be,
P2 = 0x6dbcc2bc,
P3 = 0x50e7d09a,
P4 = 0x78591f87;
DWORD
vars7C = P4 & 0xFFFFFF00 | (unsigned
__int8
)0xb7ad;
// 不知道对不对
P3 &= 0xFFFF00FF;
P3 |= 0xb7ad & 0xFF00;
// todo: unknown
DWORD
plaintext[2] = {0x556E2853, 0x4393DF16};
DWORD
key[4] = {P1, P3, P2, vars7C};
DWORD
result[2];
xteaDec(plaintext, key, result);
printf
(
"%lx %lx\n"
, result[0], result[1]);
DWORD
plaintext2[2] = {0x1989FB2B, 0x83F5A243};
DWORD
key2[4] = {vars7C, P2, P1, P3};
DWORD
result2[2];
xteaDec(plaintext2, key2, result2);
printf
(
"%lx %lx\n"
, result2[0], result2[1]);
BYTE
flag[17] = {0};
DWORD2BYTE(flag, result[0],
"little"
);
DWORD2BYTE(&flag[4], result2[0],
"little"
);
DWORD2BYTE(&flag[8], result2[1],
"little"
);
DWORD2BYTE(&flag[12], result[1],
"little"
);
printf
(
"%s\n"
, flag);
printf
(
"%08lx %08lx %08lx %08lx\n"
, result[0], result2[0], result2[1] ,result[1]);
return
0;
}
// @FF FE
// #0F 20
// -11 B7
Block[546] = 0xDEAD;
Block[256] = 0xfe;
Block[528] = 0x20;
Block[547] = 0xb7;
// _
__int64
__fastcall sub_140003320(
__int64
a1, unsigned
__int8
a2,
char
a3)
{
__int64
result;
// rax
result = (unsigned
int
)(dword_140027A50 + 1);
dword_140027A50 = result;
if
( (unsigned
int
)result <= 1 )
{
result = a1 + 548;
*(_BYTE *)(a1 + 548 + ((
int
)a2 >> 4) + 1) = a3;
// 549 ~ 565
}
return
result;
}
// @
__int64
__fastcall sub_140003390(
__int64
a1,
char
a2,
char
a3)
{
__int64
result;
// rax
result = (unsigned
int
)(dword_140027A54 + 1);
dword_140027A54 = result;
if
( (unsigned
int
)result <= 1 )
{
result = a1 + 257;
*(_BYTE *)(a1 + 257 + a2) = a3;
// 注意-1溢出 - 256
}
return
result;
}
// #
__int64
__fastcall sub_1400033F0(_BYTE *a1,
char
a2,
char
a3)
{
__int64
result;
// rax
result = (unsigned
int
)(dword_140027A50 + 1);
dword_140027A50 = result;
if
( (unsigned
int
)result <= 1 )
{
result = (unsigned
__int8
)a1[256];
if
( (_DWORD)result == 0xFE )
{
result = (unsigned
int
)a2;
if
( (
int
)result < 0x10 )
{
result = (
__int64
)(a1 + 513);
a1[a2 + 513] = a3;
// 513 ~ 768 528
}
}
}
return
result;
}
// ?
__int64
__fastcall sub_140003470(
__int64
a1,
char
a2,
char
a3)
{
__int64
result;
// rax
result = (unsigned
int
)(dword_140027A58 + 1);
dword_140027A58 = result;
if
( (unsigned
int
)result <= 1 )
{
result = *(unsigned
__int16
*)(a1 + 528) / 3;
if
( !(*(unsigned
__int16
*)(a1 + 528) % 3) )
{
result = a1 + 530;
*(_BYTE *)(a1 + 530 + (a2 & 0xC)) = a3;
// 530 ~ 542 -> 530, 534, 538, 542
}
}
return
result;
}
// -
__int64
__fastcall sub_1400035E0(_BYTE *a1,
char
a2,
char
a3)
{
__int64
result;
// rax
result = (unsigned
int
)(dword_140027A60 + 1);
dword_140027A60 = result;
if
( (unsigned
int
)result <= 1 )
{
result = *((unsigned
__int16
*)a1 + 264) / 16;
// a1[528]
if
( !(*((unsigned
__int16
*)a1 + 264) % 16) )
{
result = *((unsigned
__int16
*)a1 + 264) / 16;
if
( (unsigned
int
)(*((unsigned
__int16
*)a1 + 264) / 16) < 3 )
{
result = (unsigned
int
)a2;
if
( (
int
)result <= *((unsigned
__int16
*)a1 + 264) )
{
result = (
__int64
)(a1 + 530);
a1[a2 + 530] = a3;
}
}
}
}
return
result;
}
// @FF FE
// #0F 20
// -11 B7
Block[546] = 0xDEAD;
Block[256] = 0xfe;
Block[528] = 0x20;
Block[547] = 0xb7;
// _
__int64
__fastcall sub_140003320(
__int64
a1, unsigned
__int8
a2,
char
a3)
{
__int64
result;
// rax
result = (unsigned
int
)(dword_140027A50 + 1);
dword_140027A50 = result;
if
( (unsigned
int
)result <= 1 )
{
result = a1 + 548;
*(_BYTE *)(a1 + 548 + ((
int
)a2 >> 4) + 1) = a3;
// 549 ~ 565
}
return
result;
}
// @
__int64
__fastcall sub_140003390(
__int64
a1,
char
a2,
char
a3)
{
__int64
result;
// rax
result = (unsigned
int
)(dword_140027A54 + 1);
dword_140027A54 = result;
if
( (unsigned
int
)result <= 1 )
{
result = a1 + 257;
*(_BYTE *)(a1 + 257 + a2) = a3;
// 注意-1溢出 - 256
}
return
result;
}
// #
__int64
__fastcall sub_1400033F0(_BYTE *a1,
char
a2,
char
a3)
{
__int64
result;
// rax
result = (unsigned
int
)(dword_140027A50 + 1);
dword_140027A50 = result;
if
( (unsigned
int
)result <= 1 )
{
result = (unsigned
__int8
)a1[256];
if
( (_DWORD)result == 0xFE )
{
result = (unsigned
int
)a2;
if
( (
int
)result < 0x10 )
{
result = (
__int64
)(a1 + 513);
a1[a2 + 513] = a3;
// 513 ~ 768 528
}
}
}
return
result;
}
// ?
__int64
__fastcall sub_140003470(
__int64
a1,
char
a2,
char
a3)
{
__int64
result;
// rax
result = (unsigned
int
)(dword_140027A58 + 1);
dword_140027A58 = result;
if
( (unsigned
int
)result <= 1 )
{
result = *(unsigned
__int16
*)(a1 + 528) / 3;
if
( !(*(unsigned
__int16
*)(a1 + 528) % 3) )
{
result = a1 + 530;
*(_BYTE *)(a1 + 530 + (a2 & 0xC)) = a3;
// 530 ~ 542 -> 530, 534, 538, 542
}
}
return
result;
}
// -
__int64
__fastcall sub_1400035E0(_BYTE *a1,
char
a2,
char
a3)
{
__int64
result;
// rax
result = (unsigned
int
)(dword_140027A60 + 1);
dword_140027A60 = result;
if
( (unsigned
int
)result <= 1 )
{
result = *((unsigned
__int16
*)a1 + 264) / 16;
// a1[528]
if
( !(*((unsigned
__int16
*)a1 + 264) % 16) )
{
result = *((unsigned
__int16
*)a1 + 264) / 16;
if
( (unsigned
int
)(*((unsigned
__int16
*)a1 + 264) / 16) < 3 )
{
result = (unsigned
int
)a2;
if
( (
int
)result <= *((unsigned
__int16
*)a1 + 264) )
{
result = (
__int64
)(a1 + 530);
a1[a2 + 530] = a3;
}
}
}
}
return
result;
}
function
awaitHook() {
Java.perform(
function
(){
var
ptr = Module.findBaseAddress(
"libnative-lib.so"
);
if
(ptr==
null
){
return
0;}
Interceptor.attach(ptr.add(0x011E6C),{
onEnter:
function
(arg){
console.log(
"\nHooking - AESEncrypt - IV: \n"
+ hexdump(arg[0].add(176), {length:16}));
console.log(
"\nHooking - AESEncrypt - Text: \n"
+ arg[1].readCString());
},
onLeave:
function
(arg){
console.log(
"\nHooking - AESEncrypt - EncText: \n"
, hexdump(arg, {length:32}));
console.log(
"Hooking - AESEncrypt - EXIT"
);
}
})
Interceptor.attach(ptr.add(0x00011820), {
onEnter:
function
(args) {
console.log(
"\narg[1] - AESKey\n"
+ hexdump(args[1], {length:16}));
},
onLeave:
function
(arg) {
// console.log("leave");
}
})
})
}
setImmediate(
function
(){
setTimeout(awaitHook,10);
})
// frida -U come.wmctf.crackme111 -l ctf.js --no-pause
function
awaitHook() {
Java.perform(
function
(){
var
ptr = Module.findBaseAddress(
"libnative-lib.so"
);
if
(ptr==
null
){
return
0;}
Interceptor.attach(ptr.add(0x011E6C),{
onEnter:
function
(arg){
console.log(
"\nHooking - AESEncrypt - IV: \n"
+ hexdump(arg[0].add(176), {length:16}));
console.log(
"\nHooking - AESEncrypt - Text: \n"
+ arg[1].readCString());
},
onLeave:
function
(arg){
console.log(
"\nHooking - AESEncrypt - EncText: \n"
, hexdump(arg, {length:32}));
console.log(
"Hooking - AESEncrypt - EXIT"
);
}
})
Interceptor.attach(ptr.add(0x00011820), {
onEnter:
function
(args) {
console.log(
"\narg[1] - AESKey\n"
+ hexdump(args[1], {length:16}));
},
onLeave:
function
(arg) {
// console.log("leave");
}
})
})
}
setImmediate(
function
(){
setTimeout(awaitHook,10);
})
// frida -U come.wmctf.crackme111 -l ctf.js --no-pause
Interceptor.attach(ptr.add(0x011624), {
onEnter:
function
(args) {
console.log(
"\narg[1] - RC4Key\n"
+ args[1].readCString());
},
onLeave:
function
(arg) {
// console.log("leave");
}
})
Interceptor.attach(ptr.add(0x011624), {
onEnter:
function
(args) {
console.log(
"\narg[1] - RC4Key\n"
+ args[1].readCString());
},
onLeave:
function
(arg) {
// console.log("leave");
}
})
console.log(
"hooking - EncData[32]\n"
, hexdump(ptr.add(0x046000),{length:32}));
console.log(
"hooking - EncData[32]\n"
, hexdump(ptr.add(0x046000),{length:32}));
from
Crypto.Cipher
import
ARC4
rc4CipherText
=
bytearray(bytes.fromhex(
"18 76 eb 87 76 3e 77 08 c0 8d 56 25 9e 35 0d 16 23 65 61 6a 14 9d 4f 1c 64 21 7d 78 ba 53 91 22"
))
for
i, v
in
enumerate
(rc4CipherText):
rc4CipherText[i]
=
v ^
0x50
key
=
"Hello from C++"
rc4
=
ARC4.new(key.encode())
aesCipherText
=
rc4.decrypt(rc4CipherText).
hex
()
print
(aesCipherText)
from
Crypto.Cipher
import
ARC4
rc4CipherText
=
bytearray(bytes.fromhex(
"18 76 eb 87 76 3e 77 08 c0 8d 56 25 9e 35 0d 16 23 65 61 6a 14 9d 4f 1c 64 21 7d 78 ba 53 91 22"
))
for
i, v
in
enumerate
(rc4CipherText):
rc4CipherText[i]
=
v ^
0x50
key
=
"Hello from C++"
rc4
=
ARC4.new(key.encode())
aesCipherText
=
rc4.decrypt(rc4CipherText).
hex
()
print
(aesCipherText)
#include <stdio.h>
#include <memory.h>
#include "AES.h"
//
// Public Definitions
//
/* moved to rijndael.h */
//
// Internal Definitions
//
/*
* Encryption Rounds
*/
int
g_aes_key_bits[] = {
/* AES_CYPHER_128 */
128,
/* AES_CYPHER_192 */
192,
/* AES_CYPHER_256 */
256,
};
int
g_aes_rounds[] = {
/* AES_CYPHER_128 */
10,
/* AES_CYPHER_192 */
12,
/* AES_CYPHER_256 */
14,
};
int
g_aes_nk[] = {
/* AES_CYPHER_128 */
4,
/* AES_CYPHER_192 */
6,
/* AES_CYPHER_256 */
8,
};
int
g_aes_nb[] = {
/* AES_CYPHER_128 */
4,
/* AES_CYPHER_192 */
4,
/* AES_CYPHER_256 */
4,
};
/*
* aes Rcon:
*
* WARNING: Rcon is designed starting from 1 to 15, not 0 to 14.
* FIPS-197 Page 9: "note that i starts at 1, not 0"
*
* i | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
* -----+------------------------------------------------------------------------------------------
* | [01] [02] [04] [08] [10] [20] [40] [80] [1b] [36] [6c] [d8] [ab] [4d] [9a]
* RCON | [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00]
* | [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00]
* | [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00]
*/
static
const
uint32_t g_aes_rcon[] = {
0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000,
0x1b000000, 0x36000000, 0x6c000000, 0xd8000000, 0xab000000, 0xed000000, 0x9a000000
};
/* aes sbox and invert-sbox */
static
const
uint8_t g_aes_sbox[256] = {
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};
static
const
uint8_t g_inv_sbox[256] = {
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbe, 0x40, 0xa3, 0x9e, 0x80, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x02, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x04, 0xc1, 0xaf, 0xbd, 0x03, 0x00, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbf, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x81, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x01, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
};
uint8_t aes_sub_sbox(uint8_t val)
{
return
g_aes_sbox[val];
}
uint32_t aes_sub_dword(uint32_t val)
{
uint32_t tmp = 0;
tmp |= ((uint32_t)aes_sub_sbox((uint8_t)((val >> 0) & 0xFF))) << 0;
tmp |= ((uint32_t)aes_sub_sbox((uint8_t)((val >> 8) & 0xFF))) << 8;
tmp |= ((uint32_t)aes_sub_sbox((uint8_t)((val >> 16) & 0xFF))) << 16;
tmp |= ((uint32_t)aes_sub_sbox((uint8_t)((val >> 24) & 0xFF))) << 24;
return
tmp;
}
uint32_t aes_rot_dword(uint32_t val)
{
uint32_t tmp = val;
return
(val >> 8) | ((tmp & 0xFF) << 24);
}
uint32_t aes_swap_dword(uint32_t val)
{
return
(((val & 0x000000FF) << 24) |
((val & 0x0000FF00) << 8) |
((val & 0x00FF0000) >> 8) |
((val & 0xFF000000) >> 24) );
}
/*
* nr: number of rounds
* nb: number of columns comprising the state, nb = 4 dwords (16 bytes)
* nk: number of 32-bit words comprising cipher key, nk = 4, 6, 8 (KeyLength/(4*8))
*/
void
aes_key_expansion(AES_CYPHER_T mode, uint8_t *key, uint8_t *round)
{
uint32_t *w = (uint32_t *)round;
uint32_t t;
int
i = 0;
printf
(
"Key Expansion:\n"
);
do
{
w[i] = *((uint32_t *)&key[i * 4 + 0]);
printf
(
" %2.2d: rs: %8.8x\n"
, i, aes_swap_dword(w[i]));
}
while
(++i < g_aes_nk[mode]);
do
{
printf
(
" %2.2d: "
, i);
if
((i % g_aes_nk[mode]) == 0) {
t = aes_rot_dword(w[i - 1]);
printf
(
" rot: %8.8x"
, aes_swap_dword(t));
t = aes_sub_dword(t);
printf
(
" sub: %8.8x"
, aes_swap_dword(t));
printf
(
" rcon: %8.8x"
, g_aes_rcon[i/g_aes_nk[mode] - 1]);
t = t ^ aes_swap_dword(g_aes_rcon[i/g_aes_nk[mode] - 1]);
printf
(
" xor: %8.8x"
, t);
}
else
if
(g_aes_nk[mode] > 6 && (i % g_aes_nk[mode]) == 4) {
t = aes_sub_dword(w[i - 1]);
printf
(
" sub: %8.8x"
, aes_swap_dword(t));
}
else
{
t = w[i - 1];
printf
(
" equ: %8.8x"
, aes_swap_dword(t));
}
w[i] = w[i - g_aes_nk[mode]] ^ t;
printf
(
" rs: %8.8x\n"
, aes_swap_dword(w[i]));
}
while
(++i < g_aes_nb[mode] * (g_aes_rounds[mode] + 1));
/* key can be discarded (or zeroed) from memory */
}
void
aes_add_round_key(AES_CYPHER_T mode, uint8_t *state, uint8_t *round,
int
nr)
{
uint32_t *w = (uint32_t *)round;
uint32_t *s = (uint32_t *)state;
int
i;
for
(i = 0; i < g_aes_nb[mode]; i++) {
s[i] ^= w[nr * g_aes_nb[mode] + i];
}
}
void
aes_sub_bytes(AES_CYPHER_T mode, uint8_t *state)
{
int
i, j;
for
(i = 0; i < g_aes_nb[mode]; i++) {
for
(j = 0; j < 4; j++) {
state[i * 4 + j] = aes_sub_sbox(state[i * 4 + j]);
}
}
}
void
aes_shift_rows(AES_CYPHER_T mode, uint8_t *state)
{
uint8_t *s = (uint8_t *)state;
int
i, j, r;
for
(i = 1; i < g_aes_nb[mode]; i++) {
for
(j = 0; j < i; j++) {
uint8_t tmp = s[i];
for
(r = 0; r < g_aes_nb[mode]; r++) {
s[i + r * 4] = s[i + (r + 1) * 4];
}
s[i + (g_aes_nb[mode] - 1) * 4] = tmp;
}
}
}
uint8_t aes_xtime(uint8_t x)
{
return
((x << 1) ^ (((x >> 7) & 1) * 0x1b));
}
uint8_t aes_xtimes(uint8_t x,
int
ts)
{
while
(ts-- > 0) {
x = aes_xtime(x);
}
return
x;
}
uint8_t aes_mul(uint8_t x, uint8_t y)
{
/*
* encrypt: y has only 2 bits: can be 1, 2 or 3
* decrypt: y could be any value of 9, b, d, or e
*/
return
((((y >> 0) & 1) * aes_xtimes(x, 0)) ^
(((y >> 1) & 1) * aes_xtimes(x, 1)) ^
(((y >> 2) & 1) * aes_xtimes(x, 2)) ^
(((y >> 3) & 1) * aes_xtimes(x, 3)) ^
(((y >> 4) & 1) * aes_xtimes(x, 4)) ^
(((y >> 5) & 1) * aes_xtimes(x, 5)) ^
(((y >> 6) & 1) * aes_xtimes(x, 6)) ^
(((y >> 7) & 1) * aes_xtimes(x, 7)) );
}
void
aes_mix_columns(AES_CYPHER_T mode, uint8_t *state)
{
uint8_t y[16] = { 2, 3, 1, 1, 1, 2, 3, 1, 1, 1, 2, 3, 3, 1, 1, 2};
uint8_t s[4];
int
i, j, r;
for
(i = 0; i < g_aes_nb[mode]; i++) {
for
(r = 0; r < 4; r++) {
s[r] = 0;
for
(j = 0; j < 4; j++) {
s[r] = s[r] ^ aes_mul(state[i * 4 + j], y[r * 4 + j]);
}
}
for
(r = 0; r < 4; r++) {
state[i * 4 + r] = s[r];
}
}
}
void
aes_dump(
char
*msg, uint8_t *data,
int
len)
{
int
i;
printf
(
"%8.8s: "
, msg);
for
(i = 0; i < len; i++) {
printf
(
" %2.2x"
, data[i]);
}
printf
(
"\n"
);
}
int
aes_encrypt(AES_CYPHER_T mode, uint8_t *data,
int
len, uint8_t *key)
{
uint8_t w[4 * 4 * 15] = {0};
/* round key */
uint8_t s[4 * 4] = {0};
/* state */
int
nr, i, j;
/* key expansion */
aes_key_expansion(mode, key, w);
/* start data cypher loop over input buffer */
for
(i = 0; i < len; i += 4 * g_aes_nb[mode]) {
printf
(
"Encrypting block at %u ...\n"
, i);
/* init state from user buffer (plaintext) */
for
(j = 0; j < 4 * g_aes_nb[mode]; j++)
s[j] = data[i + j];
/* start AES cypher loop over all AES rounds */
for
(nr = 0; nr <= g_aes_rounds[mode]; nr++) {
printf
(
" Round %d:\n"
, nr);
aes_dump(
"input"
, s, 4 * g_aes_nb[mode]);
if
(nr > 0) {
/* do SubBytes */
aes_sub_bytes(mode, s);
aes_dump(
" sub"
, s, 4 * g_aes_nb[mode]);
/* do ShiftRows */
aes_shift_rows(mode, s);
aes_dump(
" shift"
, s, 4 * g_aes_nb[mode]);
if
(nr < g_aes_rounds[mode]) {
/* do MixColumns */
aes_mix_columns(mode, s);
aes_dump(
" mix"
, s, 4 * g_aes_nb[mode]);
}
}
/* do AddRoundKey */
aes_add_round_key(mode, s, w, nr);
aes_dump(
" round"
, &w[nr * 4 * g_aes_nb[mode]], 4 * g_aes_nb[mode]);
aes_dump(
" state"
, s, 4 * g_aes_nb[mode]);
}
/* save state (cypher) to user buffer */
for
(j = 0; j < 4 * g_aes_nb[mode]; j++)
data[i + j] = s[j];
printf
(
"Output:\n"
);
aes_dump(
"cypher"
, &data[i], 4 * g_aes_nb[mode]);
}
return
0;
}
int
aes_encrypt_ecb(AES_CYPHER_T mode, uint8_t *data,
int
len, uint8_t *key)
{
return
aes_encrypt(mode, data, len, key);
}
int
aes_encrypt_cbc(AES_CYPHER_T mode, uint8_t *data,
int
len, uint8_t *key, uint8_t *iv)
{
uint8_t w[4 * 4 * 15] = {0};
/* round key */
uint8_t s[4 * 4] = {0};
/* state */
uint8_t v[4 * 4] = {0};
/* iv */
int
nr, i, j;
/* key expansion */
aes_key_expansion(mode, key, w);
memcpy
(v, iv,
sizeof
(v));
/* start data cypher loop over input buffer */
for
(i = 0; i < len; i += 4 * g_aes_nb[mode]) {
/* init state from user buffer (plaintext) */
for
(j = 0; j < 4 * g_aes_nb[mode]; j++)
s[j] = data[i + j] ^ v[j];
/* start AES cypher loop over all AES rounds */
for
(nr = 0; nr <= g_aes_rounds[mode]; nr++) {
aes_dump(
"input"
, s, 4 * g_aes_nb[mode]);
if
(nr > 0) {
/* do SubBytes */
aes_sub_bytes(mode, s);
aes_dump(
" sub"
, s, 4 * g_aes_nb[mode]);
/* do ShiftRows */
aes_shift_rows(mode, s);
aes_dump(
" shift"
, s, 4 * g_aes_nb[mode]);
if
(nr < g_aes_rounds[mode]) {
/* do MixColumns */
aes_mix_columns(mode, s);
aes_dump(
" mix"
, s, 4 * g_aes_nb[mode]);
}
}
/* do AddRoundKey */
aes_add_round_key(mode, s, w, nr);
aes_dump(
" round"
, &w[nr * 4 * g_aes_nb[mode]], 4 * g_aes_nb[mode]);
aes_dump(
" state"
, s, 4 * g_aes_nb[mode]);
}
/* save state (cypher) to user buffer */
for
(j = 0; j < 4 * g_aes_nb[mode]; j++)
data[i + j] = v[j] = s[j];
}
return
0;
}
void
inv_shift_rows(AES_CYPHER_T mode, uint8_t *state)
{
// uint8_t *s = (uint8_t *)state;
// int i, j, r;
//
// for (i = 1; i < g_aes_nb[mode]; i++) {
// for (j = 0; j < g_aes_nb[mode] - i; j++) {
// uint8_t tmp = s[i];
// for (r = 0; r < g_aes_nb[mode]; r++) {
// s[i + r * 4] = s[i + (r + 1) * 4];
// }
// s[i + (g_aes_nb[mode] - 1) * 4] = tmp;
// }
// }
uint8_t result[16];
*result = *(state+0);
// result[0] = s[0]
result[4] = *(state+4);
// result[4] = s[4]
result[8] = *(state+8);
// result[8] = s[8]
result[12] = *(state+12);
// result[12] = s[12]
result[5] = *(state+1);
// result[1] = s[5]
result[9] = *(state+5);
// result[5] = s[9]
result[13] = *(state+9);
// result[9] = s[13]
result[1] = *(state+13);
// result[13] = s[1]
result[10] = *(state+2);
// result[2] = s[10]
result[2] = *(state+10);
// result[10] = s[2]
result[14] = *(state+6);
// result[6] = s[14]
result[6] = *(state+14);
// result[14] = s[6]
result[15] = *(state+3);
// result[3] = s[15]
result[11] = *(state+15);
// result[15] = s[11]
result[7] = *(state+11);
// result[11] = s[7]
result[3] = *(state+7);
// result[7] = s[3]
for
(
int
i=0;i<16;i++)
state[i]=result[i];
}
uint8_t inv_sub_sbox(uint8_t val)
{
return
g_inv_sbox[val];
}
void
inv_sub_bytes(AES_CYPHER_T mode, uint8_t *state)
{
int
i, j;
for
(i = 0; i < g_aes_nb[mode]; i++) {
for
(j = 0; j < 4; j++) {
state[i * 4 + j] = inv_sub_sbox(state[i * 4 + j]);
}
}
}
void
inv_mix_columns(AES_CYPHER_T mode, uint8_t *state)
{
uint8_t y[16] = { 0x0e, 0x0b, 0x0d, 0x09, 0x09, 0x0e, 0x0b, 0x0d,
0x0d, 0x09, 0x0e, 0x0b, 0x0b, 0x0d, 0x09, 0x0e};
uint8_t s[4];
int
i, j, r;
for
(i = 0; i < g_aes_nb[mode]; i++) {
for
(r = 0; r < 4; r++) {
s[r] = 0;
for
(j = 0; j < 4; j++) {
s[r] = s[r] ^ aes_mul(state[i * 4 + j], y[r * 4 + j]);
}
}
for
(r = 0; r < 4; r++) {
state[i * 4 + r] = s[r];
}
}
}
int
aes_decrypt(AES_CYPHER_T mode, uint8_t *data,
int
len, uint8_t *key)
{
uint8_t w[4 * 4 * 15] = {0};
/* round key */
uint8_t s[4 * 4] = {0};
/* state */
int
nr, i, j;
/* key expansion */
aes_key_expansion(mode, key, w);
/* start data cypher loop over input buffer */
for
(i = 0; i < len; i += 4 * g_aes_nb[mode]) {
printf
(
"Decrypting block at %u ...\n"
, i);
/* init state from user buffer (cyphertext) */
for
(j = 0; j < 4 * g_aes_nb[mode]; j++)
s[j] = data[i + j];
/* start AES cypher loop over all AES rounds */
for
(nr = g_aes_rounds[mode]; nr >= 0; nr--) {
printf
(
" Round %d:\n"
, nr);
aes_dump(
"input"
, s, 4 * g_aes_nb[mode]);
/* do AddRoundKey */
aes_add_round_key(mode, s, w, nr);
aes_dump(
" round"
, &w[nr * 4 * g_aes_nb[mode]], 4 * g_aes_nb[mode]);
if
(nr > 0) {
if
(nr < g_aes_rounds[mode]) {
aes_dump(
" mix"
, s, 4 * g_aes_nb[mode]);
/* do MixColumns */
inv_mix_columns(mode, s);
}
/* do ShiftRows */
aes_dump(
" shift"
, s, 4 * g_aes_nb[mode]);
inv_shift_rows(mode, s);
/* do SubBytes */
aes_dump(
" sub"
, s, 4 * g_aes_nb[mode]);
inv_sub_bytes(mode, s);
}
aes_dump(
" state"
, s, 4 * g_aes_nb[mode]);
}
/* save state (cypher) to user buffer */
for
(j = 0; j < 4 * g_aes_nb[mode]; j++)
data[i + j] = s[j];
printf
(
"Output:\n"
);
aes_dump(
"plain"
, &data[i], 4 * g_aes_nb[mode]);
}
return
0;
}
int
aes_decrypt_ecb(AES_CYPHER_T mode, uint8_t *data,
int
len, uint8_t *key)
{
return
aes_decrypt(mode, data, len, key);
}
int
aes_decrypt_cbc(AES_CYPHER_T mode, uint8_t *data,
int
len, uint8_t *key, uint8_t *iv)
{
uint8_t w[4 * 4 * 15] = {0};
/* round key */
uint8_t s[4 * 4] = {0};
/* state */
uint8_t v[4 * 4] = {0};
/* iv */
int
nr, i, j;
/* key expansion */
aes_key_expansion(mode, key, w);
memcpy
(v, iv,
sizeof
(v));
/* start data cypher loop over input buffer */
for
(i = 0; i < len; i += 4 * g_aes_nb[mode]) {
/* init state from user buffer (cyphertext) */
for
(j = 0; j < 4 * g_aes_nb[mode]; j++)
s[j] = data[i + j];
/* start AES cypher loop over all AES rounds */
for
(nr = g_aes_rounds[mode]; nr >= 0; nr--) {
aes_dump(
"input"
, s, 4 * g_aes_nb[mode]);
/* do AddRoundKey */
aes_add_round_key(mode, s, w, nr);
aes_dump(
" round"
, &w[nr * 4 * g_aes_nb[mode]], 4 * g_aes_nb[mode]);
if
(nr > 0) {
if
(nr < g_aes_rounds[mode]) {
aes_dump(
" mix"
, s, 4 * g_aes_nb[mode]);
/* do MixColumns */
inv_mix_columns(mode, s);
}
/* do ShiftRows */
aes_dump(
" shift"
, s, 4 * g_aes_nb[mode]);
inv_shift_rows(mode, s);
/* do SubBytes */
aes_dump(
" sub"
, s, 4 * g_aes_nb[mode]);
inv_sub_bytes(mode, s);
}
aes_dump(
" state"
, s, 4 * g_aes_nb[mode]);
}
/* save state (cypher) to user buffer */
for
(j = 0; j < 4 * g_aes_nb[mode]; j++) {
uint8_t p = s[j] ^ v[j];
v[j] = data[i + j];
data[i + j] = p;
}
}
return
0;
}
void
aes_cypher_128_test()
{
#if 1
uint8_t buf[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
uint8_t key[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
#else
uint8_t buf[] = { 0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d,
0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34 };
uint8_t key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c };
#endif
printf
(
"\nAES_CYPHER_128 encrypt test case:\n"
);
printf
(
"Input:\n"
);
aes_dump(
"data"
, buf,
sizeof
(buf));
aes_dump(
"key "
, key,
sizeof
(key));
aes_encrypt(AES_CYPHER_128, buf,
sizeof
(buf), key);
printf
(
"\nAES_CYPHER_128 decrypt test case:\n"
);
printf
(
"Input:\n"
);
aes_dump(
"data"
, buf,
sizeof
(buf));
aes_dump(
"key "
, key,
sizeof
(key));
aes_decrypt(AES_CYPHER_128, buf,
sizeof
(buf), key);
}
void
aes_cypher_192_test()
{
uint8_t buf[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
uint8_t key[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 };
printf
(
"\nAES_CYPHER_192 encrypt test case:\n"
);
printf
(
"Input:\n"
);
aes_dump(
"data"
, buf,
sizeof
(buf));
aes_dump(
"key "
, key,
sizeof
(key));
aes_encrypt(AES_CYPHER_192, buf,
sizeof
(buf), key);
printf
(
"\nAES_CYPHER_192 decrypt test case:\n"
);
printf
(
"Input:\n"
);
aes_dump(
"data"
, buf,
sizeof
(buf));
aes_dump(
"key "
, key,
sizeof
(key));
aes_decrypt(AES_CYPHER_192, buf,
sizeof
(buf), key);
}
void
aes_cypher_256_test()
{
uint8_t buf[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
uint8_t key[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
printf
(
"\nAES_CYPHER_256 encrypt test case:\n"
);
printf
(
"Input:\n"
);
aes_dump(
"data"
, buf,
sizeof
(buf));
aes_dump(
"key "
, key,
sizeof
(key));
aes_encrypt(AES_CYPHER_256, buf,
sizeof
(buf), key);
printf
(
"\nAES_CYPHER_256 decrypt test case:\n"
);
printf
(
"Input:\n"
);
aes_dump(
"data"
, buf,
sizeof
(buf));
aes_dump(
"key "
, key,
sizeof
(key));
aes_decrypt(AES_CYPHER_256, buf,
sizeof
(buf), key);
}
#include <stdio.h>
#include <memory.h>
#include "AES.h"
//
// Public Definitions
//
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
- [原创] Go AST 浅析 8821
- [原创]KCTF2022 Q1 第四题 飞蛾扑火 9078
- KCTF2022 Q1 第三题 石像病毒 6813
- [原创]KCTF2022 Q1签到题 险象环生 2617
- [原创] KCTF2021秋季赛 声名远扬 16499