您的位置:金沙js28com > 程序开发 > 由一个萌妹子引发的CTF Writeup

由一个萌妹子引发的CTF Writeup

2019-04-01 12:38

  前几天在刷 CTF 题的时候遇到一个比较有意思的题,题目本身难度一般,但是涉及到的几个点还是值得记录一下的,于是便有了此文。

  对于不需要更新内容的图片来说,可以直接将文件内容以 base64 编码的方式写入到网页文件中,这样做的好处是节省了一个 HTTP 请求。当然对于本题来说肯定不是为了这个目的。

  如果我们猜测没错的话,这里面存在一个文件读取的过程,读取的文件通过 jpg 参数控制,这里如果 jpg 的参数值没有进行过滤限制,就可能存在任意文件读取漏洞。为了验证漏洞,我们尝试读取 index.php 文件。构造链接:

  1、 注释内容,CTF 题目中通常会采用注释作为一种提示手段,说明注释内容中有解题的关键点。

  注释里面有两个时间和一个版权信息,时间通常和密码有关,目前没发现密码相关的地方,所以先从版权信息入手,查一下 PhpStorm。通过搜索得知 PhpStorm 是一个 php 的集成开发软件,在通过它创建项目时会自动创建一个.idea 文件夹,在该文件夹下面存在项目的一些配置文件,尝试访问其中的 workspace.xml

  当我们看到 fl3g_ichuqiu.php 和 config.php 这两个文件的名字的时候,疑点二里面的两个过滤语句的目的就比较明显了。

  根据可疑点 2 中的正则替换的目的,就是不希望我们构造来读取 fl3g_ichuqiu.php 中的内容,因为 fl3g_ichuqiu.php 中的」_」不属于 [a-zA-Z0-9],会被替换为空。而第二个字符串过滤的目的,是不希望我们直接读取 config.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

  根据加密函数的算法和已知的 guest 加密对,我们可以算出 rnd 的值和加密 key 的前 5(guest 字符串的长度)位,而我们要获得 system 的加密值,需要知道 rnd 和 key 的前 6(system 的长度)位,因此需要对加密 key 的第 6 位进行爆破。

  首先验证 python 脚本的加密算法是否存在问题,利用固定的 key 值(998771)和 rnd 值(suNF)对「system」进行加密,加密结果与用相同的 key 值和 rnd 值的原始 php 加密函数结果进行对比,发现结果果然存在差异。

  在 base64 中「=」用于补位,两个结果中的补位符不同,说明 base64 编码前的二进制字节数不同。我们回到 base64 编码前的内容看看到底是什么?

  这个结果差异很明显,在 php 中显示为字符的「º」在 python 中被编码为两个字节。这也就是为什么 php 中的 base64 编码结果需要 2 个字节补位,而 python 结果中只需要一个,这里 python 多出了一个字节。

  这里的主要原因是在 python 中我们对字符进行了 utf-8 的编码方式,「º」字符的十进制数为 186,大于 127,在 utf-8 中会被编为两个字节。而 php 中应该是采用了单字节的编码方式,导致了差异的产生,知道了差异在哪里,就很好解决了,我们在 python 中将 utf-8 换成 latin-1 后运行脚本。

  题目虽然没有涉及太深的技术,但是确实涵盖了一些 CTF 中的基本考察点。

本文链接:由一个萌妹子引发的CTF Writeup