JSON解析不一致性漏洞探究

admin 2024年4月10日14:54:29评论12 views字数 4527阅读15分5秒阅读模式
背  景

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易 于机器解析和生成。它基于JavaScript语言标准ECMA-262第3版(1999年12月)的一个子集。随着时间的推移,JSON已经超越了JavaScript,成为许多编程语言支持的标准数据格式之一。

如HTTP 请求走私等攻击一样,json解析器之间以及多阶段请求处理的差异可能引入严重的漏洞,即使是在严格遵守规范的解析器,也不可避免的与规范存在偏差,这是为什么?

  1. 关于JSON的规范有多个,各规范定义有一定的差异

  • ECMAScript Standard:ECMAScript是JavaScript语言的标准化名称,定义了JSON作为JavaScript的一个子集,但实际应用超出了JavaScript;

  • IETF JSON RFC 8259:提供了一个严格和精确的JSON数据交换格式规范,这个标准旨在确保JSON数据的交换在不同的系统间能够保持一致性和可靠性。

  1. 规范文档对于一些定义是开放式的描述,例如 IETF JSON RFC 8259 对重复键的描述:

An object whose names are all unique is interoperable in the sense that all software implementations receiving that object will agree on the name-value mappings. When the names within an object are not unique, the behavior of software that receives such an object is unpredictable. Many implementations report the last name/value pair only. Other implementations report an error or fail to parse the object, and some implementations report all of the name/value pairs, including duplicates.

只是说明了各种解析器对重复键值处理的各种现象,并没有规定当重复键出现时应怎么处理。

那么主要有哪些JSON解析差异可能会导致漏洞?

  • 重复键的优先级差异

  • 特殊键解析差异:字符截断和注释

  • JSON序列化结构差异

  • 浮点数和整数表示差异

  • 解析容错机制和其他bug

  • ……

更多的差异分类和细节可参考文章,下面我们看一些真实的cve漏洞案例。

漏洞案例
01

案例1:Sophos XG认证绕过 CVE-2022-1040

数据流

Sophos XG Firewall各组件调用关系可以简化如下:

JSON解析不一致性漏洞探究

apache接受用户的http请求后转发给jetty处理过滤后,通过类似于 HTTP 的 TCP 和 UDP 协议转发给csc服务,csc处理系统的核心业务,它的核心部分是用C语言编写的,逻辑部分是通过Perl C语言接口(Perl C Language Interface)用Perl语言编写的。

核心方法分析

具体的漏洞细节分析这里不做过多描述,参考 文章CVE-2022-1040 Sophos XG Firewall Authentication bypass

这里只分析下关键的绕过逻辑,看下登录绕过的poc数据包:

JSON解析不一致性漏洞探究

主要起作用的是modejson两个参数,jetty侧会通过org.json-20090211个库解析json参数传的json数据,通过cscClient.generateAndSendAjaxEvent发送到CSC做认证,发送前会将mode参数put到解析后的json中,如果这里返回的状态码是200或者201,则认为是登录认证通过。

JSON解析不一致性漏洞探究

jetty侧的org.json-20090211这个库对于重复键会抛出异常

JSON解析不一致性漏洞探究

运行结果如下:

JSON解析不一致性漏洞探究

csc使用的json-c这个库来解析输入的数据,对于重复键,则取后面一个

JSON解析不一致性漏洞探究

运行结果如下:

JSON解析不一致性漏洞探究

并且当json的key中出现unicode空字符时,json-c对空字符会做截断,但org.json-json库会保留

JSON解析不一致性漏洞探究

运行结果如下:

JSON解析不一致性漏洞探究

这个漏洞就是利用了这两个库的解析差异特性导致的绕过,我们使用下面命令开启debug,查看poc请求时的参数变化

JSON解析不一致性漏洞探究

送请poc请求,从日志可以看到,经过jetty侧org.json-json库解析转发到csc时,同时包含了modemodeu0000p0melo两个键

JSON解析不一致性漏洞探究

但是通过csc的createJsonvalidateJson方法解析后,原本的json数据只有一个mode键了,并且值为后一个键716,如下图,csc认为是请求的716模块,并且请求参数合法,导致返回了200状态码和其他符合jetty侧登录判断的数据,这就导致了登录绕过。

JSON解析不一致性漏洞探究

02

案例2:Apache APISIX CVE-2022-25757

Apache Apisix使用了request-validation插件,它可以用来检查HTTP请求头和BODY内容,request-validation.lua中使用cjson.safe库解析字符串为json对象。

JSON解析不一致性漏洞探究

对于重复键,cjson.safe 优先取后面的键值去验证,而上游应用程序的 JSON 库选择第一个出现的值,例如 jsoniter gojay 3,所以发送类似下面的json数据就能绕过数据校验,将非法数据请求到上游服务。

JSON解析不一致性漏洞探究

这是一个典型的由于重复键优先级不一致导致的问题。

03

案例3:CouchDB 权限提升 CVE-2017-12635

CouchDB是一个NoSQL数据库,有点像 JSON blob的大型键值存储,具有数据验证、查询和用户身份验证功能。CouchDB通过/_users接口来管理用户账户,通过 PUT请求到 /_users/org.couchdb.user:your_username来创建或修改账户,服务器会使用 Javascript的validate_doc_update 函数检查,确保用户不会尝试让自己成为管理员。

