JSON格式的胜利:一次未授权接口的曲折发现之旅
字数 1565 2025-09-01 11:26:10
JSON格式的胜利:未授权接口发现与利用技术详解
前言:渗透测试中的思维突破
渗透测试往往如同迷宫探索,当常规路径受阻时,需要转换视角寻找非常规突破口。本文详细解析一次通过前端代码分析和协议层认知差发现未授权接口的完整过程,展示了现代Web应用安全测试中的关键技术和思维方法。
0x01 初始侦察与常规测试
1.1 目标系统初探
- 目标系统:
http://www.xxxx.com/#/login - 登录页面为单页应用(SPA)架构,采用前端路由(#/形式)
1.2 常规渗透手法尝试
1.2.1 弱口令爆破
- 尝试组合:admin/admin123、test/123456等常见凭证
- 系统响应:
- 明确返回"账号或密码错误"
- 触发5分钟账户锁定策略
- 结论:爆破防护机制完善
1.2.2 Cookie篡改测试
- 修改
authenticated=false为true→ 服务端校验有效 - 删除身份校验参数 → 302重定向至登录页
- 添加
X-Forwarded-For头伪造IP → 无权限响应
1.2.3 目录扫描
- 工具:常规目录爆破工具
- 结果:
- 大量404响应
- 仅暴露非敏感路径:
/robots.txt/static/
- 结论:入口点加固良好
0x02 前端代码分析突破
2.1 前端资源分析
- 开发者工具(F12)检查:
- 主要加载两个JS文件:
vendor.js(第三方库)index.js(业务核心代码)
- 主要加载两个JS文件:
2.2 关键接口发现
在index.js中发现多个API接口路径,例如:
/api/user/list
/api/auth/check
/api/data/export
2.3 突破思路形成
- 未授权接口可能来源:
- 开发环境残留接口
- 权限校验遗漏接口
- 测试阶段未删除接口
0x03 自动化接口提取与测试
3.1 接口路径提取脚本
import re
import sys
import json
def extract_paths(js_content):
"""从JavaScript代码中提取所有以/开头或./开头的路径"""
# 模式1: 匹配"/..."形式的路径(带变量处理)
pattern1 = r'["\'](/[^"\'\s]+)["\']'
# 模式2: 匹配"./..."形式的路径
pattern2 = r'["\'](\.[^"\'\s]+)["\']'
# 模式3: 匹配模板字符串中的路径
pattern3 = r'`([^`]+)`'
# 模式4: 匹配require/import中的路径
pattern4 = r'(?:require|import)$?["\']([^"\')]+)["\']$?'
combined_pattern = f'({pattern1})|({pattern2})|({pattern3})|({pattern4})'
paths = set()
for match in re.finditer(combined_pattern, js_content):
for i in range(1, 5):
path = match.group(i)
if path:
clean_path = re.sub(r'\\{1,2}', '', path) # 删除转义字符
clean_path = clean_path.rstrip('"\'').lstrip('"\'') # 移除引号
clean_path = re.sub(r'\$\{([^}]+)\}', r'{\1}', clean_path) # 处理模板变量
paths.add(clean_path)
return sorted(paths, key=lambda x: (not x.startswith('/'), x))
def main():
if len(sys.argv) < 2:
print("Usage: python extract_paths.py <js_file>")
sys.exit(1)
js_file = sys.argv[1]
try:
with open(js_file, 'r', encoding='utf-8') as f:
js_content = f.read()
paths = extract_paths(js_content)
print(f"从{js_file}中提取了{len(paths)}个路径:")
for i, path in enumerate(paths, 1):
print(f"{i:4d}. {path}")
with open(f"{js_file}_paths.json", 'w', encoding='utf-8') as f:
json.dump(paths, f, indent=2, ensure_ascii=False)
with open(f"{js_file}_paths.txt", 'w', encoding='utf-8') as f:
f.write('\n'.join(paths))
except Exception as e:
print(f"错误: {e}")
if __name__ == '__main__':
main()
3.2 脚本功能详解
- 多模式匹配:支持四种常见路径格式
- 路径清洗:处理转义字符、引号和模板变量
- 结果输出:同时生成JSON和TXT格式结果
3.3 批量接口测试
- 工具:Burp Suite Intruder
- 方法:
- 对每个接口发送GET/POST双请求
- 初始响应:
- GET返回404 Not Found
- POST返回400 Bad Request
- 异常发现:特定接口响应不同
0x04 协议层突破:JSON格式的胜利
4.1 问题分析
- 服务器可能以JSON解析数据
- 默认Content-Type导致解析失败:
application/x-www-form-urlencodedtext/plain
4.2 关键调整
- 请求头添加:
Content-Type: application/json - 请求体保持JSON格式
4.3 成功利用
- 特定接口返回异常长度
- 数据泄露内容:
- 业务人员信息
- 包含姓名、手机号等敏感数据
0x05 漏洞成因分析
-
身份校验缺失:
- 接口未实施服务端身份验证
- 仅依赖前端鉴权
-
协议层缺陷:
- 服务端未严格验证调用来源
- 依赖前端传递JSON格式
-
开发遗留问题:
- 测试接口未移除
- 环境配置差异导致
0x06 防御建议
6.1 接口安全加固
-
统一鉴权:
- 服务端强制身份验证
- 采用JWT或Session令牌
-
输入验证:
- 严格验证Content-Type
- 强制要求特定头部
6.2 开发规范
-
接口管理:
- 生产环境移除测试接口
- 接口文档与实现一致
-
安全测试:
- 自动化接口扫描
- 未授权访问测试
6.3 监控与响应
-
异常请求监控:
- 记录非常规Content-Type请求
- 监控敏感接口访问
-
应急响应:
- 敏感数据泄露预案
- 快速修复机制
结语:安全是持续对抗的过程
本次渗透的核心价值在于:
- 前端代码分析:暴露潜在攻击面
- 协议层认知差:发现非常规突破点
- 自动化工具:提升测试效率
安全防御需要从开发到运维的全生命周期关注,每一次"山穷水尽"都可能隐藏着未被细察的突破口,这正是安全工作的挑战与魅力所在。