PHP文件上传流式表示WAF跨越

admin 2022年7月4日16:01:07评论0 views字数 3023阅读10分4秒阅读模式

简介

  • PHP文件上传实现规范为RFC1867

  • 实验环境为PHP 7.3.4 + nginx 1.20.1,关于上传部分的相关源码在github,PHP解析multipart/form-data请求体的入口函数SAPI_POST_HANDLER_FUNC

  • PHP 调试环境参考

  • PHP 示例代码

<?php var_dump ( $_FILES ); ?>
  • 文件解析的简要流程如下

PHP文件上传流式表示WAF跨越

技巧

前向截断

  • /名处理文件名进行类似向截断info.txt/info.php的文件经php后会info.php

PHP文件上传流式表示WAF跨越

  • 调用栈如下

PHP文件上传流式表示WAF跨越

  • 其中有一段注释如下,其本意是为了解决IE上传文件时所有路径名的问题

     /* 只有在* 它是有效路径分隔符的情况下,win32 系统才需要在技术上进行  检查。然而,IE 总是     在用户的文件系统上发送文件的完整路径,这意味着除非     用户执行 basename(),否则他们会得到一个虚假的文件名。在 IE 的用户群将     * 降至零或问题得到修复之前,此代码必须为所有系统保持启用状态。*/
  • 关键函数在php_ap_basename,该函数会寻找/显示最后出现的位置,并从该位置截断断字,导致造成了前向的截断

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

PHP文件上传流式表示WAF跨越

  • 在解析header时候,只是对内存进行了拷贝,内存视图变成了

PHP文件上传流式表示WAF跨越

  • 解析了中的时间长度,即表示表示,在filename使用时,内存中的字符串结束了,导致造成的断断续续strlenfilenamestrlen00

头文件:#include  < string . h >strlen ()函数用来计算字符串的长度,其原型为:
unsigned int strlen ( char * s );【参数说明】s为指定的字符串strlen ()用于计算指定的字符串 长度,不包括结束字符
  • 的,00可以对$_POST断变量名也可以进行截断,对$GET$_COOKIE等变量名00会引发400错误

  • 示例代码

    <?php var_dump ( $_POST );
    • 正常请求


PHP文件上传流式表示WAF跨越

  • 在名称添加后,可以看到$_POST变量00postxxxpost

PHP文件上传流式表示WAF跨越

  • $_POST变量值添加00不影响,但会中的长度则增加1

PHP文件上传流式表示WAF跨越

文件名的有意的会被触发

  • 服装展示

PHP文件上传流式表示WAF跨越

  • php_ap_getword的关键函数,当出现+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 == '' ) {
res = estrdup ( * line );
* line += strlen ( * line );
返回 资源
}
res = estrndup ( * line , pos - * line );
while ( * pos == stop ) {
++ pos ;
}
*线 = 位置
返回 资源}

;可以影响文件名解析的结果

  • 类似filename=info.php;.txt;这样的字符串经过PHP处理后,会变成info.php注意filename的值没有用双引号失败,双引号包裹会导致

PHP文件上传流式表示WAF跨越

  • 在解析Content-Disposition会先进行;词,使用=进行分词。所以,然后,类似的字符串第一次filename=info.php;.txt;词后的结果是这样的filename=info.php/txtfilenameinfo.php

SAPI_API  SAPI_POST_HANDLER_FUNC ( rfc1867_post_handler )  /* {{{  */ { 
//...
// 使用 ; 进行分词
while ( * cd && ( pair = getword ( mbuff -> input_encoding , & cd , ';' )))
{
//...
// 按照 = 进行解析
if ( strchr ( pair , '=' )) {
// ...
}
// ...
}
// ... }

双写filename

  • php解析Content-Disposition时,按照从前的顺序,结果有不同的变量名,如果之后进行值的覆盖,关键代码

PHP文件上传流式表示WAF跨越

失败的上传 - 1

  • filename00字符为时,上传会失败。如下所示,在filename首字符前插入00,导致上传失败

PHP文件上传流式表示WAF跨越

  • 关键码

if  (文件名[ 0 ]  ==  '' )  { #if DEBUG_FILE_UPLOAD 
sapi_module . sapi_error ( E_NOTICE , "没有文件上传" ); #endif
cancel_upload = UPLOAD_ERROR_D ;
}

失败的上传 - 2

  • name]字符为时,则导致上传失败,如下所示

PHP文件上传流式表示WAF跨越

  • 关键代码*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 ++ ; }

总结

  • 实战灵活时,以上各种技巧可以组合

  • 以上的技巧基于y4tacker文章以及php源码得来,相信深读源码的话,会有更多的技巧

参考

  • https://www.ietf.org/rfc/rfc1867.txt

  • https://github.com/php/php-src/tree/PHP-7.3.4

  • https://www.jianshu.com/p/894efc7e67a5

  • https://blog.csdn.net/qq_16885135/article/details/119811883

  • https://y4tacker.github.io/2022/06/21/year/2022/6/%E6%8E%A2%E5%AF%BBJava%E6%96%87%E4%BB%B6%E4%B8 %8A%E4%BC%A0%E6%B5%81%E9%87%8F%E5%B1%82%E9%9D%A2waf%E7%BB%95%E8%BF%87%E5%A7%BF %E5%8A%BF%E7%B3%BB%E5%88%97%E4%BA%8C/#%E7%81%B5%E6%B4%BB%E7%9A%84parseQuotedToken

来源先知(https://xz.aliyun.com/t/11486#toc-0)


注:如有绘画请联系删除





PHP文件上传流式表示WAF跨越

欢迎大家一起加群讨论学习和交流

PHP文件上传流式表示WAF跨越

快乐要懂得分享,

加倍的快乐。


原文始发于微信公众号(衡阳信安):PHP文件上传流式表示WAF跨越

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年7月4日16:01:07
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   PHP文件上传流式表示WAF跨越https://cn-sec.com/archives/1157785.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息