漏洞就出在Javascript JSON 解析器(在验证脚本中使用)与 CouchDB 内部使用的名为 jiffy 的解析器(Erlang语言)之间存在差异。看下这两个解析器对相同键的处理。

Erlang

JSON解析不一致性漏洞探究

Javascript

JSON解析不一致性漏洞探究

jiffy保留了2个重复键,用于验证的javascript取后面一个键值,并且CouchDB 数据内部表示的 getter 函数只会返回第一个值。

JSON解析不一致性漏洞探究

所以我们可以通过下面的请求,让javascript解析是空,认为是非管理员用户,通过验证,而jiffy则新增的是管理员用户,从而越权新增一个admin权限用户。

JSON解析不一致性漏洞探究

如何批量检测json解析器的差异性

当我们漏洞挖掘的项目有多个json解析器的情况下,可以对文章JSONTestSuite这个工具稍作修改,就可以快速验证两个或多个解析器存在的差异。

01

工具介绍

如下图,run_test.py是主要的代码逻辑入口,parsers目录下是各种解析器,tests目录下是针对RFC 8259做了各种变形的json,test_transform目录是各种解析器识别容易有差异性json数据(超大数字、重复键、空字符等)。

JSON解析不一致性漏洞探究

run_test.py会对parsers目录下各种解析器做一个包装,将解析器执行的命令返回状态结果记录到log.txt,然后做解析美化记录到results目录下,下面是生成的parsing.html中的对比图表,包含各种解析器对不同json数据解析后返回的状态。

JSON解析不一致性漏洞探究

工具是针对RFC 8259标准对各json析器做的测试用例,对比的是命令执行返回状态的差异,也就是判断解析是否符合预期的成功、异常或失败。下面是run_test.py执行结果的判断:

JSON解析不一致性漏洞探究

如果有2个以y_开头的json用例都解析成功了,但是解析出来的内容不同,会被结果解析忽略,导致报告不会输出这种用例的结果。

所以对于解析器的差异性识别,除了解析结果的状态,我们也在意解析后的内容,所以对run_test.py调用解析器部分稍作修改,以便对比解析后的内容,下面是原来代码调用解析器部分:

JSON解析不一致性漏洞探究

不考虑将运行结果美化,将上面代码部分替换为如下简化代码,获取解析结果并直接输出。

JSON解析不一致性漏洞探究

02

工具实践(CVE-2022-1040)

现在我们通过前文的CVE-2022-1040为例,来看如何通过这个工具来批量比较org.json-20090211json-c这两个json解析器的差异性。

parsers目录中只有2016版本的org.json包,所以我们需要自己去下载org.json-20090211版本的jar包,并参考TestJSONParsing.java写一个主函数调用jar去解析,然后打一个jar包供run_tests.py调用。

JSON解析不一致性漏洞探究

TestJSONParsing.jar放在parsers下的子目录下,子目录假设以test_java_org_json_2009_02命名,对应在run_tests.pyprograms数组中新增一个解析器。

JSON解析不一致性漏洞探究

parsers目录本身已有了json-c解析器,但是格式是Mach-O的,如果想要在正常的其他架构下运行需要自己下载对应的版本并编译,将编译后的二进制文件移动到parsers/test_json-c/bin目录下并重命名为test_json-c(与run_tests.pyprograms数组中的对应)。

并通过filter参数限制我需要比较的2个解析器,效果如下:

JSON解析不一致性漏洞探究

通过上面的重复键解析结果可以看到,json-c解析器能获取重复键的最后一个,而org.json则异常了,并且对于nul的key解析也有差异。

除了这2个差异之外,还可以看到很多其他的差异,例如带注释的json数据{"a":"b"}/**/

JSON解析不一致性漏洞探究

超大数字解析 {9999E9999:1}

JSON解析不一致性漏洞探究

这里只是简单的做一个解析后内容的输出,如果当json用例非常多时,有差异的结果就比较难找,读者可参考项目的结果美化逻辑,对结果做进一步的美化,方便对比。

总  结

本文介绍了导致json解析差异性的背景,结合3个由JSON解析差异性导致的经典CVE进行分析,并通过修改已有工具和集成新的解析器实现批量的json差异性检测。

参考链接

Parsing JSON is a Minefield

An Exploration of JSON Interoperability Vulnerabilities

JSONTestSuite

Apache Apisix安全评估

Remote Code Execution in CouchDB

【版权说明】

本作品著作权归p0melo所有

未经作者同意,不得转载

JSON解析不一致性漏洞探究

p0melo

天工实验室安全研究员

专注于Web安全与代码审计

往期回顾
01
IoT设备常见Web Server漏洞挖掘思路分析
02
探索 D-Bus 跨进程消息传递中的安全风险
03
Windows Hypervisor & 内核调试的几种常见/不常见方法
04
FortiGate SSLVPN CVE-2024-21762漏洞利用分析
JSON解析不一致性漏洞探究
每周三更新一篇技术文章  点击关注我们吧!

原文始发于微信公众号(破壳平台):JSON解析不一致性漏洞探究

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年4月10日14:54:29
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   JSON解析不一致性漏洞探究https://cn-sec.com/archives/2644512.html

发表评论

匿名网友 填写信息