请注意,本文编写于 1671 天前,最后修改于 1671 天前,其中某些信息可能已经过时。
这道题从比赛的时候就困扰了我好久然后我就放弃了,主要是当时觉得应该强行脱壳,但是壳是一个vmp的壳,脱壳难度十分困难。于是开了脱壳这个坑,等到试题的非官方题解在网上的博客越来越多,我才发现这道题并不是强行脱壳的题目。毕竟之前也看过,说是只要在比赛上遇见vmp壳的题目,多半不用强行脱壳。在看了众多大佬的题解后,发现了两种不同的做法。首先是第一种,binwalk在1.jpg里面提取出一个压缩包,压缩包里面是一个64位带vmp壳flag.exe,通过X64Dbg动态调试,还原代码,控制动态调试程序完成flag的动态输出。(这是大多数大佬使用的方法,但是我一直都觉得这不是个常规解法)第二种方法,是我无意间在一个师傅的博客上发现的,我翻遍了所有博客,只有这位师傅用了这种方法。并且从解题流程上看来,这个解法很有可能是出题人想要的解法。但是我尝试去复现了这个解法,有一步十分困难,就是steghide脚本跑密码。由于我找不到很好的字典文件,并且题目没有关于密码的提示,导致我最后没能将那个txt文件提取出来。下面来复现一下两种做法,菜鸡一枚,大佬轻喷。
binwalk提取flag.exe,应该是没有啥问题的,于是我们看一下,发现是VMP的壳,IDA的静态分析肯定是做不了了。由于是exe程序,我们可以点开输入看看有什么反应。随便输入一串字符,没反应,再随机输入,仍然没反应,气急败坏多砸几下键盘,发现程序居然有输出,并且在输出之后还可以继续输入。多次尝试,发现在输入六个字符,数字或者是字符串后总会一串乱码,并且乱码是随机的。所以可以初步断定,这个输出应该不是某个输入进行固定的加密然后输出的。
由于有壳,所以不能静态分析,拖入X64DBG,运行SharpOD x64插件,进入调试界面。运行一下程序,由于我们知道程序是以六个为一组进行输入的,在搜索字符串的时候很容易就找到了一个可疑的字符串“%S %S %S %S %S %S”,跳转过去。
由于是动态调试,输入自己想输入的字符串,观察栈帧,找到Scanf函数执行完毕后的返回地址。这个地方真的是学艺不精,动态调试实在是太不熟练了。调试了好久才找到两处关键代码,第一处是一个输入的比较,判断是否满足6个字符的输入,第二处则为关键的比较函数。
在比较处打上断点,重新开始调试程序,这里值得注意的是,在输入不足六个的时候,是没有办法命中断点的,所以一定要保证输入到达六个字符。分析一下汇编,这个地方我就吃了汇编语言不熟练的亏,自己调试了好多遍,才勉强看懂。这个地方将你的输入进行了一次比较,比较完成后将“ZF”位变成0,由于我们的输入应该不会正确所以我们判断这个跳转我们应该让他实现。另外的就是,如果不实现这次跳转,就会进入到一个jmp语句,之后就会回到我们输入的地方。所以我们一定不能让程序执行到jmp处。至于后面的那个循环,是一个非常大的跳转,一开始我没有让他实现,这个时候就没有输出了,当我们不管这个跳转的时候,我们发现直接点运行,会再次命中断点,这很像是在对一个输入的字符串进行逐个判断(这里我就感觉输入应该是中文,直觉没有啥依据)。果不其然在执行了六次比较后,输出了flag。
这个地方,我还看见另一种做法,就是再找到关键函数后,dump内存,直接找到比较的字符串。但这个方法我没有进行尝试,这里就不写了,就在刚刚那个师傅的博客里,有兴趣的话可以直接去看他的题解。他们找关键函数的方法可比我聪明的多,用到了修改游戏内存的CE,进行了对内存的监视。说句题外话,我第一次接触这类工具的时候,是当时初中和我最好的好朋友张学霸在玩一款叫《暗影格斗》的游戏,但是那个游戏有行动力的限制。当时我们用的叫做“烧饼修改器”,还是张学霸手把手教我修改无线钻石的呢!扯远了,回来!!
首先直接将图片用steghide查看,需要密码。于是我们运行一下脚本,爆破密码,也不知道这位师傅用的啥样的字典,我是没有爆破出来。一开始我以为是脚本的问题,于是我自己加密了一个图片,设置了密码,运行了一下脚本发现是可以跑出来的。
那就应该是字典的问题了,脚本应该没啥问题。
按那位师傅解出来的六个字符放到程序里,跑出最后结果。
所以第二种解法的问题应该出在字典上,到时候等官方题解出来之后,如果有这种解法,那么我就去找一个好一点的字典。(QWQ)
这个地方把我上网嫖的py脚本放上来,毕竟我想了好久才想明白。首先这个脚本是python2的python3会报错,我是在Linux上跑的,win上没试。用到三个文件,第一个是题目给的图片,第二个是解密之后信息的去处,第三个就是密码字典。主要是怕自己下次又把电脑搞坏了,在这里也算是留一个档吧。
# -*- coding: utf8 -*-
#author:pcat
#http://pcat.cnblogs.com
from subprocess import *
def foo():
stegoFile='1.jpg'
extractFile='hide.txt'
passFile='wordlist.txt'
errors=['could not extract','steghide --help','Syntax error']
cmdFormat='steghide extract -sf "%s" -xf "%s" -p "%s"'
f=open(passFile,'r')
for line in f.readlines():
cmd=cmdFormat %(stegoFile,extractFile,line.strip())
p=Popen(cmd,shell=True,stdout=PIPE,stderr=STDOUT)
content=unicode(p.stdout.read(),'gbk')
for err in errors:
if err in content:
break
else:
print content,
print 'the passphrase is %s' %(line.strip())
f.close()
return
if __name__ == '__main__':
foo()
print 'ok'
pass
这道题之所以耽误了这么久的时间,主要是自己的汇编与动态调试不过关,整个过程也是摸索着大佬的题解才走过来的,下一次要是还有这样涉及动态调试的题目,恐怕以我现在的水平还是无法胜任。所以动态调试与汇编语言的练习也应该提上日程了。
全部评论 (暂无评论)
info 还没有任何评论,你来说两句呐!