[GXYCTF2019]minecraft
三个文件, 一个主程序, 一个动态库和一个静态库!(https://tianyu.xin/usr/uploads/2022/03/2750068171.png)
猜测unknown56是strlen, 要求长度大于等于5小于等于32
string2long函数要反回1, 没有其他要求了
!(https://tianyu.xin/usr/uploads/2022/03/1168574274.png)
直接看dll
!(https://tianyu.xin/usr/uploads/2022/03/1601185536.png)
需要v10满足这个条件
!(https://tianyu.xin/usr/uploads/2022/03/2961809180.png)
这里input给到v12, v12个给到v8, v8给到v20, v20四个一组影响14进而影响v9, 后面暂时不考虑, 我们动调看一下这儿对输入做了什么, 这儿函数太多一个扣一个, 八成里面还一大堆c++, 肉眼分析效率不高
!(https://tianyu.xin/usr/uploads/2022/03/799595299.png)
这两个对应3CE0和33E0, 第一个是拷贝, 第二个把我的11111111变成了MTExMTExMTE=, 猜测是BASE系列或者变表BASE
!(https://tianyu.xin/usr/uploads/2022/03/3314196431.png)
base64没跑了
!(https://tianyu.xin/usr/uploads/2022/03/3590062711.png)
来关注一下func3-7
func3把base64后的值再改一次放进v25, 没进去看怎么改的, 但是通过strlen能判断v25还是一个字符串
func4第一次把MTEx提取了出来, 猜测是四位四位提取, 那我猜v25可能是间址复制?瞎猜的没有依据, 我觉得不影响分析.一方面是放进v22里, 另一方面是返回一个指针(可能是v22的也可能不是, 但是值相同), 提示在这里已经输入了10个而非8个1, 要求长度大于等于0xA
func5应该是需要分析一下, MTEx进去之后变成了这样
!(https://tianyu.xin/usr/uploads/2022/03/2118321863.png)
并且这里也证实了v19就是v22的地址(其实进func4看一眼也能知道), 这里MTEx变成\0TEx, 我猜测可能是清空了吧..func5本身不是特别好看, 决定跟跟汇编, 另外也把输入变一下, 让四位不同
!(https://tianyu.xin/usr/uploads/2022/03/601328962.png)
这个地方发现v11里仍然是B64
!(https://tianyu.xin/usr/uploads/2022/03/2324180446.png)
不过全初始化之后是这样的, D8F7752F不知道是干嘛的
注意这里后面还有个MDEy, 最后一段被重复了两次(其实我猜是题出的有bug)
!(https://tianyu.xin/usr/uploads/2022/03/1488913136.png)
这恰好还给了我们提示, 这个东西传入四位b64, 然后还我四位, 之后直接对比. 前面那些, 一概没用.
接下来要看看这个函数到底怎么变的
!(https://tianyu.xin/usr/uploads/2022/03/797116099.png)
就是它
好, 直接进去看了一遍没看出来, 这里面也很多调用, 我们还是动调
4D 54 49 7A 变成了 27 0E 48 7A
!(https://tianyu.xin/usr/uploads/2022/03/3095336557.png)
这里好像有点意思, 看看
!(https://tianyu.xin/usr/uploads/2022/03/683212175.png)
这个东西能找到一个算法.猜测应该是4位哈希碰撞, 和查到的MurmurHash都有这个长的和47两个magic number, 没跑了, 试试网上的能不能直接用, 但是网上的没有0xE6546B64, 好吧, 过了一遍汇编其他地方都没有运算, 我是不是可以猜测他就只有这两行呢 ~, 直接F5当下来跑一次123试试看看结果一不一样就好了
!(https://tianyu.xin/usr/uploads/2022/03/4189368520.png)
```cpp
#include <cstdio>
#include <cstdint>
int hash(uint8_t a[]) {
uint64_t res = 0;
for(int i = 0; i < 4; i ++ ) {
res ^= 0xC6A4A7935BD1E995ui64 * (((0xC6A4A7935BD1E995ui64 * a) >> 47) ^ (0xC6A4A7935BD1E995ui64 * a));
res *= 0xC6A4A7935BD1E995ui64;
res = res + 3864292196i64;
}
return (int)res;
}
int main() {
uint8_t s[] = "MTIz";
printf("%x\n", hash(s));
}
```
结果7a480e27, 非常完美好吧, 猜对了.
这样的话就三位三位爆破即可, 四位感觉爆不动, 还是得3位然后b64
```python
target = [
0x6C43B2A7, 0x7954FD91,
0x0A3E9532, 0xB87B5156,
0xDA847742, 0x2395E7F3,
0xA679D954, 0xE1FAAFF7
]
import base64
import string
import subprocess
for i in string.printable :
for j in string.printable :
for k in string.printable :
s = base64.b64encode((i+j+k).encode(encoding='utf-8'))
prp = subprocess.Popen(".\crash.exe", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
prp.stdin.write(s)
out, err = prp.communicate()
if int(out) in target :
print(i+j+k, target.index(int(out)))
```
然后我就体会到了Python的慢.
```cpp
#include <cstdio>
#include <cstdint>
uint32_t target[] = {
0x6C43B2A7, 0x7954FD91,
0x0A3E9532, 0xB87B5156,
0xDA847742, 0x2395E7F3,
0xA679D954, 0xE1FAAFF7
};
int hash(uint8_t a[]) {
uint64_t res = 0;
for(int i = 0; i < 4; i ++ ) {
res ^= 0xC6A4A7935BD1E995ui64 * (((0xC6A4A7935BD1E995ui64 * a) >> 47) ^ (0xC6A4A7935BD1E995ui64 * a));
res *= 0xC6A4A7935BD1E995ui64;
res = res + 3864292196i64;
}
return (int)res;
}
int main() {
for(int cur = 0; cur < 8;) {
for(uint8_t i = 0x20; i < 0x7F; i ++ )
for(uint8_t j = 0x20; j < 0x7F; j ++ )
for(uint8_t k = 0x20; k < 0x7F; k ++ )
for(uint8_t l = 0x20; l < 0x7F; l ++ ) {
uint8_t tmp[] = {i, j, k, l};
if(target == hash(tmp)) {
printf("%c%c%c%c", i, j, k, l);
goto LABEL_1;
}
}
LABEL_1 :
cur ++;
}
}
```
反倒是爆4位的Cpp更快一些
BASE64:R1hZe0lfaGF2ZV9ub19naXIxX2ZyaWVO
额, 这好像还差四位, 我笑死了...但是Flag有意义, 能猜出来是啥
{I_have_no_gir1_frieNd} 最近ctf的帖太多了,老师傅们都来卷{:301_997:} 我只会看热闹。 啊 我甚至连这是什么语言都没看明白。 我来看看
页:
[1]