BugkuCTF-WEB题文件上传

启动场景
发现是文件上传
BugkuCTF-WEB题文件上传_第1张图片
只能上传图像,不能上传PHP文件,那应该是寻找漏洞上传PHP文件
PHP文件里写入一句话木马

使用burp抓包,不断尝试发现发现需要修改的地方有三个:
一个是http head里的Content-Type: multipart/form-data;
请求头部的 Content-Type 内容 随便改个大写字母过滤掉 比如 mulTipart/form-data (其t为大写)
Multipart里的部分字母改成大写的。

第二个是文件的的Content-Type: application/octet-stream,改成image/jpeg

第三个是文件后缀名改成php4
(依次尝试php4,phtml,phtm,phps,php5(包括一些字母改变大小写))分别将后缀名修改为php2, php3, php4, php5, phps, pht, phtm, phtml(php的别名),发现只有php4没有被过滤
BugkuCTF-WEB题文件上传_第2张图片
之后上传成功
BugkuCTF-WEB题文件上传_第3张图片
关闭代理,浏览器显示文件路径
BugkuCTF-WEB题文件上传_第4张图片
以菜刀连接:
BugkuCTF-WEB题文件上传_第5张图片
在这里插入图片描述
进入服务器后台,在根目录发现flag
BugkuCTF-WEB题文件上传_第6张图片
打开flag
得到flag

后来有大佬教了我做事,说都上了马了自己不会扒来看嘛,哇我真的是蠢,这都没想到,直接血的教训记了下来,并扒了源码分析:
参考源码.php文件

<html>
<body>
<?php 
$flag = "flag{test}"
?>
<form action="index.php" method="post" enctype="multipart/form-data">
My name is margin,give me a image file not a php<br>
<br>
<input type="file" name="file" id="file" /> 
<input type="submit" name="submit" value="Submit" />
</form>
<?php
function global_filter(){
 $type =  $_SERVER["CONTENT_TYPE"];//$_SERVER是一个服务器端的变量数组,提供许多关于服务器及客户端请求的变量值,像客户端浏览器类型、IP地址等
 if (strpos($type,"multipart/form-data") !== False){//strpos() 函数查找字符串在另一字符串里第一次出现的位置。strpos() 函数对大小写敏感。
  $file_ext =  substr($_FILES["file"]["name"], strrpos($_FILES["file"]["name"], '.')+1);//strrpos()查找字符串在另一字符串最后一次出现位置
        $file_ext = strtolower($file_ext); //strtolower() 函数把字符串转换为小写。
  if (stripos($file_ext,"php") !== False){
   American("Invalid File
"
); } } } //这里判断multipart/form-data用了strpos,该函数区分大小写,所以用Multipart/form-data的理由找到了,这样就能绕过里面的if ?> <?php global_filter(); if ((stripos($_FILES["file"]["type"],'image')!== False) && ($_FILES["file"]["size"] < 10*1024*1024)){ if ($_FILES["file"]["error"] == 0){ $file_ext = substr($_FILES["file"]["name"], strrpos($_FILES["file"]["name"], '.')+1); $file_ext = strtolower($file_ext); $allowexts = array('jpg','gif','jpeg','bmp','php4'); //array() 创建数组 if(!in_array($file_ext,$allowexts)){ American("give me a image file not a php"); } //这里定了个白名单,只漏了个php4出来,只能用php4的原因也找到了 $_FILES["file"]["name"]="bugku".date('dHis')."_".rand(1000,9999).".".$file_ext; //rand() 函数返回随机整数。 //date() 函数格式操作本地日期和时间,并返回已格式操作的日期字符串。 if (file_exists("upload/" . $_FILES["file"]["name"])){ //file_exists() 函数检查文件或目录是否存在。 echo $_FILES["file"]["name"] . " already exists.
"
; } else{ if (!file_exists('./upload/')){ mkdir ("./upload/"); system("chmod 777 /var/www/html/upload"); //system — 执行外部程序,并且显示输出 } move_uploaded_file($_FILES["file"]["tmp_name"],"upload/" . $_FILES["file"]["name"]);//move_uploaded_file — 将上传的文件移动到新位置 echo "Upload Success
"
; $filepath = "upload/" . $_FILES["file"]["name"]; echo "Stored in: " ."< a href='" . $filepath . "' target='_blank'>" . $filepath . "
"
; } } } else{ if($_FILES["file"]["size"] > 0){ echo "You was catched! :)
"
; } } ?> </body> </html> <?php /* $_SERVER是一个服务器端的变量数组,提供许多关于服务器及客户端请求的变量值,像客户端浏览器类型、IP地址等 通过 print_r($_SERVER)可以输出其里包含了那些内容 strpos() 函数查找字符串在另一字符串里第一次出现的位置。strpos() 函数对大小写敏感。 strrpos() - 查找字符串在另一字符串里最后一次出现的位置(区分大小写) 例如:echo strrpos("You love php, I love php too!","php"); 结果返回21 $_FILES -- $HTTP_POST_FILES [已弃用]HTTP 文件上传变量 PHP $_FILES 是一个预定义的数组,用来获取通过 POST 方法上传文件的相关信息。如果为单个文件上传,那么 $_FILES 为二维数组;如果为多个文件上传,那么 $_FILES 为三维数组。 $_FILES['myFile']['name'] 客户端文件的原名称。 $_FILES['myFile']['type'] 文件的 MIME 类型,需要浏览器提供该信息的支持,例如"image/gif"$_FILES['myFile']['size'] 已上传文件的大小,单位为字节。 $_FILES['myFile']['tmp_name'] 文件被上传后在服务端储存的临时文件名,一般是系统默认。可以在php.ini的upload_tmp_dir 指定,但 用 putenv() 函数设置是不起作用的。 $_FILES['myFile']['error'] 和该文件上传相关的错误代码。['error'] 是在 PHP 4.2.0 版本里增加的。下面是它的说明:(它们在PHP3.0以后成了常量) UPLOAD_ERR_OK 值:0; 没有错误发生,文件上传成功。 strtolower() 函数把字符串转换为小写。 date() 函数格式操作本地日期和时间,并返回已格式操作的日期字符串。 rand() 函数返回随机整数。 file_exists() 函数检查文件或目录是否存在。 如果指定的文件或目录存在则返回 true,否则返回 false。 system — 执行外部程序,并且显示输出 move_uploaded_file — 将上传的文件移动到新位置 */ ?>

你可能感兴趣的:(#,BugkuCTF-WEB,php,html5,mvc)