DVWA靶场文件上传漏洞全级别通关及源码深度解析
在Web安全领域,文件上传漏洞是一种常见且危害极大的安全漏洞。DVWA(Damn Vulnerable Web Application)靶场提供了一个理想的练习环境,帮助安全人员理解和利用这种漏洞。本文将详细介绍如何在DVWA靶场的文件上传模块中,通过不同安全级别的挑战,并附带源码审计,帮助读者深入理解文件上传漏洞的防范与利用。
一、Low级别
在Low级别,文件上传功能没有进行任何过滤和检查,允许上传任意类型的文件。
通关步骤:
- 创建一个PHP文件(如test.php),内容可以是一句简单的PHP代码,用于验证上传是否成功。
- 在DVWA的File Upload模块中上传该文件。
- 上传成功后,通过访问
http://[服务器IP]:[端口]/hackable/uploads/test.php
来验证文件是否成功执行。
源码审计:
php复制代码
if( isset( $_POST[ 'Upload' ] ) ) { | |
$target_path = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/"; | |
$target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] ); | |
if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) { | |
$html .= '<pre>Your image was not uploaded.</pre>'; | |
} else { | |
$html .= "<pre>{$target_path} successfully uploaded!。</pre>"; | |
} | |
} |
源码中没有对上传文件的类型、内容或文件名进行任何检查,存在严重的安全隐患。
二、Medium级别
在Medium级别,文件上传功能增加了对文件类型和大小的限制,只允许上传JPEG和PNG格式的图片,且文件大小小于100KB。
通关步骤:
- 尝试上传一个PHP文件,会发现上传失败。
- 修改上传文件的Content-Type为image/jpeg或image/png,然后使用BurpSuite等抓包工具进行抓包,修改请求包中的文件类型信息,即可绕过限制成功上传PHP文件。
源码审计:
php复制代码
if( isset( $_POST[ 'Upload' ] ) ) { | |
// ... | |
$uploaded_type = $_FILES[ 'uploaded' ][ 'type' ]; | |
$uploaded_size = $_FILES[ 'uploaded' ][ 'size' ]; | |
if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) && $uploaded_size < 100000 ) { | |
// ... | |
} else { | |
$html .= '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>'; | |
} | |
} |
源码中虽然对文件类型和大小进行了限制,但仅通过Content-Type和文件大小进行判断,容易被绕过。
三、High级别
在High级别,文件上传功能增加了对文件头的检查,确保上传的文件是有效的图片文件。
通关步骤:
- 尝试上传一个PHP文件,会发现上传失败。
- 可以尝试修改PHP文件的文件头,使其看起来像一个有效的图片文件(如GIF89a),或者使用工具将PHP代码隐藏到图片中。
- 结合文件包含漏洞,利用include()函数将引入的文件作为PHP代码进行解析并执行。
源码审计:
php复制代码
if( isset( $_POST[ 'Upload' ] ) ) { | |
// ... | |
$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 ) ) { | |
// ... | |
} else { | |
$html .= '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>'; | |
} | |
} |
源码中增加了对文件扩展名和文件头的检查,但仍然存在一定的绕过方法,如修改文件头或利用文件包含漏洞。
四、Impossible级别
在Impossible级别,文件上传功能采取了一系列严格的措施来防止文件上传漏洞的产生。
通关步骤:
- 尝试上传一个PHP文件,会发现上传失败。
- 该级别下,文件上传功能使用了CSRF-Token、随机文件名称、文件后缀名检查、Content-Type检查、文件头检查以及使用GD库对图片进行重新编码等措施,极大地提高了安全性。
源码审计:
php复制代码
if( isset( $_POST[ 'Upload' ] ) ) { | |
// Check Anti-CSRF token | |
checkToken($_REQUEST['user_token'], $_SESSION['session_token'], 'index.php'); | |
// ... | |
$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 && | |
($uploaded_type == 'image/jpeg' || $uploaded_type == 'image/png') && | |
getimagesize( $uploaded_tmp ) ) { | |
// Strip any metadata, by re-encoding image | |
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 ); | |
// ... | |
} else { | |
$html .= '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>'; | |
} | |
// Generate Anti-CSRF token | |
generateSessionToken(); | |
} |
源码中采取了多种安全措施,有效地防止了文件上传漏洞的产生。
总结
通过DVWA靶场的文件上传漏洞挑战,我们可以深入理解文件上传漏洞的防范与利用。在实际开发中,应严格限制上传文件的类型、内容、大小以及文件名,并采取多种安全措施来防止文件上传漏洞的产生。同时,定期进行安全审计和漏洞扫描也是保障Web应用安全的重要手段。