[CTF]Bugku love

[CTF]Bugku love 100

{写博客不重要,记录思路最重要}

1.直接运行,发现有一句话,可以用来搜索,在ollydbg或者IDA中搜索,可以搜到,直接定位到关键位置

2.IDA中搜索flag可以发现wrong flag和right flag位置可以直接F5反编译或者空格出结构图,这里分析结构图

3.读如下汇编总结算法:

上面的代码主要是对用户输入的处理,其中strlen计算了str的长度,随后进行了一系列处理,具体的处理函数在4110BE和411127中,比较复杂,后面再考虑。然后再一次统计了str的长度

上图,将处理后的str与0比较,判断是否为空(这里我理解错了,下面会纠正),不空则进入下图

上图中将处理后的str与str2进行比较,比较长度即处理后的str本身的长度,比较结果即判断flag正误。

4. 输出str2发现不是flag,说明上面确实对str进行了一定的算法处理,自习观察第一幅图,发现dest所存应该在4110BE中被处理,而不是411127,因为411127函数调用时,dest已经拷贝完毕。进入发现一个奇怪的字符串:

显然,这是base64加密所用的映射表,将str2用base64解密,发现解密后并不是flag,进入4110BE函数:

该函数中首先出现了malloc相关函数,实在申请内存,可以不管,以及又出现了若干411127,说明该函数没有特别性,不考虑,重点在下面这里:

for循环处,i<3是因为只准备了3个缓冲格子,即上面的0,1,2,v7>=1则是当User_Input(我自己改的变量名)识别完后就不再处理

break处,i没有进行前置加说明处理完毕,跳出

接下来的if语句,就是对于缓冲格子中分别有1个、2个、3个内容时的处理办法,其中数组的第64位是=,所以这就是一个base64的加密算法,说明上来直接base64是没有问题的

那么为什么base64完的结果离居然还有@?

F5一下,发现这里在两次j_strlen之间有一个这个:

这是哪里来的,for语句只能来自于循环框图,仔细一看,原来是这里,所以这里不是判断是否非空,而是判断是否读完,在读完前,会给每一个字符ascii加上字符所在位置值

故写代码如下:

import base64
string = "[email protected]@dH"
flag = ""
for i in range(len(string)):
    # ord(char) is change a char to its ascii
    # char(int) is change an ascii to a char
    flag+=chr(ord(string[i])-i)
flag = base64.b64decode(flag)
print flag

得到flag