64位Linux ELF
先进到16B0
两个问题, 一个ready一个tidbit, 都只要一个字符, 第一个问题只要不是EOF都会进到下一个里, 而且不会存.
tidbit那个问题有一个判断变量v2无论如何都是0, 感觉要撕汇编, 这个循环应该是需要进去的, 然后在C510函数里变换, 到C5A0函数里比对, 要求比对要成功
去看看汇编, C8AD这里有一条js指令, 前面test 0, 0, js恒假, 扬掉, 但是这样就一定会走到我们不想要的分支了, 好吧, Computer is not magic, 到不了就是到不了, 这个分支可能就是恒假骗人的.
到C510这个函数看看到底把输入变什么了(第一步先看看这个参数是不是确实是输入)
没有什么问题, 继续看哪里动了
每次的操作就是当
i<a[1]-a[0]时, input[i]^=key, a = a +1(这里的input和a本质上是同一个东西,不过a是个移动的指针), key = key+i +(key+i)/0xFF
我们还可以提出来最后的比对Table
unsigned char ida_chars[] =
{
0xE1, 0xE6, ..... , 0xE3, 0x44
};
额, 这好像更像一个sbox啊.., 比对函数还可能是个加密函数, 我晕
但是其实从这儿还是能看出来是直接比对的, 不过是每隔四个一比, 这个75也正好和300长的数组互相印证
整体上还是能看出来一点flag的样子, 但是还有细节处理错了, 我猜可能是保留问题
#include <cstdio>
#include <cstdint>
unsigned char ida_chars[] =
{
0xE1, ......, 0x54, 0x76,
0xE0, 0x64, 0xEE, 0x9D, 0x9B, 0x2D, 0x9B, 0x5F, 0x72, 0x7F,
0x3B, 0xD9, 0xDF, 0x05, 0x69, 0xF0, 0x9F, 0xF0, 0xA3, 0x8C,
0xE6, 0xCD, 0xEF, 0xB4, 0xBC, 0x44, 0x54, 0x3E, 0xE3, 0x44
};
int main() {
int8_t key = 0x91;
int64_t tmp;
for(int i = 0; i < 75; i ++ ) {
putchar((ida_chars[4*i] ^ key)&0xFF);
tmp = key + i;
key = tmp + tmp/0xFF;
}
}
然后变成了这样, 后面还是有点乱套. 结合代码看, 感觉是v6+v6/0xFF这里可能出现了一点问题, 因为后面虽然乱但还都是可见字符, 可能是一个+1-1的问题, 接下来我发现了这个v6/0xff竟然全都是0?这不应该.
在i为0xF的时候, tmp本应该是0x106, 这样/0xFF的值应该是1, 对应的, key应该从0xFA到0xA, 但是我的代码是从0xFA到0x9, 正好少了1
输出了一下tmp的值,发现tmp是负的.
原来问题在这个小小的u上.....
pctf{th3_m0d3rn_st34m_3ng1n3_w45_1nv3nt3d_1n_1698_buT_th3_b3st_0n3_in_1940}