news 2026/10/21 17:41:07

App渗透测试实战:SQL注入与人脸识别逻辑绕过登录任意账号

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
App渗透测试实战:SQL注入与人脸识别逻辑绕过登录任意账号

做App渗透测试这几年,我见过不少有意思的漏洞,但这个案例值得单独拿出来聊聊:一个带人脸识别登录的App,攻击链路竟然是SQL注入换数据,再抓住人脸识别接口的校验缺陷,最终成功登录任意账号。整个过程不算花哨,但每一个环节都踩在常见的业务逻辑盲区上。如果你也负责移动端安全测试,或者正在开发带生物识别登录的App,这篇应该能给你一些实打实的参考。

先说清楚背景:这是一次有授权书的渗透测试,目标是某公司自己的业务App,测试范围限定在登录、注册、人脸识别相关接口,没有碰其他系统。安全测试的底线是授权,没有授权任何人都不该去“试”别人的系统。下面所有操作都基于这个前提展开。

1. 渗透测试前的思考与测试范围界定

1.1 为什么App渗透和Web渗透不一样

很多人觉得App渗透就是把Web测试那套搬到手机上,其实差别不小。Web端你直接面对一个浏览器,参数都在URL和请求头里,改起来直观。App端多了一层客户端,很多校验被挪到了前端逻辑里,服务端反而成了“睁眼瞎”。

这次测试的第一个感受就是:抓包拿到的请求远没有Web端那么“干净”。App会把一些参数加密,或者把关键状态放在本地数据库里,我们不仅要在后端找漏洞,还得分析客户端逻辑。特别是人脸识别这类功能,如果服务端不校验结果,客户端就敢“骗”自己。

1.2 本次测试的目标资产与授权边界

目标是一个模拟的金融类App,名字就不提了,我们内部叫它“模拟项目X”。测试前已经确认了三件事:

  1. 授权方是系统所有者,测试范围覆盖Android端和对应的服务端API。
  2. 只测试登录、注册、人脸识别相关的接口,不深入业务数据。
  3. 测试过程中涉及的数据全部脱敏,不下载、不传播真实用户信息。

这个边界很重要。渗透测试最怕的就是“测着测着跑偏”,拿到数据库就开始翻全表。我的习惯是:先明确要验证的核心风险链路,其他区域一律不碰。这次的链路很清晰——先看登录接口有没有注入,再看人脸识别有没有逻辑漏洞,最后验证是否能登录任意账号。

2. 从登录接口找到SQL注入

2.1 登录请求的正常流程

目标App的登录流程是:输入手机号和密码,点击登录,客户端把数据提交到/api/login接口,服务端验证成功后返回一个包含Token和用户信息的JSON。整个流程和主流App没什么区别。

我先打开抓包工具,配置好代理,然后正常登录一次,把请求报文记录下来。登录接口的参数大概是这个样子的:

POST /api/login HTTP/1.1 Host: app-api.example.com Content-Type: application/json {"phone":"13800138000","password":"e10adc3949ba59abbe56e057f20f883e"}

注意那个password,看起来像是MD5。App在客户端先把密码做了一次哈希再传给服务端,这种做法本身没问题,但服务端如果直接用这个哈希去拼接SQL,问题就来了。

2.2 用常规手段探测注入点

我习惯先从参数最“诚实”的开始试探。所谓“诚实”,就是不带任何恶意前缀,只观察普通请求和异常请求的响应差异。第一步,我把phone字段改成一个不存在的号码,看看返回什么;第二步,在号码后面加一个英文单引号,看看会不会报错。

加了单引号之后,服务端返回了一个500错误,响应体里还带了一长串类似数据库驱动的错误信息。到这一步,基本可以确定这个参数存在SQL注入,而且属于拼接型注入。数据库类型从错误信息里的关键词能看出来,应该是MySQL。

接下来要做的是确认注入类型。我分别试了布尔盲注和时间盲注:把条件改成恒真和恒假,响应内容有明显差异;在条件里加上SLEEP函数,响应时间会延迟。这就让我多了一个更可靠的信息通道——即使页面不直接回显数据,也能通过响应时间和布尔差异一点点抽出数据库里的内容。

