攻防世界ctf - rev新手题

最近实习中总有大把的时间闲着,我便趁着这段时间好好的做一做逆向的题目,希望可以提升一下自己吧。而且好像又重燃了对web的乐趣,所以我可能也会做一些web的题目。双修大法。

一、Reversing-x64Elf-100

很简单的逆向题,但这也算是好久以来第一个自己做出来的逆向题,需要好好记录一下。

下载附件后就一个文件,先拖进exeinfop查一下壳和位数,然后直接拖进ida。

按照以往的经验找到main函数,直接静态分析即可,发现主要判断逻辑在sub_4006FD中

进入之后发现如下

分析还是比较好分析的,但是这题主要时间花在了python代码的一些细节上,下面是解题脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
tag = list("Dufhbmf")
tag1 = list("pG`imos")
tag2 = list("ewUglpt")
flag = []

for i in range(0, 12):
if i % 3 == 0:
flag.append(chr(ord(tag[2 * (i // 3)]) - 1))
elif i % 3 == 1:
flag.append(chr(ord(tag1[2 * (i // 3)]) - 1))
elif i % 3 == 2:
flag.append(chr(ord(tag2[2 * (i // 3)]) - 1))

result_string = ''.join(flag)
print(result_string)

最后输出 如下,Code_Talkers即为本题flag

小结

主要是python代码上面,char型不能直接减一,需要先用ord()函数转成Ascii,而且强制转换在python里面是函数int(),需要括起来。而且字符串想改成字符数组需要用list()函数,往数组里面加需要用append()函数,而且字符数组想以字符串输出,需要用join函数。

二、666

这题与上面题类似,只需静态分析即可,还是先拖进exeinfop,发现是64位,拖进ida,进行分析,先找到main函数,如下

别看上来给了一个flag,按照以往经验,肯定不对xs,大致思路如下:

先是存储输入到v5,然后进入主要函数encode进行处理,处理结果以地址形式放到s中,接下来是先判断输入的长度是否正确,然后与enflag比较,一样即证明输入正确。

其中strcmp是比较字符串的函数,为0则证明两个字符串相等,因此!strcmp基本都是判断两个字符串是否相等

接下来是encode函数,最开始我以为是个官方函数,结果google了半天发现不是,然后点进去如下

很容易就可以看懂,下面是解题脚本

1
2
3
4
5
6
7
8
9
10
tag = list("izwhroz\"\"w\"v.K\".Ni")
flag = []
i = 0
while i < 18:
flag.append(chr((ord(tag[i]) ^ 18) - 6))
flag.append(chr((ord(tag[i+1]) ^ 18) + 6))
flag.append(chr(ord(tag[i+2]) ^ 18 ^ 6))
i += 3
flag_ = ''.join(flag)
print(flag_)

没想到^运算解方程的时候也可以直接移到等号另一侧,记下来

最后结果如下,其中unctf{b66_6b6_66b}就是flag了

小结

下面主要是这个题中学到的一些新技巧

查看key的值(之前对于这个问题总是一知半解),在ida中点进key,如下

然后点击dd,摁H即可变为10进制,摁Q变为16进制

还有就是enflag的导出,刚点进去的时候如下,看见一堆双引号的我是一脸懵逼的

然后发现一个方法,就是点击enflag,直接ctrl+x,就会出现如下,就可以直接粘贴出来了,也发现了双引号其实也是字符串的一部分。他甚至还用\给你转义好了可以直接用,很棒

三、easyRE1 | lucknum

这两题有点过于简单了,都是直接拖进ida,就发现flag了(确实easy)

但是我卡了好久最后甚至看的题解才做出来。中间我甚至以为这串字符串是什么编码,试了半天也没做出来。最后原因竟是需要用flag{}括起来。不明觉厉,前面的第一题我最开始用flag括起来不对,然后直接输入就对了。但这题还必须括起来。。

flag如图,即为flag{db2f62a36a018bce28e46d976e3f9864}

flag如图 flag{c0ngr@tul@ti0n_f0r_luck_numb3r}

四、reverse_re3 迷宫题

这题我分析了好久也没有思路,我最后做完总结一下,还是因为不会把迷宫从ida里面导出来或者直接看出来。最后无奈求助了题解,发现可以在ida里面直接看迷宫,又自己摸索了一下,最后做出来了。也算是对迷宫题有了一个初步的了解。

这题的思路最开始我是一脸懵的,后来看了题解再看看才逐渐了解。你在玩一种很新的迷宫。(对我来说)

首先进入main函数

发现进入了sub_940()函数,点进去

看到wasd的时候就知道是迷宫了,然后发现函数sub_86c每次循环都会用到,点进去,如下,这时已经知道202020里面就是迷宫数组了,但是不知道如何有效的表示出来,具体表示方法一会再说。

其中202AB0最开始为0,之后会自增,增到2便退出函数,如下

而且结合上下两个图,发现迷宫应该是15*15的,而且有三个迷宫,由202AB0控制,只有当前面的输入循环完后v2仍为0才算通过了一个迷宫,需要通过三个迷宫才算成功。然后就可以返回上面看具体的wasd移动判断函数了。

再看i j 在当前迷宫里面循环,当找到3的时候便停止,并且把i j分别存入行数和列数,便于之后判断。(后面看迷宫的时候也会发现每个迷宫只有一个3)

点进判断“d”的函数,如下

根据上面的分析,很容易看出202AB0为控制当前是哪个迷宫的,而且从前面得到的行列数开始判断,这个函数是判断d的,也就是右移,所以如果下一步是1则证明正确,就把下一步变成3,而所在的3变为1,这样就方便前面的函数下次找3的时候找到咱们移动后的位置开始判断,这样就实现了移动。并且如果下一步是4则返回1退出,也就是退出循环。即宏观来看:

每个迷宫从3开始,途中必须每一步都要经过1,然后最终到达4证明当前迷宫通关。

小结

然后下面是展示迷宫的操作:先点进去,迷宫最开始是下面这种情况,

然后只需要右键-array如下

然后如下设置,设置总数量,每行的数量,然后显示index,以及间距调为1,就

就会出现下面的样式

然后根据迷宫走,会走出下面的字符串,直接md5加密得到flag

ddsssddddsssdssdddddsssddddsssaassssdddsddssddwddssssssdddssssdddss

即flag{aeea66fcac7fa80ed8f79f38ad5bb953}

五、总结

写完这篇文章我感觉我才算刚刚入门逆向。学会了编写一些简单的脚本解题,并且对一些ida的操作更加熟悉。也对迷宫题有了一些新的解题思路。

希望之后能越来越好吧