PHP文件上传漏洞

PHP任意文件上传漏洞(cve-2006-7243):

  • 在PHP版本小于5.3.4的move_uploaded_file()函数中,存在CVE-2006-7243这个漏洞。
    -形成原因:move_uploaded_file()底层源码用c编写,判断上传文件路径的时候使用了char指针,C语言中char指针以\0作为字符串结束的标志,所以会文件名被\0截断。\0后面的内容会被忽略。

  • 这里的问题是,可以在文件名中插入空字符,利用插入空字符的方式,攻击者可以上传任意文件,引起远程代码执行漏洞等。

  • 在上传文件的文件名中,可以使用\0进行截断,例如1.php\0.jpg。
    下面是move_uploadea_file()的源代码:

/* {{{ proto bool move_uploaded_file(string path, string new_path)
   Move a file if and only if it was created by an upload */
PHP_FUNCTION(move_uploaded_file)
{
	char *path, *new_path;
	size_t path_len, new_path_len;
	zend_bool successful = 0;

#ifndef PHP_WIN32
	int oldmask; int ret;
#endif

	if (!SG(rfc1867_uploaded_files)) {
		RETURN_FALSE;
	}

	ZEND_PARSE_PARAMETERS_START(2, 2)
		Z_PARAM_STRING(path, path_len)
		Z_PARAM_PATH(new_path, new_path_len)
	ZEND_PARSE_PARAMETERS_END();

	if (!zend_hash_str_exists(SG(rfc1867_uploaded_files), path, path_len)) {
		RETURN_FALSE;
	}

	if (php_check_open_basedir(new_path)) {
		RETURN_FALSE;
	}

	if (VCWD_RENAME(path, new_path) == 0) {
		successful = 1;
#ifndef PHP_WIN32
		oldmask = umask(077);
		umask(oldmask);

		ret = VCWD_CHMOD(new_path, 0666 & ~oldmask);

		if (ret == -1) {
			php_error_docref(NULL, E_WARNING, "%s", strerror(errno));
		}
#endif
	} else if (php_copy_file_ex(path, new_path, STREAM_DISABLE_OPEN_BASEDIR) == SUCCESS) {
		VCWD_UNLINK(path);
		successful = 1;
	}

	if (successful) {
		zend_hash_str_del(SG(rfc1867_uploaded_files), path, path_len);
	} else {
		php_error_docref(NULL, E_WARNING, "Unable to move '%s' to '%s'", path, new_path);
	}

	RETURN_BOOL(successful);
}

代码的链接为:https://github.com/php/php-src/blob/d3ca28f5694e7848fb2b238bbe3e9564230ae65e/ext/standard/basic_functions.c

对于这个漏洞进行测试:
我们准备了一个PHP脚本

<?php echo "<script>alert('xixixiixix')</script>";?>
  • 在DVWA中找到 file upoload板块,(DVWA security设置安全等级)

low级:
这个级别没有进行任何检测,可以直接上传PHP代码
使用后缀为.php文件,直接上传成功
在这里插入图片描述
访问地址验证:
在这里插入图片描述
脚本成功在服务区运行
Medium级:
1.写一个PHP的弹窗,将文件后缀改成.jpg格式:
在这里插入图片描述

2.使用burp抓包,在hex中使用00将.jpg截断:
在这里插入图片描述
将其上传成PHP文件 保证能在服务器执行

提示上传成功
在这里插入图片描述
3.验证是否能在服务端执行:
在这里插入图片描述
用url访问文件 可以成功执行
在看源代码:

<?php 

if( isset( $_POST[ 'Upload' ] ) ) { 
    // Where are we going to be writing to? 
    $target_path  = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/"; 
    $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] ); 

    // File information 
    $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ]; 
    $uploaded_type = $_FILES[ 'uploaded' ][ 'type' ]; 
    $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ]; 

    // Is it an image? 
    if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) && 
        ( $uploaded_size < 100000 ) ) { 

        // Can we move the file to the upload folder? 
        if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) { 
            // No 
            echo '<pre>Your image was not uploaded.</pre>'; 
        } 
        else { 
            // Yes! 
            echo "<pre>{$target_path} succesfully uploaded!</pre>"; 
        } 
    } 
    else { 
        // Invalid file 
        echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>'; 
    } 
} 

?> 

增加了三个变量分别用于表示上传文件的名字、类型和大小

猜你喜欢

转载自blog.csdn.net/baidu_41871794/article/details/83627762