由一个萌妹子引发的CTF Writeup

栏目: Python · 发布时间: 5年前

内容简介:前几天在刷 CTF 题的时候遇到一个比较有意思的题,题目本身难度一般,但是涉及到的几个点还是值得记录一下的,于是便有了此文。题目给出的 URL 链接形式为:

前言

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

不一样的图片加载方式

题目给出的 URL 链接形式为: http://www.XXXX.com/index.php?jpg=hh.jpg 浏览器打开显示动漫美少女图片。

由一个萌妹子引发的CTF Writeup

通过查看源码发现图片是以 base64 编码的方式载入的

由一个萌妹子引发的CTF Writeup

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

文件读取漏洞

通过 URL 的链接形式和源码返回内容我们可以猜测一下后端的实现过程:

首先,通过 jpg 参数接收 hh.jpg 值定位到硬盘上的图片文件;

然后,将图片内容读取出来进行 base64 编码;

最后,输出到返回文件中。

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

http://www.XXXX.com/index.php?jpg=index.php

果然返回了 index.php 的 base64 编码内容

由一个萌妹子引发的CTF Writeup

进行 base64 解码后的内容:

由一个萌妹子引发的CTF Writeup

从 index.php 源码中也验证了我们刚才猜测的处理过程。

两个疑点

index.php 源码内容里面有两个比较可疑的点。

 1、 注释内容,CTF 题目中通常会采用注释作为一种提示手段,说明注释内容中有解题的关键点。
 2、 对 file 变量的值进行了正则和字符串替换。

针对疑点一:

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

由一个萌妹子引发的CTF Writeup

这里面出现了 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 的内容。

由一个萌妹子引发的CTF Writeup

一个加解密算法

fl3g_ichuqiu.php 解码后的内容如下:

由一个萌妹子引发的CTF Writeup

由一个萌妹子引发的CTF Writeup

这是一个加解密函数,得到 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 位进行爆破。

具体爆破脚本如下:

由一个萌妹子引发的CTF Writeup

由一个萌妹子引发的CTF Writeup 由一个萌妹子引发的CTF Writeup 由一个萌妹子引发的CTF Writeup

编码的坑

然而在爆破脚本运行之后结果却是比较失望

由一个萌妹子引发的CTF Writeup

并没有如期获取到 flag,接下来就是漫长的调试和分析问题。

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

 Php 运行结果为:c3VORkS6RUlYRg==
 Python 结果为:c3VORkTCukVJWEY=

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

由一个萌妹子引发的CTF Writeup

如图中,编码的内容是 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 后运行脚本。

由一个萌妹子引发的CTF Writeup 由一个萌妹子引发的CTF Writeup

成功获得了 Flag。

总结

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

  图片的 base64 编码方式
  常规的文件读取漏洞
  集成环境的信息泄露问题
  正则和字符串的过滤绕过
  加解密逆向
  爆破的思想
  不同字符编码的问题(这个应该是个意外)

*本文作者:京东安全,转载请注明来自FreeBuf.COM


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

R Cookbook

R Cookbook

Paul Teetor / O'Reilly Media / 2011-3-22 / USD 39.99

With more than 200 practical recipes, this book helps you perform data analysis with R quickly and efficiently. The R language provides everything you need to do statistical work, but its structure ca......一起来看看 《R Cookbook》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具