当前位置:首页 >> 网络通讯 >> 网络安全 >> 内容

php上传绕过及缺陷经验解说

时间:2013/4/19 12:10:00 作者:平凡之路 来源:xuhantao.com 浏览:

1) GIF89A伪造文件头上传.
缺陷:文件只验证上传Type是否为image/gif等这样的类型,GIF89A是用CA32m
等这些反汇编16进制工作在文件头获取的!搜狗电脑知识网

2)SQL查询绕过(鸡助)

如: $token = explode(".",$upload_filename);
.......................................
$extension = $tokens[count($tokens)-1]; //获取最后一个后缀
..............................
$result = forum_exec_query("SELECT * From $extensions_table WHERE extension = '$extension' AND file_type = 'Image'",$link);
........................................................................................

需要GPC=off Apache解释漏洞
我们上传文件:

shell.xsser.php.' or 'a'='a

闭合:

.........extension = ' ' or 'a'='a' AND file_type = 'image'.......

空 or 'a'='a' 就是进行了或运算: 错误 or 对 =对 这样就能使sql查询成功了! 而且Apache解释漏洞能获取Webshell.
3)strrpos()函数造成的漏洞
先介绍下strrpos()这函数:

定义和用法
strrpos() 函数查找字符串在另一个字符串中最后一次出现的位置。
如果成功,则返回位置,否则返回 false。
语法
strrpos(string,find,start)
参数   描述
string   必需。规定被搜索的字符串。
find   必需。规定要查找的字符。
start   可选。规定开始搜索的位置。

看漏洞形成代码:

.........
$upfiletype="gif|jpg";
............
$size=$_FILES['userfile']['size'];
$strFileName=$_FILES['userfile']['name'];
$arrName = explode(".",$strFilename);
$intName = sizeof($arrName);
$extName = strtolower($arrName[$intName-1]); //作用取得上传文件的后缀名.
if (false !== strrpos($upfiletype,$extName)){} //问题出在这里.
else{
echo "不允许上传".$extName."类型的文件";
exit;
}
.......................................................

程序限制后缀为jpg何gif是吧,但是strrpos函数只读取一个字符串的,如:
jpg中有p字符,那么php也有p字符. 囧ORZ。。。。 就成功不返回false了。。。

<?php
if (flase !== strrpos('jpg','php')){
echo "ture";
}else{
echo "ORZ";
}
?>


4) move_uploaded_file()+rename()函数与某些逻辑缺陷
百度搜索下:ImgUpload V2.01汉化版里面的upload.php(文章字数关系不贴了.)

switch($_FILES[$whichfile]['error']


是你上传文件的大小,小型一点的木马可以绕过.

$split_ext = explode(',', $globalvars->settings['allowed_ext']);
$split_img = explode('.', $_FILES[$whichfile]['name']);
//这个为我们上传的文件如xsser.php explode分割后

$split_img[0]是xsser $split_img[1]是php
$globalvars->settings['allowed_ext']
的值为 jpg:allow,jpeg:allow,png:allow,bmp:allow,gif:allow
$split_values = explode(':', $split_ext[$i]);
//把上面那些数值:分割出来 成了 jpg allow jpeg allow 这样的类型.
假如我们上传xsser.jpg 被分割成$split_img[0]是xsser,而$split_img[1]是jpg,那么$split_values[0]是jpg,$split_values[1]是allow
后面有if判断他们的关系.
然后move_uploaded_file函数把我们的xsser.jpg移动到
$user_dat['usrdir'] . "/" . $_FILES[$whichfile]['name']
这个目录里.
这个目录是我们的用户名注册产生的,如用户是xsser 那么目录就是xsser了。
if(move_uploaded_file ($_FILES[$whichfile]['tmp_name'], $user_dat['usrdir'] . "/" . $_FILES[$whichfile]['name']))
如果函数成功移动xsser.jpg到了xsser目录if语句就Ture.
随后rename函数将xsser.jpg进行改名字:
rename($user_dat['usrdir'] . "/" . $_FILES[$whichfile]['name'], $user_dat['usrdir'] . "/" . $split_img[0] . "." . strtolower
($split_img[1]));
strtolower函数将文件后缀转换为小写.
看着是没问题的,其实问题出在rename问题上:
WINDOWS系统下,要想文件改名字失败,需要两种情况:
1.已经有了这个用户名,文件名字不能重复。
2.文件名字有特殊字符。
我们来看看这个判断:
if($split_values[0] == strtolower($split_img[1]) && $split_values[1] == "allow")
我们上传xsser.jpg.php
$split_img[1]是jpg $split_img[0]是xsser 我们的$split_img[2]是php 这个if没有判断$split_img[2],可以成功绕过.
到了下面的rename会改名为xsser.jpg
rename($user_dat['usrdir'] . "/" . $_FILES[$whichfile]['name'], $user_dat['usrdir'] . "/" . $split_img[0](xsser) . "." .
strtolower($split_img[1])(jpg));
//上面的括号是我的注释.
如果我们上传两处的话呢?
第一次上传xsser.jpg.php ->改名为xsser.jpg
第二次上传xsser.jpg.php ->尝试改名为xsser.jpg->但是文件存在不能改名->xsser.jpg.php出现了!!!
5)程序员对empty的错误认识
only_guest
$nameExt = strtolower($COMMON->getFileExtName($_FILES['Filedata']['name'])); $allowedType = array('jpg', 'gif', 'bmp', 'png',
'jpeg'); if(!in_array($nameExt, $allowedType)){ $msg = 0; } if(empty($msg)){$filename = getmicrotime().'.'.$nameExt;
$file_url = urlencode($CONFIG->baseUrl.'data/files/'.$date."/".$filename);
 
$filename = $dest.$filename;
............................................................
$msg = 0 然后if(empty($msg) 程序员对empty错误认识了,认为empty和0->flase 1->ture. empty函数只是判断参数是否为空,$msg=0了显然不为空了。。。 伤不起囧。。。。
6)程序缺陷一:
Jannock
代码中:
$filename = paramsFmt(urldecode($_GET["filename"])); //filename我们完全可以控制!
.............................
然后:
$nameExt = strtolower($COMMON->getFileExtName($_FILES['file']['name']));
$unallowedType = array('php', 'jsp', 'asp', 'sh', 'pl', 'js', 'jar', 'jad', 'class', 'java');
if(in_array($nameExt, $unallowedType)){
if($ft == '1'){
echo 'pe';
}else if($ft == '2'){
echo 'fe';

exit;
}
恩 对我们上传的程序进行了判断呢.
...................................
$filenameNew = $dest.$filename; //完全完全可以控制
if(empty($_FILES["file"]['error'])){
move_uploaded_file($_FILES["file"]["tmp_name"],$filenameNew); //上传了。
....................................................................
伤不起啊$_GET["filename"]我们能直接赋值,果断能覆盖绕过啊~~~~~
7)缺陷一归:
鬼哥用友软件再再暴用
xxx.php. 这样一样可以解析为 php 的 绕过了expload分割数组验证,而且xx.php.某些系统能解释php.
修复判断:判断最后一个字符是否为

相关文章
  • 没有相关文章
  • 徐汉涛(www.xuhantao.com) © 2024 版权所有 All Rights Reserved.
  • 部分内容来自网络,如有侵权请联系站长尽快处理 站长QQ:965898558(广告及站内业务受理) 网站备案号:蒙ICP备15000590号-1