一个请求要穿过五层:漏洞到底从哪一层长出来
你点提交的时候,以为你在做一件事。
实际上你做的是:让一串字符,从浏览器出发,穿过五道关卡,最后落到某一台机器的某一层。
漏洞不在任何一道关卡上。
漏洞是这条路的某一环,有人少写了一行校验。
浏览器 → Nginx → 后端程序 → 数据库 → 系统内核

五层各做什么
第一层 浏览器。 你敲进输入框的东西,在这里被编码、打包、带上请求头发出。前端的校验都在这一层,但前端的校验不防攻击者——攻击者不走浏览器。
第二层 Nginx 或其他反向代理。 它做三件事:解析 HTTP、决定转给哪个后端、做一次粗粒度过滤。它看不懂业务,只看得懂协议。
第三层 后端程序。 拿参数、做校验、拼逻辑、调数据库。这一层是业务校验的主战场,也是绝大多数漏洞的出生地。
第四层 数据库或其他后端服务。 它收到的是一段要执行的指令。它不区分"这是用户的值"和"这是程序的指令"。
第五层 内核。 进程、文件、socket 都在这里,最终落到 openat、execve、connect。
每一层都在假设上游是干净的
Nginx 假设 HTTP 报文是合法的。后端假设 Nginx 过滤过了。数据库假设后端给的是安全的语句。内核假设应用只做该做的事。
每一层都在假设,每一层都没有验证。
假设链条上任何一环破了,后面的层来不及反应,因为它们不知道前面破了。
三个漏洞,三种漏法
SQL 注入,漏在第四层。
数据库收到的那条语句里,你输入的值被当成了语法的一部分。数据库没有被骗,它是严格按语法执行的,只不过这段语法是攻击者写的。
根在第三层:后端把值和指令拼在了一起。
SSRF,漏在第三层到第五层之间。
后端拿到你给的 URL,没有限制目标地址,直接让内核去 connect。第三层少了一个校验,第五层就真的去连了。
文件上传,漏在第五层。
文件落到某个目录,如果那个目录被解析执行,execve 就发生了。第三层的后缀校验形同虚设,因为真正决定"这个文件会不会被执行"的,是第五层的运行时配置。
判断的落点是那一层
看到一个现象,先问它落在哪一层。
能返回数据但碰不到别人的数据,是第三层的业务校验没拦住,但数据层还有隔离。能读到文件内容,是第五层的权限和路径校验失效。能执行命令,说明已经穿过第五层,天花板在 uid 上。
定级看链的终点,不看起点。
同一个注入点,能查自己的订单是现象;能查别人的订单是漏洞;能读文件、能执行命令是接管。
你怎么用这条链
下次遇到一个接口报错,或者一个参数能注入,别急着写 payload。
先画出这条链:这个参数从哪进来,经过哪几层,到哪一层会被谁处理。
找到那一层少写的那行校验,比找到 payload 更有用。 payload 是这一层的产物,校验才是根。
仅限授权测试,严禁非法滥用。
读到这里,说明你在认真看。加入社群,与我们一起深挖底层。
或点此直接进入「星巡底层研习」 →
扫码加入交流社群