第三届上海大学生网络安全大赛 junkcode writeup

这个题题目名字是junkcode,给人的第一反应是要去除花指令 ~ ~ ~

其实做题的过程和花指令并没有半毛钱关系,只是干扰了IDA的使用,从而无法进行静态分析而已

因为重点思路总是习惯性的放在了去花上,导致了其实很简单的算法,没有跟踪到数据的起始和目标节点,浪费了很多分析时间。


首先运行,看到error in open flag.

打开IDA,静态分析

第三届上海大学生网络安全大赛 junkcode writeup_第1张图片

这就是花指令的作用,看起来心烦,不知道程序在干什么。于是OD来动态调试


第三届上海大学生网络安全大赛 junkcode writeup_第2张图片

根据字符串提示以及exit的退出,我们猜测,程序需要读取名为flag的内容,从而与flag.enc的内容进行运算后的比对。

于是在当前目录下新建个flag文件,写入任意字符,成功绕过检验。得知我们需要填入的就是flag


于是,跟随着一堆花指令,我们看到了这个

第三届上海大学生网络安全大赛 junkcode writeup_第3张图片

memset告诉我们,已经开始了初始化,所以很快要开始进行计算和验证判断了


看到了这个,一个=,马上想到base64加密

第三届上海大学生网络安全大赛 junkcode writeup_第4张图片

验证一下,解密之后是我输入的ABCDEFGHIJKLMNOPQRSTUVWXYZ


接下来是自己经验不足,做题太少,分析习惯不好而导致的多次重复分析浪费时间

接下来会在EAX中找到如下的三个重复字符串

第三届上海大学生网络安全大赛 junkcode writeup_第5张图片

经过多次调试,发现,除了第一个字符串是根据我输入的flag经过base64加密从而生成的字符串外,其他三个字符串都是常数字符串!

我关注的重点一直放在了这三个字符串是使用什么算法生成的,因为一直没能找到,尝试在数据窗口下断一直错误。但是,其实,关注的重点应该是,这四个字符串合起来一直在做什么

第三届上海大学生网络安全大赛 junkcode writeup_第6张图片

注意到这个,数据的转移时从ds到了ss,也就是说,从数据窗口进入了堆栈!

那么我们需要观察循环的次数以及规律

第三届上海大学生网络安全大赛 junkcode writeup_第7张图片

很简单的把四个字符串的首字符连接了起来


到了3550这里就是当前循环的终止点


那么去我们的ss段也就是局部变量的地方查看一下

第三届上海大学生网络安全大赛 junkcode writeup_第8张图片

可以在堆栈段看到数据,以字符串形式查看就是这样


然后一路没有发现太多的有特征的东西,直到这个字符串

第三届上海大学生网络安全大赛 junkcode writeup_第9张图片

这里是把一个字符按照16进制的形式转化。比如 ‘a’ = 0x61,则转化为61

所以根据这个lea edx , dword ptr ss:[ebp - 0x810],可以找到我们得到的中间数据保存在了这里

第三届上海大学生网络安全大赛 junkcode writeup_第10张图片

数据来源在这里

第三届上海大学生网络安全大赛 junkcode writeup_第11张图片

这个就很好理解了,把0x42的数据转成两位,变成了0x3432~~~

那么我们需要知道420E这一堆字符串是从哪里来的

第三届上海大学生网络安全大赛 junkcode writeup_第12张图片


合理的脑洞猜测:这个题既然使用了base64的加密,那么很可能顺手调用个解密(于是我们可以猜测,是不是用了base32和base64的很多功能)

跟踪多次后,发现这里是循环终止条件

就是某个栈中的局部循环变量和字符串长度做比较


运行到了这里发现思路暂时正确

第三届上海大学生网络安全大赛 junkcode writeup_第13张图片

然后到下一步处理

第三届上海大学生网络安全大赛 junkcode writeup_第14张图片

就是每一个位置加上0x10


然后看到这里

就得到了这个奇怪的字符串


所以逆向这个简单算法就好

正向:把flag用base64进行加密,用加密后的字符串+三个常数字符串进行拼接,再base64解密,字符转化,每个字符增加0x10

逆向过程直接上代码

def hextonum(x):
	if x>='A' and x<='F':
		return ord(x) - ord('A') + 10
	elif x>='a' and x<='f':
		return ord(x) - ord('a') + 10
	else:
		return ord(x) - ord('0')

#hextonum(x) <---> int(x,16)

import base64
s = 'FFIF@@IqqIH@sGBBsBHFAHH@FFIuB@tvrrHHrFuBD@qqqHH@GFtuB@EIqrHHCDuBsBqurHH@EuGuB@trqrHHCDuBsBruvHH@FFIF@@AHqrHHEEFBsBGtvHH@FBHuB@trqrHHADFBD@rquHH@FurF@@IqqrHHvGuBD@tCDHH@EuGuB@tvrrHHCDuBD@tCDHH@FuruB@tvrIH@@DBBsBGtvHH@GquuB@EIqrHHvGuBsBtGEHH@EuGuB@tvrIH@BDqBsBIFEHH@GFtF@@IqqrHHEEFBD@srBHH@GBsuB@trqrHHIFFBD@rquHH@FFIuB@tvrrHHtCDB@@'
a = ''
for i in xrange(0,len(s),2):
	n1 = chr(ord(s[i]) - 0x10)
	n2 = chr(ord(s[i + 1]) - 0x10)
	number = 16 * int(n1,16) + int(n2,16)
	#m = n1 + n2
	#number = int(m,16)
	a += chr(number)
a = base64.b64encode(a)
b = ''
for i in xrange(0,len(a),4):
	b += a[i]
for i in xrange(0,4 - len(b) % 4):
	b += '='
print base64.b64decode(b)


参考链接:

https://www.52pojie.cn/thread-658440-1-1.html

http://www.freebuf.com/articles/rookie/153078.html

你可能感兴趣的:(CTF之旅,reverse)