netcat,简写为 nc,是 unix 系统下一个强大的命令行网络通信工具,用于在两台主机之间建立 TCP 或者 UDP 连接,并提供丰富的命令进行数据通信。nc 在网络参考模型属于应用层。使用 nc 可以做很多事情:建立连接,发送数据包,监听端口,扫描端口,处理 ip4 和 ip6,和 telnet 不同,nc 会区分错误输出和标准输出,telnet 则都是标准输出。
nc 强大之处在于输出是标准输出(stdout), 输入来自标准输入(stdin), 以至于可以很容易通过管道和重定向直接使用或被其他程序和脚本调用。正因为它的这种特性, 以至于你能发挥你的想象力用它做很多事情:
使用 nc 可以非常简单的构建一个基本的客户端/服务端模型。
首先在一个终端窗口,开启一个本地端口的监听。
nc -l 1234
现在 nc 就在监听 1234 端口,等待一个连接。再另开一个控制台(或另一台主机),使用 nc 连接该主机和端口。
nc 127.0.0.1 1234
这样,连接就已经建立起来了,默认是 TCP 连接,现在在任意一个控制台输入内容,另一个控制台都会收到,此时,nc 已不关心谁是客户端,谁是服务端了。
上面的例子,再扩展一下,就可以构建一个数据传输模型。
nc 在开启了端口监听后,将收到的内容输出到指定文件
nc -l 1234 > out.txt
在第二个机器(或控制台)上,连接该主机和端口,并向该主机传输文件
nc 127.0.0.1 1234 < in.txt
与 www.baidu.com 的 80 端口建立一个 TCP 连接
nc www.baidu.com 80
此时,仅仅是建立了一个 TCP 连接,本地的端口号是随机的。
也可以指定端口,使用 nc -p 1234 www.baidu.com 80 ,即采用本地 1234 端口与百度 80 端口建立连接。
还可以设定连接时间,nc -w 5 www.baidu.com 80,即连接 5s 后自动断开。
此外,-v选项可以让 nc 输出详细的日志;-u可以建立一个 UDP 连接。
现在使用 HTTP 协议,模拟浏览器访问百度。
echo -n "GET / HTTP/1.0\r\n\r\n" | nc -p 1234 www.baidu.com 80
上面用法也可以这样写:
nc -p 1234 www.baidu.com 80
GET / HTTP/1.0
(回车)
(回车)
注意空格和回车。
端口扫描经常被系统管理员和黑客用来发现在一些机器上开放的端口,帮助他们识别系统中的漏洞。
检查本机 8088 - 8090 端口是否开启
nc 127.0.0.1 -z 8088-8090
有些网络不能直接访问, 只能通过代理服务才能访问
通过代理连接 host.example.com 的 42 端口,下面是一些例子,未实际验证。
# 使用 HTTP 代理 http://10.2.3.4:8080 与 host.example.com 的 42 端口连接
$ nc -x10.2.3.4:8080 -Xconnect host.example.com 42
# 使用 socks4 代理 socks4://10.2.3.4:8080 连接 host.example.com 的 42 端口
$ nc -x10.2.3.4:8080 -X4 host.example.com 42
# 使用 socks5 代理 socks5://10.2.3.4:8080 连接 host.example.com 的 42 端口
$ nc -x10.2.3.4:8080 -X5 host.example.com 42
把 192.168.0.2 上的文件 demo.tar.bz2 发送到 192.168.0.3, 并保存为 demo.tar.bz2:
在 192.168.0.3 上: nc -l 1234 > demo.tar.bz2
在 192.168.0.2 上: nc 192.168.0.3 1234 < demo.tar.bz2
通过在 192.168.0.2 与 192.168.0.3 上建立 TCP 连接来实现聊天:
在 192.168.0.3 上: nc -l 1234
在 192.168.0.2 上: nc 192.168.0.3 1234
这样, 双方就可以相互交流了, 使用 Ctrl+C 退出
监听 8080 端口, 如果通过 http 访问, 则返回文件 file 的内容, 然后断开:
{ printf 'HTTP/1.0 200 OK\r\nContent-Length: %d\r\n\r\n' "$(wc -c < file)"; cat file; } | nc -l 8080">)"}
配合 tar 命令和管道, 在两台主机之间传输文件夹内容
把 192.168.0.2 的文件夹 dir 发往 192.168.0.3
在 192.168.0.2 上: tar -cvf - dir | nc -l 1234
在 192.168.0.3 上: nc 192.168.0.2 1234 | tar xvf -
使用 tar 的 -j 选项(bzip2) 或 z 选项(gzip) 进行数据压缩传输
配合 dd 命令和管道, 进行远程磁盘读写
把 192.168.0.2 上的 /dev/sda 克隆到 192.168.0.3 上的 /dev/sdb:
在 192.168.0.2 上: dd if=/dev/sda | nc -l 1234
在 192.168.0.3 上: nc 192.168.0.2 1234 | dd of=/dev/sdb
可以打开一个远程主机的 bash, 对远程主机进行操作
从本地远程打开 192.168.0.3 的 shell:
在 192.168.0.3 上: nc -l 1234 -e /bin/bash
在本地: nc 192.168.0.3 1234
如果不支持 -e 或 -c 选项, 可以这样做:
$ mkfifo /tmp/tmp_fifo
$ cat /tmp/tmp_fifo | /bin/sh 2>&1 | nc -l 1234 > /tmp/tmp_fifo
在服务端访问客户端的 shell
服务器 192.168.0.2 访问本地 shell:
在服务器上: nc -l 1234
在本机: nc 192.168.0.2 1234 -e /bin/bash