在安全测试目标时,最有趣的测试部分是它的 API。API 是动态的,它们比应用程序的其他部分更新得更频繁,并且负责许多后端繁重的工作。在现代应用程序中,我们通常会看到 REST API,但也会看到其他形式,例如 GraphQL 甚至 SOAP。
当我们第一次对某个目标进行安全测试时,我们需要做大量研究,以了解其主要功能以及它们在幕后如何工作。建议花一些时间来阅读有关目标及其服务的信息。例如,如果我们正在破解一个汽车租赁应用程序,那么一开始最好的做法是了解该公司的服务(租赁、销售、支持、折扣等)。有了对目标服务的了解,我们将在其应用程序中寻找反映的功能并尝试破解它们。
在这篇文章中**,我们将讨论 API 侦察方法**,以便更好地了解我们的攻击面。我们不会在这里深入讨论常见的 API 攻击。
为什么要使用特殊的 API 侦察方法而不只是使用工具?
可以说"单击应用程序向您显示的每个按钮"是一个很好的做法。理解函数最简单的方法就是简单地使用它并分析我们得到的响应。
然而,屏幕上的按钮并不总是包含应用程序包含的全部 API。我们需要假设我们只看到 API 的部分的三个主要原因:
-
我们不知道具有不同权限级别的用户是否比我们拥有更多的API
-
可能有一些未记录的 API,开发人员尚未为其创建 Web 界面
-
可能有一些旧的 API 已被开发人员删除了其 Web 界面,但仍可在后端运行
进行彻底的 API 侦察的另一个很好的理由是,这是了解更多有关应用程序的底层和核心并同时暴露秘密的好方法。
#1 --- API 文档
但在许多情况下,我们正在测试运行产品(应用程序)的目标,该目标具有其 API 的可用文档,例如 WSDL 文件的 Swagger。通常,文档是为了方便其他想要将目标 API 集成到其应用程序中的开发人员而提供的。但有时,除了过度曝光之外,文档可以无任何理由地公开访问。
无论如何,这是一个非常有用的信息。它不仅映射了主应用程序的 API 端点,还解释了 API 本身的功能:
-
特定端点期望获取什么类型的数据(整数/字符串、JSON/XML、POST/PUT/GET 等)
-
发送请求所需的标头
-
我们可能从请求中得到的响应
-
特定端点所需的身份验证级别
在上面的示例中,我们可以看到 Uber 如何为其他开发人员提供其 API 文档。请注意请求中的不同标头,其中包括一些参数,如授权码、客户端 ID 和客户端密钥。这些参数对于正确执行 API 可能至关重要,文档为我们提供了很好的解释。
使用应用程序 API 文档的另一种方法是查找其 Swagger/WSDL 文件。我们不仅可以阅读它们来了解 API 结构,还可以将这些文件加载到 Postman 并开始使用它们!
并非每个应用程序都有它,但查找和阅读文档可以节省我们的时间,并给出有关该应用程序的几乎所有问题的答案。
如果我们的目标没有 API 文档,我们可以为应用程序创建自己的文档,而不需要付出太多的努力。请阅读本文中的更多信息:当目标不存在时如何为目标制作流氓 API 文档:https://danaepp.com/how-to-craft-rogue-api-docs-for-a-target-when-they-dont-exist。
#2 --- API 开源情报研究
正如我们之前提到的,API 是应用程序中非常动态的部分,并且会不时发生变化。这意味着两件重要的事情:
-
开发人员不断开发 API,并可能使用不同的工具来构建、测试和记录不同 API 的版本
-
我们很有可能可以找到应用程序 API 的旧版本,并且它们可能不如生产中的当前版本安全!
让我们来谈谈一些我们可以轻松使用并快速获得结果的 OSINT 工具。
Google Dorking
当我们接近目标时,首先要做的事情之一就是结合 Google 的高级搜索选项和 API 的一些指示性关键字。快速的 Google dorking 搜索可能会给我们:
-
与API相关的目标子域
-
目标的API文档页面
-
API端点------旧版本和当前版本
以下是有关星巴克的一些结果的示例:
这个简单的搜索当然不会映射星巴克的整个 API 表面,但它为我们提供了更多线索,指向拥有其 API 的公司的更多子域。
一些更有用的搜索表单:
-
site:target.com inurl:"/v1"
-
site:target.com inurl:"/api"
-
site:target.com inurl:"/graphql"
-
site:target.com title:"api*"
WaybackMachine
WaybackMachine 是发现 API 端点并同时获取一些秘密的最佳工具之一。我们都知道,通过搜索 URL,我们可以查看目标在特定日期的页面。神奇的是,我们还可以在 GET 请求中获取 URL 列表。注意下图:
只需搜索公司的域名并过滤工作"api",我们就得到了一些 API 端点,甚至包含 GraphQL。
如果我们查看公司的更多子域,我们可能会看到越来越多的 API 端点。在许多情况下,我能够在 Wayback 中找到用户名、令牌、身份验证密钥和 JWT 等凭证。
使用这些找到的凭据,我有时可以测试具有不同用户权限的身份验证后 API 端点。
此外,建议将 GAU:https://github.com/lc/gau或Waymore: https://github.com/xnl-h4ck3r/waymore集成**到您的侦察自动化中,以拉取更多 API 端点**。
Postman
这是开发人员测试 API 的最常用工具之一,无需前端接口来发送请求,并且比仅使用curl 方便得多。
Postman 在postman.com:https://www.postman.com/中作为 SaaS 应用程序提供,允许开发人员共享项目,以使团队更轻松地工作。postman项目,也称为postman收藏,通常被认为是私人的。但在很多情况下,你会看到这些藏品是公开开放的。在集合中,有许多细节,例如参数、标头、正文数据、环境变量和授权令牌。
如果我们足够幸运,能够接触到目标的postman集合,那么它可能比找到官方 API 文档页面更好。这些不仅仅是我们在那里看到的没有真实内容的示例,这些是应用程序开发人员发送的真实请求和来自后端的真实响应。我们可以了解很多关于应用程序的内部环境和目标的底层核心。最好的部分之一 - 通常具有查询后端的高权限的凭据!
在上图中,我们可以看到属于我的一位客户的postman收藏。正如您所看到的,这是发送到 localhost:8080 的 POST 请求的示例,因为它是在临时环境中发送的。但有一个令牌和一个 cookie 仍然可以在生产环境的渗透测试中使用。
GitHub
如果您的目标有一个可供您访问的 GitHub 存储库,那么花一些时间研究应用程序的代码是一个好主意。通过几个关键字,我们将最大程度地找到 API 端点以及它们如何工作的详细说明。
API 的一些常见关键字:
-
/v1
-
/api
-
apikey
-
api_key
-
api文档
-
api_secret
-
x-api-key
-
/graphql
与 Postman 和 WaybackMachine 一样,在 GitHub 中我们也有很好的机会找到一些可能对后续合作步骤有用的秘密和凭据。
#3 --- 应用程序的 HTML 和 Javascript
为了将 API 请求从前端发送到后端,前端应用程序使用 Javascript 进行 XHR/AJAX 调用。这意味着 API 端点本身应该在客户端源代码中提及。在 FireFox 中,如果我们打开 DevTools (F12) 并打开"调试器"选项卡(或 Chrome 中的"源"选项卡),我们将看到目标的地址和一个向下的小箭头。单击小箭头,我们将获取前端的资源,包括 Javascript 文件。
找到 Javascript 文件后,我们通常会得到一大块精简的代码,没有换行和空格。它的发生是为了提高用户体验的性能。在这种情况下,我们可以使用 JS 修饰器:https://beautifier.io/ 进行代码美化。之后,只需将代码复制到代码编辑器(例如 VSCode 或 Sublime)中,然后开始搜索 API 请求。
要在代码中搜索API调用,我们首先需要了解应用程序中API调用的结构。花一些时间阅读您看到的不同函数和变量。搜索API、v1、v2、user等关键字 以及与 API 相关的其他常用词。另一件要做的事情是搜索指示发送到后端的请求的 HTTP 方法。
另外,**如果我们想要一个自动化工具,我们可以使用Katana:https://github.com/projectdiscovery/katana 。这是一个爬虫工具。Katana 最重要的功能之一是 Javascript 解析。有了这个,我们可以在许多 JS 文件上运行,并在几分钟内获得目标上 API。**一个好的建议是使用 Katana 并查看输出,然后再次运行它,并对特定的 Web 应用程序进行更多自定义。
通过查看应用程序的 HTML 和 Javascript,我们可以映射大多数 API 调用,甚至找到那些未公开的API(shadow api):https://www.cloudflare.com/learning/security/api/what-is-shadow-api/。在我最近的一次测试中,应用程序的用户界面公开了大约 30 个 API 调用,而在提取 Javascript 代码后,我能够公开 140 多个 API 端点,而这些端点仅通过使用应用程序是看不见的。
由于shadow api 的暴露程度较小,因此它们往往具有较高的潜在漏洞,因为它们也很少经过测试。
#4 --- 主动扫描 --- 模糊测试
到目前为止,我们只讨论了发现 API 的被动方法,与目标本身的接触最少。被动操作仍然使我们能够发现后端存在的许多甚至大多数 API 端点。但是,当 API 端点不暴露给我们正在使用的应用程序时,会发生什么情况呢?我不是在谈论shadow API,而是在谈论后端存在的其他端点,并假设为另一个应用程序提供服务,例如内部或员工应用程序。
例如,当一家公司开发少量从一个后端 (api.target.com) 获取数据的前端应用程序(Web 和mobile)时,例如一个用于客户的面板和另一个用于经理的面板。
如果我们无法访问另一个应用程序,或者我们甚至不知道它的存在,通过模糊测试,我们可以找到更多的端点来测试!
当谈到 API 模糊测试时,我们需要考虑两件重要的事情:
-
模糊器/扫描器:它是发送 HTTP 请求并通过响应进行过滤的工具。
-
词汇表/字典:我们模糊测试的内容。一个好的字典是找到只运行通用单词的漏洞和浪费时间之间的区别。
我们来谈谈他们吧。
模糊器/扫描器
现在有很多工具通过模糊测试在 API 发现方面做得很好。对于带有端点列表的简单 GET 请求,我们始终可以使用 Burp Intruder、ffuf、GoBuster、 Kiterunner:https://github.com/assetnote/kiterunner等工具,甚至构建我们自己的模糊器。在大多数情况下,我发现ffuf:https://github.com/ffuf/ffuf 和 Kiterunner**都是很棒的工具,不仅在速度方面,而且在它带来的有用功能方面,例如按大小、状态代码、单词等进行过滤。**特别是 Kiterunner,结合 Assetnote 的相关列表,这个工具非常适合现代 Web 应用程序(NodeJS、Flask、Rails 等)。
使用单个命令,您就可以很好地了解目标的 API :
./kr scan https://target.com -w ~/wordlists/routes-large.json
此外,除了 API 端点之外**,我们还必须发现后端接受哪些参数** 。当然,有合法请求的"默认"参数,但如果还有"影子参数"怎么办?也许我们可以找到一个多个漏洞,除了模糊目标之外,我们没有其他方法可以找到该漏洞。**对于这项任务,我认为Arjun:https://github.com/s0md3v/Arjun是最好的工具之一。
Arjun 是一个 Python 工具,它只需将 GET 请求发送到具有大量不同参数的给定 URL。最后,该工具将返回我们有效参数列表以供进一步测试。我将在以后有关黑客 API 的文章中详细介绍 Arjun 的使用。
单词表/字典
使用正确的字典是 API 渗透测试成功的关键。对于这个任务有一些很棒的资源:SecLists:https://github.com/danielmiessler/SecLists 、 Assetnote:http://wordlists.assetnote.io/、 FuzzDB:https://github.com/fuzzdb-project/fuzzdb等等。
专业人士总是会尝试根据目标获得更具体的单词表。例如,如果我们知道我们的目标是基于 Django 作为后端的汽车租赁 Web 应用程序,我们可以将 Django 的通用单词列表与汽车租赁的自定义单词列表结合起来。对于第一个单词列表,我们可以使用 assetnote:
对于第二个**,我们可以要求 ChatGPT 生成汽车租赁的常见 API 端点列表**:
#5------Mobile(移动端)
假设我们的目标是一家送货公司。它有一个网络应用程序,我们可以在其中下订单、付款,也许还有更多功能。但如果快递公司也有移动应用程序,那么就有可能有一些特别适用于手机的功能,例如通过 GPS 获取精确位置。
在这种情况下,这可能意味着Web 应用程序的 Javascript 中存在的 API 与 APK 文件中存在的 API 端点不同。
移动应用程序渗透测试是一个很大的不同主题,因此我们不会在本文中讨论太多细节,但我们可以使用 JADX 和 MobSF 等静态分析工具来获得驻留在 APK 中的一些硬编码 API 端点。
有一些镜像网站,例如APKPure:https://apkpure.com/ ,我们可以将APK下载到我们的机器上,以便用分析工具打开它。建议使用静态和动态分析来映射应用程序发送的每个调用,使用 MobSF 等工具也非常有效。
MobSF 是一种自动分析工具,它获取 APK 文件并构建有关文件内部结构的报告:
从报告中,我们可以获得一些硬编码的 URL 和域,可以帮助我们更全面地了解目标的 API 。
总结
当我们测试 API 时,我们必须充分了解应用程序的工作原理、它提供的功能以及我们可用的整个表面。通过使用上述方法,我们将彻底构建应用程序的形象,并为测试不同应用程序的 API 奠定良好的基础。
测试 API 有时更像是一项研究,我们必须使用不同的工具、资源甚至手动技术才能发现它的每一个部分。如果我们长期关注某个目标(几周或几个月),我们可能会看到它的 API 随着时间的推移而变化和增长,而测试它们的最佳时机是当它们是全新的或仍处于未公开状态时。
申明:本账号所分享内容仅用于网络安全技术讨论,切勿用于违法途径,所有渗透都需获取授权,违者后果自行承担,与本号及作者无关,请谨记守法。