CTF reverse练习 Sad Code
最近入坑了一点 CTF 竞赛,东西太多太杂了,但是 reverse 题貌似还比较好做的样子。
题目链接Sad Code
文件下载下来是一个压缩包,可以直接解压出一个 exe,运行之后让输入 flag。扔进 DIE 里发现没有壳,是 32 位的程序,于是扔进 IDA pro 里面。
反编译出主函数,一眼就能看到有字符串 "correct",满足上面的一大堆条件后就能输出这个字符串。


程序的流程大概就是输入字符串 Str,变形一下变成 8 行 4 列的字符数组,再存到 v14 中,并且每一行最后再多添一个 0(字符串结尾,但是对流程影响不大)。
然后对于每一行,首先送进函数 sub_4130CD 中得到 Destination,再送进函数 sub_413BDB 中得到一个值 v4。
第 46、47 行综合起来看应该就是把每一轮的 v4 依次存进 v15、v16[0]~v16[6] 中。
最后经过两个又臭又长的判断,通过之后就能显示 "correct",说明输入了正确的 flag。
要反向去得到 flag 首先就要破解这两个大 if。这两个 if 分别能写成一个 4 元的线性方程组,可以写一个高斯消元来算出每个未知数的值。
得到了 v15、v16[0]~v16[6] 这 8 个值之后再看 sub_4130CD 和 sub_413BDB 两个函数。
sub_4130CD 容易看出来是将一个字符数组的每一个字符转换成两个 16 进制数,存在 Destination 中,先存高位再存低位。
sub_413BDB 也很容易看出来是将一个 16 进制整数的数组转换成一个大整数,小下标做高位,大下标做低位。
所以得到了 v15、v16[0]~v16[6] 之后,分别将它们转换成 16 进制,用数组存储,一个下标存一位,先存高位。然后再将得到的数组两两合并成一个 char,就得到了 flag。
mtr = [[0] * 5 for _ in range(4)]
mtr[0] = [-4, 7, 1, -2, 0x212278F95]
mtr[1] = [-2, -1, 3, 5, 0x146E7D971]
mtr[2] = [10, 2, -5, 8, 0x419AB1349]
mtr[3] = [7, 15, -2, -3, 0x7C35A4CA7]
# guassian elimination
for i in range(4):
for j in range(i + 1, 4):
if mtr[j][i] != 0:
factor = mtr[j][i] / mtr[i][i]
for k in range(5):
mtr[j][k] -= factor * mtr[i][k]
# back substitution
for i in range(3, -1, -1):
for j in range(i - 1, -1, -1):
if mtr[j][i] != 0:
factor = mtr[j][i] / mtr[i][i]
for k in range(5):
mtr[j][k] -= factor * mtr[i][k]
# print the result
for i in range(4):
mtr[i][4] /= mtr[i][i]
print(f"x{i + 1} = {mtr[i][4]:.6f}")
# x1 = 1230193475, x2 = 2069513800, x3 = 1515673409, x4 = 1093489484
mtr[0] = [15, -1, -1, 35, 0xF867F3C4C]
mtr[1] = [1, -24, 38, 1, 0x7AFCBCA32]
mtr[2] = [32, 38, -1, -1, 0x139360369D]
mtr[3] = [1, -1, 41, -25, 0x653CABE3E]
# guassian elimination
for i in range(4):
for j in range(i + 1, 4):
if mtr[j][i] != 0:
factor = mtr[j][i] / mtr[i][i]
for k in range(5):
mtr[j][k] -= factor * mtr[i][k]
# back substitution
for i in range(3, -1, -1):
for j in range(i - 1, -1, -1):
if mtr[j][i] != 0:
factor = mtr[j][i] / mtr[i][i]
for k in range(5):
mtr[j][k] -= factor * mtr[i][k]
# print the result
for i in range(4):
mtr[i][4] /= mtr[i][i]
print(f"x{i + 1} = {mtr[i][4]:.6f}")
# x5 = 1396920641, x6 = 1111960908, x7 = 1497979470, x8 = 1381060733
ary1 = [1230193475, 2069513800, 1515673409, 1093489484, 1396920641, 1111960908, 1497979470, 1381060733]
ary2 = [[ary1[i] // 16 ** (7-j) % 16 for j in range(8)] for i in range(8)]
ary3 = [[ary2[i][j] * 16 + ary2[i][j+1] for j in range(0, 8, 2)] for i in range(8)]
print(ary3)
for i in range(8):
for j in range(4):
print(chr(ary3[i][j]), end="")


浙公网安备 33010602011771号