网络分析工具:NetCat

https://fastly.jsdelivr.net/gh/techkoala/techkoala.github.io@master/images/Network/NetCat/netcat.webp
网络瑞士军刀 —— NetCat

简单来说,NetCat (nc) 是一个命令行工具,能够让你很方便、很灵活地操纵 传输层协议(TCP & UDP)

nc 可以在两台设备上面相互交互,即侦听模式/传输模式

nc 包含以下主要功能:

  • Telnet 功能
  • 获取 banner 信息
  • 传输文本信息
  • 传输文件 / 目录
  • 加密传输文件,默认不加密
  • 远程控制
  • 加密所有流量
  • 流媒体服务器
  • 远程克隆硬盘

一般来说,nc 的命令行包括如下几个部分:

1
nc 命令选项 主机 端口

本文内容基于 OpenBSD 社区的变种(也叫 OpenBSD netcat,部分命令与原版有差异。 )

下面列举了一些常用选项,更多选项参见 OpenBSD manual page

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
选项	   是否有 “选项值”	   说明
-h	   NO	           输出 nc 的帮助
-v	   NO	           在网络通讯时,显示详细的输出信息
-n	   NO	           对命令行中的主机,不进行域名解析,如果主机是 IP 地址,需要用该选项
-p	  YES	           指定端口号
-l	  NO	           开启监听模式,nc 作为服务端,如不加,nc 默认作为客户端
-u	  NO	           使用 UDP 协,如不加该选项,默认是 TCP 协议
-w	  YES	           设置连接的超时间隔(N 秒)
-q	  YES	           让 nc 延时(N 秒)再退出
-z	  NO	           开启 zero-I/O 模式,该选项仅用于端口扫描
-k	  NO	           配合 -l 选项使用,可以重复接受客户端连接
-X	  YES	           指定代理的类型
-x	  YES	           以 IP:port 的格式指定代理
-d    NO               后台模式

这部分可以没有,可以以 IP 地址 形式表示,也可以以 域名 形式表示。

这部分可以没有,可以是单个端口,可以是端口范围。

经常有这种需求,要判断某个主机的监听端口是否能连上。导致监听端口无法连接,通常有两种原因:

  1. 监听端口没开启
  2. 监听端口虽然开启,但是被防火墙阻拦了

对第 1 个原因,(如果你能在该主机上运行命令)可以直接用 netstat 这个命令查看监听端口是否开启;但对于第 2 个原因,netstat 就用不上了,这时候就可以用 nc 来帮你搞定。

用如下命令可以测试某个 IP 地址上的某个监听端口是否开启:

1
nc -nv ip port

注: 默认情况下 nc 会等待很久,然后才告诉你连接失败。如果你所处的网络环境稳定且高速(比如:局域网内),那么,你可以追加 -w 选项,设置一个比较小的超时值。在下面的例子中,超时值设为 3 秒。

1
nc -nv -w 3 ip port

假设你正在配置防火墙规则,禁止 TCP 的 8080 端口对外监听。那么,你如何验证自己的配置生效?

为了叙述方便,设想如下场景: 有两台主机 ——主机 C 充当客户端,主机 S 充当服务端。 然后要判断主机 S 上的防火墙是否会拦截其它主机对 8080 TCP 端口的连接。

主机 S 上运行 nc,让它在 8080 端口,命令如下:

1
nc -lv -p 8080

然后在 “主机 C” 上运行 nc,测试 “主机 S” 上的 8080 端口是否可达

注: 在默认情况下,nc 开启 listen 模式充当服务端,在接受第一次客户端连接之后,就会把监听端口关闭。如果你想要让 nc 始终监听模式,使之能重复接受客户端发起的连接,可以追加 -k 选项。

下面这个命令,用来扫描的端口范围从 1 到 1024

1
nc -znv ip 1-1024

选项 -z 是指开启 zero-I/O 模式。该模式 nc 只判断某个监听端口是否能连上,连上后与对端进行数据通讯。

**注:**端口扫描的时候,-v 选项会把成功/失败的结果统统打印出来。通常关注的都是 “扫描成功” 的那些端口。因此,可以用可以配合使用 grep 过滤一下,只打印扫出来的端口

1
nc -znv ip 1-1024  2>&1 | grep succeeded

此外,由于 -v 选项产生的输出位于 stderr,上述命令中的 2>&1 用来把 stderr 合并到 stdout

另: nc 默认超时较大,导致扫描速度较慢。建议根据网络情况合理设置超时值,加快扫描速度。

如果某个服务器运行了 SSH 服务端,那么用如下命令可以看出:该服务器的操作系统类型,以及 SSH server 的版本。

1
2
3
echo "EXIT" | nc -vq 5 -n ip 22
OR
echo "EXIT" | nc -vq 5 domain 22

用 nc 进行端口转发,需要运行两个 nc 进程,一个充当服务端,另一个是客户端,然后用管道让把两个进程的标准输入输出``交叉配对。所谓的交叉配对就是——每一个 nc 进程的标准输出都对接到另一个 nc 进程的标准输入。如此一来,就可以完美地建立双向通讯。

步骤 1:创建命名管道

用下面这个简单的命令创建一个 “命名管道”,其名称叫做 nc_pipe

1
mkfifo nc_pipe

步骤 2:同时启动两个 nc

1
nc -l -p 1234 < nc_pipe | nc 127.0.0.1 5678 > nc_pipe

运行上述命令之后,就可以把本机的 1235 端口重定向到本机的 5678 端口。

为了叙述方便,假设你有两台主机 A 与 B,你要把 A 主机上的文件 file1 传输到 B 主机上,保存为 file2

1
2
3
4
5
先在接收端 B 主机运行如下命令
nc -l -p port > file2

然后在发送端 A 主机运行如下命令
nc ip port < file1

两者端口号要相同

假设你要把 A 主机 /dev/sda 磁盘的原始数据整个复制到 B 主机的 /dev/sdb 磁盘。

1
2
3
4
5
先在接收端(B 主机)运行如下命令
nc -lp port | dd of=/dev/sdb

然后在发送端 A 主机运行如下命令
dd if=/dev/sda | nc ip port

将 A 主机的 bash 发给 B 主机

1
2
3
4
5
A:
nc -lp port -c bash

B:
nc ip port
1
2
3
4
5
A:
cat test.mp4 | nc -lp port

B:
nc -nv ip port | mplayer -vo x11 -cache 4000

A 让 test.MP4 这个文件成为的形式发送到 B,B 用 mplayer 播放,接收多少播放多少,指定缓存 4000bytes。

收集目标机上的进程信息

1
2
3
4
5
nc -l -p port > ps.txt
将远程发送过来的内容保存在本地

Ps aux |nc -nv ip port -q 1
标准输入完成后 delay 一秒钟,会发送到侦听端