
本文共 11765 字,大约阅读时间需要 39 分钟。
圣诞莫得安排于是跑去做了一下ChaMd5的圣诞题,不得不说让我这个逆向手很有做misc的成就感哈哈哈(误)。既然活动都结束了就来放一下wp吧,顺便整理一下批量处理文件的方法(pyinstaller批量解包+批量补文件头转格式+python和命令行的批量自动交互)。
题目指路:
So...begin!
下载题目压缩包,解压可以看到有59个exe。
(好家伙,这是考批量处理文件吧= =不得不说图标还挺好看的,费心了
不过看到自定义图标,逆向人第一个就想到了这些是用pyinstaller打包的exe啦。虽然也有可能是MFC,不过这里明显不是。
随便拖一个exe进ida,查看字符串看到有很多“py”字样,很明显就是pyinstaller这条路。
所以果断走流程解包(单个文件处理可以看->,这里不细讲了,重点在多文件的批量处理)。
bat批量应用python脚本
这里写bat脚本
@echo offfor %%i in (*) do ( echo %%i python2 pyinstxtractor.py %%i)
(*)指当前目录,%%i就像平时用的for(int i=0;......)的那个i一样是个变量,echo是为了看处理到哪个文件了。
处理结束后得到59个解压文件包
python批量提取
然后继续写脚本(这次用python,因为bat实在是不熟)把文件夹里的无后缀文件提取出来,复制到manyPYC文件夹下,方便后续处理。
import osimport os.pathimport reimport shutilsrc='./'dst='../manyPYC/'allFile=os.listdir(src)pattern=r'^[0-9]+$'for fileName in allFile: if os.path.isdir(fileName): for file in os.listdir(fileName): if re.match(pattern,file)!=None: num=file shutil.copy(src+fileName+'/'+file,dst+num) if file=='struct': shutil.copy(src+fileName+'/'+file,dst+num+'_struct')
一般是两个有用的,一个是struct,另一个文件名在entry point里会提到,一般是跟exe同名的,不过这里不一样(是数字。
另外这里线性扫描一定是先扫到以数字命名的文件再到同目录下的struct文件,所以不用担心num未定义的问题。
python批量补头修复pyc
根据uncompyle的反编译规则,批量添加magic number,并输出.pyc。
import ossrc='.'allFile=os.listdir(src)for file in allFile: if 'struct' in file: with open(file,'rb') as f: magic=f.read(8) with open(file[:-7],'rb') as f: context=f.read() with open(file[:-7]+'.pyc','wb') as f: f.write(magic) f.write(context)
提取struct的前八个字节补到同名文件里去,并改名为.pyc。
注意:这里提前用010Editor看了一下以数字命名的文件和struct是差八个字节,有点特殊。
bat批量应用指令
然后写bat脚本执行:
@echo offfor %%i in (*) do ( echo %%i uncompyle6 %%i > %%i.py)
得到59个python文件。
这里其实是出来像1.pyc.py
这样的文件,有强迫症的朋友(比如我)可以写个脚本把中间的.pyc去掉hhh。
python和命令行的批量自动交互
随便查看一个(比如1.py
)
import hashlib, base64from Crypto.Cipher import AESfrom Crypto import Randomdef decrypt(data, password): bs = AES.block_size if len(data) <= bs: return data unpad = lambda s: s[0:-ord(s[(-1)])] iv = data[:bs] cipher = AES.new(password, AES.MODE_CBC, iv) data = unpad(cipher.decrypt(data[bs:])) return dataencrypt_data = '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'md5 = hashlib.md5()fn = raw_input()md5.update(fn)if '4a47a0db6e60853dedfcfdf08a5ca249' == md5.hexdigest(): print 'Are you robot?' print '25 + 3 = ?' ans = int(raw_input()) if int(ans) == 28: try: md5 = hashlib.md5() inp = str(int(ans)) md5.update(inp) password = md5.hexdigest() encrypt_data = base64.b64decode(encrypt_data) decrypt_data = decrypt(encrypt_data, password) f = open(fn, 'wb') f.write(decrypt_data) f.close() except: pass
可以看到,逻辑是先输入一个字符串,第一个check是md5值等于一个已给值(通过chamd5的网站查到该md5值为1.png,突然扣题?hhh),第二个check是简单的人机测试,都通过的话就会输出一张1.png
的图片。
这个地方的批量处理是我卡得最最最最最最久的一个地方 TvT
因为bat完全是现学,不会写,于是想到用python进行跟命令行的交互。
一开始查到的资料是用subprocess,但是读输出的时候死活读不进去(因为要过人机测试就得把式子读进去),去查subprocess文档没什么头绪,往后查又说是什么输出流阻塞balabala,总之没太看懂(tcl
后来好不容易看到有一篇提到说用pexpect。然后查了一些文档,诶,居然交互成功了!暴风哭泣!
理论上说前面用bat写的地方都可以改成用pexpect写,不过这不是之前还不知道嘛(。)
以及,多亏这里搞通了,后面xctf刚好遇到一道逆向是可以用这种命令行交互爆破的(不是pwntools能连上的那种特殊架构文件),直接拿脚本改改就能用,省了几个小时的搜索时间hhh。
于是开始写脚本进行多次交互啦,逻辑很简单:
import pexpectfor i in range(1,60): r=pexpect.spawn("python2",[str(i)+".py"]) r.sendline(str(i)+".png") r.readline() r.readline() exper=r.readline()[:-6] r.sendline(str(eval(exper))) r.wait()
得到59个png。
python连接png
当时做的时候因为懒得搞图像识别,所以直接手动记录这些图片上的字符。后来受到官方上发的wp的启发,感觉可以把这些png用PIL库连起来,就不用一张张点着看了。
这里我是把每个图片最左边6px提取出来横向拼接成一张图片,方便照着打hhh,调整了一下让字符大概居中排列(因为原图背景是透明的,所以这里提取出来就成黑的了= =。
png连接脚本:
from PIL import Imagecnt=0base=6colorData=[[] for _ in range(base*59)]for x in range(1,60): img=Image.open(str(x)+'.png') rgb_img=img.convert('RGB') width,height=img.size for i in range(base): col=i+cnt*base for j in range(height): colorData[col].append(rgb_img.getpixel((i,j))) cnt+=1widthALL=len(colorData)heightALL=max([len(arr) for arr in colorData])imgALL=Image.new("RGB",(widthALL,heightALL))for i in range(widthALL): h=len(colorData[i]) for j in range(h): imgALL.putpixel([i,(heightALL-h)//2+j],colorData[i][j])imgALL.save("res.png")
通过观察可以发现,有用的字符都为红/绿/蓝的纯色,于是在脚本上做一些改进,把符合条件的像素点置黑,其余置白,更方便观察。
最后改进的脚本:
from PIL import Imagecnt=0base=6RED=(255,0,0)GREEN=(0,255,0)BLUE=(0,0,255)BLACK=(0,0,0)WHITE=(255,255,255)colorData=[[] for _ in range(base*59)]for x in range(1,60): img=Image.open(str(x)+'.png') rgb_img=img.convert('RGB') width,height=img.size for i in range(base): col=i+cnt*base for j in range(height): if rgb_img.getpixel((i,j)) in [RED,GREEN,BLUE]: colorData[col].append(BLACK) else: colorData[col].append(WHITE) cnt+=1widthALL=len(colorData)heightALL=max([len(arr) for arr in colorData])imgALL=Image.new("RGB",(widthALL,heightALL))for i in range(widthALL): h=len(colorData[i]) for j in range(h): imgALL.putpixel([i,(heightALL-h)//2+j],colorData[i][j])imgALL.save("res.png")
轻松记录下59个字符:https://www.chamd5.org/e1f10acc44f611ebb3780242ac130002.png
打开有
get flag
flag{ChaMd5_Ch33r_Up}
没想到这么晚交还水了个第三哈哈哈,溜了溜了(
发表评论
最新留言
关于作者