关于工具,这里不推荐直接用自动化注入工具一把梭。手动确认一次请求如何返回差异,能帮你判断WAF策略和过滤规则。如果是纯手测,至少这一步能让你理解漏洞成因。

2.3 确认注入类型与数据库信息

通过布尔盲注和时间盲注的组合,我很快确认了以下信息:

信息项确认结果
数据库类型MySQL
注入参数phone
注入类型拼接型,非数字型 -- 均以文本形式直接拼入SQL
可用输出通道布尔差异、时间延迟

这里有个容易被忽略的地方:手机号参数在服务端即使有正则校验,如果校验的是“长度范围”而不是“字符白名单”,单引号一样能传进去。很多开发者会在一开始加一道“是否以数字开头”的判断,但忘了校验后续字符,结果照样被注入。

确认了这些之后,后面的利用就顺理成章了。

3. 基于注入结果的分析与利用

3.1 获取敏感数据

拿到了注入点,我按顺序做了三件事:查当前数据库名、查表名、查关键表结构。整个过程用了经典的information_schema查询,但具体payload这里就不展开了。重点说说查到了什么。

数据库里除了常规用户表,还有一张专门存储人脸特征开关的表。里面有一个字段叫face_enabled,控制某个用户是否需要走人脸识别验证。手动在数据库里看到这个字段的那一刻,我就意识到这条漏洞链不只是“拿到账号”这么简单,它很可能和人脸识别绕过直接联动。

用户表里的数据倒没有让我太意外:手机号、昵称、密码哈希、以及一个会话状态字段。密码哈希不是明文,但格式很老,用的是不带盐的MD5。这种哈希在今天的算力下基本等于裸奔,不过我没有去暴力破解,因为后续测试根本不需要真实密码。

3.2 为什么密码哈希不能直接用

有人可能会问:既然数据库密码哈希都拿到了,为什么不直接登录,还要费劲绕人脸识别?这里有个技术细节。

这个App的登录逻辑分为两步:第一步是账号密码校验,服务端检查哈希是否匹配,匹配后不直接发Token,而是返回一个“待验证”状态,要求客户端继续调用人脸识别接口完成第二因子验证。第二步校验通过后才发真正的登录凭证。

所以就算我把密码哈希改成另一个人的,或者直接去掉密码校验条件,服务端也会在第二步把人脸识别接口拦住。也就是说,光是SQL注入还不足以让我登录成功,必须接着解决人脸识别那关。

3.3 发现关键字段:人脸识别状态标识

深入看接口文档和客户端代码后,发现了一个更尴尬的设计:人脸识别流程里,服务端只认一个名为faceVerifyStatus的字段,客户端把这个字段从0改成1,服务端就认为人脸验证通过。

这个字段在数据库里也有一份,但服务端判断的时候没有去查数据库,而是直接信任客户端上传的JSON字段。同时,SQL注入查到的face_enabled字段,本身也只是用来在前端控制要不要弹出人脸识别框,服务端并未做二次校验。

到这里,整个攻击链路的逻辑已经闭环了:

  1. 通过SQL注入获取任意用户的手机号、密码哈希、以及人脸识别开关状态。
  2. 通过修改登录请求里的手机号模拟任意用户,配合直接改数据库里的密码哈希?其实不用改数据库,因为服务端校验时用的是客户端传过去的密码哈希对比数据库,如果我们把请求里的password改成目标用户数据库里的MD5哈希,理论上就通过了第一步。
  3. 在第二步人脸识别请求里,把faceVerifyStatus改成1,骗过服务端。
  4. 拿到正式的登录Token,成功登录目标账号。

这个链条的技术门槛其实不高,但每个环节都精准踩中了服务端“过度信任前端”的通病。

4. 绕过人脸识别并成功登录APP

4.1 人脸识别验证的两种实现方式

抛开这个案例,目前主流App的人脸识别登录大概分两种架构:

  • 服务端校验:客户端把人脸照片传给服务端,服务端调用人脸识别引擎完成比对,返回“通过/不通过”,并记录本次验证流水号。这种架构下,客户端很难篡改结果,因为服务端自己就是裁判。
  • 前端校验:人脸识别SDK在客户端本地完成活体检测和人脸比对,比对通过后SDK返回一个结果对象,客户端再把结果提交给服务端。如果服务端不校验这个结果的真伪,只判断结果里的状态字段,那就是漏洞。

