0x00 写在前面
从零学习php,最终目的实现代码审计入门,软件采用sublime text,环境使用phpstudy搭建,数据库是navicat,需要有基本的前端基础、简单的php+mysql后端基础、渗透知识和漏洞原理,文章跟随流沙前辈学习记录,看看曾经遥不可及的代码审计能不能慢慢啃下来。
本章为代码审计入门第九篇-DVWA靶场篇,对DVWA靶场漏洞进行代码审计。最近两门课期末考试,因为平时上课摸鱼太多,所以这几天狂补知识点导致很久没更新,今日继续学习。
0x01 文件上传
文件上传模块,注释写在代码里,尽量用详细的语言描述代码含义。
level-low
low等级只是接收了上传文件,对于文件类型、文件后缀等信息都没有做判断
low.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' ] );
// $_FILES专门获取文件上传的各种信息,在这里是获取客户端文件的原名称,basename() 函数返回路径中的文件名
// .=拼接上传上去的路径和文件名
// Can we move the file to the upload folder?
if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
// $_FILES上传的文件有一个临时存放的位置,把它的临时位置move到$target_path的位置,也就是我们正式存储的位置
// 前面还有还有一个感叹号取反,如果不这样做的话或者说没有这样执行
// No
$html .= '<pre>Your image was not uploaded.</pre>';
// 输出信息提示
}
else {
// Yes!
$html .= "<pre>{$target_path} succesfully uploaded!</pre>";
// 如果这样做的话,输出路径和文件名,成功上传
}
}
?>
level-medium
中等级与low相比,主要增加了对上传文件的类型限制
medium.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' ];
// 定义三个变量,$_FILES获取上传文件的信息,获取上传之前的文件的名称、类型、大小
// Is it an image?
if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) &&
( $uploaded_size < 100000 ) ) {
// 判断上传的文件MIME类型必须是image/jpeg或者image/png并且size小于100K
// 这条限制过去下面继续执行判断和low相同
// Can we move the file to the upload folder?
if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
// No
$html .= '<pre>Your image was not uploaded.</pre>';
}
else {
// Yes!
$html .= "<pre>{$target_path} succesfully uploaded!</pre>";
}
}
else {
// Invalid file
$html .= '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
}
}
?>
level-high
相比于与medium限制更加严格
high.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);
// strropsjie函数查找"."在$uploaded_name出现的位置+1然后用substr截取该部分字符串
// 啥意思呢?假如我上传11.php,出现的位置是3+1=4,4对应的是p开始,截取出来是php
// 作用总结就是从上传的文件名中截取出扩展名
$uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
$uploaded_tmp = $_FILES[ 'uploaded' ][ 'tmp_name' ];
//这部分一致,定义变量,$_FILES获取上传文件的信
// Is it an image?
if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) &&
( $uploaded_size < 100000 ) &&
getimagesize( $uploaded_tmp ) ) {
// 定义白名单jpg、jpeg、png并且大小小于100k并且getimagesize函数检测上传的是不是图片,同时满足这些条件继续执行
// Can we move the file to the upload folder?
if( !move_uploaded_file( $uploaded_tmp, $target_path ) ) {
// No
$html .= '<pre>Your image was not uploaded.</pre>';
}
else {
// Yes!
$html .= "<pre>{$target_path} succesfully uploaded!</pre>";
}
// 这部分相同
}
else {
// Invalid file
$html .= '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
// 不满足提示必须啊上传jpeg、png文件
}
}
?>
level-impossible
impossible写的有些复杂,咱个水平肯定绕不过去的。首先文件名根据时间戳md5随机生成,如果前端找不到图片位置,上传成功也连接不上。第二个还有一个图片重写功能,就是说虽然你上传过来了但我不用,我把图片元素复制一份然后销毁再自己生成,这点有效避免图片马的使用。