php7fpm漏洞,fpm远程代码执⾏漏洞(CVE 1、搭建docker环境(yum install docker-re)
2、拉取镜像
配置l⽂件,并拉取镜像
docker-compose up -d
version: ‘2‘services:
nginx:
image: nginx:1volumes:- ./www:/usr/share/nginx/html- ./f:/etc/nginx/conf.f
depends_on:-php
ports:- "8080:80"php:
image: php:7.1.32-fpm
volumes:- ./www:/var/www/html
server {
listen80default_server;
listen [::]:80default_server;
root/usr/share/nginx/html;
index index.html index.php;
server_name _;
location/{
try_files $uri $uri/ =404;
}
location~ [^/]\.php(/|$) {
fastcgi_split_path_info^(.+?\.php)(/.*)$;
include fastcgi_params;
fastcgi_param PATH_INFO
$fastcgi_path_info;
fastcgi_index index.php;
fastcgi_param REDIRECT_STATUS200;
fastcgi_param SCRIPT_FILENAME/var/www/html$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT/var/www/html;
fastcgi_pass php:9000;
}
}
⼆、源码分析
static void init_request_info(void)
{
fcgi_request *request = (fcgi_request*) SG(server_context);
//⽂件绝对路径
char *env_script_filename = FCGI_GETENV(request, "SCRIPT_FILENAME"); //env_path_translated值和env_script_filename值⼀样
char *env_path_translated = FCGI_GETENV(request, "PATH_TRANSLATED"); char *script_path_translated = env_script_filename;
char *ini;
int apache_was_here = 0;
/* some broken servers do not have script_filename or argv0
* an example, IIS configured in some ways. then they do more
* broken stuff and set path_translated to the cgi script location */
if (!script_path_translated && env_path_translated) {
script_path_translated = env_path_translated;
}
/* initialize the defaults */
SG(request_info).path_translated = NULL;php8兼容php7吗
SG(request_info).request_method = NULL;
SG(request_info).proto_num = 1000;
SG(request_info).query_string = NULL;
SG(request_info).request_uri = NULL;
SG(request_info).content_type = NULL;
SG(request_info).content_length = 0;
SG(sapi_headers).http_response_code = 200;
if (script_path_translated) {
const char *auth;
//获取request请求中的参数
char *content_length = FCGI_GETENV(request, "CONTENT_LENGTH");
char *content_type = FCGI_GETENV(request, "CONTENT_TYPE");
char *env_path_info = FCGI_GETENV(request, "PATH_INFO");
char *env_script_name = FCGI_GETENV(request, "SCRIPT_NAME");
...
if (CGIG(fix_pathinfo)) {
struct stat st;
char *real_path = NULL;
char *env_redirect_url = FCGI_GETENV(request, "REDIRECT_URL");
char *env_document_root = FCGI_GETENV(request, "DOCUMENT_ROOT");
char *orig_path_translated = env_path_translated;
char *orig_path_info = env_path_info;
char *orig_script_name = env_script_name;
char *orig_script_filename = env_script_filename;
int script_path_translated_len;
...
if (script_path_translated &&
//script_path_translated_len是请求uri_path中第⼀个斜杠前的内容:如,则变量的值为/var/www/html/index.php的长度(script_path_translated_len = strlen(script_path_translated)) > 0 &&
(script_path_translated[script_path_translated_len-1] == ‘/‘ ||
#ifdef PHP_WIN32
script_path_translated[script_path_translated_len-1] == ‘\\‘ ||
#endif
(real_path = tsrm_realpath(script_path_translated, NULL)) == NULL)
) {
//字符串复制
char *pt = estrndup(script_path_translated, script_path_translated_len);
//url的长度取决于nginx的配置当请求url,%0atest.php。script_path_translated来⾃于nginx的配置,
为/var/www/html/index.php/123\ntest.php
int len = script_path_translated_len;
...
int ptlen = strlen(pt);
int slen = len - ptlen;
//request中path_info的长度,此参数值可控
int pilen = env_path_info ? strlen(env_path_info) : 0;
int tflag = 0;
char *path_info;
if (apache_was_here) {
/
* recall that PATH_INFO won‘t exist */
path_info = script_path_translated + ptlen;
tflag = (slen != 0 && (!orig_path_info || strcmp(orig_path_info, path_info) != 0));
} else {
//在c语⾔中,char *变量,加⼀个int数字,是⼀个使指针指向的地址偏移
path_info = env_path_info ? env_path_info + pilen - slen : NULL;
tflag = (orig_path_info != path_info);
}
下⾯的代码进⾏举例分析:
path_info = env_path_info ? env_path_info + pilen - slen : NULL;
替换成类似代码:由此可以看出,下⾯的代码在c语⾔中可以起到偏移char *⾸地址的#include
int main() {
char *a = "aaaaaaaa";
char *b = a-2;
printf("%s",b);
//path_info[0]此地址对应的是path_info的⾸地址。根据fpm代码,则是可操作堆上任意数据置为0,那我们就可以把_fcgi_data_seg结构体的char* pos置零
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论