“模拟项目X”属于第二种,而且连结果签名都没有。也就是说,前端SDK返回的结果完全可以被手动改成“验证通过”。严格说,这已经不是“绕过人脸识别算法”,而是绕过了服务端的人脸识别逻辑。

4.2 实战绕过的思路解析

我没有去破解人脸识别SDK,也没有试图伪造人脸图像,只是利用抓包工具拦截了人脸验证完成的提交请求。请求里大概长这样:

POST /api/face/verify Host: app-api.example.com {"faceVerifyStatus":0,"userId":"10086"}

我把faceVerifyStatus改成1,其他参数保持不变,放行这个请求。服务端收到后,直接返回了“验证成功”,紧接着下发登录Token。整个过程不到五秒,绕过成功。

这里有一个值得思考的细节:我并没有把数据库里的face_enabled改成0,虽然我可以通过SQL注入做到这件事。这既是为了控制影响范围,也说明这个漏洞的根本原因不在数据库状态,而在于服务端没有独立验证人脸识别结果。就算我把所有用户的face_enabled都改成0,攻击者依然可以自己构造一个faceVerifyStatus=1的请求通过登录。

绕过成功后,我用该测试账号登录App首页,截了一张图留作证据,然后立刻退出,没有做任何进一步操作。测试报告里也只描述了“可以登录任意被锁定人脸验证的用户”,而没有扩大利用范围。

4.3 登录成功后的操作边界

渗透测试和真实攻击的分水岭在哪?就在拿到权限之后的“下一步”。真实攻击者可能会继续翻通讯录、查交易记录、甚至横向打后台;但作为测试人员,我的目的是证明业务风险,不是赚钱。

所以我强烈建议每一个安全测试者在做这类验证时,给自己立一条铁律:拿到登录凭证、看一眼证明能访问页面,就收手。需要更深入验证漏洞影响时,也只在测试账号自己的数据范围内操作。别用漏洞去读取真实用户的信息,更别把别人数据截图发到群里炫耀。这是职业底线。

5. 遇到的高频问题与排查心得

5.1 常见问题表格:注入不成功、人脸识别绕过无效等

问题现象可能原因排查思路
加了单引号没报错服务端做了转义或过滤换布尔盲注,观察恒真和恒假条件响应差异
时间盲注速度太慢每条请求都在外部等待延时控制SLEEP参数,用二分法缩短次数
拿到密码哈希却不能登录密码哈希可能加盐或服务端另有校验先看客户端提交格式,对照数据库哈希格式,还可能是二次校验
修改faceVerifyStatus没生效服务端有签名校验或流水号校验检查请求里是否还有verifyId之类字段,需要一并伪造
抓不到App的HTTPS流量未安装抓包工具证书,或开启SSL Pinning使用支持SSL Pinning绕过的Hook方案,具体根据目标环境决定

这些经验不是一次性得来的,踩过的坑多了,就习惯了。

5.2 实测中的三个关键经验

第一,SQL注入探测别死磕一个参数。我在手机号参数上试了很多次都没反应,以为是误报,后来把手机号、密码、验证码三个参数都加单引号测试,才最终锁定手机号参数。原因是密码参数在客户端已经被MD5处理,特殊字符根本带不到服务端。

第二,时间盲注的延时配置一定要合理。我一开始用SLEEP(5),单次请求要等五秒,加上网络延迟,拖慢了整个测试节奏。后来改成SLEEP(1),并且每个条件只做三次对比,准确度反而更高。时间盲注不是延时越长越精准,而是刚好能区分真假响应就行。

第三,绕过逻辑漏洞前先搞清楚整个业务链路。我在测人脸识别绕过时,一开始只改了faceVerifyStatus,但服务端返回“参数缺失”。翻了下正常流程的请求日志,发现还需要带上客户端生成的bizToken。后来我把正常请求和篡改请求放在一起对比,找到那个缺失字段,才成功过关。逻辑漏洞利用,往往是“差一个字段就通”。

6. 修复建议与安全加固

6.1 SQL注入修复

