文件上传(File Upload):
文件上传漏洞是指由于程序员在对用户文件上传部分的控制不足或者处理缺陷,而导致的用户可以越过其本身权限向服务器上上传可执行的动态脚本文件。这里上传的文件可以是木马,病毒,恶意脚本或者WebShell等。这种攻击方式是最为直接和有效的,“文件上传”本身没有问题,有问题的是文件上传后,服务器怎么处理、解释文件。如果服务器的处理逻辑做的不够安全,则会导致严重的后果。
因为获得管理员权限最快最直接,所以该漏洞在渗透中用的最多。
环境: 物理机(win10 x64)访问搭建了DVWA的虚拟机(win7 x86) IP地址为:192.168.157.137
工具: 中国菜刀。在Github上,或者在官网下载。务必下载来源可靠的。
Low
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中用域字符串拼接,所以 $target_path变量中存储上传文件的相对路径。
move_uploaded_file函数:
move_uploaded_file(file,newloc)
file,规定要移动的文件,newloc,规定文件的新位置。成功返回True。
所以这个级别的源码,不对上传的文件做任何过滤处理,将上传文件直接接受并将相对路径显示出来。
使用一句话木马进行攻击
- 创建一个木马文件test.php
- 上传至服务器
可以通过给的提示获得文件的位置为 :
http://192.168.157.137/DVWA-master/hackable/uploads/test.php
- 通过中国菜刀连接到服务器
操作文件或获取shell
Medium
Medium源码
<?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>';
}
}
?>
源码分析
与Low级别源码相比较,多了对上传文件的类型和大小的限制,只允许jpeg文件和png文件上传.
解决思路:
- 使用抓包,在数据包中将类型从application/octet-stream改为image/jpeg
- 结合其他漏洞,在Apache 的 conf 里添加一行配置
AddType application/x-httpd-php .jpg
,再制作一个图片一句话木马,上传并用中国菜刀控制。
实施攻击
思路1
抓包修改已经判断过的类型.
上传成功并且知道路径,之后的与LOW级别的一致
思路2
使用xss漏洞或者是csrf漏洞,在网站管理员不知情的情况下,在Apache 的 conf 里添加配置 AddType application/x-httpd-php .jpg
制作一个一句话木马过程:
- 准备三个文件
一个存有一句话木马的php文件
写一个批处理文件,内容为cmd
准备一张图片 - cmd切换到该目录下运行
copy 1.jpg/b+test.php ts.jpg
生成一句话木马,剩余的与LOW类似,发送至客户端并使用中国菜刀控制
成功!
High
High源码
<?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>';
}
}
?>
分析
与Medium源码比较,大体思想是一致的,不过这个是 分割出第一个’.'之后的所有后缀名(譬如1.jpg.jpg分割后就是jpg.jpg),再使用白名单进行匹配, 并且要求小于100000字节。所以Medium中的思路一被堵死了,没办法通过抓包修改类型来绕过。
但是如果配置文件中有AddType application/x-httpd-php .jpg
,那思路二是没有问题的,因为上传的一句话木马图片,是一张再正常不过的照片,但是使用php解析就是一个webshell,而若我们解决了将jpg使用php解析的难点,那么按照Medium的思路二就可以实施攻击。
Impossible
Impossible源码
<?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 "<pre><a href='${target_path}${target_file}'>${target_file}</a> succesfully uploaded!</pre>";
}
else {
// No
echo '<pre>Your image was not uploaded.</pre>';
}
// Delete any temp files
if( file_exists( $temp_file ) )
unlink( $temp_file );
}
else {
// Invalid file
echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
}
}
// Generate Anti-CSRF token
generateSessionToken();
?>
分析
与之前的源码相比较,综合了中级和高级,限定了后缀名白名单,大小,判断类型,将文件名以MD5加密的方式保存等等的方式。可以说上传的必须是图片,且做了多种限制,并且保存的名称与路径未知。
但是包含一句话木马的图片仍然可以上传至服务器。
也可以使用中国菜刀连接。
但是文件上传漏洞需要:
- 文件成功的上传
- 知道上传之后的文件名
- 知道上传文件所保存的路径
- 在 Apache 的 conf 里有这样一行配置
AddType application/x-httpd-php .jpg
而这里若不是因为之前的级别让我知道了文件保存在哪里,并且自己投机取巧在配置文件中加上可以让.jpg以.php文件方式解析的设置,那只凭这个漏洞不可能成功。
但是也给了我提醒,可以使用xss,或者csrf使管理员在不知情的情况下在改变配置文件,而上传的文件也可以写成在一个已知的目录下创建一个一句话木马的php程序,这样就解决了以上几个问题。