i春秋 WEB“百度杯”CTF比赛 九月场 -- Code
打开链接,发现jpg参数貌似可以文件任意读取
读取index一波
发现返回的形式是依然是image,并且经过base64加密
解密获得index.php源码
会对file进行一些常规的过滤,然后以图片的形式展示出来
13行的config有点可疑,先记录下来
由于需要读取的falg文件未知,当下需要先对目录结构做个了解(第三行的phpstorm是个题眼)
扫描一波
结果不出所料,不仅存在config.php,workspace.xml也存在
直接访问workspace.xml 可知当前目录下fl3g_ichuqiu.php
直接访问读取不到什么信息,那就直接在index.php构造参数读取一波源码
审计一下发现访问时会在客户端读取或存储一个名为user的COOKIE,既然想拿到flag就需要输入正确的COOKIE配合key进行decrypt操作使username变成'system',进而获取flag
如果要知道正确的COOKIE就要知道key,要知道key就需要对现存储的COOKIE进行分析
分析encrypt发现会对第一个参数txt(guest)统一右移十位,然后会产生一个4位随机数和key拼接后MD5
加密,之后将移位后的txt与加密后的key进行异或,最后将4位随机数与异或后的结果进行拼接,并base64加密。
首先可以通过COOKIE存储的数据结合函数return的形式,逆推出4位随机数的值(rnd)与异或加密后的结果(ttmp)。
其次可以根据异或的特性(a^b=c <==> a^c=b)计算出与rnd加密后的key。
此时问题来了,因为位数的限制(guest),最后得到加密后的key仅有5位,这里先留个疑问。
既然COOKIE的值可控,审计一下decrypt
函数开始会对传进来的txt(user的COOKIE)在base64解密后进行一个分割:rnd(4位)+txt(4位之后)
之后根据传入的rnd与key进行和encrypt一样的加密操作,之后依然是吧加密的结果与txt异或,然后整体向左移10位,最后输出结果。
首先从入口处,因为函数会对传入的COOKIE存在与下文key加密的rnd的值,在rnd可控的同时也可以对加密后的key进行控制
其次因为我们最终的目的是使其返回的值为system(tmp1=‘’system‘’),所以可以逆推成需要key与txt异或的结果。
因加密后的key可控,所以我们可以异或出相应的txt,但由于可控的key只有5位,而结果需要6位,所以还需要爆破一下。
基本流程:
查看COOKIE --> 记录rnd与加密后的key --> 根据加密后的key通过与处理后的system异或计算相应的txt(5位) --> 将得到的txt与rnd构造起来(base64(rnd+txt+1位(数字、大小写字母))) --> 在fl3g_ichuqiu.php界面填入user的COOKIE进行爆破 --> 获取flag
最后说一下自己踩的坑吧:
- 代码里的循环移位不是凯撒加密,仅仅是对ASCII进行一下加减,所以不要对移位后结果惊讶..
- 不要对计算出有限位数的key过于深究,前期获取5位key(不是前五位哦,下标从1开始的~),后期爆破下一位key即可。