网站漏洞扫描的第一步,不是上来就用工具乱扫,而是先确认你的站点指纹。所谓指纹,就是服务器跑的是什么Web容器、什么后端语言、用了哪些开源CMS或框架。直接看HTTP响应头,Server字段有时候会直接出卖Nginx版本,X-Powered-By可能暴露PHP版本。如果这些头被隐藏了,用Wappalyzer这类浏览器插件也能抓出前端框架和JS库。更隐蔽的指纹藏在静态资源路径里,比如看到/wp-content/就知道是WordPress,看到/sites/default/files/大概率是Drupal。指纹不清,漏洞检测就是瞎猫碰死耗子。
被动式信息收集:不碰服务器也能挖出的致命隐患很多站长以为不扫自己的站就没事,其实搜索引擎缓存和公共档案馆里藏着一大堆敏感信息。直接在搜索引擎里搜site:你的域名 filetype:sql,看看有没有数据库备份文件被索引。再搜site:你的域名 inurl:admin,看后台入口是不是裸露在外。更狠的是搜site:你的域名 intitle:"index of",这能找出目录浏览漏洞,服务器上的文件目录结构一览无余。还有GitHub和GitLab上的代码仓库,搜一下域名或者公司名,经常能发现程序员不小心提交上去的数据库密码、API密钥和内部文档。这些信息一旦被利用,根本不需要什么高级攻击手段,直接就能长驱直入。
SQL注入检测:别再相信单引号报错那套老黄历了现在绝大多数SQL注入点都不会傻傻地弹个数据库错误给你看。盲注才是主流。检测数字型参数时,在参数后面加and 1=1和and 1=2,看两次返回的页面内容长度、响应时间或者HTTP状态码是否有差异。如果参数是字符串型,用单引号闭合测试,但别指望报错,要观察页面是否出现内容缺失、空白或者跳转。时间盲注更隐蔽,在参数后拼接and sleep(5)-- ,如果服务器真的卡了5秒才响应,那这个注入点就坐实了。用sqlmap跑的时候别上来就--risk=3 --level=5,那等于在服务器上放鞭炮,先用手工确认注入类型,再逐步提高检测强度,既精准又低调。
XSS漏洞挖掘:输入框不是唯一攻击面别只盯着搜索框和留言板。URL里的参数、HTTP Referer头、User-Agent头,甚至文件上传时的文件名,都可能是反射型XSS的触发点。测试payload不要只会用<script>alert(1)</script>,现在很多WAF已经把这个当儿歌一样拦截了。换成<img src=x onerror=alert(1)>或者<svg onload=alert(1)>,绕过概率大得多。DOM型XSS更隐蔽,需要读前端JavaScript代码,找那些把location.hash或document.referrer直接写进innerHTML的地方。存储型XSS的检测要特别注意富文本编辑器,很多编辑器看似过滤了标签,但用大小写混合或者嵌套标签就能绕过,比如<scr<script>ipt>这种经典套路在某些老版本里依然有效。
文件上传漏洞:从后缀名校验到内容欺骗的攻防博弈文件上传点的检测要分三步走。第一步看前端,浏览器F12打开开发者工具,找到上传表单的accept属性,如果只限制了.jpg和.png,直接改成.php试试。第二步看后端对文件后缀的处理,上传一个test.php.jpg,看服务器是取最后一个后缀还是第一个。如果遇到黑名单过滤,试试.php5、.phtml、.phar这些冷门后缀。第三步看文件内容校验,有些服务器会读文件头判断类型,那就把PHP一句话木马写在图片文件的尾部,用copy /b image.jpg + shell.php merged.jpg命令合成,上传后配合文件包含漏洞去执行。还有更绝的,直接上传.htaccess文件,把.jpg后缀映射为PHP解析,这样任何图片都能变成后门。
命令注入与代码执行:参数污染带来的连锁反应凡是系统命令执行函数出现在代码里的地方,都是高危区。PHP里的system()、exec()、passthru()、shell_exec(),Python里的os.system()、subprocess.call(),只要参数里有用户可控的输入,就存在命令注入风险。检测时在参数后面拼接管道符和常见命令,比如| ls、|| dir、&& whoami。如果应用对管道符做了过滤,试试换行符%0a或者反引号。代码执行漏洞更可怕,PHP里的eval()和assert()是重灾区,如果发现参数被直接拼进eval里,尝试注入phpinfo(),能执行就说明代码执行漏洞存在。老版本的ThinkPHP和Struts2框架,某些特定路由天生就带着命令执行的后门,指纹识别阶段如果确认了框架版本,直接上对应的EXP验证就行。
权限绕过与越权检测:水平越权比垂直越权更难防垂直越权就是普通用户干了管理员的事,检测方法很直接,用普通用户Cookie去访问管理员专属的接口,看能不能成功。水平越权更隐蔽,比如修改URL里的用户ID参数,看能不能看到别人的订单、个人信息或者私信。检测时准备两个同权限级别的账号A和B,登录A之后,把涉及资源ID的参数改成B的ID,如果返回了B的数据,水平越权就坐实了。批量检测可以用Burp Suite的Intruder模块,把ID参数设成变量,从1遍历到1000,看返回包里有没有敏感信息。很多API接口虽然做了前端权限控制,但后端根本没校验当前用户是否有权访问该资源,这种漏洞一抓一大把。
快速修复:从漏洞确认到上线热补丁的黄金四小时漏洞确认后别急着改代码,先评估影响范围。查日志,看这个漏洞有没有被利用过的痕迹。SQL注入点查数据库慢查询日志,文件上传漏洞查服务器最近新增的可执行文件,命令注入查shell历史记录。确认没被入侵后再动手修。修的时候遵循最小改动原则,能加一层过滤就别动底层逻辑。SQL注入的根治方法是参数化查询,把所有拼接SQL的地方改成预编译语句。XSS的修复核心是输出编码,根据上下文选择HTML实体编码、JavaScript编码或者URL编码。文件上传漏洞最稳妥的方案是重命名文件,用随机字符串做文件名,后缀强制白名单,文件存在专门的静态资源服务器上,关闭脚本执行权限。命令注入的修复是把用户输入从命令参数中剥离,用数组方式传参,避免拼接字符串。
临时防御策略:WAF规则的自定义与精准拦截如果代码修复需要排期,先上WAF规则顶住。但别用通用规则,那误报率太高。针对刚发现的SQL注入点,写一条只拦截该接口、该参数、特定payload特征的规则。比如参数id里出现select加from的组合,就在那个接口上临时拦截。文件上传漏洞的临时规则是禁止该上传目录执行任何脚本,在Nginx里加一条location规则,对该目录下的所有文件直接返回403。同时开启该目录的访问日志详细记录,监控后续有没有人尝试访问上传的文件。如果是命令注入,在WAF层面拦截管道符、分号、反引号等特殊字符,但只针对存在漏洞的那个URL参数,避免影响其他正常业务。
源码审计与自动化扫描的结合:让工具做苦力,让人做判断自动化扫描器跑出来的报告,至少有一半是误报。拿到报告后第一件事不是挨个修,而是按漏洞类型分类,然后手工验证。验证时先看漏洞所在的URL和参数,结合业务逻辑判断是否真的存在风险。比如扫描器报了一个反射型XSS,但那个参数是前端用来做页面跳转的redirect参数,实际利用需要用户点击链接,危害等级就要降一降。反过来,如果扫描器没报,但代码审计发现某个文件包含函数的参数来自用户输入,这就是个定时炸弹。代码审计时重点关注include()、require()、unserialize()这些危险函数,跟踪它们的参数来源,看是否经过过滤。反序列化漏洞的检测要构造POP链,这需要深入理解目标框架的对象结构,工具很难自动完成,必须人工分析。
日志监控与入侵检测:修完漏洞后的持续观察漏洞修复上线不代表万事大吉。在修复后的至少一周内,密切监控相关接口的访问日志。看有没有人还在尝试用老payload攻击,如果有,说明攻击者手里有你的漏洞信息,需要溯源排查。同时检查服务器进程列表和计划任务,防止攻击者在你修漏洞之前就已经植入了后门。重点关注那些名称看起来像系统进程但路径异常的进程,以及crontab里新出现的定时任务。Webshell的检测可以用find命令搜索最近修改的PHP、JSP、ASPX文件,结合关键字搜索,比如eval、base64_decode、system等函数在文件中的出现频率。如果条件允许,部署文件完整性监控工具,对Web目录下的文件增删改进行实时告警。
纵深防御体系的构建:单点修复不如体系加固每次漏洞修复都是一次加固整个防御体系的机会。把这次漏洞的成因抽象出来,看看是开发规范的问题,还是框架配置的问题,或者是服务器权限管理的问题。如果是开发规范缺失,就在代码提交前加一道自动化安全扫描,把常见漏洞拦在测试环境。如果是框架配置不当,就整理一份安全配置基线,所有新项目必须按基线配置。服务器层面,Web容器运行账号的权限要降到最低,只给Web目录的读权限,上传目录的写权限,其他目录一概禁止访问。数据库账号按需授权,前端展示用的数据库连接只给SELECT权限,后台管理才给写权限。应用层、中间件层、系统层三层权限隔离,就算某一层被突破,攻击者也寸步难行。
漏洞检测和修复从来不是一次性的工作,而是持续对抗的过程。精准检测靠的是对业务逻辑的深入理解和手工验证的耐心,快速修复靠的是对系统架构的熟悉和应急响应的流程。把每次漏洞当成一次压力测试,修一个漏洞,补一片短板,安全水位才能逐步抬升。
