对JSON Web Services的Fuzz研究
模糊JSON服务,特别是使用Python,Ruby和JavaScript等动态脚本语言实现的服务通常是一项富有成效的工作。 然而,我的观察是,在测试过程中,这种情况很少做得很好。 在这篇博文中,我想给你一个关于我如何倾向于这样做的简要说明。 不用说,我使用我自己的工具箱,因为它是专门为此设计的,但如果这是您的想法,您可以使用自己的工具。 让我们开始吧。
JSON Web服务是以JSON文档作为输入的简单Web服务。 它们可以从您喜爱的云基础设施(如AWS,Azure和Google Cloud)广泛获得,可用于手机,手表,电视和冰箱。 几乎所有东西都与JSON通信。 这种丰富的原因是因为与其他文档格式(如XML,YAML,INI等)不同,JSON相对简单,紧凑并且不容易出现奇怪的错误。 所有现代编程语言和环境都支持JSON的属性和易用性。
在很多编程语言中,例如JavaScript,以及Ruby和Python的扩展,JSON都是一流的公民。 这意味着JSON文档不仅仅是外来的对象模型,而且是自然的对象,因此它们可以像任何其他普通对象一样被访问。 例如,请考虑以下请求:
POST /path/to/service HTTP/1.1
Host: service
Content-Length: xxxx
Content-Type: application/json
{
"profile": {
"name": "Bob",
"age": 40
}
}
为了访问属性“profile”中的字段“name”,开发人员可能会在JavaScript中执行如下操作:
// this is what you will normally see in ES5
updateProfile(body.profile.name, body.profile.age)
// ...or in modern ES6 may even look like this which looks a bit safer
const { profile={} } = body
const { name, age } = profile
updateProfile(name, age)
请注意,“姓名”和“年龄”字段均直接从“个人资料”中提取。 还注意到我们没有验证这两个领域的类型,也没有对它们进行规范化。 虽然在这个例子中这太方便了,但绝大多数公开代码并不太可能。
利用这一点在很大程度上取决于服务和“updateProfile”函数的实际功能。 因此,我们可以遵循的没有特定的开发风格。 我们无法贴上一些已知的坏字,希望看到快速的结果。 相反,我们需要分析应用程序行为并推断可能发生的情况以及是否有机会进行开发。 这是我们需要卷起袖子并开始模糊的地方。 模糊什么和如何?
显然,我们需要为名称和年龄道具尝试不同的值。 而且,我们需要尝试一些意想不到的容器值,例如数组和对象。 例如,updateProfile函数可能会预期一个对象,例如{first,last}而不是一个字符串。 这些检查可能被实现,而不考虑如何使用“updateProfile”函数以及从JSON主体反序列化的数据,结果,它有助于代码中的分支,其中可能包含当名称字段仅仅是 串。 这些是我们需要通过模糊自动尝试的事情。
我将在此练习中使用AppBandit,但如果您想编写自己的置换器,您还可以使用Fuzzer甚至自己的工具。 我已经为AppBandit和HTTPView做了这个,所以我不想浪费我的周期,因此我为什么要使用这些工具。
我们启动AppBandit并打开一个新的Fuzzer选项卡。 在内部,我们需要像下面的截图一样设置基本请求。 在这种情况下,我们没有做任何事情。 这只是准备下一阶段的指南。
现在我们需要配置JSON文档,以便我们可以对不同的组合进行置换。 为此,我们将使用JSON Fuzz生成器。 导航到正文并从下拉列表中选择JSON模糊。 在第一个领域,我们需要设置我们的文档。 在第二个领域,我们将设置您的有效载荷。
如果我们只在有效载荷字段中输入一个简单的字符串,它将按原样使用。 例如,如果有效载荷是“测试”,那么JSON模糊生成器将生成两个文档,如下所示:
{
"profile": {
"name": "test",
"age": 40
}
}
and
{
"profile": {
"name": "Bob",
"age": "test"
}
}
但是,这不会帮助我们找到任何漏洞,因此我们将使用其他一些生成器来提取更多价值。 让我们使用一个字典生成器,我们可以从下拉列表中选择。 从字典的下拉列表中选择FuzzDB,然后选择“攻击/ json / JSON_Fuzzing.txt”。 请记住,AppBandit默认不会嵌入任何这些字典。 当你需要它们时,它们将被当场下载。
现在我们已经加载了列表,我们也可以编辑它,以便我们可以包含我们自己的有效载荷。 随意添加任何你认为可能有用的东西。 更多的有效载荷我们拥有更好的模糊性。 这就是说,你可以预览如何在箭头按钮的帮助下生成有效载荷。 请注意,目前我们正在以JSON格式正确引用有效负载,这意味着它们将被解释为字符串。
这不是我们想要的。 我们想要的是使用原始JSON,并且要做到这一点,我们需要选择“Parse payload”和“Ignore payload parsing errors”选项。 现在它可以正确生成,如下图所示。
我们完成了这个。 退出发生器弹出窗口并使用箭头按钮循环访问取样的模糊器有效负载。 注意如何正确生成一切。
在我们点击播放按钮之前,我喜欢配置更多选项。 将请求超时设置为更方便的一项,并将最大连接数增加到60,以便我们可以更快地完成这项工作。
有时,应用程序可能因某种原因而行为不当。 不要失望。 如果发生这种情况,请单击Fork按钮以创建当前配置的精确副本并执行另一个测试。 这很容易。
现在我们完成了。 测试立即完成。 下一步是分析结果,看看服务是否有什么奇怪的事情发生。 这背后没有科学。 您只需要浏览结果集以找出不当行为,并且如果您使用AppBandit重新发送工具重复此操作,以便您可以进一步确认并进一步探索/利用。
我知道我没有深入研究一旦发现问题后应该怎么做。 如果您仔细考虑,这是一个开放式问题。 与SQL注入或跨站点脚本和本地文件包含不同,这不是预定义的漏洞。 换句话说,我们可以注入一些有趣的字符来实现某种代码执行。 但是,使用正确的JSON负载,我们可以控制可能导致漏洞的代码。 尽管目前我无法透露任何真实世界的情景,但我们当然看到很多情况下,这种方法会产生有趣和可利用的结果。
原文:https://secapps.com/blog/2018/03/fuzzing-json-web-services
相关文章
- 1条评论
- 澄萌奚落2022-05-29 13:00:33
- 字段“name”,开发人员可能会在JavaScript中执行如下操作:// this is what you will normally see in ES5updateProfile(body.profile.name, body.profile.age)//