[GWCTF 2019]xxor
[GWCTF 2019]xxor
首先可以到汇编界面从新定义(U+P)一下main函数,不然看着会有点乱
分析

追踪input变量
可以看到每次循环是获取四字节的输入
但后面对于tmp变量的赋值我就有点看不懂了,不要紧,直接动调
动态调试
连接linux,下断点开调

我不知道为什么输入字符会直接跳出循环,所以输入了数字
F8步过

可以看到tmp1和tmp2被赋值了第一次输入和第二次输入
分析tea_encode

我们可以继续动调下去,可以看到v0和v1分别被赋值了tmp1和tmp2的值,会这样的原因是(unsigned int *)&tmp1,这里tea_encode函数调用的是tmp1的地址,而tmp1和tmp2的地址仅相差4字节,在使用a1[1]时,其实是a1的地址加上一个unsigned int指针的大小,即四字节,刚好就是tmp2的地址,这下就明白是如何赋值的了
继续跟进看如何赋值
此时tmp1和tmp2加密后的值是这样
再看看v4是如何赋值的

是将tmp2作为高地址,tmp1作为低地址拼接起来
按F4完成循环,v4进行了三次这样的赋值

最后在sub_400770函数中进行比较

这里a1是个_DWORD指针,类似与unsigned int指针,所以每次调用v4中四个字节的值
编写脚本
现在算是分析完了,把sub_400770函数中的值进行以每两组代入tea_encode就可以解出flag了
z3求解
from z3 import *
x2, x3, x4 = Ints('x2 x3 x4')
s = Solver()
s.add(x2 - x3 == 0x84A236FF)
s.add(x3 + x4 == 0xFA6CB703)
s.add(x2 - x4 == 0x42D731A8)
if s.check() == sat:
result = s.model()
# 转换为 Python 整数
x2 = hex(result[x2].as_long())
x3 = hex(result[x3].as_long())
x4 = hex(result[x4].as_long())
print(x2, x3, x4)
魔改tea加密求解
tea对称加密,魔改轮数和加密算法,进行三轮加密
#include <iostream>
using namespace std;
int main() {
unsigned int v[6] = { 0xDF48EF7E, 0x20CAACF4, 0xe0f30fd5, 0x5c50d8d6, 0x9e1bde2d, 0x84F30420 };
int key[4] = { 2, 2, 3, 4 };
int r = 64;
for (int i = 0; i < 6; i += 2) {
unsigned int v0 = v[i];
unsigned int v1 = v[i + 1];
unsigned int sum = 0x458BCD42 * r;
for (int j = 0; j < r; j++) {
v1 -= (v0 + sum + 20) ^ ((v0 << 6) + key[2]) ^ ((v0 >> 9) + key[3]) ^ 0x10;
v0 -= (v1 + sum + 11) ^ ((v1 << 6) + *key) ^ ((v1 >> 9) + key[1]) ^ 0x20;
sum -= 0x458BCD42;
}
v[i] = v0;
v[i + 1] = v1;
}for (unsigned int i = 0; i < 6; i++) {
for (unsigned int j = 2; j < 3; j--) { //转为大端序
printf("%c", *((char*)&v[i] + j));
}
}
}
解出flag flag{re_is_great!}

浙公网安备 33010602011771号