多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

14行日志识别三种Web攻击:SQL注入、XSS与目录遍历分析实战

14行日志识别三种Web攻击:SQL注入、XSS与目录遍历分析实战 1. 拿到陌生日志先别慌着“找病毒”这个场景要先讲清楚。Day 31 的练习题目是一句话陌生日志 14 行三种攻击自己认。什么意思呢就是别人丢给你一份日志文件没有上下文、没有告警提示、没有攻击 IP 清单就 14 行。你要自己判断这份日志里有没有问题如果有有几种攻击怎么认出来的这其实是安全分析里的一项基本功。很多人觉得日志分析就是拿工具扫一遍或者用 SIEM 平台的告警规则跑一下但在实际工作中你一定会遇到没有规则覆盖、没有上下文支撑的“裸日志”。这时候唯一能靠的就是你的眼睛和分析思路。14 行日志虽然数据量小但信息密度高非常适合练手——它逼着你把每一步判断从“凭感觉”变成“按特征走”。这篇文章适合谁正在学网安分析入门的人、刚接手安全运维的新人、以及想从“看流量”过渡到“看日志”的测试同学。文章会带你走完一遍完整的分析流程先讲方法论再拆三种攻击在日志里的特征然后逐行过那份 14 行日志最后讲坑。读完你能自己动手去翻日志而且知道自己每一步在做什么。2. 攻击者一定会留下痕迹关键是你认得出哪些痕迹2.1 为什么攻击一定会在日志里留痕先说一个基本认知任何对 Web 应用的攻击本质上都是一次 HTTP 请求或者一系列 HTTP 请求。而 Web 服务器默认就会把请求记录下来——时间、来源 IP、请求行、状态码、响应大小、Referer、User-Agent这些字段构成了访问日志。有的新手会问那攻击者不能抹掉日志吗理论上可以但在实际中攻击者往往没有 Web 服务器的写权限或者根本没有意识到自己的扫描行为已经被记录了。就算他在事后清了系统日志他在 Web 层发出的请求也已经存在了而且 Web 日志的清理权限通常和 Web 服务运行用户绑定不是那么容易拿到的。所以访问日志是安全分析里非常可靠的第一现场。还有一点要注意日志体系是分层的。Web 访问日志只管 HTTP 请求应用日志记录业务逻辑数据库有慢查询日志和二进制日志操作系统有安全的登录日志。一条完整的攻击链路往往会跨多层但在 Day 31 这个阶段先练好 Web 访问日志这一层把攻击请求从正常流量里挑出来是最基础也最实用的一步。2.2 第一类攻击SQL注入的日志指纹SQL 注入的攻击原理这里不展开讲重点说它在日志里的模样。SQL 注入是把数据库查询语句的片段塞进请求参数里目的是让后端拼接出来的 SQL 改变语义。那日志里的参数位置就会出现一些“不像正常业务数据”的内容。最常见的指纹有单引号在 URL 里编码成%27是 SQL 注入最典型的信号因为单引号在 SQL 语句里是字符串的边界符正常业务参数几乎不会出现它。恒真/恒假条件AND 11、OR 11、OR 11这类表达式目的是让 where 条件永远成立。联合查询关键字UNION SELECT为了把目标表的查询结果并进当前查询从而拖出其他表的数据。注释符--、#、/*用来截断原 SQL 的后半部分。延时函数SLEEP(5)、BENCHMARK(10000000,MD5(1))这类属于时间盲注通过响应时间判断注入点是否存在。举个例子日志里出现这样一行GET /product.php?id1%27%20OR%20%271%27%3D%271 HTTP/1.1百分号解码之后是/product.php?id1 OR 11。这一眼就可以高度怀疑 SQL 注入。判断的时候记住一个原则看参数值是否出现“数据库语义”。普通商品 ID、搜索关键词、用户昵称都不会包含 SQL 关键字和单引号一旦出现就要重点标记。2.3 第二类攻击XSS的日志指纹XSS 跨站脚本和 SQL 注入的区别在于语义不同。SQL 注入是往数据库语句里塞内容XSS 是往浏览器解析的 HTML/JavaScript 里塞内容。所以 XSS 的日志指纹主要看有没有“浏览器会执行的标签和事件”。常见指纹标签script、img、svg、iframe、a等。在 URL 里通常被编码为%3C和%3E。事件处理器onerror、onload、onclick、onmouseover。攻击者最常用的是onerroralert(1)因为只要图片加载失败就会触发。伪协议javascript:尤其是在iframe、a标签的 src 或 href 里。常见的反射点参数搜索框的q、keyword、search这类参数最容易出现 XSS 尝试因为开发者经常把用户输入直接回显到页面里。在日志里长这样GET /search?q%3Cscript%3Ealert(1)%3C/script%3E HTTP/1.1解码后是/search?qscriptalert(1)/script。看到尖括号加标签名XSS 的优先级就要拉满。判断 XSS 时要和 SQL 注入区分开如果参数值是script、事件属性、javascript:这一类优先想到 XSS如果参数值是单引号、UNION SELECT、SLEEP()这类优先想到 SQL 注入。2.4 第三类攻击目录遍历/路径穿越的日志指纹目录遍历攻击也叫路径穿越的思路更“野”它不去改参数而是直接攻击 URL 里的路径部分通过../跳出 Web 根目录去读服务器上的敏感文件比如/etc/passwd、/etc/shadow、Windows 下的win.ini、应用配置里的web.config。日志指纹路径里直接出现连续的../比如GET /../../../../etc/passwd。URL 编码变体%2e%2e%2f解码是../、%2e%2e/混用、..%2f混用。双重编码%252e%252e%252f这种是为了绕过一次解码的防护。目标文件典型/etc/passwd、/etc/shadow、/windows/win.ini、WEB-INF/web.xml、.git/config。User-Agent 异常大量目录遍历扫描都来自脚本工具比如python-requests、curl、sqlmap而不是真实浏览器。可以这样理解正常用户是在商场的楼层里逛走的路径是“楼层号/店铺号”目录遍历攻击是沿着楼梯往地下车库钻还一路往上试想把整栋楼的档案室门都踹开。日志里看到的../越多说明他走得越深。3. 14行日志逐行过完整分析实操3.1 先把14行日志摊开为了演示方便我用标准 Nginx 日志格式构造了一份练习样本共 14 行。你可以复制到编辑器里跟着思路自己走一遍192.168.1.105 - - [31/Oct/2024:09:12:18 0800] GET / HTTP/1.1 200 4521 - Mozilla/5.0 (Windows NT 10.0; Win64; x64) 192.168.1.105 - - [31/Oct/2024:09:12:20 0800] GET /css/style.css HTTP/1.1 200 2891 http://example.com/ Mozilla/5.0 (Windows NT 10.0; Win64; x64) 192.168.1.105 - - [31/Oct/2024:09:12:22 0800] GET /js/app.js HTTP/1.1 200 8733 http://example.com/ Mozilla/5.0 (Windows NT 10.0; Win64; x64) 203.0.113.44 - - [31/Oct/2024:09:14:01 0800] GET /product.php?id1%20AND%2011 HTTP/1.1 200 4521 http://example.com/product.php Mozilla/5.0 203.0.113.44 - - [31/Oct/2024:09:14:03 0800] GET /product.php?id1%27%20OR%20%271%27%3D%271 HTTP/1.1 200 4521 http://example.com/product.php Mozilla/5.0 203.0.113.44 - - [31/Oct/2024:09:14:05 0800] GET /product.php?id1%20UNION%20SELECT%20username,password%20FROM%20users HTTP/1.1 500 0 http://example.com/product.php Mozilla/5.0 203.0.113.44 - - [31/Oct/2024:09:14:06 0800] GET /product.php?id1%20AND%20SLEEP(5) HTTP/1.1 200 4521 http://example.com/product.php Mozilla/5.0 198.51.100.77 - - [31/Oct/2024:09:16:42 0800] GET /search?q%3Cscript%3Ealert(1)%3C/script%3E HTTP/1.1 200 5121 http://example.com/search Mozilla/5.0 (Windows NT 10.0; Win64; x64) 198.51.100.77 - - [31/Oct/2024:09:16:44 0800] GET /search?q%3Cimg%20srcx%20onerroralert(1)%3E HTTP/1.1 200 5121 http://example.com/search Mozilla/5.0 (Windows NT 10.0; Win64; x64) 198.51.100.77 - - [31/Oct/2024:09:16:46 0800] GET /search?qjavascript%3Aalert(document.cookie) HTTP/1.1 200 5121 http://example.com/search Mozilla/5.0 (Windows NT 10.0; Win64; x64) 198.51.100.77 - - [31/Oct/2024:09:16:48 0800] GET /search?q%22%3E%3Csvg%20onloadalert(1)%3E HTTP/1.1 200 5121 http://example.com/search Mozilla/5.0 (Windows NT 10.0; Win64; x64) 192.0.2.10 - - [31/Oct/2024:09:20:15 0800] GET /../../../../etc/passwd HTTP/1.1 404 153 - python-requests/2.31.0 192.0.2.10 - - [31/Oct/2024:09:20:17 0800] GET /%2e%2e/%2e%2e/%2e%2e/etc/passwd HTTP/1.1 403 0 - python-requests/2.31.0 192.0.2.10 - - [31/Oct/2024:09:20:19 0800] GET /static/..%2f..%2f..%2fwindows/win.ini HTTP/1.1 404 153 - python-requests/2.31.0这 14 行如果直接扔给新手很多人会把每个字段都从头读到尾然后越看越慌。实际上不用这样一步一步来。3.2 第一遍扫读先把正常流量挑出去拿到日志的第一件事不是逐行分析而是做“分层”。从时间戳看这批日志集中在 09:12 到 09:20 之间大约 8 分钟时间跨度很短。从来源 IP 看一共有 4 个 IP192.168.1.105、203.0.113.44、198.51.100.77、192.0.2.10。这说明访问来自四个不同的客户端天然就可以按 IP 分组来观察行为模式。先看192.168.1.105的三行请求路径是/、/css/style.css、/js/app.js这是典型的打开首页并加载静态资源的顺序。时间连续、请求路径正常、UA 是 Windows ChromeReferer 是首页地址。这三行可以直接判定为正常流量不用再纠结。再看另外三个 IP就明显不是正常浏览行为了。203.0.113.44连续请求同一个接口/product.php参数 id 的值越来越奇怪198.51.100.77盯着/search的参数 q 反复测试192.0.2.10的请求连路径都歪了直接往etc/passwd和win.ini方向走。到这里已经被分成了“正常加三类可疑”的格局。3.3 逐IP核对三种攻击的认领过程现在进入逐行核验阶段重点是解码参数、对照特征、确认攻击类型。先看203.0.113.44这 4 行。第一行id1%20AND%2011%20是空格解码后是id1 AND 11这是 SQL 注入最经典的恒真条件探测。第二行id1%27%20OR%20%271%27%3D%271解码后是id1 OR 11单引号和 OR 条件一起出现SQL 注入的置信度直接拉满。第三行id1%20UNION%20SELECT%20username,password%20FROM%20users解码后是id1 UNION SELECT username,password FROM users这是联合查询注入试图拖取 users 表的账号密码字段。第四行id1%20AND%20SLEEP(5)解码后是id1 AND SLEEP(5)典型的时间盲注。这 4 行连起来看攻击者走的是一条完整的探测链路先试恒真条件再试闭合单引号然后尝试 UNION 注入拖数据最后用延时函数做时间盲注。四条全部指向同一个参数 id攻击类型可以确认是 SQL 注入而且手法比较熟练不是随手乱扫的脚本。接着看198.51.100.77这 4 行。第一行q%3Cscript%3Ealert(1)%3C/script%3E解码后是qscriptalert(1)/script标准的反射型 XSS 探针。第二行q%3Cimg%20srcx%20onerroralert(1)%3E解码后是img srcx onerroralert(1)用图片加载失败触发事件。第三行qjavascript%3Aalert(document.cookie)解码后是javascript:alert(document.cookie)尝试通过伪协议读取 Cookie。第四行q%22%3E%3Csvg%20onloadalert(1)%3E解码后是svg onloadalert(1)通过闭合 HTML 属性来逃逸上下文。这 4 行的共同点是全部围绕/search的 q 参数而且 payload 全部是浏览器端语义——标签、事件、伪协议。可以确认是 XSS 注入尝试。注意这里所有请求都返回 200说明服务端正常处理了搜索请求但有没有把脚本原样回显到页面并执行日志看不出来需要后续到浏览器里验证。最后看192.0.2.10这 3 行。第一行路径是/../../../../etc/passwd裸的../序列目标直指 Linux 账户文件。第二行/%2e%2e/%2e%2e/%2e%2e/etc/passwd%2e%2e解码后是..这是 URL 编码变体。第三行/static/..%2f..%2f..%2fwindows/win.ini把斜杠编码成%2f目标换成了 Windows 下的win.ini说明攻击者在同时探测不同平台的目标文件。这 3 行的共同点是路径中出现多点../或编码..目标都是服务器系统文件而且 UA 是python-requests/2.31.0根本不是浏览器。综合判断是目录遍历/路径穿越攻击。这里两个请求返回 404一个返回 403说明服务端配置拦截了一部分但没有完全拦截住所有变体需要继续查后续日志确认有没有成功读取。3.4 三看三对照14行日志的分析结论把三组结论汇总之后就非常清晰了来源IP目标参数/路径特征关键词判定结果203.0.113.44/product.php?idAND 11、单引号、UNION SELECT、SLEEPSQL注入198.51.100.77/search?qscript标签、onerror、javascript:、svgXSS192.0.2.10/etc/passwd、/win.ini../、%2e%2e、..%2f目录穿越整个分析过程其实就是“三看”看 IP 行为是否连贯、看参数值是否有数据库语义或浏览器语义、看路径和 UA 是否偏离正常用户。你不需要记住每一个 payload只要抓住“数据语义”这个核心三种攻击自己就认出来了。4. 新手最容易翻车的4个日志分析误区4.1 误区一看到百分号编码就当成攻击这个坑在带新人的时候见过太多次。URL 里有%20、%3C、%3E不代表一定是攻击因为正常业务也会对特殊字符做 URL 编码。比如用户搜索“书籍 ”前端很可能就会把编码成%3C提交。单一百分号编码不是攻击特征关键要看编码后的内容是什么语义。%3Cscript%3E是危险的因为解码出来是 HTML 标签%E4%B9%A6只是“书”这个汉字的 UTF-8 编码完全正常。实操建议分析前先把参数值解码再判断内容语义不要看着一长串百分号就紧张。4.2 误区二把状态码当唯一判断标准新手特别容易得出结论说“返回 200 说明攻击成功返回 404 说明攻击失败”。这是错的。状态码只能说明 Web 服务器当时怎么响应的不能说明应用内部逻辑发生了什么。举个例子SQL 注入的UNION SELECT请求返回 500可能说明 SQL 语法被数据库拒绝但也可能是后端代码抛了异常这两者的安全后果完全不同。XSS 的请求如果返回 200只是说明搜索服务响应正常脚本是否被回显和执行日志里根本看不到。目录穿越返回 403可能是 WAF 拦截也可能是业务路径本身就存在 403 权限控制。状态码要结合响应内容、响应大小、后续请求一起来看单看状态码会得出很多错误结论。4.3 误区三只盯Web访问日志标题里的场景是 Web 访问日志但实际攻击往往会在多个日志层面留下痕迹。SQL 注入如果成功数据库的慢查询日志、错误日志里可能有记录如果攻击者下载了敏感文件应用日志或对象存储的访问日志里也可能有对应的下载记录XSS 如果成功回显之后攻击者可能会带着窃取的 Cookie 再发请求这个后续请求会出现在访问日志里但要靠时间线关联才能发现。所以建议是分析访问日志发现问题后不要停在 Web 层继续去翻应用日志、数据库日志、系统安全日志形成完整的时间线。4.4 误区四忽略User-Agent的判断价值这次样本里目录穿越的 UA 是python-requests/2.31.0这是脚本工具的特征。虽然攻击者可以伪造 UA但大多数自动化扫描器为了省事不会伪造所以 UA 在日志分析里是一个非常有用的初筛信号。看到python-requests、curl、sqlmap、nikto、masscan这类 UA即使请求看起来正常也应该提高警惕。不过要注意UA 只能作为辅助判断不能单独当成攻击证据。有些攻击者会故意伪造成 Chrome 的 UA尤其是有经验的攻击者。UA 异常是“加分类条件”不是“定罪条件”。5. 日志分析之后的动作从识别到处置5.1 确认攻击影响五步走识别出三种攻击之后不能只写一份分析报告就完事还要做影响确认。建议按五步走按来源 IP 查全量日志把几个可疑 IP 在这个时间段前后的所有请求全部拉出来确认看到的 14 行是不是全部有没有遗漏的更早尝试或后续动作。验证参数是否被回显对于 XSS到前端页面里手动验证一下搜索框是否把 q 参数的值原样输出到 HTML对于 SQL 注入拿注入点在测试环境复现一次确认能不能拖出数据。查数据库慢查询日志如果 SQL 注入成功数据库一定有异常查询记录重点是执行时间异常长或返回结果量异常的语句。核实敏感文件是否被读取目录穿越请求虽然大多返回 404/403但如果业务系统确实存在可穿越的漏洞要检查服务器上对应文件的访问时间以及有没有外传迹象。形成时间线和整改建议把所有相关日志按时间顺序排出来写清攻击入口、利用方式、影响范围给开发一份修复建议。5.2 建立自己的日志特征速查表经过这个练习应该积累一套属于自己的攻击特征速查表。不用一开始就做大而全从最常遇见的开始攻击类型日志中的特征信号重点关注位置SQL注入单引号、AND/OR、UNION SELECT、SLEEP/BENCHMARK、注释符参数值XSS尖括号、script/img/svg标签、onerror/onload事件、javascript:伪协议参数值目录穿越连续../、%2e%2e、%2f、/etc/passwd、/win.ini、WEB-INF请求路径扫描探测高频请求、夸张UA、大量404、短时间遍历多个路径IP行为、UA这套表可以写在笔记里也可以做成监控规则。如果你在用 ELK 或者 Loki 做日志集中管理可以把这些特征转成正则表达式或查询语句做成告警规则。比如 Loki 采集 Web 日志后用一条包含UNION SELECT的查询语句就能把 SQL 注入的日志筛出来。集中化日志平台的真正价值就在这里当你积累了几十上百条特征规则后14 行日志去人工识别的工作量就可以变成系统自动给你推送的告警。5.3 从人工分析到自动化规则的过渡建议这个练习做完之后很自然会想到一个问题以后日志量大了不能每次都靠人肉看。这时候再考虑自动化。但自动化一定要建立在人工分析经验的基础上因为你得先知道攻击长什么样才能写出规则。我的建议是这样的节奏先用纯人工方式分析完至少 10 份陌生日志样本把每次识别的过程记录下来然后从中提炼高频特征写成简单的过滤规则再把这些规则放在测试环境里跑一遍看看有没有误报和漏报最后才部署到生产环境的监控平台。直接拿着一份现成的规则集套用很容易出现两种情况——规则太严格导致大量误报或者规则太宽松导致真实攻击被放过去。只有自己亲手分析过的特征你才知道它到底可靠不可靠。6. 写下这篇分析之后的体会6.1 从14行日志到更多日志的关键一步这个 Day 31 的练习虽然只有 14 行但分析流程完全可以复用到几十万行的日志上先分层、再分组、然后对可疑部分逐行解码核对。我自己带新人时的要求是这 14 行日志不要用任何工具纯靠眼睛和文本编辑器完成等流程熟练了再引入工具效果会好很多。6.2 保留一份自己的“攻击样本库”最后分享一个个人习惯我会把每次分析日志时遇到的典型攻击请求脱敏后保存成一个样本库按攻击类型分目录每一条都标注当时的识别依据和结论。这个样本库比任何教程都有用因为它是你亲手分析出来的。遇到陌生日志时先在自己的样本库里搜一遍特征大多数情况都能找到相似的案例。三种攻击自己认的能力就是这么一点点积累起来的。
返回列表