这个问题的修法不复杂,但需要覆盖到所有查询路径。

  1. 服务端使用参数化查询或预编译语句,避免字符串拼接SQL。
  2. 对手机号参数增加严格白名单校验,前端校验不算数,服务端必须做。
  3. 关闭数据库报错信息输出,避免攻击者通过错误堆栈判断数据库类型。
  4. 定期审计数据库账号权限,业务库账号不要用高权限账号连接。

如果我建议只挑一条最优先落地,那就是参数化查询。它可以从根上让SQL注入消失,而不是靠过滤黑名单去补漏洞。黑名单总有绕过方法,参数化没有。

6.2 人脸识别逻辑修复

这里要说一句得罪人的话:凡是人脸识别能通过改状态字段绕过的,基本都是架构问题,不是SDK质量问题。

正确做法是人脸识别结果必须由服务端自己产生,或者至少由服务端验证结果签名。如果用人脸识别SDK,也必须开启服务端验证模式,把识别结果提交到服务端进行二次确认,并使用防篡改签名。

更进一步的建议是引入一次性会话ID。用户在人脸识别前,服务端下发一个随机会话ID,人脸识别结果必须绑定这个ID,并且服务端校验ID的使用状态和使用次数。这样即使攻击者伪造结果,也无法绕开会话ID的关联性。

6.3 测试过程中的合规提醒

再重申一次:这篇文章里的所有操作,都只能在明确授权的测试环境中进行。开发人员在自己公司系统上做安全测试,也需要提前拿到书面授权,别因为目标是自己公司的就觉得没问题。出去接私活或帮朋友“看看系统”,没有授权书一律拒绝。

安全测试的目的是帮助系统更安全,不是展示攻击能力。我一直觉得,一个合格的渗透测试者,应该在交付漏洞报告时附带修复方案,而不是只扔一个“漏洞存在”的报告。推动修复落地,比炫耀技术更难,也更有价值。

说回这个项目,让我印象最深的不是SQL注入有多深,也不是人脸识别绕过有多巧妙,而是很多App开发团队在赶进度时,把“客户端的人脸识别通过”当成了“服务端的人脸识别通过”。这种信任错位,才是安全漏洞真正滋生的土壤。希望这篇记录能让你在设计自己的App时,少踩一次这个坑。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/21 17:39:24

基于LSTM-Adaboost的配电网短期负荷预测Matlab实现

最近在做一个配电网的短期负荷预测项目,数据预处理、特征工程折腾了一圈,最后在预测模型上卡住了。试过传统的ARIMA、支持向量回归,效果怎么说呢,能用,但总觉得差点意思。后来把LSTM和Adaboost结合起来搞了一套混合模型…

作者头像 李华
网站建设 2026/10/21 17:39:23

汇川H3U多轴混控模板设计:3步进3伺服CANlink总线与触摸屏配方实战

很多同行看到“汇川H3U 三个步进 三个伺服,伺服还走CANlink”这种组合,第一反应就是程序会不会很乱:步进要发脉冲,伺服要写总线,触摸屏还要来回切画面,一套下来光地址规划就够头疼的。这套配置我前后做过…

作者头像 李华
网站建设 2026/10/21 17:38:51

多智能体+行业工作台:可嵌入业务系统的AI协作框架

1. 项目概述:这不是一个“AI插件”,而是一套可嵌入业务流程的智能协作系统“开源了!给业务装上 AI 团队:MyCoWork 的多智能体与行业工作台”——这个标题里藏着三个被多数人忽略的关键判断点:第一,“装上”…

作者头像 李华
网站建设 2026/10/21 17:38:37

AI CRM销售话术生成能力榜单:原圈科技领衔的五大选型维度

1. 2026年AI CRM赛道:为什么“会说话”突然成了基本功今年的CRM市场有一个明显变化:客户不关心你的系统里存了多少条数据,只关心你能不能把数据变成“人话”。过去我们选CRM,看的是字段配置、流程审批、商机阶段这些老四样&#x…

作者头像 李华
网站建设 2026/10/21 17:38:25

DeepSeek Harness桌面端:本地化AI工作流的可信实践

1. 这不是又一个“桌面客户端”,而是本地化AI工作流的真正起点“DeepSeek Harness 桌面端来啦!更便捷更安全的选择”——看到这个标题,我第一反应不是点开下载,而是停顿了三秒。不是因为怀疑技术能力,而是因为过去三年…

作者头像 李华