靶场搭建
在本地内网搭建使用需要准备:PHPStudy、upload-labs源码
PHPStudy:https://old.xp.cn/download.html
upload-labs源码:https://github.com/c0ny1/upload-labs
点击下方链接使用夸克下载:
免费白嫖!8大网站渗透靶场+4大Windows纯净iso操作系统
下载完成过后将upload-labs源码解压到PHPStudy程序上级目录phpStudy_pro\WWW中:
打开PHPStudy启动Apache2.4.39
upload-labs关卡涉及知识点:
- Pass-01(前端验证)- Pass-02(MIME验证)- Pass-03(黑名单验证)- Pass-04(.htaccess)- Pass-05(黑名单验证,.user.ini)- Pass-06 (黑名单绕过,大小写绕过)- Pass-07(黑名单验证,空格绕过)- Pass-08 (黑名单验证,点号绕过)- Pass-09(黑名单,特殊字符::$DATA绕过)- Pass-10(黑名单 点 空格 点)- Pass-11(双写绕过)- Pass-12 (白名单绕过 00截断GET型)- Pass-13 (白名单绕过,post 00截断)- Pass-14(图片马)- Pass-15(getimagesize)- Pass-16(exif_imagetype)- Pass-17(二次渲染)- Pass-18(条件竞争)- Pass-19(条件竞争)- Pass-20(自由关)- Pass-21
关卡实践
1、Pass-01(前端验证)
这一关是前端验证,只需要解决前端限制,查看源码
function checkFile() { var file = document.getElementsByName('upload_file')[0].value; if (file == null || file == "") { alert("请选择要上传的文件!"); return false; } //定义允许上传的文件类型 var allow_ext = ".jpg|.png|.gif"; //提取上传文件的类型 var ext_name = file.substring(file.lastIndexOf(".")); //判断上传文件类型是否允许上传 if (allow_ext.indexOf(ext_name + "|") == -1) { var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name; alert(errMsg); return false; }}
这是通过js代码实现上传规则限制的,识别的是文件后缀(.jpg、.png、.gif)。只允许上传图片,可以上传方式:直接上传图片马、在前端限制中添加其他格式、
上传php木马(因为在前端审核文件类型所以添加php格式或删除):
然后删除js弹窗函数删除:
点击上传就上传成功了:
2、Pass-02(MIME验证)
MIME验证
抓包修改Content-Type允许上传的类型:
Content-Type:image/jpeg
点击发送就成功上传了后门:
3、Pass-03(黑名单验证)
黑名单验:
黑名单限制了.asp .aspx .php .jsp文件后缀。
我们只需要上传特殊后缀就行(例如:.php1、.phps、.pht 等):
4、Pass-04(.htaccess)
<FilesMatch "yanshu.png">SetHandler application/x-httpd-php<FilesMatch>
就是告诉apache遇到“yanshu.png”文件时要用php解析
5、Pass-05(黑名单验证,.user.ini)
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".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");
源码中有黑名单验证,这一关多过滤了Pass-04关的.htaccess但少过滤了大小写绕过。可以使用.user.ini、大小写绕过(.pHp、.Php)
.user.ini文件内容:
auto_prepend_file=yanshu.jpg
重新之定义php.ini让每个文件都自动包含yanshu.jpg。上传.user.ini文件后在上传yanshu.jpg
6、Pass-06(黑名单绕过,大小写绕过)
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".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",".ini");
源码中有黑名单验证,这一关多过滤了Pass-04、Pass-05关的.htaccess、.ini但少过滤了大小写绕过(.pHp、.Php)、和空格绕过(.php )
7、Pass-07(黑名单验证,空格绕过)
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".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",".ini");
源码中有黑名单验证,这一关过滤了Pass-04、Pass-05关的.htaccess、.ini但少过滤了大小写绕过(.pHp、.Php)、和空格绕过(.php )
8、Pass-08(黑名单验证,点号绕过)
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".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",".ini");
这一关可以在上传是拦截数据包在文件格式后面添加"."这里是“yanshu.php.”
9、Pass-09(黑名单,特殊字符::$DATA绕过)
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".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",".ini");
这一关几乎把能过滤的都过滤掉了,可以使用“::$DATA”php在window的时候如果文件名+"::$DATA"会把::$DATA之后的数据当成文件流处理,不会检测后缀名,且保持"::$DATA"之前的文件名 他的目的就是不检查后缀名。在这里抓包修改文件名为“yanshu.php::$DATA”
10、Pass-10(黑名单 点 空格 点)
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".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",".ini");
在这里可以抓包修改文件格式后缀,添加. .例如“yanshu.php. .”
11、Pass-11(双写绕过)
$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");
使用bp抓包把yanshu.php改成yanshu.pphphp
12、Pass-12(白名单绕过 00截断GET型)
只允许jpg png gif文件格式上传在12关中底层代码move_uploaded_file遇到0x00会截断0x表示16进制,URL中%00解码成16进制就是0x00。
我们可以尝试bp抓包将yanshu.php上传,把upload/后面添加yanshu.php%00。下面的文件名改为yanshu.jpg
13、Pass-13(白名单绕过,post 00截断)
制作图片马
copy 普通png格式图片.png/b + php木马.php 图片马.png
copy yanshu.png/b + yanshu.php yanshu2.php
在这里会生成一个yanshu2.php图片,这个yanshu2.php就是图片马
上传
上传十四关的图片马
17、Pass-17(二次渲染)
上传正常的GIF图片下载回显的图片,用010Editor编辑器进行对比两个GIF图片内容,找到相同的地方(指的是上传前和上传后,两张图片的部分Hex仍然保持不变的位置)并插入PHP一句话,上传带有PHP一句话木马的GIF图片
from PIL import Image, ImageDraw, ImageFont
import os
def create_gif_frames(output_dir, text, font_size=20, duration=100):
if not os.path.exists(output_dir):
os.makedirs(output_dir)
font = ImageFont.truetype("arial.ttf", font_size)
frames = []
for i in range(随便一个帧数都行,我建议10):
image = Image.new('RGB', (400, 200), color='white')
draw = ImageDraw.Draw(image)
draw.text((50, 80), text, fill='black', font=font)
frame_path = os.path.join(output_dir, f"frame_{i}.png")
image.save(frame_path)
frames.append(frame_path)
return frames, duration
def generate_gif(input_frames, output_path, duration):
images = [Image.open(frame) for frame in input_frames]
images[0].save(
output_path,
save_all=True,
append_images=images[1:],
duration=duration,
loop=0
)
if __name__ == '__main__':
output_dir = 'gif_frames'
output_gif = 'output.gif'
text = '二次渲染GIF'
frames, duration = create_gif_frames(output_dir, text)
generate_gif(frames, output_gif, duration)
print(f"GIF已生成: {output_gif}")
18、Pass-18(条件竞争)
第十八关主要是对条件竞争的考察,我们看代码他是先将图片上传上去,才开始进行判断后缀名、二次渲染。如果我们在上传上去的一瞬间访问这个文件,那他就不能对这个文件删除、二次渲染。这就相当于我们打开了一个文件,然后再去删除这个文件,就会提示这个文件在另一程序中打开无法删除。
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");
$file_name = $_POST['save_name'];
$file_ext = pathinfo($file_name,PATHINFO_EXTENSION);
if(!in_array($file_ext,$deny_ext)) {
$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 = '禁止保存为该类型文件!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
这关为开放性关卡,绕过黑名单的方法很多,可以发现文件名没有进行首位去空,也没有删除末尾的点,也没有转小写,没有去::$DATA,黑名单没有禁用ini...方法很多大家自行尝试。
21、Pass-21(数组验证)
这一关是利用数组绕过验证
完
联系方式/圈子
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论