upload-labs
首先得了解一下webshell是什么
webshell
Webshell是黑客经常使用的一种恶意脚本,其目的是获得服务器的执行操作权限
webshell就是以asp、php、jsp或者cgi等网页文件形式存在的一种代码执行环境,主要用于网站管理
、服
务器管理、权限管理
等操作。使用方法简单,只需上传一个代码文件,通过网址访问,便可进行很多日常操作,极大地方便了使用者对网站和服务器的管理。正因如此,也有小部分人将代码修改后当作后门程序
使用,以达到控制网站服务器
的目的。顾名思义,“web”的含义是显然需要服务器开放web服务,“shell”的含义是取得对服务器某种程度上操作命令。webshell主要用于网站和服务器管理,由于其便利性
和功能强大,被特别修改后的webshell也被部分人当作网站后门工具使用。
简单的说来,webshell就是一个asp或php木马后门,黑客在入侵了一个网站后,常常在将这些 asp或php木马后门文件放置在网站服务器的web目录中,与正常的网页文件混在一起。然后黑客就可以用web的方式,通过asp或php木马后门控制网站服务器,包括上传下载文件、查看数据库、执行任意程序命令等。
那么,我们就得提到两个概念:木马&后门
木马
“木马”全称是“特洛伊木马(TrojanHorse)”,原指古希腊士兵藏在木马内进入敌方城市从而占领敌方城市的故事。在Internet上,“特洛伊木马”指一些程序设计人员在其可从网络上下载 (Download)的应用程序或游戏中,包含了可以控制用户的计算机系统的程序,可能造成用户的系统被破坏甚至瘫痪。
后门
大家都知道,一台计算机上有65535个端口,那么如果把计算机看作是一间屋子,那么这65535个端口就可以它看做是计算机为了与外界连接所开的65535 扇门。每个门的背后都是一个服务。有的门是主人特地打开迎接客人的(提供服务),有的门是主人为了出去访问客人而开设的(访问远程服务)——理论上,剩下的其他门都该是关闭着的,但偏偏由于各种原因,很多门都是开启的。
于是就有好事者进入,主人的隐私被刺探,生活被打扰,甚至屋里的东西也被搞得一片狼迹。这扇悄然被开启的门——就是“后门”。
大家都知道,一台计算机上有65535个端口,那么如果把计算机看作是一间屋子,那么这65535个端口就可以它看做是计算机为了与外界连接所开的65535 扇门。每个门的背后都是一个服务。有的门是主人特地打开迎接客人的(提供服务),有的门是主人为了出去访问客人而开设的(访问远程服务)——理论上,剩下的其他门都该是关闭着的,但偏偏由于各种原因,很多门都是开启的。
于是就有好事者进入,主人的隐私被刺探,生活被打扰,甚至屋里的东西也被搞得一片狼迹。这扇悄然被开启的门——就是“后门”。
特点
webshell最大的特点就是可以穿越防火墙,由于与被控制的服务器或远程主机交换的数据都是通过80端口传递的,因此不会被防火墙拦截。并且使用webshell一般不会在系统日志中留下记录,只会在网站的web日志中留下一些数据提交记录,没有经验的管理员是很难看出入侵痕迹的。
webshell是网站入侵的脚本攻击工具,黑客通过入侵网站上传webshell后获得服务器的执行操作权限,比如执行系统命令、窃取用户数据、删除web页面、修改主页等。
pass-01
查看源代码
- 定义函数checkFile,来验证所上传的文件是否符合要求
- 获取输入文件。通过
document.getElementsByName
获取页面中名为upload_file
的文件输入框的值。 注意:document.getElementsByName
返回的是一个HTMLCollection,因此需要通过索引[0]
获取第一个元素的值。 - 3~6行:if条件引导,判断所上传文件是否为空,如果为空就输出“请选择要上传的文件!”
- 定义允许上传的文件类型
- 提取上传文件的扩展名
file.lastIndexOf(".")
:找到文件名中最后一个.
的位置。file.substring(...)
:从该位置开始提取字符串,直到文件名的末尾。 - 9~14行判断上传文件是否允许上传。
allow_ext.indexOf(ext_name + "|")
:在allow_ext
字符串中查找ext_name + "|"
。如果找不到,返回-1
,返回错误提示“该文件不允许上传,请上传。。。。”
经实践可以看到我们确实无法上传php文件了,那我们将后缀改为jpg,用bp抓包然后改后缀名
如此我们便上传成功了
pass-02
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name']
if (move_uploaded_file($temp_file, $img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '文件类型不正确,请重新上传!';
}
} else {
$msg = UPLOAD_PATH.'文件夹不存在,请手工创建!';
}
}
分析:
- 初始化变量is_upload的值为false
- 初始化变量msg的值为null(空)
- 检查是否通过post方法提交了表单
- 检查UPLOAD_PATH是否存在,否则提示“文件夹不存在,请手工创建(16.17行)”
- 检查文件的MIME类型是否为图片,确保用户上传的文件格式为JPEG、PNG或GIF格式,否则提示“文件类型不正确,请重新上传(13.14行)”
- 获取临时文件路径:
$_FILES['upload_file']['tmp_name']
是PHP上传文件时的临时存储路径。 - 构建文件路径:将文件存储到uplod_path下,并保留原始文件名
- 8~11行:移动上传文件:用move_uploaded_file函数将目标文件移动到指定路径,如果成功,则变量is_upload的值为ture,否则设置错误信息
此关同第一关相同,先上传jpg后缀的文件,然后bp抓包,改后缀为php
补充一个知识:MIME类型
该题的文件识别中的


MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的标准,用来表示文档、文件或字节流的性质和格式。
MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。
浏览器通常使用 MIME 类型(而不是文件扩展名)来确定如何处理URL,因此 We b服务器在响应头中添加正确的 MIME 类型非常重要。如果配置不正确,浏览器可能会无法解析文件内容,网站将无法正常工作,并且下载的文件也会被错误处理。
pass-03
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$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)) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
if (move_uploaded_file($temp_file,$img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
分析:
初始化变量is_upload的值为false
初始化变量msg的值为空
检查是否通过post的方法提交了表单
检查是否存在文件UPLOAD_PATH,否则提醒“文件夹不存在,请手工创建!(24~27)”
定义了一个数组,包含了禁止上传的文件扩展名(来防止用户上传可能执行的脚本文件),否则提示“不逊于上传。。。”
获取上传文件的原始文件名,并删除文件名末尾的点
从文件名中提取最后一个.及其后面的内容
将扩展名换为小写
去除肯能存在的::$DATA字符串,防止NTFS流攻击
去除扩展名首尾的空格
检查文件扩展名是否在禁止列表里
移动上传文件至目标路径【move_uploaded_file确保文件安全的转移到目标文件; date("YmdHis") . rand(1000, 9999) :生成唯一的文件名】
可以知道这关对上传文件的后缀有所限制,不允许上传.asp,.aspx,.php ,.jsp
但是在php中,.php3、.php4、.php5、.pht、.phtml、.phps 的文件都会被解析为 php 文件。
所以将后缀改为任一个都能上传成功
pass-04
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".php1",".html",".htm",".phtml",".pht",".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",".ini");
$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)) {
$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 . '文件夹不存在,请手工创建!';
}
}
初始化变量is_upload为false
初始化变量msg为空
检查文件是否通过post方法提交表单
检查是否存在文件UPLOAD_PATH,否则提示“文件不存在,请手工创建”
定义了一个数组【包含禁止上传的文件的文件扩展名】
获取文件名并删除文件末尾的点(6.7)
从文件名中提取最后一个“.”及后面的内容(得到扩展名)(8)
将扩展名转换为小写(可以不分大小写的识别扩展名)(9)
去除可能存在的::DATA字符串,防止NTFS流攻击(10)
去除扩展名首尾的空格(11)
检查文件扩展名是否在禁止列表(13)
将所上传的文件移动到指定路径