三个文件, 一个主程序, 一个动态库和一个静态库
猜测unknown56是strlen, 要求长度大于等于5小于等于32
string2long函数要反回1, 没有其他要求了
直接看dll
需要v10满足这个条件
这里input给到v12, v12个给到v8, v8给到v20, v20四个一组影响14进而影响v9, 后面暂时不考虑, 我们动调看一下这儿对输入做了什么, 这儿函数太多一个扣一个, 八成里面还一大堆c++, 肉眼分析效率不高
这两个对应3CE0和33E0, 第一个是拷贝, 第二个把我的11111111变成了MTExMTExMTE=, 猜测是BASE系列或者变表BASE
base64没跑了
来关注一下func3-7
func3把base64后的值再改一次放进v25, 没进去看怎么改的, 但是通过strlen能判断v25还是一个字符串
func4第一次把MTEx提取了出来, 猜测是四位四位提取, 那我猜v25可能是间址复制?瞎猜的没有依据, 我觉得不影响分析.一方面是放进v22里, 另一方面是返回一个指针(可能是v22的也可能不是, 但是值相同), 提示在这里已经输入了10个而非8个1, 要求长度大于等于0xA
func5应该是需要分析一下, MTEx进去之后变成了这样
并且这里也证实了v19就是v22的地址(其实进func4看一眼也能知道), 这里MTEx变成\0TEx, 我猜测可能是清空了吧..func5本身不是特别好看, 决定跟跟汇编, 另外也把输入变一下, 让四位不同
这个地方发现v11里仍然是B64
不过全初始化之后是这样的, D8F7752F不知道是干嘛的
注意这里后面还有个MDEy, 最后一段被重复了两次(其实我猜是题出的有bug)
这恰好还给了我们提示, 这个东西传入四位b64, 然后还我四位, 之后直接对比. 前面那些, 一概没用.
接下来要看看这个函数到底怎么变的
就是它
好, 直接进去看了一遍没看出来, 这里面也很多调用, 我们还是动调
4D 54 49 7A 变成了 27 0E 48 7A
这里好像有点意思, 看看
这个东西能找到一个算法.猜测应该是4位哈希碰撞, 和查到的MurmurHash都有这个长的和47两个magic number, 没跑了, 试试网上的能不能直接用, 但是网上的没有0xE6546B64, 好吧, 过了一遍汇编其他地方都没有运算, 我是不是可以猜测他就只有这两行呢 ~, 直接F5当下来跑一次123试试看看结果一不一样就好了
#include <cstdio>
#include <cstdint>
int hash(uint8_t a[]) {
uint64_t res = 0;
for(int i = 0; i < 4; i ++ ) {
res ^= 0xC6A4A7935BD1E995ui64 * (((0xC6A4A7935BD1E995ui64 * a[i]) >> 47) ^ (0xC6A4A7935BD1E995ui64 * a[i]));
res *= 0xC6A4A7935BD1E995ui64;
res = res + 3864292196i64;
}
return (int)res;
}
int main() {
uint8_t s[] = "MTIz";
printf("%x\n", hash(s));
}
结果7a480e27, 非常完美好吧, 猜对了.
这样的话就三位三位爆破即可, 四位感觉爆不动, 还是得3位然后b64
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的慢.
#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[i]) >> 47) ^ (0xC6A4A7935BD1E995ui64 * a[i]));
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[cur] == 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}