渗透测试之API测试技巧

1. 可预测性旧版API

若API形式为:/api/v3/login,那么可尝试/api/v2/login/api/v1/login等。

2. 语义相似性

若API形式为:/api/mobile/login,那么可尝试/api/phone/login/api/wx/login等,再比如download_receiptexport_receipt等。

3. 不安全的直接对象引用(IDOR)

比如如下JSON Response

1
{"user_id":233,"nickname":"w2n1ck","phone":"15566668888"}

那么可尝试:

1
2
3
4
5
6
GET /api/user/{user_id} //查询用户
GET /api/user/{orther_user_id} //查询其他用户
POST /api/user/{user_id} //修改用户信息
PUT /api/user/{user_id} //修改用户信息
POST /api/user //创建新用户
DELETE /api/user/{user_id} //删除用户

4. 命令注入

在Ruby on Rails App的情况下,如果开发人员使用了Kernel#open函数的话,使用1管道符测试命令注入

5. 根据返回包判断对象属性

比如更新某功能时

1
2
3
PUT /api/videos/233
{"name":"my_video","format":"mp4"}

但是在其他接口可能会有该对象的其他属性

1
2
3
GET /api/my_videos
{[{"id":233,"file_name":"my_video.mp4","path":"/my_video/path/"}]}

尝试添加隐藏属性

1
2
3
PUT /api/videos/233
{"name":"my_video","format":"mp4","path":"/my_video/path/../../evil/path"}

6. 平台不一致性

若web端限制较严格,可以尝试在app端测试

7. REST API & SOAP API

对于Rest API可以修改Content-Typeapplication/xml,并在body中添加xml代码,看是否会有错误产生。

8. header & body

http body / header 中的参数比url中的参数更容易受到攻击。

9. JWT

如果API使用JWT验证,那么CSRF就无法利用了。

10. UUID

即使id是UUID或其他非数字字符串,也要尝试发送一个数字值,比如使用/user/detail?userId=1替换/user/detail?userId=616d6bad-536e-44bb-9bf5-05042c9bffe8

11. 集群绕过

如果不同业务功能被分配到了不同的集群机器上,那么可能导致绕过。

1
2
3
# 修改密码为例
POST /api/reset_pass //需要旧密码
PUT /api/update_user //添加reset_pass中的参数可能直接就修改密码了

12. 子域名

不同子域名可能使用同一套API,可尝试在其他子域名测试。比如admin.w2n1ck.com,可尝试admin-api.w2n1ck.comadmin-api-v1.w2n1ck.com

13. 静态资源

由于大部分系统对静态资源的处理方式不同,所以静态资源很容易出现越权等问题。

14. 客户端

如果最新的APP无法找到突破口,可尝试下载旧版的客户端程序。

15. API重要程度

开发者可能对比较重要的接口做的防护更加完善,多留意一些不重要的API。

16. 非生产环境

开发者对于一些重要接口可能会做一些频次等限制,但是非生产环境可能就没这些限制措施。

17. 前端

前端js、webpack可能包含了大量API接口及参数。

18. 白盒审计

若通过某种途径获取到dll,jar,rar等源码,可通过反编辑等手段,阅读源码在源码中找API。

19. 导出功能

若API存在导出功能,比如导出PDF,可尝试注入特定的HTML代码。

20. 属性变形

1
2
3
4
5
6
7
8
# 数组
{"id":111} --> {"id":[111]}
# Json
{"id":111} --> {"id":{"id":111}}
# 参数污染
id=111&id=222
# 通配符
{"id":"*"}

21. XSS防护

如果响应包是Content-type: application/json,就不要考虑XSS攻击了。

22. 参数组合

.net应用可能会使用Path.Combine(path_1,path_2)来组合参数,将两者连接起来得到一个完整的路径。web 应用程序的上下文中,第一个参数通常是指向图像或用户文档存储位置的绝对目录路径, 第二个参数通常是用户控制的,那么在某种程度上,如果参数path_2是绝对路径,则忽略参数path_1。

参考文章:

https://github.com/smodnix/31-days-of-API-Security-Tips/blob/master/README.md

https://apidock.com/ruby/Kernel/open

https://www.praetorian.com/blog/pathcombine-security-issues-in-aspnet-applications

https://medium.com/@inonst/a-deep-dive-on-the-most-critical-api-vulnerability-bola-1342224ec3f2

大爷,赏个铜板呗!