multipart/form-data
请求体的入口函数在SAPI_POST_HANDLER_FUNC
<?php var_dump ( $_FILES ); ?>
\
和/
名处理文件名进行类似向截断info.txt/info.php
的文件经php后会info.php
/* 只有在* 它是有效路径分隔符的情况下,win32 系统才需要在技术上进行 \ 检查。然而,IE 总是 在用户的文件系统上发送文件的完整路径,这意味着除非 用户执行 basename(),否则他们会得到一个虚假的文件名。在 IE 的用户群将 * 降至零或问题得到修复之前,此代码必须为所有系统保持启用状态。*/
\
和/
显示最后出现的位置,并从该位置截断断字,导致造成了前向的截断static char * php_ap_basename ( const zend_encoding * encoding , char * path ) {
char * s = strrchr ( path , '\\' );
char * s2 = strrchr (路径, '/' );
if ( s && s2 ) {
if ( s > s2 ) {
++ s ;
} 其他 {
s = ++ s2 ;
}
返回 s ;
} else if ( s ) {
return ++ s ;
} else if ( s2 ) {
return ++ s2 ;
}
返回 路径;}
00
的名字处理文件名进行后向截断类似info.php(00)xxx
的文件经php之后会变成info.php
header
的时候,只是对内存进行了拷贝,内存视图变成了filename
使用时,内存中的字符串结束了,导致造成的断断续续strlen
filename
strlen
\0
00
头文件:#include < string . h >strlen ()函数用来计算字符串的长度,其原型为:
unsigned int strlen ( char * s );【参数说明】s为指定的字符串。strlen ()用于计算指定的字符串的 长度,不包括结束字符“ \0 ” 。
00
可以对$_POST
断变量名也可以进行截断,对$GET
,$_COOKIE
等变量名00
会引发400
错误<?php var_dump ( $_POST );
$_POST
变量中00
postxxx
post
$_POST
变量值添加00
不影响,但会中的长度则增加1
\
会被触发\+quote
这样的两个事件时,会触发\
只取quote
的值static char * php_ap_getword ( const zend_encoding * encoding , char ** line , char stop ) {
char * pos = * line , quote ;
字符 * res ;
while ( * pos && * pos != stop ) {
if (( quote = * pos ) == '"' || quote == '\'' ) {
++ pos ;
while ( * pos && * pos != quote ) {
// 这里会发射 \ 字符
if ( * pos == '\\' && pos [ 1 ] && pos [ 1] == 报价) {
pos += 2 ;
} 其他 {
++位置;
}
}
if ( * pos ) {
++ pos ;
}
} 其他 ++位置;
}
if ( * pos == '\0' ) {
res = estrdup ( * line );
* line += strlen ( * line );
返回 资源;
}
res = estrndup ( * line , pos - * line );
while ( * pos == stop ) {
++ pos ;
}
*线 = 位置;
返回 资源;}
;
可以影响文件名解析的结果filename=info.php;.txt;
这样的字符串经过PHP处理后,会变成info.php
,注意filename
的值没有用双引号失败,双引号包裹会导致Content-Disposition
会先进行分;
词,使用=
进行分词。所以,然后,类似的字符串第一次分filename=info.php;.txt;
词后的结果是这样的filename=info.php
/txt
filename
info.php
SAPI_API SAPI_POST_HANDLER_FUNC ( rfc1867_post_handler ) /* {{{ */ {
//...
// 使用 ; 进行分词
while ( * cd && ( pair = getword ( mbuff -> input_encoding , & cd , ';' )))
{
//...
// 按照 = 进行解析
if ( strchr ( pair , '=' )) {
// ...
}
// ...
}
// ... }
filename
Content-Disposition
时,按照从前的顺序,结果有不同的变量名,如果之后进行值的覆盖,关键代码filename
首00
字符为时,上传会失败。如下所示,在filename
首字符前插入00
,导致上传失败if (文件名[ 0 ] == '\0' ) { #if DEBUG_FILE_UPLOAD
sapi_module . sapi_error ( E_NOTICE , "没有文件上传" ); #endif
cancel_upload = UPLOAD_ERROR_D ;
}
name
首]
字符为时,则导致上传失败,如下所示*tmp == ']'
当时,skip_upload = 1
促成了处理,当时,加载了上传的while ( * tmp ) {
if ( * tmp == '[' ) {
c ++ ;
} else if ( * tmp == ']' ) {
c -- ;
if ( tmp [ 1 ] && tmp [ 1 ] != '[' ) {
skip_upload = 1 ;
休息;
}
}
如果 ( c < 0) {
跳过上传 = 1 ;
休息;
}
tmp ++ ; }
来源:先知(https://xz.aliyun.com/t/11486#toc-0)
如有侵权,请联系删除
推荐阅读