BUUCTF [b01lers2020]little_engine
64位Linux ELF先进到16B0
!(https://tianyu.xin/usr/uploads/2022/03/313450511.png)
!(https://tianyu.xin/usr/uploads/2022/03/1848634967.png)
两个问题, 一个ready一个tidbit, 都只要一个字符, 第一个问题只要不是EOF都会进到下一个里, 而且不会存.
tidbit那个问题有一个判断变量v2无论如何都是0, 感觉要撕汇编, 这个循环应该是需要进去的, 然后在C510函数里变换, 到C5A0函数里比对, 要求比对要成功
去看看汇编, C8AD这里有一条js指令, 前面test 0, 0, js恒假, 扬掉, 但是这样就一定会走到我们不想要的分支了, 好吧, Computer is not magic, 到不了就是到不了, 这个分支可能就是恒假骗人的.
到C510这个函数看看到底把输入变什么了(第一步先看看这个参数是不是确实是输入)
!(https://tianyu.xin/usr/uploads/2022/03/3697966360.png)
没有什么问题, 继续看哪里动了
每次的操作就是当
i<a-a时, input^=key, a = a +1(这里的input和a本质上是同一个东西,不过a是个移动的指针), key = key+i +(key+i)/0xFF
!(https://tianyu.xin/usr/uploads/2022/03/471759423.png)
我们还可以提出来最后的比对Table
```c
unsigned char ida_chars[] =
{
0xE1, 0xE6, ..... , 0xE3, 0x44
};
```
额, 这好像更像一个sbox啊.., 比对函数还可能是个加密函数, 我晕
!(https://tianyu.xin/usr/uploads/2022/03/853302235.png)
但是其实从这儿还是能看出来是直接比对的, 不过是每隔四个一比, 这个75也正好和300长的数组互相印证
!(https://tianyu.xin/usr/uploads/2022/03/603996841.png)
整体上还是能看出来一点flag的样子, 但是还有细节处理错了, 我猜可能是保留问题
```cpp
#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 ^ key)&0xFF);
tmp = key + i;
key = tmp + tmp/0xFF;
}
}
```
!(https://tianyu.xin/usr/uploads/2022/03/2704216539.png)
然后变成了这样, 后面还是有点乱套. 结合代码看, 感觉是v6+v6/0xFF这里可能出现了一点问题, 因为后面虽然乱但还都是可见字符, 可能是一个+1-1的问题, 接下来我发现了这个v6/0xff竟然全都是0?这不应该.
在i为0xF的时候, tmp本应该是0x106, 这样/0xFF的值应该是1, 对应的, key应该从0xFA到0xA, 但是我的代码是从0xFA到0x9, 正好少了1
输出了一下tmp的值,发现tmp是负的.
!(https://tianyu.xin/usr/uploads/2022/03/233783467.png)
原来问题在这个小小的u上.....
pctf{th3_m0d3rn_st34m_3ng1n3_w45_1nv3nt3d_1n_1698_buT_th3_b3st_0n3_in_1940} ps:第二个问题不只要一个字符, 我的Writeup都是边做边写的, 当时以为只要一个字符...后面就忘改了 真狠不错啊,就不看不太懂
页:
[1]