netcat: 读 / 写网络数据的瑞士军刀

用 netcat 命令实现 TCP/UDP 的数据传输。

概述

功能

在 shell 脚本中通过 TCP/UDP 协议读 / 写数据。

例如可以实现

  • 扫描端口
  • 聊天
  • 文件传送
  • 代理服务

一些功能 demo

端口扫描

检测机器打开的端口

1
nc -z -n -v  10.10.20.11  78-90
1
2
# 输出
10.10.20.11 80 (http) open
  • -z 表示连接成功之后 马上断开连接
  • -v verbose 详细输出
  • -n 表示不要使用 DNS 反向查询 IP 的域名

机器通信

S,C 两台机器

  • S: 10.10.20.11
  • C: 10.10.20.12

S 机器监听端口,C 机器在 S 启动之后建立连接:

1
2
3
4
# S
nc -l -k 1567
# C
nc -w 10 10.10.20.11 1567
  • -l 保持连接,并且将数据输出到 stdout,并从 stdin 读取数据
  • -k 强制待命,客户端断开之后服务器也不断开
  • -w 设置连接断开时间(秒)

传送文件 / 目录

传送文件

服务器 -> 客户端:
S 作为服务器先启动,C 作为客户端后启动,下同

1
2
3
4
# S
nc -l 1567 < some.file
# C
nc 10.10.20.11 1567 > some.file

机器 C 上,较新版 nc 运行完毕之后不会断开连接,根据文档,使用下两个参数之一可以在接受完毕之后断开连接:

  • -N 遇到 EOF 立即断开连接
  • -q 0 遇到 EOF 等待 0 秒之后断开连接

但我在 ubuntu20.04 上 OpenBSD netcat (Debian patchlevel 1.206-1ubuntu1) 这个版本上没有测试成功。

客户端 -> 服务器:

1
2
3
4
# S
nc -l 1567 > some.file
# C
nc -N 10.10.20.11 1567 < dl.sh

这里的 -q -N 参数可以正常工作

传送目录

服务器 -> 客户端:
传递目录需要将目录打包成一个文件再传递

1
2
3
4
# S
tar -cvf - test-nc | nc -l 1567
# C
nc 10.10.20.11 1567 | tar -xvf -

同上,这里客户端接受完目录之后不会自动退出

客户端 -> 服务器:

1
2
3
4
# S
nc -l 1567 | tar -xvf -
# C
tar -cvf - test-nc | nc 10.10.20.11 1567

传送加密文件

客户端 -> 服务器

1
2
3
4
# S
nc -l 1567 | mcrypt -m ecb -F -k password -q -d > some.file
# C
mcrypt -m ecb -F -k password -q < some.file | nc -N 10.10.20.11 1567

mcrpyt 参数

  • -m 模式
  • -F 输出到 stdout
  • -k 密码
  • -q 安静模式,忽略警告信息

克隆硬盘

服务器 -> 客户端

1
2
3
4
# S:
dd if=/dev/sda | nc -l 1567
# C
nc 127.0.0.1 1567 | dd of=dev/sda`

dd 会读取硬盘的原始数据,会随着分区表拷贝所有的信息

代理服务

代理 ssh 流量

客户端 操作 服务器:

打开一个 shell,如果我们没有权限安装 ssh 也可以用 netcat 创建远程 shell

1
2
3
4
5
# S
mkfifo /tmp/tmp_fifo
cat /tmp/tmp_fifo | /bin/bash -i 2>&1 | nc -l 1567 > /tmp/tmp_fifo
# C
nc 127.0.0.1 1567

会创建一个连接,并且在连接成功时知性 /bin/bash

  1. 服务器从网络接受输入写入 fifo 文件中
  2. cat 命令读取 fifo 文件内容兵发送至 bash
  3. bash 的输出重定向至 nc
  4. nc 将数据发送至 client
  5. 其中:fifo 使读取等待,让这个过程可以一直执行,

利用这个 nc + fifo 还可以实现创建 HTTP 代理服务器等功能。

服务器 操作 客户端:

1
2
3
4
5
# S
nc -l 1567
# C
mkfifo /tmp/tmp_fifo
cat /tmp/tmp_fifo | /bin/bash -i 2>&1 |nc 10.10.20.11 1567 > /tmp/tmp_fifo

原理同上;用于 client 位于内网或者防火墙背后,client 连接上 server 之后,可以使用 server 来反向操作 client 的 shell