原文:
https://bendtheory.medium.com/finding-and-exploiting-unintended-functionality-in-main-web-app-apis-6eca3ef000af
把上篇文章提到的放在一起+攻击!
使用上述技术的组合,你肯定会收获一些有价值的API目标,支持在主web应用程序中嵌入的应用程序。
下面是两个真实的单页应用程序的例子,这些应用程序都是由api支持的,我在入侵一个私有程序时发现了一些漏洞。我已经为这个目标工作了近一年,通过重复和试验这些技术,我仍然在寻找新的漏洞。
例1 - IDOR泄露用户配置文件数据
1. 在一个大型burp项目中,我能够使用burplist.py脚本导出一个包含超过100k个独特单词的定制单词列表
2. 我启动ffuf开始brute强迫这个新单词列表,很快被Akamai阻止
3. 为了继续扫描,我发现了一个西班牙语网站的生产镜像,它没有受到Akamai的保护,并继续进行。在这里寻找使用“origin”一词的域名也很有效。
4. 一个有趣的词触发了302响应,并提示进行身份验证。这与https://example.com/MyExampleApp类似
5. 我导航到URL,登录,然后被重定向到类似https://example.com/MyExampleApp/dashboard的地方
6. BurpJSLinkFinder在https://example.com/MyExampleApp/resources/scripts/main.js上发现了一个JS文件,其中包含许多链接,其中很多都是以/api开头的
50 — /api/Account/Login
51 — /api/Account/LogOut
52 — /api/Account/Token
53 — /api/Account/CreateProfile
54 — /api/Account/GetProfile
55 — /api/Account/DeleteProfile
56 — /api/Account/UpdateProfile?
57 — /api/Account/UpdateUserPreferences?
7. 在检查main.js中的代码时,上面的每个url似乎都是从代码片段中提取的,就像这样
this.baseUrl = "/MyExampleApp"
login = function(content) {
var url = this.baseUrl + "/api/Account/Login";
var body = {
body: JSON.stringify(content),
};
return this.http.request("post", url, body)
}
8. 查看我的代理历史显示,一些API请求已经启动,以初始化应用程序。
237 https://www.example.com POST /MyExampleApp/api/Account/Login
238 https://www.example.com GET /MyExampleApp/api/Account/Token
9. 我向burp发送了其中一个POST请求(带有JSON正文),并将有效负载位置设置为基本API URL。我加载了BurpJSLinkFinder找到的所有API端点作为有效负载,并开始了攻击。

10. 我忽略了404个响应,并专注于405个不允许的方法、400个错误请求和200个OK响应。
11. GetProfile端点返回一个400响应,内容如下:
{"error":{"code":123,"message":"Invalid userName value"}}
12. 现在我知道,可能需要一个名为userName的JSON参数来从API检索信息。
13. 把我的用户名放在username返回了我自己的个人资料信息,但然后我需要找到另一个用户名是使用应用程序泄露信息。
14. 从这里开始,我通过混合和匹配第一个首字母和一个常见的姓来强制使用burp的用户名。我使用了两个有效载荷列表,a-z和SecLists中的common-surnames.txt
15. 在几百个请求之后,burp发现有些响应时间比其他请求长,我成功地泄漏了有效用户名的PII !
16. 从这里开始,我用有效的用户名在其他API端点上重新运行了相同的攻击,以发现其他泄漏和升级影响
我因为这个漏洞得到了1000美元的赏金。
例2 - API信息公开升级到管理员权限
1. 当我查看Burp的被动捕获的站点地图为我的目标的主要web应用程序,我遇到这样一个端点:https://www.example.com/xyzadmin/home
2. “xyz”是我以前见过的另一个产品的首字母缩写,但我没有见过这个管理后台。
3. 当我导航到这个页面时,它是空的,没有有趣的内容。然而,BurpJSLinkFinder完全点亮了!它在一个名为main.js的javascript文件中发现了超过450个url
4. 有许多有趣的端点需要寻找和测试,但有几个让我眼前一亮:
328 — /xyzadmin/api/Users/showUsers
329 — /xyzadmin/api/Users/showAdmins
5. 直接导航到这些端点完全符合我的预期,它们向我显示了整个应用的所有用户和所有公司管理员的JSON对象!
6. 我有一个简单的高严重的漏洞坐在那里,但我肯定这可能成为一个关键的挖掘。
7. 在再次查看BurpJSLinkfinder转储文件时,我发现了另一个有趣的端点:/xyzadmin/api/Users/AddOrUpdateAdmin……
8. 因为我已经从上面的/showAdmins端点泄露了表示“Admin”用户的JSON对象,所以我知道我需要发送POST请求到/AddOrUpdateAdminto升级权限:
{
"admins": [
{
"0": {
"email": "",
"firstName": null,
"lastName": null,
"userName": "admin",
"phoneNumber": "",
"password": null,
"userRole": "admin",
"id": "deadbeef-6969-f420-e911-cafebabe",
"active": true,
"type": "Admin"
}
}, {
"1": {
"email": "",
"firstName": null,
"lastName": null,
"userName": "admin2",
"phoneNumber": "",
"userRole": "admin",
"password": null,
"id": "deadbeef-aced-bead-baff-12345678",
"active": true,
"type": "Admin"
}
}
]
}
9. 所以现在我已经大致了解了应该在请求中发送的数据,但是我仍然不知道最终的请求主体是什么样子的。
10. 回头看看javascript文件,我发现了一个函数定义,它提供了关于请求结构的一些答案。以下是高度精简和清晰的:
function createAdmin(){
var adm = new Admin()
adm.userName = this.newUserNameValue
adm.userRole = "Admin"
var body = new postBody({
user: adm,
modifiedBy: this.loggedInUser
})
this.client.AddOrUpdateAdmin(n)
}
10. 从这段代码中,我推断出创建一个新管理员的JSON post体应该是这样的:
{
"user": {
"email": "",
"firstName": null,
"lastName": null,
"userName": "bendtheory",
"phoneNumber": "",
"userRole": "admin",
"password": null,
"id": "deadbeef-aced-bead-baff-87654321",
"active": true,
"type": "Admin"
},
"modifiedBy": "bendtheory"
}
11. 在Repeater选项卡中,我创建了一个POST请求到/xyzadmin/api/Users/AddOrUpdateAdmin,发送它,并得到了一条消息{"success":true,"message":"OK"}
12. 然后我重新加载了/xyzadmin/主页,我可以访问所有的东西。我可以添加,删除,修改任何用户在整个应用程序。
api无处不在,尤其是在最杂乱的Burp项目中。在发现这两个错误的同一个程序上工作了将近一年之后,我仍然在寻找新的有趣的api,这些api充斥着idor、信息披露和越权漏洞。
本文迁移自知识星球“火线Zone”