第十一关:进入靶场环境查看源码:

对代码进行分析
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","pht","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess","ini");
$file_name = trim($_FILES['upload_file']['name']);
$file_name = str_ireplace($deny_ext,"", $file_name);//替换函数
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH.'/'.$file_name;
if (move_uploaded_file($temp_file, $img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
我们看见本关源码是将名单中有的尾缀替换成空,并且是一次过滤,那么我们可以采用重复写php的方式绕过过滤
.phphpp,具体操作如图


上传成功。
第十二关:进入靶场环境查看源码

对代码进行分析
$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
$ext_arr = array('jpg','png','gif');
$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
if(in_array($file_ext,$ext_arr)){
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
if(move_uploaded_file($temp_file,$img_path)){
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else{
$msg = "只允许上传.jpg|.png|.gif类型文件!";
}
}
我们对代码进行分析可以看出这是一个很明显的白名单过滤,只允许上传jpg|png|gif格式的文件。而且对文件进行重命名,那么我们对于白名单绕过的方式有%00截断。

此方法的原理为参数save_path可控,我们截取下关键代码对此方法原理进行分析
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;/*如果我们在save_path中传入文件上传路径+1.php代码就会像下面这么运行*/
$img_path = ../upload/1.php%00."/".rand(10, 99).date("YmdHis").".".$file_ext;
/*%00会截断后面文件的重命名*/
上传成功

第十三关:进入靶场环境查看源码

对代码进行分析
$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
$ext_arr = array('jpg','png','gif');
$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
if(in_array($file_ext,$ext_arr)){
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
if(move_uploaded_file($temp_file,$img_path)){
$is_upload = true;
} else {
$msg = "上传失败";
}
} else {
$msg = "只允许上传.jpg|.png|.gif类型文件!";
}
}
依旧是白名单绕过,唯一的区别就是上一关参数save_path是以GET形式传参,而本关是以POST形式传参,我们依旧使用%00截断,从而绕过过滤。

此处%00需要手动解码,上传成功。

以POST方式提交的数据需要手动解码,因为POST不会自动解码。%00截断只使用与PHP版本小于5.3。