php7 fpm 漏洞,fpm 远程代码执行漏洞(CVE

1、搭建docker环境(yum install docker-re)

2、拉取镜像

配置docker-compose.yml文件,并拉取镜像

docker-compose up -d

version: ‘2‘services:

nginx:

image: nginx:1volumes:- ./www:/usr/share/nginx/html- ./default.conf:/etc/nginx/conf.d/default.conf

depends_on:-php

ports:- "8080:80"php:

image: php:7.1.32-fpm

volumes:- ./www:/var/www/html

default.conf

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;

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置零

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值