基于MySQL的Phar反序列化

背景

一直都知道MySQL可以的LOAD DATA LOCAL INFILE可以触发反序列化漏洞

但是都没有自己做过实验

现在跟进一下

变量

主要分为两组

  • mysqli
  • PDO

关于MySqli的测试,可以基于网上的脚本Rogue-MySql-Server-master

至于PDO的测试需要自己分析数据,写个脚本即可

MySqli测试

首先还是尝试一下简单的文件读取

前置参数的设置

mysql.ini

无关紧要,如果在本地测试,如下

image-20210709150846315

需要打开

  • local-infile=1
  • secure_file_priv=""

php.ini

必要参数,此参数非默认参数,所以想要通过mysqli触发phar已基本不可能

  • mysqli.allow_local_infile = On

image-20210709151148750

测试文件读取

本地测试

直接使用查询,依赖于mysql.ini的配置

image-20210709151315124

脚本测试

测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
namespace app\controller;

use app\BaseController;

class Index extends BaseController
{
public function test()
{
$m = mysqli_init();
mysqli_options($m, MYSQLI_OPT_LOCAL_INFILE, true);
$s = mysqli_real_connect($m, 'localhost', 'root', '123456', 'test', 3307);
$p = mysqli_query($m, 'select version();');
}
}

成功读取

image-20210709151722366

测试反序列化

脚本测试

image-20210709152019606

结论

需要php.ini的硬性支持,基本不存在

PDO测试

PDO不依赖于php.ini中的mysqli的配置

但是PDO默认禁用掉了本地文件读取

但是和mysqli不一样的是,不需要修改配置文件,可以通过代码软加载

前置条件

必须,可以通过代码添加

  • PDO::MYSQL_ATTR_LOCAL_INFILE => true

不添加配置结果

image-20210709154143584

开启预编译的PDO

测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
namespace app\controller;

use app\BaseController;
use PDO;

class Index extends BaseController
{
public function test()
{
$user = "root";
$pass = "123456";
try {
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass, array(
PDO::MYSQL_ATTR_LOCAL_INFILE => true
));
$row = $dbh->query('SELECT version();');
var_dump($row);
$dbh = null;
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
}
}

可以看到,数据是和mysqli一致的

image-20210709154001472

成功读取

image-20210709154322702

反序列化测试

image-20210709154456227

关闭预编译操作的PDO

测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php
namespace app\controller;

use app\BaseController;
use PDO;
use think\facade\Db;

class Index extends BaseController
{
public function test()
{
$user = "root";
$pass = "123456";
$id = 1;
try {
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass, array(
PDO::MYSQL_ATTR_LOCAL_INFILE => true,
PDO::ATTR_EMULATE_PREPARES => false
));
$pdo = $dbh->prepare('SELECT * from users where id=:id;');
$pdo->bindParam ( ':id', $id);
$pdo->execute();
var_dump($pdo);
$dbh = null;
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
}
}

多了几条

image-20210709160845444

自己写下交互

成功读取文件

image-20210709161040363

成功触发反序列化

image-20210709161129152

end

至于为什么要做这个当然是遇到真实环境啦