前言:渗透中的“山重水复”
渗透测试常如迷宫探索——看似死路时,一个微小细节的突破可能打开全新攻击面。本文复盘一次对某业务系统(http://www.xxxx.com/#/login)的授权渗透过程:从登录页的僵局,到前端代码的蛛丝马迹,最终通过接口协议层的认知差突破未授权访问。整个过程印证了“漏洞常生于逻辑边界的模糊地带”这一安全箴言。
0x01 初探:常规手法的全面溃败
弱口令爆破:
- 尝试admin/admin123、test/123456等常见弱口令组合,系统返回“账号或密码错误”且触发5分钟锁定策略。
登录绕过的尝试:
- 修改Cookie中的authenticated=false为true → 服务端校验失效;
- 删除身份校验参数 → 302重定向至登录页;
- 添加X-Forwarded-For头伪造IP → 无权限响应
目录扫描的失望:
- 使用目录扫描,返回大量404,仅暴露/robots.txt、/static/等非敏感路径
这里不一一列举了
此时结论: 统入口点均被加固,需转向非常规攻击面。
0x02 转机:前端代码的“宝藏地图”
在浏览器按F12调出开发者工具,发现前端仅加载两个JS文件:
- vendor.js(第三方库)
- index.js(业务核心代码)
关键发现:
在index.js中定位到多个API接口,如下:
突破思路: 未授权接口可能因开发环境残留、权限校验遗漏而暴露。
0x03 自动化:高效碰撞接口的武器
尝试拼接其中一个接口,返回异常,无数据
如果手工测试多个接口效率极低,无需多言,直接编写正则脚本提取所有/api/路径,生成api_list.txt,这里我用的是python
import reimport sysimport jsondef extract_paths(js_content):"""从JavaScript代码中提取所有以/开头或./开头的路径"""# 模式1: 匹配"/..."形式的路径(带变量处理)pattern1 = r'["\'](\/(?:[^"\'\/\n]|\/[^"\'\/\n])+?)[\'"]'# 模式2: 匹配"./..."形式的路径pattern2 = r'["\'](\.\/(?:[^"\'\.\/\n]|\/\.[^"\'\.\/\n])+?)[\'"]'# 模式3: 匹配模板字符串中的路径pattern3 = r'`(\/(?:[^`\n\\]|\\.)+?)`'pattern4 = r'`(\.\/(?:[^`\n\\]|\\.)+?)`'# 组合模式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('"\'') # 移除尾部引号# 处理变量:将${variable}替换为{variable}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>")print("Example: python extract_paths.js app.js")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}")# 保存到JSON文件(用于程序分析)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))print(f"\n结果已保存到:\n- {js_file}_paths.json\n- {js_file}_paths.txt")except Exception as e:print(f"错误: {e}")sys.exit(1)if __name__ == '__main__':main()
Burp Intruder批量拼接:
- 通过index.js文件发现基本使用的请求方法是GET和POST
- 加载字典,对每个接口发送GET/POST双请求;
GET请求

POST请求

初始结果GET返回Not Found,POST返回400 Bad Request,本以为要结束这次渗透时,发现有个接口引起了我注意!
GET请求显示请求资源不存在,GET请求显示请求处理失败

分析复盘: 根据这个接口初步分析服务器可能以JSON解析数据,服务器可能默认按 application/x-www-form-urlencoded(表单键值对)或 text/plain(纯文本)解析,导致 JSON 数据被误判为乱码或无效格式
0x04 决胜点:JSON格式的“钥匙”
OK调整攻击策略: 请求头加上
Content-Type: application/json
重新拼接: 有接口返回不一样的字段长度,查看数据包发现泄露数据!,存在大量业务人员的信息,包括名字,手机号等一些信息!!
至此渗透结束,漏洞成因,接口未实施身份校验,且依赖前端传递JSON格式,服务端未严格验证调用来源
结语
本次渗透的核心突破点在于前端代码暴露接口+协议层格式认知差。攻击者常因开发环境的配置差异(如测试接口未移除)、权限校验的疏忽(如仅依赖前端鉴权)得手。安全是持续对抗的过程。每一次“山穷水尽”的背后,可能隐藏着未被细察的突破口——这正是渗透测试的魅力与价值所在。
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf
客服小蜜蜂(微信:freebee1024)




重新拼接:
有接口返回不一样的字段长度,查看数据包发现泄露数据!,存在大量业务人员的信息,包括名字,手机号等一些信息!!

至此渗透结束,漏洞成因,接口未实施身份校验,且依赖前端传递JSON格式,服务端未严格验证调用来源