创建PHP一句话木马文件,
上传被拦截。查看源码发现页面是通过前端JS方式就行的验证。那么我是通过以下两种方式上传上去的。
浏览器禁用JS,刷新页面,直接上传PHPshell文件,上传成功。
将PHPshell文件后缀改为.JPG或者其他图片格式,上传,BP抓包,修改JPG为PHP,发送后,可以看到上传成功,并获得了上传路径。
上传成功后,我使用的是中国蚁剑链接shell的,连接成功。
Tips:本关对数据包的MIME进行检查
扩展学习:
最早的HTTP协议中,并没有附加的数据类型信息,所有传送的数据都被客户程序解释为超文本标记语言HTML 文档,而为了支持多媒体数据类型,HTTP协议中就使用了附加在文档之前的MIME数据类型信息来标识数据类型。
常见的MIME类型(通用型):
超文本标记语言文本 .html text/html
xml文档 .xml text/xml
XHTML文档 .xhtml application/xhtml+xml
普通文本 .txt text/plain
RTF文本 .rtf application/rtf
PDF文档 .pdf application/pdf
Microsoft Word文件 .word application/msword
PNG图像 .png image/png
GIF图形 .gif image/gif
JPEG图形 .jpeg,.jpg image/jpeg
au声音文件 .au audio/basic
MIDI音乐文件 mid,.midi audio/midi,audio/x-midi
RealAudio音乐文件 .ra, .ram audio/x-pn-realaudio
MPEG文件 .mpg,.mpeg video/mpeg
AVI文件 .avi video/x-msvideo
GZIP文件 .gz application/x-gzip
TAR文件 .tar application/x-tar
任意的二进制数据 application/octet-stream
Content-Type: application/octet-stream
为 Content-Type: image/jpeg
上传成功,获得路径。在配置文件中找到 #AddType application/x-httpd-php .php .phtml
,去除此行 #
注释符并在末尾添加 .php3 .php5
等,如图:
Tips:根据提示,本关黑名单过滤了尽可能可以解析的文件后缀,除了.htaccess
.htaccess是什么文件?
.htaccess文件(或者”分布式配置文件”),全称是Hypertext Access(超文本入口)。提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。作为用户,所能使用的命令受到限制。管理员可以通过Apache的AllowOverride指令来设置。
概述来说,htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。
Unix、Linux系统或者是任何版本的Apache Web服务器都是支持.htaccess的,但是有的主机服务商可能不允许你自定义自己的.htaccess文件。
启用.htaccess,需要修改httpd.conf,启用AllowOverride,并可以用AllowOverride限制特定命令的使用。如果需要使用.htaccess以外的其他文件名,可以用AccessFileName指令来改变。例如,需要使用.config ,则可以在服务器配置文件中按以下方法配置:AccessFileName .config 。
笼统地说,.htaccess可以帮我们实现包括:文件夹密码保护、用户自动重定向、自定义错误页面、改变你的文件扩展名、封禁特定IP地址的用户、只允许特定IP地址的用户、禁止目录列表,以及使用其他文件作为index文件等一些功能。
本关采用.htaccess修改配置,从而达到文件上传目录里的文件均可以被当作PHP文件来解析。
AddType application/x-httpd-php .png 或者 <FilesMatch "文件名"> SetHandler application/x-httpd-php </FilesMatch>
Tips:上传目录存在php文件(readme.php)
网上谣传通过改变后缀名大小写即可通关,可查看源码发现,大小写是被过滤的。
工具提示readme.php
本关应该和这个文件有关,查阅大量资料后得知,应该是要使用和上一个.htaccess
类似的.user.ini
来完成。
.user.ini
文件auto_prepend_file = 1.jpg
.user.ini
再上传1.jpg
/upload/readme.php?w328=phpinfo();
.user.ini
和1.jpg
添加图片头欺骗GIF89a
不行。GIF89a auto_prepend_file = 1.jpg
GIF89a 一句话木马
php.ini
配置,不行。$_REQUEST
改为$_POST
,也不行。Tips:禁止上传.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.Html|.Htm|.pHtml|.jsp|.jspa|.jspx|.jsw|.jsv|.jspf|.jtml|.jSp|.jSpx|.jSpa|.jSw|.jSv|.jSpf|.jHtml|.asp|.aspx|.asa|.asax|.ascx|.ashx|.asmx|.cer|.aSp|.aSpx|.aSa|.aSax|.aScx|.aShx|.aSmx|.cEr|.sWf|.swf|.htaccess后缀文件!
禁止了很多,但通过看源码发现,本关没有过滤大小写。
查看源码,本关卡没有做空格过滤。
查看本关卡源码,本关卡未做::$DATA
过滤。
::$DATA作用
php在windows中如果文件名+”::$DATA”会把::$DATA之后的数据当成文件流处理,不会检测后缀名,且保持”::$DATA”之前的文件名(Windows文件流特性,所以仅限windows服务器绕过)
::$DATA
,发包,成功,如下图:::$DATA
扩展学习:
str_ireplace() 函数替换字符串中的一些字符(不区分大小写)。
把字符串 “Hello world!” 中的字符 “WORLD”(不区分大小写)替换成 “Peter”:
<?php echo str_ireplace("WORLD","Peter","Hello world!"); ?>
本关源码:
黑名单过滤,本关采用双写绕过
本关卡源码:
url中%00表示ascll码中的0 ,而ascii中0作为特殊字符保留,表示字符串结束,所以当url中出现%00时就会认为读取已结束。
使用情况:
截断条件:
save_path=../upload/
后面追加shell.php%00
发送,成功,如下图:本关卡和上一关卡类似,只不过发送请求方式由get改成了post,post就不能直接使用%00截断,需要在hex进行二进制00截断。
Tips:
copy yang.jpg/b+shell.php/a shellpic.jpg
回车,图片木马生成成功,如下图:function getReailFileType($filename){ $file = fopen($filename, "rb"); $bin = fread($file, 2); //只读2字节 fclose($file); $strInfo = @unpack("C2chars", $bin); $typeCode = intval($strInfo['chars1'].$strInfo['chars2']); $fileType = ''; switch($typeCode){ case 255216: $fileType = 'jpg'; break; case 13780: $fileType = 'png'; break; case 7173: $fileType = 'gif'; break; default: $fileType = 'unknown'; } return $fileType; } $is_upload = false; $msg = null; if(isset($_POST['submit'])){ $temp_file = $_FILES['upload_file']['tmp_name']; $file_type = getReailFileType($temp_file); if($file_type == 'unknown'){ $msg = "文件未知,上传失败!"; }else{ $img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$file_type; if(move_uploaded_file($temp_file,$img_path)){ $is_upload = true; } else { $msg = "上传出错!"; } } }
file
,在地址栏补全?file=upload/图片名称.jpg
回车,如下图:方法同Pass-14
程序出错无法正常访问,其他题做完了再过来修复完成。
Tips:重新渲染的了图片
源码:
<?php include '../config.php'; include '../head.php'; include '../menu.php'; $is_upload = false; $msg = null; if (isset($_POST['submit'])){ // 获得上传文件的基本信息,文件名,类型,大小,临时文件路径 $filename = $_FILES['upload_file']['name']; $filetype = $_FILES['upload_file']['type']; $tmpname = $_FILES['upload_file']['tmp_name']; $target_path=UPLOAD_PATH.'/'.basename($filename); // 获得上传文件的扩展名 $fileext= substr(strrchr($filename,"."),1); //判断文件后缀与类型,合法才进行上传操作 if(($fileext == "jpg") && ($filetype=="image/jpeg")){ if(move_uploaded_file($tmpname,$target_path)){ //使用上传的图片生成新的图片 $im = imagecreatefromjpeg($target_path); if($im == false){ $msg = "该文件不是jpg格式的图片!"; @unlink($target_path); }else{ //给新图片指定文件名 srand(time()); $newfilename = strval(rand()).".jpg"; //显示二次渲染后的图片(使用用户上传图片生成的新图片) $img_path = UPLOAD_PATH.'/'.$newfilename; imagejpeg($im,$img_path); @unlink($target_path); $is_upload = true; } } else { $msg = "上传出错!"; } }else if(($fileext == "png") && ($filetype=="image/png")){ if(move_uploaded_file($tmpname,$target_path)){ //使用上传的图片生成新的图片 $im = imagecreatefrompng($target_path); if($im == false){ $msg = "该文件不是png格式的图片!"; @unlink($target_path); }else{ //给新图片指定文件名 srand(time()); $newfilename = strval(rand()).".png"; //显示二次渲染后的图片(使用用户上传图片生成的新图片) $img_path = UPLOAD_PATH.'/'.$newfilename; imagepng($im,$img_path); @unlink($target_path); $is_upload = true; } } else { $msg = "上传出错!"; } }else if(($fileext == "gif") && ($filetype=="image/gif")){ if(move_uploaded_file($tmpname,$target_path)){ //使用上传的图片生成新的图片 $im = imagecreatefromgif($target_path); if($im == false){ $msg = "该文件不是gif格式的图片!"; @unlink($target_path); }else{ //给新图片指定文件名 srand(time()); $newfilename = strval(rand()).".gif"; //显示二次渲染后的图片(使用用户上传图片生成的新图片) $img_path = UPLOAD_PATH.'/'.$newfilename; imagegif($im,$img_path); @unlink($target_path); $is_upload = true; } } else { $msg = "上传出错!"; } }else{ $msg = "只允许上传后缀为.jpg|.png|.gif的图片文件!"; } } ?>
经过查询大量资料以及各种尝试后,确认将制作好的木马图片上传后,程序会对上传的图片进行二次渲染,打开已上传的文件查看十六进制代码,会发现之前添加进去的一句话代码没有了。而且验证了jpg、png、gif三种绕过二次渲染方式是不同的。这里说一下GIF的。
/upload-labs/include.php?file=upload/3187.gif
本关用到的软件:
Tips:需要代码审计
介绍:
条件竞争漏洞是一种服务器端的漏洞,由于服务器端在处理不同的请求时是并发进行的,因此如果并发处理不当或相关操作顺序设计的不合理时,将会导致此类问题的发生。
原理:
上传文件源代码里没有校验上传的文件,文件直接上传,上传成功后才进行判断:如果文件格式符合要求,则重命名,如果文件格式不符合要求,将文件删除。
由于服务器并发处理(同时)多个请求,假如a用户上传了木马文件,由于代码执行需要时间,在此过程中b用户访问了a用户上传的文件,会有以下三种情况:
本关源码:
$is_upload = false; $msg = null; if(isset($_POST['submit'])){ $ext_arr = array('jpg','png','gif'); $file_name = $_FILES['upload_file']['name']; $temp_file = $_FILES['upload_file']['tmp_name']; $file_ext = substr($file_name,strrpos($file_name,".")+1); $upload_file = UPLOAD_PATH . '/' . $file_name; if(move_uploaded_file($temp_file, $upload_file)){ if(in_array($file_ext,$ext_arr)){ $img_path = UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext; rename($upload_file, $img_path); $is_upload = true; }else{ $msg = "只允许上传.jpg|.png|.gif类型文件!"; unlink($upload_file); } }else{ $msg = '上传出错!'; } }
这关消耗了我大量的time😩
<?php $myfile = fopen("shell_pass18.php","w") or die("Unable to open file!"); $txt = '<? xxxxxx echo "i am";?>'; fwrite($myfile, $txt); fclose($myfile); ?>
上面代码中的xxxxxx
用下图中代码替换
intruder
,先点击Clear §
清除自动添加的标签,在请求头HOST地址后面追加?a=1
并给1
添加标签Add §
,点击Payload
Payload type
类型选择Numbers
,From=1
,To=20000
发送请求数量,这里随便,我尝试10000,可能手速不够快,没成功。Step=1
。设置完成,点击Start attack
开始爆破。(←点击Start attack
之前,先看第4步)第二个链接里的shell-18.php
就是shell文件里的代码,在竞争过程中会自动生成。准备好后,点击Start attack
然后切换到浏览器,开始刷新页面。建议一边观察upload
文件夹,一边刷新。如下图:
shell-18.php
,中国菜刀链接,成功。本关我采用了很多种方式去尝试,得出这种结果成功率是比较高的。
本关需要在Linux运行,其他关卡通关完了再回来弄吧。
本关偷懒方式:
本关偷懒方式:
upload-labs:https://github.com/c0ny1/upload-labs