Y1rannn 发表于 2022-3-26 00:45

[NPUCTF2020]芜湖

!(https://tianyu.xin/usr/uploads/2022/03/937921903.png)


挺明显的混淆痕迹

!(https://tianyu.xin/usr/uploads/2022/03/1149623066.png)


进来的函数长这样, 稍稍命名发现最好还是动调, 上面这一部分都没见输入, 不管啥都能动调拿不香么

!(https://tianyu.xin/usr/uploads/2022/03/1513960211.png)


它说了一大堆也没见输入.

!(https://tianyu.xin/usr/uploads/2022/03/99063848.png)


我盲猜好吧, 一共34条话, 每条长度在lenTable里, 信息在binTable里, binTable被解密之后输出, 但是我猜binTable没用完,后面还有

!(https://tianyu.xin/usr/uploads/2022/03/1118155824.png)


我尝试一下直接patch这个34, 让它再来一次(其实应该真的去看看这个bin有没有那么大, 但是我懒了)

好吧, 说到这儿我发现还得patch lentable, 我们还是去bintable看看猜测对不对

程序能访问到的最后一个是bin],0x5b0, 看看bin多长, 1472 = 0x5c0, 不过后面全是0, 看来猜错了.

可是应该也没有反调, 那答案究竟在哪里呢

!(https://tianyu.xin/usr/uploads/2022/03/2118936297.png)


lentable长度基本上都是32, 40之类的, 但是bin却用42做一行, 会藏在每行后面么? 把bintable按每行42个看..后面也都是空的, 没什么问题, 没有办法, 我们去func1里面看看吧

每次把v2的第i位取出, 做func1的第一个参数, 第二个参数则是'a'的第i位, 返回值填到v2的第i位

!(https://tianyu.xin/usr/uploads/2022/03/1054520769.png)


func1长这样

!(https://tianyu.xin/usr/uploads/2022/03/1060561046.png)


那我看来它就是构造了一个完全没用到的string, 然后返回了两个参数的一个逻辑运算值, 先分析下func1这个逻辑运算到底啥样的, v2 = !(a1 & a2) , v3 = !(a1& v2) ...

v4 = v2, v5 = !(v2 & a2), v6 = !(v5&v3), 化简一下 : !(!(!((a1a2)a2))(!((a1a2)a1)) ... 这东西应该就是.. a1^a2 ? 随便验证一下, 这就是五个与非门的串

```python
>>> def f1(a, b) :
...   return not (a&b)
...
>>> def f2(a, b) :
...   v2 = f1(a, b)
...   v3 = f1(a, v2)
...   v4 = v2
...   v5 = f1(b, v4)
...   return f1(v3, v5)
...
>>> f2(0, 0)
False
>>> f2(0, 1)
True
>>> f2(1, 1)
False
```



'a' 是0b110001, 这个输出汉字的变换明白了, 可是那个没用的string数据还是没有解开.

我觉得不妨尝试一下把那些数据也用同样的方式跑一下, 毕竟这程序也没别的地方了

!(https://tianyu.xin/usr/uploads/2022/03/1154751815.png)


这里我忽略了这个func2... 是在找数据的时候通过xref一层一层发现的, 那现在就有两个入手点了, 另外还看到了一个base64表, 我想从表这儿入手

!(https://tianyu.xin/usr/uploads/2022/03/1487677735.png)


看一下func2到底干了啥吧

!(https://tianyu.xin/usr/uploads/2022/03/2431882882.png)


都在围绕这个string1做事, 我们直接去string1的地址

!(https://tianyu.xin/usr/uploads/2022/03/2670539256.png)


是个Base64.. 我都看了一遍就是这些汉字串的Base64

(https://blog.csdn.net/xnightmare/article/details/103774379)

答案在这儿:

!(https://tianyu.xin/usr/uploads/2022/03/247320795.png)


晕, 这不是谜语题么, 这正常谁能想到啊, 不过转B64明文再解密这一步确实有点怪, 算提示?

写个脚本撕了吧, 每个=能提供两位的隐写

```cpp
#include <cstdio>
#include <cstring>
#include <cstdint>
#include <string>
using std :: string;
uint8_t binTable1 = {
{84u,84u,24u,89u,84u,56u,12u,47u,87u,56u,4u,47u,84u,0u,50u,47u,84u,84u,16u,36u,87u,0u,46u,46u,84u,17u,12u,23u,45u,38u,92u,92u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u},
... 略{2u,82u,55u,22u,59u,57u,40u,6u,3u,54u,39u,15u,0u,54u,44u,6u,5u,83u,88u,24u,3u,38u,51u,74u,7u,6u,92u,92u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u,0u}
};
int lenTable1 = {
32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 20, 40, 40, 40, 16, 32, 32, 32, 40, 24, 32, 24, 28, 20, 40, 28, 32, 28, 20, 40, 28, 32, 28, 0
};
string s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
uint8_t b64;
void change(uint8_t* Src, uint8_t* Dst, int len) {
    for(int i = 0; i < len; i ++ ) {
      uint8_t tmp = 0;
      for(int j = 0; j < 8; j ++ ) {
            tmp = (tmp << 1) | (((Src >> (7 - j)) & 1) ^ (('a' >> (7 - j)) & 1));
      }
      Dst = tmp;
    }
}
int main() {
    for(int i = 0; i < 35; i ++ ) {
      change(binTable1, b64, lenTable1);
    }
    for(int i = 0; i < 35; i += 2) {
      uint8_t tmp = 0;
      tmp = s.find(b64-3]) & 0xF;
      tmp <<= 4;
      tmp |= s.find(b64-3]) & 0xF;
      putchar((char)tmp);
    }
}
//npuctf{Fly1ng!!!}
```

zhang1314 发表于 2022-3-26 01:49

0xchuxiuyun 发表于 2022-3-26 09:31

又是隐写

wzt0524 发表于 2022-3-26 12:14

士喂知己者屎 发表于 2022-3-26 19:54

不明觉厉

tencentma 发表于 2022-3-26 23:02

这个帖子写的详细,看来是楼主自己操作的,我觉得有些地方可以模仿一些楼主。
页: [1]
查看完整版本: [NPUCTF2020]芜湖