PHP文件上传流式表示WAF跨越
2022-12-22 09:0:52 Author: 编码安全研究(查看原文) 阅读量:45 收藏

简介

  • 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 ); ?>
  • 文件解析的简要流程如下

技巧

前向截断

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

  • 调用栈如下
  • 其中有一段注释如下,其本意是为了解决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
  • 在解析header时候,只是对内存进行了拷贝,内存视图变成了
  • 解析了中的时间长度,即表示表示,在filename使用时,内存中的字符串结束了,导致造成的断断续续strlenfilenamestrlen\000
头文件:#include < string . h >strlen ()函数用来计算字符串的长度,其原型为:
unsigned int strlen ( char * s );【参数说明】s为指定的字符串strlen ()用于计算指定的字符串 长度,不包括结束字符\0
  • 的,00可以对$_POST断变量名也可以进行截断,对$GET$_COOKIE等变量名00会引发400错误
  • 示例代码
    <?php var_dump ( $_POST );
    • 正常请求

  • 在名称添加后,可以看到$_POST变量00postxxxpost
  • $_POST变量值添加00不影响,但会中的长度则增加1

文件名的有意的\会被触发

  • 服装展示
  • 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 == '\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/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时,按照从前的顺序,结果有不同的变量名,如果之后进行值的覆盖,关键代码

失败的上传 - 1

  • filename00字符为时,上传会失败。如下所示,在filename首字符前插入00,导致上传失败
  • 关键码
if (文件名[ 0 ] == '\0' ) { #if DEBUG_FILE_UPLOAD
sapi_module . sapi_error ( E_NOTICE , "没有文件上传" ); #endif
cancel_upload = UPLOAD_ERROR_D ;
}

失败的上传 - 2

  • 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 ++ ; }

总结

  • 实战灵活时,以上各种技巧可以组合
  • 以上的技巧基于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)

如有侵权,请联系删除

推荐阅读

实战|记一次奇妙的文件上传getshell
「 超详细 | 分享 」手把手教你如何进行内网渗透
神兵利器 | siusiu-渗透工具管理套件
一款功能全面的XSS扫描器
实战 | 一次利用哥斯拉马绕过宝塔waf
BurpCrypto: 万能网站密码爆破测试工具
快速筛选真实IP并整理为C段 -- 棱眼
自动探测端口顺便爆破工具t14m4t
渗透工具|无状态子域名爆破工具(1秒扫160万个子域)
查看更多精彩内容,还请关注橘猫学安全:
每日坚持学习与分享,觉得文章对你有帮助可在底部给点个“再看

文章来源: http://mp.weixin.qq.com/s?__biz=Mzg2NDY1MDc2Mg==&mid=2247498562&idx=1&sn=fd1708be6b04c71e2c5aac92861547e5&chksm=ce64a827f9132131d883c93098b1c80b3a0509d38dce6a9bdc371c643540ea0dc0f87fd39caa#rd
如有侵权请联系:admin#unsafe.sh