XCTF 4thWHCTF2017 creakme

exe文件 运行一下

随便输一下

ps.这个曹操身边的故事挺有意思的 但是没啥卵用.......

查一下壳无壳

ida载入 发现找不到main函数 直接看start感觉逻辑乱乱的(萌新求不喷.....)

百度之,可能是MFC写的,小白真的是纯小白 一脸蒙蔽,第一次接触MFC 看一下大神的题解照着复现了一遍 但是大佬中间有的地方讲的不明白,可能是觉得太简单不需要讲了吧....我尽量写的详细一点

我们知道(其实并不知道MessageBoxA函数是于创建、显示并操作一个消息对话框的,像这种题目基本上都是将用户的输入进行各种异或啊,调整顺序啊之类的和正确密码比对,正确就会提示你输入正确或者干脆直接显示出来flag之类的,所以如果我们能找到提示用户输入正确的对话框,再往上追溯调用就大概率找到判断函数!找到之后分析里面的逻辑就可以反向算出flag。

于是在各个函数里面寻找,其中有两个函数调用了MessageBoxA这个函数,分别是sub_4016E0和sub_401720,寻找一下他们的调用关系 发现都是sub_4015E0函数调用的,看一下它的逻辑:

可以看出来我们的判断并没有错!肯定是if里面的判定条件决定了是否调用MessageBoxA输出正确的提示,所以我们看一下sub_401630这个函数

我们直接看函数的主体部分 首先是一个srand生成随机数,然后令v4=rand[0]%10 再将v2和v3对应的某一位数值进行比对

我们知道(其实并不知道)srand函数是随机数发生器的初始化函数。srand和rand()配合使用产生伪随机数序列。

什么意思呢,就是rand()函数是通过系统所给定的数字作为种子,生成一串随机序列的函数,但是如果种子一样rand()得到的序列也是不变的,而srand()是可以改变种子值的函数。

不过对于这道题的逻辑,由于初始以10作为种子,rand[0]为0x47(71);以1作为种子,rand[0]为0x29(41),模10后都令v4=1,所以产生的v4不会有变化,一直是1

解决了v4的问题,判断的逻辑就很清楚了:a2的每一个值和v3+96的第n*10+1个值比对

往上找了一下

这里有一个strcpy函数,将内存中的一串字符串赋值到了v2+96上,继续往下分析就会知道在这里的v2+96就是v3+96,所以现在已经很明白了,只要将这个字符串每隔十个取出来(直到取到320就结束)就是最后的flag啦!

s = ";f1K3{c5:efl21t4;1t1zaxpim9}5+?gtux;=vc9v{v7+buhU{bT=-am2q}=fh[xk{y?xrqe{?}l5-sd2-Mo+:j{9=sY[dalvpx?z3{?no{[k5ll{zjsu5[kfla+r6Zg72o0skq6cGl5cw[=d?3v9q5-vkjSv{4sqtg=f0cz{+jurjfl[tb]lrfF1;2}udhb?0g8{om:T4dh;z:oz-Dn=m=ux;o[gs9{+zqx+sq-dsxctcvykUs2oddrt43pwv:f0;njkrb9los6g0{ih?rqantfx$sslqd:rvqixr;j{?o:sn+[i[yA11;gsmr8lm0?3};+iv+Tf:4Gtv2:-20upi0]7?77=;qzx{m-W;0vtueh]ko8d?=w:fbhd{E:;19?p=k:b+}doht6wpEq-z]2qbV1}dh416qw9:xm[;ed;:ecb-0:ni-s4u2kf6]2wn45amzjrun=ofkx-=hmgo-lz;j909=rmo7xcj4le0hxs[i]-vjl[?o12:sv4upio7ma1hRy7556+57krev:hLQ+1cx65z5v5];6n=[p83;n={zm{k2p"
flag=''
for i in range(len(s)//10):
    flag+=s[i*10+1]
    if(i*10==320):
        break
print(flag)

最后得到:

flag{The-Y3ll0w-turb4ns-Upri$ing}

第一次提交不对,只提交{}里面的内容就好啦!

原文地址:https://www.cnblogs.com/dyhaohaoxuexi/p/10645342.html