内容简介:前几天在刷 CTF 题的时候遇到一个比较有意思的题,题目本身难度一般,但是涉及到的几个点还是值得记录一下的,于是便有了此文。题目给出的 URL 链接形式为:
前言
前几天在刷 CTF 题的时候遇到一个比较有意思的题,题目本身难度一般,但是涉及到的几个点还是值得记录一下的,于是便有了此文。
不一样的图片加载方式
题目给出的 URL 链接形式为: http://www.XXXX.com/index.php?jpg=hh.jpg 浏览器打开显示动漫美少女图片。
通过查看源码发现图片是以 base64 编码的方式载入的
对于不需要更新内容的图片来说,可以直接将文件内容以 base64 编码的方式写入到网页文件中,这样做的好处是节省了一个 HTTP 请求。当然对于本题来说肯定不是为了这个目的。
文件读取漏洞
通过 URL 的链接形式和源码返回内容我们可以猜测一下后端的实现过程:
首先,通过 jpg 参数接收 hh.jpg 值定位到硬盘上的图片文件;
然后,将图片内容读取出来进行 base64 编码;
最后,输出到返回文件中。
如果我们猜测没错的话,这里面存在一个文件读取的过程,读取的文件通过 jpg 参数控制,这里如果 jpg 的参数值没有进行过滤限制,就可能存在任意文件读取漏洞。为了验证漏洞,我们尝试读取 index.php 文件。构造链接:
http://www.XXXX.com/index.php?jpg=index.php
果然返回了 index.php 的 base64 编码内容
进行 base64 解码后的内容:
从 index.php 源码中也验证了我们刚才猜测的处理过程。
两个疑点
index.php 源码内容里面有两个比较可疑的点。
1、 注释内容,CTF 题目中通常会采用注释作为一种提示手段,说明注释内容中有解题的关键点。 2、 对 file 变量的值进行了正则和字符串替换。
针对疑点一:
注释里面有两个时间和一个版权信息,时间通常和密码有关,目前没发现密码相关的地方,所以先从版权信息入手,查一下 PhpStorm。通过搜索得知 PhpStorm 是一个 php 的集成开发软件,在通过它创建项目时会自动创建一个.idea 文件夹,在该文件夹下面存在项目的一些配置文件,尝试访问其中的 workspace.xml
这里面出现了 fl3g_ichuqiu.php 和 config.php 两个新文件。其中 fl3g_ichuqiu.php 文件应该就是我们获取 flag 的关键文件。我们可以利用文件读取漏洞去读取该文件。
针对疑点二:
当我们看到 fl3g_ichuqiu.php 和 config.php 这两个文件的名字的时候,疑点二里面的两个过滤语句的目的就比较明显了。
根据可疑点 2 中的正则替换的目的,就是不希望我们构造 http://www.XXXX.com/index.php?jpg=fl3g_ichuqiu.php 来读取 fl3g_ichuqiu.php 中的内容,因为 fl3g_ichuqiu.php 中的」_」不属于 [a-zA-Z0-9],会被替换为空。而第二个字符串过滤的目的,是不希望我们直接读取 config.php 文件,这里面明显存在关键信息。
但是我们正好可以利用」config」替换 fl3g_ichuqiu.php 中的」_」, 来绕过正则对「_」的过滤。构造 http://www.XXXX.com/index.php?jpg=fl3gconfigichuqiu.php 。来读取 fl3g_ichuqiu.php 的内容。
一个加解密算法
fl3g_ichuqiu.php 解码后的内容如下:
这是一个加解密函数,得到 flag 的关键是计算出「system」的加密值。已知条件是「guest」的加密值。关键是得到 key,可以看出 key 是在 config.php 文件里面定义的,而因为字符串过滤条件,我们没有办法直接读取 config.php 文件,只能利用加解密函数算出结果。
分析加密函数如下:
1、 先将待加密字符串 txt 的每位对应的 ascii 值加 10,转换为新的字符串。 2、 取随机 4 位由大小写字母或数字组成的 rnd 与参数 key 拼接,取 md5 作为加密 key 3、 将待加密字符串与加密 key 的前 n 位(n 为 txt 的长度)进行按位异或得到 ttmp 4、 将 rnd 与 ttmp 拼接进行 base64 编码获得加密后的值。
根据加密函数的算法和已知的 guest 加密对,我们可以算出 rnd 的值和加密 key 的前 5(guest 字符串的长度)位,而我们要获得 system 的加密值,需要知道 rnd 和 key 的前 6(system 的长度)位,因此需要对加密 key 的第 6 位进行爆破。
具体爆破脚本如下:
编码的坑
然而在爆破脚本运行之后结果却是比较失望
并没有如期获取到 flag,接下来就是漫长的调试和分析问题。
首先验证 python 脚本的加密算法是否存在问题,利用固定的 key 值(998771)和 rnd 值(suNF)对「system」进行加密,加密结果与用相同的 key 值和 rnd 值的原始 php 加密函数结果进行对比,发现结果果然存在差异。
Php 运行结果为:c3VORkS6RUlYRg== Python 结果为:c3VORkTCukVJWEY=
在 base64 中「=」用于补位,两个结果中的补位符不同,说明 base64 编码前的二进制字节数不同。我们回到 base64 编码前的内容看看到底是什么?
如图中,编码的内容是 rnd+ttmp,分别用 php 和 python 输出 rnd+ttmp 的内容如下:
Php 结果:suNFDºEIXF Python 结果:b’suNFD\xc2\xbaEIXF’
这个结果差异很明显,在 php 中显示为字符的「º」在 python 中被编码为两个字节。这也就是为什么 php 中的 base64 编码结果需要 2 个字节补位,而 python 结果中只需要一个,这里 python 多出了一个字节。
这里的主要原因是在 python 中我们对字符进行了 utf-8 的编码方式,「º」字符的十进制数为 186,大于 127,在 utf-8 中会被编为两个字节。而 php 中应该是采用了单字节的编码方式,导致了差异的产生,知道了差异在哪里,就很好解决了,我们在 python 中将 utf-8 换成 latin-1 后运行脚本。
成功获得了 Flag。
总结
题目虽然没有涉及太深的技术,但是确实涵盖了一些 CTF 中的基本考察点。
图片的 base64 编码方式 常规的文件读取漏洞 集成环境的信息泄露问题 正则和字符串的过滤绕过 加解密逆向 爆破的思想 不同字符编码的问题(这个应该是个意外)
*本文作者:京东安全,转载请注明来自FreeBuf.COM
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Scrapy框架爬取海量妹子图
- Java 妹子与数据库老头的交流
- Python爬知乎妹子都爱取啥名
- 数据工程师妹子养成手记——数据库篇
- 用 Python 给自己找个合适的妹子
- 推荐一个相当强的 Node.js 全栈妹子
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。