25号DASCTF七月赛的wp,日常打比赛练练手ing
F12直接给图片SRC,访问提示提交错误时间:
观察GET的参数
其中t为时间戳,是1970年1月1日以来的秒数,在 https://unixtime.51240.com/ 这个网站可以方面进行查看。
f是字符串"gqy.jpg"的base64转码,可以直接构造出exp结构:
读取路径发现问题,有一层WAF过滤("You are not allowed to do that."),测试发现在路径前面随便加上一点东西就可以绕过了。
最终exp:
逆向有三题,看赛后也没人写逆向的wp,这里简单分享一下解题思路。
这题给了两个exe,一个是辅助,一个是补丁。
首先看辅助.exe,核心代码如下图:
主要逻辑除了一些字符串输出,就是对输入的注册码进行验证,直接进行明文比较,正确的注册码应该是1_am_n0t_f1ag。
然后再看补丁.exe,核心代码如下图:
主要逻辑除了一些字符串输出,就是对辅助.exe进行注入,第一个注入是对验证注册码的条件判断进行nop,所以,无论输入的注册码是什么,都会验证成功,第二个注入是在一段对齐的无用代码代码段注入了两个数,然后会输出flag{md5(dec(What_you_found))。
当时看到这里着实没啥头绪,感觉是个脑洞题,试了几个答案都错了,就没管了,后来赛后,看群里做出来的师傅说,最后的flag是打的补丁那两个数字里比较大的那一个数的十进制然后再用md5加密。
emmm反正我没试到这个,有点脑洞,但是程序本身不难,也基本说清楚了。
这题真的simple,也拿了一血。
首先看主函数,如图:
很简单的tea加密,本来想下断调试一下,取一下v14最后的值,然后直接写个脚本逆一下就好了。但是调试的时候发现有一点点坑,在第一个函数sub_4110F0里,直接运行结束了。
然后重新调试,跟进去这个个函数,发现里面依然是一个tea加密,所以还是原来的思路运行一下取v8最后的值,然后写个简单的脚本就出来了。
调试得到的加密算法如图:
最后的解密脚本如下:
这题好晚才放,有几个点又卡了一下,赛后过一会才解出来,找出题人验证了一下,答案是正确的。
主函数wmian栈太大了,没办法反编译,试了几个方法也没成功,就直接在开头下断点准备调试看看,然后发现直接闪退,肯定有反调,先处理反调。
直接搜ExitProcess函数的交出引用,可以看到不少反调:
在跳转语句处下断点,跑一遍看看程序的执行流程。要改zf位的跳转语句其实就两个地方:
第一个在回调函数0x041183E处:
第二个在0x041518E处:
然后程序会运行到第一个关键函数sub_415250:
这里注册了一个异常处理函数,然后进行除零操作引发异常,所以关键逻辑其实在sub_411177函数。ida动态调试还是有些缺陷,这个异常处理我断不下来,想调试的话用xdbg或者od。
跟进函数到sub_411EC0,这里是才是核心处理逻辑:
字符替换就是把N换成R,T换成Y,主要看验证函数:
验证函数经过一系列累加运算后,v7数组最后要保证每个数都不大于150,v5要等于dword_41C040,这里直接z3求解就好,这里要把这里的N,Y字符串替换成0,1,然后相乘再累加,因为z3定义的未知数不支持做条件判断,具体操作直接看解密代码:
最后再把字符串替换回来:
其实有3个地方的0,1可以任意,因为那三处的dword_41C0D8[j] - dword_41C048[j]为0,但是这三处全0应该才是正确答案。
题目源自2020 DASCTF七月赛
链接:https://pan.baidu.com/s/1tIndXUOhCrn6gSP2NSKOiA
提取码:ln2b
原题目Hint:每张二维码都有6个字符被编码了,把它们提取出来!
下载得到 QrJoker.gif
,可以看到Gif中每一帧都有半张QR Code,首先把它们都分离出来:
对于这种残缺的QR Code,如果是只有右边的话,通常做法是把QR Code填涂在 https://merricx.github.io/qrazybox/ 上,然后借助网站的直接解码功能获得QR Code中的内容
但是这里的残缺QR Code多达64张,最好编写脚本完成(当然一张张描上去也行,但是我懒)
虽然每张QR Code的图案都不一样,但是有三点是一样的:
大小一样;它们都是Version 1的QR Code
格式信息一样;以第一帧的QR Code举例:
红框中读取得到 100101
,前往 https://www.thonky.com/qr-code-tutorial/format-version-tables 查阅,发现匹配上了:
于是知道这张QR Code的纠错等级为 M、掩码为 1;由于只有右边的数据而丢失了左边的纠错码,所以我们不用管纠错等级
右下方数据一样
如果熟悉QR Code的格式的话会知道,右下方是QR Code中数据的起点,它通常包含一张QR Code的编码方式和长度这两种信息;结合题目告知的「每张QR Code包含6个字符」,所以每张QR Code对内容的编码方式、内容长度都是相同的
每张残缺QR Code的数据区域就是上图中的绿色区域,它是一个6×12码元(即基本单位)大小的区域,我们首先用Python的PIL模块将QR Code中的每个码元读取进来
这里以分离出的第一帧图片为例;代码中主要是一个二重循环,我们可以用Windows中的画图程序将QR Code中每个码元的位置找出来,如:
通过这样,得知每个码元的分辨率是10×10;并且最左上角的码元的位置是(410, 90)
二重循环是每次读取一行的6个数据,依次读取完12行,得到整个6×12区域的数据(代码中,offset
的存在只是为了取到每个码元最中间的像素点)
获得一张QR Code的数据后,根据前面观察图片可知,每张QR Code的掩码都是 1,编号1对应的掩码图案就是:
这个掩码图案比较简单,对QR Code中的数据隔行进行比特翻转:
最终 data
变量就是一个6×12的矩阵,其中存储着摘除了掩码后的QR Code数据
以第一帧图片举例,运行代码得到的 data
为:
对应上了摘除掩码后的数据:
有了 data
后,就可以对其中的01字符序列进行处理了
上图是从网上找到的QR Code Version 1的结构图,可以看到,从右下角开始,它的每个数据块都是连续的,不像Version 3一样,块的顺序是不连续的:
所以对获得的 data
的处理就很简单了:
按照QR Code Version 1存放数据的顺序,读取出这张QR Code顺序正确的数据
以第一帧的图片为例,最终得到的 res
为:
这就是第一帧的QR Code的内容了
按照QR Code对数据的编码规则对上面的 res
进行解码
首先看前4 Bits的数据是 0010
,所以它采用的编码模式是字母数字模式(Alphanumeric Mode);然后又因为是Version 1的QR Code,所以内容长度占据9 Bits,内容长度的值是 0x000000110 = 6
请参考 https://www.thonky.com/qr-code-tutorial/data-encoding
所以解码代码为:
第一行代码中,由于已经知道前4 Bits是模式指示符、之后的9 Bits是长度,所以直接截掉;又因为采用Alphanumeric Mode,每两个字符占11 Bits,QR Code中有6个字符,所以有效的只是之后的33 Bits
参考 https://www.thonky.com/qr-code-tutorial/alphanumeric-mode-encoding
代码中的 mapping
是Alphanumeric Mode的映射表,可以参考 https://www.thonky.com/qr-code-tutorial/alphanumeric-table;最后便按照Allphanumeric Mode的编码方式,将每11 Bits解码成2个字符
所有QR Code中的数据提取出来后就很简单了,把得到的字符串先 unescape()
,然后多次Base64解码即可得到flag
下载后解压得到 red_blue.png
和 加密了的 flag.rar
看到图片的名字是 red_blue
,以为是双图隐写,用StegSolve导出R通道和B通道上的图片,发现不是;而且B通道上的图片反色后,跟R通道的一模一样
然后用zsteg检索图片的不同通道,发现:
R通道的最低位上隐藏了一张PNG图片的数据,用StegSolve将其导出,得到:
得到压缩包密码,解压 flag.rar
压缩包 flag.rar
存在NTFS隐写,我看别人都是解压软件直接将隐藏的 flag.txt
显示出来了;我是用010 Editor打开 flag.rar
的数据,然后搜索字符串 STM
,检索到两处,因此才怀疑有NTFS隐写
至于为什么检索字符串 STM
,请参考 https://www.rarlab.com/technote.htm#srvheaders,其中有:
STM
是Rar格式文件中,存在备用数据流的标识
既然存在NTFS隐写,就用WinRar将 flag.rar
解压后,cmd下执行 dir /r
,查看到:
notepad
指令将那个 7.jpg:flag.txt
打开,得到:
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2020-7-27 19:00
被Ssssone编辑
,原因: 纠正未解析成功的图片