安全-Pass11之黑名单双写绕过(upload-labs)
Posted 小狐狸FM
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了安全-Pass11之黑名单双写绕过(upload-labs)相关的知识,希望对你有一定的参考价值。
文章目录
前言
php
即Hypertext Preprocessor
超文本预处理器,多用于web
后端- BUUCTF的upload-labs在线靶场和本地的靶场有点差别,如果用文章的方法没法绕过时,注意看一下源码是否一致
相关介绍
其他介绍
一、题目
php
后端代码
$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 . '文件夹不存在,请手工创建!';
}
}
二、WriteUp
[1]. 函数介绍
PHP函数 | 介绍 |
---|---|
file_exists(路径) | 判断指定的文件或目录是否存在,不存在返回true,否则返回false |
isset(变量) | 如果变量存在且值不为null返回true,否则返回false |
move_uploaded_file(文件路径,文件夹路径) | 将文件移动到指定文件夹下 |
str_ireplace(字符串1,字符串2,字符串3) | 在字符串3中搜索,如果含有字符串1的子串就替换成字符串2 |
trim(字符串) | 删除字符串前后的空白符,空白符: 空格、制表符(\\t )、换行符(\\n )、回车符(\\r )、空字节符(\\0 )和垂直制表符(\\x0B ) |
[2]. 源码审计
(1). 变量判断
- 对
php
代码进行审计,if语句比较多最好从外往内分析- 第一条
if
语句只是判断了一下提交的post
请求中submit
参数是否被设置且非空
PHP:isset - Manual
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {//第一条if语句
//代码
}
(2). 路径判断
- 第二条语句判断了一下文件上传的路径存不存在,存在的话就执行里面的代码,不存在就给
$msg
设置回显信息- 通过
Seay
审计的全局搜索功能可以找到UPLOAD_PATH
是在config.php
中被定义的
Pass-02\\index.php
的代码中包含了上一级目录下的config.php
然后这个变量就可以在Pass-02\\index.php
中直接使用../
表示访问上一级的目录,所以upload-labs-master\\Pass-02\\index.php
包含的是upload-labs-master\\config.php
- 当
UPLOAD_PATH
变量在upload-labs-master\\Pass-02\\index.php
中被调用时,就会设置上传的父文件夹为upload-labs-master\\upload
$is_upload = false;
$msg = null;
if (xxx) {//第一条if语句
if (file_exists(UPLOAD_PATH)) {//第二条if语句
//代码
}else {//第二条if语句为假
$msg = UPLOAD_PATH.'文件夹不存在,请手工创建!';
}
}
(3). 黑名单
$deny_ext
是一个数组类型,存储了需要被过滤的后缀名
"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"
//代码
if (xxx) {//第一条if语句
if (xxx) {//第二条if语句
$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");
//代码
}else {//第二条if语句为假
//代码
}
}
(4). 首尾去空
$_FILES['upload_file']['name']
会获取上传文件的名称,如下图的test3.txt
trim($_FILES['upload_file']['name'])
就是删除文件名称首尾
的空白符,然后赋值给变量$file_name
PHP:trim - Manual
//代码
if (xxx) {//第一条if语句
if (xxx) {//第二条if语句
//代码
$file_name = trim($_FILES['upload_file']['name']);
//代码
}else{//第二条if语句为假
//代码
}
}
(5). 黑名单过滤
str_ireplace
的作用是,删除变量$file_name
中含有数组$deny_ext
的字符串- PHP: str_replace - Manual
"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"
//代码
if (xxx) {//第一条if语句
if (xxx) {//第二条if语句
//代码
$file_name = str_ireplace($deny_ext,"", $file_name);
//代码
}else{//第二条if语句为假
//代码
}
}
(6). 文件存储路径设置
- 在上传文件的时候,文件都会被存储在一个临时的文件夹下
我们不需要知道具体路径,只需要通过tmp_name参数获取路径即可
UPLOAD_PATH
的值为../upload
,在config.php
文件中定义- PHP: in_array - Manual
//代码
if (xxx) {//第一条if语句
if (xxx) {//第二条if语句
//代码
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH.'/'.$file_name;
//代码
}else{//第二条if语句为假
//代码
}
}
(7). 移动临时文件
- 剩余的代码仅是用于移动上传的文件,没有对文件进行过滤操作
- PHP: move_uploaded_file - Manual
//代码
if (xxx) {//第一条if语句
if (xxx) {//第二条if语句
//代码
if (move_uploaded_file($temp_file, $img_path)) {//第三条if语句
$is_upload = true;
} else {//第三条if语句为假
$msg = '上传出错!';
}
}else{//第二条if语句为假
//代码
}
}
[3]. 双写绕过
可以构造一个后缀为
.pphphp
的一句话木马文件,在服务端处理的过程和结果如下
变量 | 传入的值 | 处理后 | 代码 | 代码作用 |
---|---|---|---|---|
$file_name | test11.pphphp | test11.pphphp | $file_name = trim($_FILES['upload_file']['name']) | 删除首尾空白符 |
$file_name | test11.pphp hp | test11.php | $file_name = str_ireplace($deny_ext,"", $file_name) | 置空操作 |
因为置空的操作只执行一次,所以删除了一次中间的
php
字符串后,p
与hp
仍然组成了.php
后缀
复制返回的图片链接并访问,访问成功无报错表示
test11.php
文件被解析了
使用菜刀或蚁剑连接木马
以上是关于安全-Pass11之黑名单双写绕过(upload-labs)的主要内容,如果未能解决你的问题,请参考以下文章
安全-Pass07之黑名单空格绕过(upload-labs)
安全-Pass09之黑名单::$DATA绕过(upload-labs)
安全-Pass05之黑名单.user.ini绕过(upload-labs)