1. 从一台“看起来没漏洞”的靶机说起
很多人第一次接触红日安全靶机,都会有一种错觉:端口扫出来就那么几个,Web页面翻来覆去也就那几个功能,感觉没什么可打的。我最初也是这么想的,结果在这台机器上卡了整整一个下午,最后才发现入口藏在一个我压根没注意的细节里。这篇内容就把我完整的实战过程拆开来讲,从信息收集到拿到第一个shell,再到提权收尾,每一步为什么这么做、当时是怎么想的、踩了什么坑,全部摊开说清楚。
红日安全靶机系列在圈内算是比较经典的实战练习环境,它的特点不是堆砌花哨的漏洞,而是模拟真实业务场景下的配置疏忽和逻辑缺陷。这意味着你没法靠一个现成的exp直接打通,必须老老实实做信息收集、做服务识别、做路径枚举。适合有一定Linux基础、了解常见Web漏洞原理、但缺乏完整渗透链路实战经验的人来练手。如果你已经能独立完成常规靶机的打点,这篇里的排查思路和踩坑记录同样值得一看,因为红日的坑往往藏在“你以为已经看完了”的地方。
我这次的目标很明确:完整走一遍从外网打点到内网提权的全流程,把每一步的决策依据记录下来。下面按实际操作的顺序展开,中间会穿插大量我当时真实的判断过程和事后复盘。
2. 信息收集阶段:那些容易被跳过的细节
2.1 端口扫描不是跑完nmap就完事
拿到靶机IP之后,第一步肯定是端口扫描。我用的是比较常规的组合:
nmap -sS -sV -T4 -p- 192.168.1.100 -oN full_scan.txt全端口扫描跑下来,开放的端口并不多,大概就是22、80、3306这几个常见服务。很多人到这里就直接去看80端口的Web服务了,但我建议你先别急,把每个端口的服务版本信息仔细看一遍。比如SSH的版本号、Web中间件的类型和版本、数据库的版本,这些信息在后面找漏洞或者做密码爆破的时候都是关键线索。
我当时扫出来的结果里,80端口跑的是一个比较老的Web中间件版本,这个版本本身没有特别出名的RCE漏洞,但它的默认配置和目录结构有文章可做。22端口的SSH版本不算太新,理论上存在用户枚举的可能,但红日靶机通常不会把入口放在这种需要大量爆破的地方,所以先记下来备用。
提示:全端口扫描建议用
-p-而不是默认的1000个常用端口,红日靶机有时候会把服务开在不太常规的端口上,比如8080、8888、9000这类。我这次虽然没遇到,但之前有朋友就是因为只扫了默认端口,漏掉了关键服务。
2.2 目录枚举的字典选择和策略
Web服务确认存活之后,下一步就是目录枚举。这里有个很多人会犯的错误:拿一个大而全的字典直接怼上去,跑了几万个请求,结果要么被WAF封了IP,要么跑出来的结果太多根本看不过来。
我的做法是分两轮。第一轮用中等规模的常用字典,快速过一遍,看看有没有明显的后台、备份文件、上传点。命令大概是这样:
dirsearch -u http://192.168.1.100 -e php,html,js,txt -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt第一轮跑完,发现了几个有意思的路径:一个/admin目录返回302跳转,一个/backup目录返回403,还有一个/api目录返回200但内容是空的。这三个都值得深挖。
第二轮针对第一轮的结果做定制化枚举。比如/backup返回403,说明目录存在但禁止访问,这时候可以试试常见的备份文件名,像backup.zip、www.zip、site.tar.gz这些。/api返回200但内容为空,可能是需要特定的请求方法或者参数才能触发逻辑,这种地方往往藏着未授权的接口。
2.3 前端源码里的“意外收获”
目录枚举的同时,别忘了看前端源码。我习惯用浏览器开发者工具把Network面板打开,刷新页面,看看加载了哪些JS文件、有没有API调用、有没有注释掉的代码。
这次就是在某个JS文件里发现了一个被注释掉的接口路径,类似// /api/v1/user/list这样的。虽然被注释了,但说明这个接口在某个版本里存在过,很可能后端并没有删掉。手动访问一下,果然返回了用户列表的JSON数据,而且没有做任何权限校验。这就是典型的未授权访问漏洞,也是红日靶机里比较常见的考点。
注意:看JS文件的时候,除了找接口路径,还要留意有没有硬编码的密钥、token、加密方式。有时候前端加密的逻辑反过来就是后端的解密逻辑,这对后面构造请求很有帮助。
3. 突破口定位:从信息碎片到第一个立足点
3.1 未授权接口的利用与数据挖掘
接上面说的,那个未授权的用户列表接口返回了所有用户的信息,包括用户名、邮箱、角色,甚至还有密码的哈希值。这里就是第一个关键决策点:拿到哈希之后怎么办?
很多人第一反应是拿去解密,但红日靶机里的哈希通常是加盐的,直接查彩虹表解不出来。我的做法是先看哈希的格式,判断是什么算法。如果是MD5或者SHA1这种没有加盐的,可以试试在线解密或者本地跑字典。如果是bcrypt这种慢哈希,就别浪费时间了,直接找别的路子。
这次运气不错,返回的哈希是MD5格式,而且没有加盐。我拿其中一个管理员的哈希去查了一下,很快就出了明文。这个明文密码后来在SSH登录的时候派上了用场,这是后话。
除了密码哈希,用户列表里还暴露了系统的命名规则:管理员账号是admin,普通用户是user_xxx,服务账号是svc_xxx。这个规则在后面做密码喷洒或者权限提升的时候很有用。
3.2 文件上传点的绕过尝试
在/admin目录下,我发现了一个登录页面。用刚才拿到的管理员密码试了一下,成功登录。后台功能不多,但有一个“头像上传”的功能引起了我的注意。
上传功能是Web渗透里最常见的突破口之一。我先试了直接上传PHP文件,返回“文件类型不允许”。改成php5、phtml、php.jpg这些常见绕过后缀,都被拦了。看来前端和后端都做了校验。
这时候我回头去看上传功能的请求包,发现它是先通过一个接口检查文件类型,检查通过之后再上传到另一个接口。这种两步式的上传逻辑往往有漏洞:如果我只调用第二个上传接口,跳过类型检查,是不是就能绕过?
手动构造请求试了一下,果然可以。直接POST到上传接口,Content-Type设为image/jpeg,文件名用shell.php,服务器端只检查了Content-Type,没有检查文件内容。上传成功,返回了文件路径。访问一下,命令执行成功。
提示:遇到文件上传拦截的时候,不要只盯着后缀名绕过的思路。多看看请求的流程,有没有可以跳过的校验步骤,有没有前端校验但后端没校验的情况。红日靶机特别喜欢考这种逻辑漏洞。
3.3 从WebShell到交互式Shell的稳定化
拿到WebShell只是第一步,真正的操作才刚刚开始。WebShell的缺点是执行命令不方便,没有交互,超时时间短。所以下一步是把它升级成一个稳定的反向Shell。
我常用的方法是先用WebShell上传一个简单的Shell脚本,然后通过bash或者nc反弹一个交互式Shell回来。具体命令这里不展开,核心思路是利用靶机上已有的工具(比如bash、python、perl)建立一个TCP连接,把标准输入输出重定向到攻击机的监听端口。
反弹成功之后,第一件事是检查当前用户的权限和系统信息:
id uname -a cat /etc/os-release这次拿到的是www-data用户,权限很低,但至少有了一个稳定的立足点。接下来就是提权。
4. 权限提升:从www-data到root的完整链路
4.1 系统信息收集与提权方向判断
提权的第一步永远是信息收集。我习惯用几个自动化脚本先跑一遍,比如LinEnum、linux-exploit-suggester这些,快速看看有没有明显的提权点。但自动化脚本只能给你方向,真正的突破口往往需要手动去挖。
这次脚本跑出来的结果里,有几个值得关注的点:
- 系统内核版本比较老,理论上存在脏牛漏洞,但红日靶机通常不会让你用这种通杀型漏洞,因为太简单了。
- 有一个SUID文件比较可疑,是一个自定义的二进制程序。
/etc/passwd文件可写,但这个通常需要配合其他条件才能利用。- 有一个定时任务以root权限运行,执行的是一个可写的脚本。
这几个方向里,我优先看的是SUID文件和定时任务,因为这两个在红日靶机里出现的频率最高。
4.2 SUID文件的逆向分析与利用
那个可疑的SUID文件位于/usr/local/bin目录下,名字看起来像是一个系统管理工具。先用strings命令看看里面有没有什么线索:
strings /usr/local/bin/sysmanager输出里发现它调用了system()函数,而且参数里有一个相对路径的命令。这意味着如果我能控制环境变量或者当前工作目录,就有可能劫持这个命令的执行。
进一步用ltrace跟踪一下它的执行过程,确认它确实是以root权限调用了某个命令,而且没有使用绝对路径。这时候利用思路就清晰了:创建一个同名的恶意程序,放在PATH环境变量靠前的目录里,然后运行这个SUID文件,它就会以root权限执行我的恶意程序。
实际操作的时候要注意,SUID程序执行时会重置一部分环境变量,所以直接改PATH可能不生效。我的做法是在当前目录下创建一个同名文件,然后把当前目录加到PATH的最前面,再运行SUID程序。这样它调用那个命令的时候,就会优先执行我放在当前目录下的恶意版本。
4.3 定时任务的可写脚本利用
SUID这条路走通之后,其实已经拿到root了。但为了完整性,我还是去看了一下那个定时任务。果然,/etc/crontab里有一条记录,每隔几分钟以root权限执行/opt/scripts/backup.sh。而这个脚本的权限是777,任何用户都可以修改。
这种提权方式就更简单了,直接在脚本里追加一行反弹Shell的命令,等几分钟就能收到root权限的Shell。不过这次我已经通过SUID拿到了root,所以只是验证了一下这个路径确实可行。
注意:定时任务提权的时候,一定要确认脚本的执行周期。有些靶机的定时任务是每分钟执行一次,有些是每五分钟。如果你改完脚本等了一分钟没反应就以为失败了,可能会错过正确的利用方式。另外,有些定时任务会在执行完之后把脚本恢复原样,这种就需要用其他方法了。
4.4 提权后的痕迹清理与权限维持
拿到root之后,很多人就急着去看flag或者截图交差了。但在真实场景里,提权成功只是开始,你还需要考虑权限维持和痕迹清理。红日靶机虽然不会检测这些,但养成习惯对实战很有帮助。
权限维持方面,我通常会加一个SSH公钥到root的authorized_keys里,这样即使靶机重启或者WebShell被删了,我还能通过SSH登录。痕迹清理方面,主要是删除上传的工具、清理命令历史、恢复被修改的配置文件。这些操作在靶机环境里不是必须的,但在真实项目里是基本素养。
5. 复盘:红日靶机里那些“反直觉”的设计
5.1 为什么入口往往不在最显眼的地方
红日靶机的一个显著特点是,它不会把漏洞放在你第一眼就能看到的地方。比如这次,Web首页看起来很正常,后台登录页面也有验证码和登录失败锁定,但真正的入口是一个被注释掉的API接口。这种设计其实很贴近真实场景:开发人员在测试阶段留下的调试接口,上线时忘了删,或者以为注释掉就安全了。
所以做红日靶机的时候,信息收集阶段一定要足够耐心。目录枚举、JS分析、请求抓包,这些基础工作做得越细,后面越轻松。我见过很多人一上来就对着登录框爆破,跑了几千个密码没结果就放弃了,其实入口根本不在这里。
5.2 漏洞链的串联比单点漏洞更重要
这次从外网到root,用到了至少三个漏洞:未授权API泄露信息、文件上传逻辑绕过、SUID程序命令劫持。单独看每一个,都不是特别复杂的漏洞,但把它们串起来就能完成完整的攻击链路。
这也是红日靶机想训练的能力:在真实环境中,你很少能找到一个直接getshell的漏洞,更多时候需要把多个低危漏洞组合起来,逐步扩大战果。比如未授权API泄露的密码哈希,单独看可能只是信息泄露,但解出明文之后就能登录后台,登录后台之后才能利用上传漏洞。这种链条思维比掌握某个具体漏洞的利用方式更重要。
5.3 提权不是终点,而是新的起点
很多人拿到root之后就结束了,但在真实项目里,拿到root只是意味着你控制了这台机器,接下来还要做内网横向、权限维持、数据收集等等。红日靶机虽然只有单机,但你可以自己给自己加戏:比如拿到root之后,去看看这台机器上有没有连接其他机器的凭证,有没有内网服务的配置文件,有没有可以进一步利用的信任关系。
我这次在root的home目录下发现了一个.ssh目录,里面有一个私钥。虽然靶机环境里没有其他机器可以连,但这个私钥的存在说明这台机器可能被用作跳板机。如果在真实环境里,下一步就是拿这个私钥去尝试登录内网其他机器。
6. 给准备打红日靶机的朋友几条实在建议
第一,别急着上工具。我见过太多人一拿到IP就打开各种自动化扫描工具,结果跑了一堆结果出来,自己都不知道哪些有用。我的习惯是先手动看一遍,用浏览器访问一下Web服务,用nc连一下开放端口,对目标有个直观的感受,然后再上工具做系统性的扫描。
第二,养成记录的习惯。每做一步操作,都记下来你做了什么、得到了什么结果、下一步打算怎么做。红日靶机的链路比较长,如果不记录,很容易做到后面忘了前面。我一般会开一个文本文件,边做边写,最后复盘的时候直接看记录就行。
第三,遇到卡壳的时候,回到信息收集阶段重新看一遍。很多时候你卡住了,不是因为漏洞太难,而是因为你漏掉了某个信息。比如这次我在文件上传那里卡了很久,最后是回头看请求包才发现有两步校验的逻辑。信息收集不是一次性的工作,而是贯穿整个渗透过程的。
第四,多想想“为什么”。为什么这个接口没有权限校验?为什么这个文件有SUID权限?为什么这个脚本是777?每一个异常背后都可能藏着一条利用路径。红日靶机的设计者不会无缘无故放一个SUID文件在那里,它一定是有用的。
最后说一个我自己的小技巧:打靶机的时候,我会假装自己是一个真实的攻击者,而不是一个在做题的学生。真实攻击者不会只盯着一个点死磕,他会同时尝试多个方向,哪个先通就走哪个。这种心态上的调整,往往能让你在卡住的时候找到新的突破口。