文章总结: 本文详细分析了CTF竞赛中文件上传漏洞的攻防技术,系统阐述了漏洞成因(如路径截断、过滤不严、解析漏洞)及多种绕过手法(客户端验证绕过、黑名单/白名单绕过、Apache/IIS解析特性利用),并通过一道《从0到1:CTFer成长之路》实战题目演示了利用空字节截断和Zip路径穿越上传WebShell的全过程,最终成功获取flag。 综合评分: 88 文章分类: CTF,WEB安全,漏洞分析,实战经验,安全工具
(二)服务器验证绕过
修改Content-Type头
虽然这是在服务端进行的验证,但其可靠性并不高。服务器通过检查HTTP请求头中的Content-Type字段来判断文件类型。攻击者可以通过Burp Suite拦截请求,将恶意文件的Content-Type(如application/octet-stream)修改为合法的图片类型,例如image/gif或image/jpeg,从而绕过检测。更高级的技巧是,在恶意脚本文件的开头添加图片文件的“幻数”,例如在PHP木马前添加GIF89a,使其在文件头校验时也能伪装成一张正常的GIF图片。
黑名单过滤
黑名单过滤是一种“堵”的策略,即列出所有不允许上传的文件后缀。然而,这种方法存在天然的缺陷:无法穷尽所有可能的可执行后缀。以一份常见的黑名单为例,它可能只禁止了.php、.asp、.jsp等后缀。攻击者可以尝试上传.php3、.php4、.phtml、.cer、.cdx等同样能被服务器解析执行的后缀。此外,还可以利用一些特殊技巧进行绕过,例如:
-
大小写绕过
:在Windows系统下,
.PHP、.PhP与.php是等效的。 -
双写绕过
:如果服务器采用字符串替换的方式过滤,如将
php替换为空,那么上传pphphp,经过一次替换后就会变成php。 -
特殊字符绕过
:在文件名末尾添加空格或点(
.),如.php.或.php[空格],Windows系统在保存文件时会自动去除末尾的空格和点。
白名单过滤
白名单过滤是一种“疏”的策略,只允许指定的、安全的文件后缀(如.jpg、.png、.gif)上传。这是目前公认最安全的文件上传防御方式之一,在实战中极大地增加了攻击难度。
然而,在CTF竞赛或某些特定场景下,出题人往往会留一个文件包含的点给我们,如果网站同时存在文件包含漏洞,攻击者仍有一线生机。攻击者可以先将包含恶意代码的“图片马”以合法后缀(如.jpg)上传,然后利用文件包含漏洞,将这个图片文件当作PHP脚本进行包含和执行。
Apache文件解析缺陷
Apache服务器在处理文件后缀时,存在一些历史遗留的解析特性,可被攻击者利用。
-
多后缀解析
:Apache在解析文件名时,会从右向左寻找它“认识”的后缀。例如,对于一个名为
shell.php.123的文件,如果Apache不认识.123这个后缀,它会继续向前查找,直到发现.php,便会将其作为PHP脚本执行。这使得攻击者可以通过构造恶意文件.php.非法后缀的形式绕过检查。 -
.htaccess文件攻击:
.htaccess是Apache的分布式配置文件。如果服务器允许上传此文件,攻击者可以上传一个自定义的.htaccess文件,在其中配置规则,强制让Apache将特定后缀(如.jpg)的文件当作PHP脚本来解析。这样一来,即使上传的是图片格式,也能成功执行其中的恶意代码。
IIS6解析漏洞
老旧的IIS6.0服务器存在的解析漏洞至今仍在一些未升级的系统中构成威胁。
-
文件名解析漏洞
:利用分号(
;)进行截断。在IIS6.0中,image.asp;.jpg这样的文件名会被解析为image.asp。分号后面的内容被忽略,从而使一个看似是JPG的图片文件被当作ASP脚本执行。 -
目录名解析漏洞
:如果攻击者能够在服务器上创建一个名为
shell.asp/的目录(注意后缀是/),那么该目录下的任何文件,无论其后缀是什么(如test.jpg),都会被IIS6.0当作ASP文件来解析和执行。
三、题目练习
(一)《从0到1:CTFer成长之路》书籍配套题目
- 打开题目环境,发现是一个文件上传题目,下面给出的源代码如下:
<?php
header("Content-Type:text/html; charset=utf-8");
// 每5分钟会清除一次目录下上传的文件
require_once('pclzip.lib.php');
if(!$_FILES){
echo '
;
show_source(__FILE__);
}else{
$file = $_FILES['file'];
if(!$file){
exit("请勿上传空文件");
}
$name = $file['name'];
$dir = 'upload/';
$ext = strtolower(substr(strrchr($name, '.'), 1));
$path = $dir.$name;
function check_dir($dir){
$handle = opendir($dir);
while(($f = readdir($handle)) !== false){
if(!in_array($f, array('.', '..'))){
if(is_dir($dir.$f)){
check_dir($dir.$f.'/');
}else{
$ext = strtolower(substr(strrchr($f, '.'), 1));
if(!in_array($ext, array('jpg', 'gif', 'png'))){
unlink($dir.$f);
}
}
}
}
}
if(!is_dir($dir)){
mkdir($dir);
}
$temp_dir = $dir.md5(time(). rand(1000,9999));
if(!is_dir($temp_dir)){
mkdir($temp_dir);
}
if(in_array($ext, array('zip', 'jpg', 'gif', 'png'))){
if($ext == 'zip'){
$archive = new PclZip($file['tmp_name']);
foreach($archive->listContent() as $value){
$filename = $value["filename"];
if(preg_match('/\.php$/', $filename)){
exit("压缩包内不允许含有php文件!");
}
}
if ($archive->extract(PCLZIP_OPT_PATH, $temp_dir, PCLZIP_OPT_REPLACE_NEWER) == 0) {
check_dir($dir);
exit("解压失败");
}
check_dir($dir);
exit('上传成功!');
}else{
move_uploaded_file($file['tmp_name'], $temp_dir.'/'.$file['name']);
check_dir($dir);
exit('上传成功!');
}
}else{
exit('仅允许上传zip、jpg、gif、png文件!');
}
}
- 尝试选择一个jpg文件,上传成功。
- 建立木马php脚本,内容如下:
<?php
fputs(fopen('../hack.php','w'),'');
?>
- 尝试上传php,提示:
仅允许上传zip、jpg、gif、png文件! - 那只好尝试burpsuite拦截了,打开burpsuite,选择proxy选项卡,点击
open browser打开内置浏览器,输入容器地址,然后选择php文件上传,好,burpsuite已经拦截到了。
上传成功!,但访问提示404123456789.php.jpg,压缩到zip文件中,方便后续修改。123456789改为/../../89n1book{ThisIsUpLoadToPicfl4g}。免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:书中自有代码来 书中自有代码来 书中自有代码来《CTF之文件上传——你知道我在你的服务器上放了什么吗》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论