当前位置: 首页 > news >正文

DVWA靶场通过——文件上传漏洞

File Upload漏洞

它允许攻击者通过上传恶意文件来执行任意代码、窃取数据、获取服务器权限,甚至完全控制服务器。为了防止文件上传漏洞,开发者需要对文件上传过程进行严格的验证和处理。

1. 文件上传漏洞概述

文件上传漏洞发生在Web应用程序允许用户通过表单上传文件时,如果文件上传机制没有进行严格的验证和限制,攻击者可以上传恶意文件。这些恶意文件通常包含恶意脚本(如PHP、ASP、JSP等)或二进制代码,可能被执行,造成远程代码执行(RCE)等严重安全问题。

2. 文件上传漏洞的常见利用方式

A. 执行恶意脚本(Remote Code Execution,RCE)

攻击者可以上传一个包含恶意PHP脚本的文件,利用文件上传漏洞执行任意PHP代码。这些文件通常

以 .php、.php3、.php4 等文件扩展名上传。

攻击方式:

  1. 上传恶意文件:攻击者上传一个恶意的 .php 文件,例如 shell.php,该文件包含恶意PHP代码。
  2. 访问文件:攻击者通过浏览器访问该文件,并触发其中的PHP代码,从而执行任意命令或代码。

例如,上传一个包含以下内容的 PHP 文件:

<?php
system($_GET['cmd']);
?>

攻击者可以通过访问该文件并提供 cmd 参数来执行任意系统命令:

http://victim.com/uploads/shell.php?cmd=ls

B. 路径遍历攻击(Directory Traversal)

攻击者通过路径遍历技术(../)操纵文件路径,将上传的文件保存到服务器上的其他目录,进而绕过文件上传限制。路径遍历通常出现在文件上传过程中,没有对上传路径进行有效的校验和限制。

例如,攻击者可以通过上传带有路径遍历的文件名:

../../../../../etc/passwd

如果服务器没有适当的安全检查,攻击者能够上传并访问 /etc/passwd 文件,进而获取敏感信息。

C. 替换现有文件

攻击者可以通过上传文件覆盖已有的关键系统文件或Web应用程序文件。例如,如果应用程序未对文件名进行充分验证,攻击者可以上传一个与现有文件同名的恶意文件并覆盖它。

D. 社交工程攻击

攻击者通过上传看似无害的文件(如 .jpg、.png、.pdf 等)进行社交工程攻击,诱使管理员或其他用户打开这些文件。虽然这些文件本身不包含恶意代码,但它们可能被用来作为后续攻击的载体,或者是作为伪装用来隐藏恶意文件的手段。

E. 服务器端请求伪造(SSRF)

通过上传某些特定类型的文件(如图片、PDF文件)并且恶意地构造内容,攻击者可能利用Web应用程序执行未经授权的内部请求,甚至访问服务器上的其他内部资源。

3. 防范File Upload漏洞的最佳实践

防范文件上传漏洞需要从多个角度进行防护。下面列出了一些防范上传漏洞的最佳实践:

A. 文件类型验证

确保上传的文件类型是预期的类型。仅允许上传特定扩展名的文件(如 .jpg, .png, .pdf 等)。

  • 文件扩展名:对文件的扩展名进行严格检查,防止上传恶意脚本文件(如 .php, .jsp)。
  • MIME类型验证:不仅验证文件的扩展名,还应检查文件的 MIME 类型。例如,确保上传的图片文件具有 image/jpeg 或 image/png 类型,而不是 application/x-php 等恶意类型。

$allowed_types = ['image/jpeg', 'image/png'];
$file_type = mime_content_type($_FILES['file']['tmp_name']);
if (!in_array($file_type, $allowed_types)) {
    echo "Invalid file type!";
    exit;
}

B. 文件名验证

对上传的文件名进行严格的验证,防止路径穿越(../)攻击,确保文件保存路径是安全的。

  • 使用 basename() 函数来获取文件的基本名称,并移除任何路径部分:

$file_name = basename($_FILES['file']['name']);

  • 防止文件名中出现恶意字符(如 ..、/ 等)。

C. 限制文件大小

通过设置最大文件上传大小限制,防止上传超大文件造成的资源耗尽攻击(DoS攻击)或系统崩溃。

在PHP中可以通过配置 upload_max_filesize 和 post_max_size 来控制上传文件的最大大小:

upload_max_filesize = 5M
post_max_size = 8M

D. 限制上传的文件数量

限制每个用户或每个会话可以上传的文件数量,避免大量恶意文件上传。

E. 使用临时存储

将上传的文件首先存储在临时目录中,不直接放到 Web 可访问的目录。然后,服务器可以在对文件进行验证后,才将其移动到正式目录。

$tmp_file = $_FILES['file']['tmp_name'];
$upload_dir = '/var/www/uploads/';
$final_file = $upload_dir . basename($_FILES['file']['name']);
if (move_uploaded_file($tmp_file, $final_file)) {
    echo "File uploaded successfully.";
} else {
    echo "File upload failed.";
}

F. 文件内容扫描

上传的文件可以通过 文件内容扫描 进行进一步验证,尤其是对可执行文件(如 PHP 文件、脚本文件)进行检查。例如,检查文件是否包含恶意代码、脚本标签或 PHP 标签。

  • 对上传的 PHP 文件进行 eval() 等关键字的扫描,阻止可执行脚本的上传。

G. 限制文件扩展名

通过严格的规则来控制上传的文件类型,允许的扩展名可以是特定的静态文件类型(如 .jpg、.png、.txt 等),而拒绝其他动态文件类型(如 .php、.asp、.jsp 等)。

$allowed_extensions = ['jpg', 'png', 'jpeg', 'gif'];
$extension = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
if (!in_array(strtolower($extension), $allowed_extensions)) {
    echo "Invalid file extension!";
    exit;
}

H. 禁止执行上传文件

即使上传了有效的文件,也要确保文件不会被执行。可以通过设置正确的文件权限或禁用Web目录中的文件执行。

  • 设置上传目录的权限,确保其中的文件无法被执行:

chmod 755 /var/www/uploads

  • 配置Web服务器(如 Apache 或 Nginx)禁用上传目录下的 PHP 文件执行。
    • 在 Apache 中可以使用 Options -ExecCGI 来禁止文件执行。
    • 在 Nginx 中可以使用 location 配置来阻止 PHP 文件的执行:
      location ~* \.php$ {
          deny all;
      }

I. 使用Web应用防火墙(WAF)

部署Web应用防火墙(WAF)来防御上传恶意文件的攻击。WAF可以通过实时监控、过滤文件内容、拦截恶意请求来帮助保护Web应用。

4. 总结

文件上传漏洞是一种严重的安全风险,攻击者可以利用该漏洞执行任意代码、访问敏感数据或破坏服务器。为了

防范文件上传漏洞,开发者应当:

  • 严格验证文件类型(扩展名和MIME类型)。
  • 对文件名进行清洗,防止路径穿越和文件覆盖。
  • 使用临时存储、限制文件大小和数量,并进行文件内容扫描。
  • 对文件执行权限进行严格控制,避免上传的文件被执行。

1low难度下的File Upload漏洞利用

1,靶场提供了一个上传文件的服务,可以尝试上传一句话木马

2,将一句话木马写入1.php,然后上传文件

3,告诉了上传文件的路径,可以结合文件包含漏洞利用。这里使用蚁剑进行连接

连接成功,这里文件上传漏洞的利用十分简单攻击者满足三个条件,就能实现成功入侵:

  1. 木马上传成功,未被安全软件或firewall查杀
  2. 知道木马的文件路径
  3. 上传的木马能正常运行

low难度的靶场源码进行分析

1. 缺乏文件类型验证

  • 描述:代码没有检查上传文件的类型。这意味着攻击者可以上传任意文件,包括恶意文件(例如 .php 或 .exe 文件)。
  • 漏洞利用:攻击者可以上传恶意 PHP 文件(如 shell.php),如果上传目录没有正确配置(例如允许执行 PHP 文件),攻击者就可以通过访问该文件来执行任意代码。

2. 文件名没有消毒处理

  • 描述:文件名直接使用 basename($_FILES['uploaded']['name']) 处理,这意味着文件名中的特殊字符(如 ;, &, | 等)不会被过滤掉。攻击者可以通过上传文件名中包含特殊字符来尝试执行命令注入或路径穿越攻击。
  • 漏洞利用
    • 命令注入:如果文件名包含 shell 元字符(如 ;, &, | 等),可以通过后续的文件操作触发命令注入。
    • 路径穿越:如果文件名包含 ../,可以尝试绕过上传目录的安全限制,访问系统其他目录。

3. 上传目录的权限问题

  • 描述:代码假设上传目录 hackable/uploads/ 是安全的,但没有明确指出该目录是否有正确的权限设置。如果该目录具有执行权限(如 777),上传的 PHP 文件可以在该目录中执行。
  • 漏洞利用:攻击者上传一个 PHP Web Shell 文件并访问该文件,可以远程执行代码,进而攻击服务器。

4. 没有对文件大小进行限制

  • 描述:代码没有限制上传文件的大小。如果上传的文件过大,可能会导致服务器存储资源被耗尽,或者服务器的文件系统被攻击者滥用。
  • 漏洞利用:攻击者可以上传非常大的文件,导致服务拒绝(DoS)或占用过多存储空间。

5. 文件路径拼接不安全

  • 描述:目标路径是通过直接拼接 $_FILES['uploaded']['name'] 来生成的,没有对文件名进行规范化或安全检查。攻击者可以上传包含路径穿越字符(../)的文件名,尝试把文件上传到系统的其他敏感目录。
  • 漏洞利用:攻击者上传一个文件,文件名可能包括路径穿越,如 ../../../etc/passwd,通过这类路径攻击访问系统文件。

6. 上传过程缺乏详细的错误处理

  • 描述:如果 move_uploaded_file() 失败,系统仅输出 'Your image was not uploaded.',并没有提供具体的错误信息。这可能让攻击者更容易猜测上传失败的原因并进行反向工程。
  • 漏洞利用:如果攻击者知道文件上传失败的具体原因(例如目标路径不可写或文件类型不允许),他们可以根据这些信息调整攻击策略。

7. 目标文件路径的潜在越权

  • 描述:上传的文件没有经过额外的权限或路径验证,目标路径是直接拼接的。如果上传目录没有得到严格限制,攻击者可能通过构造特殊的路径(例如通过 .. 来“跳出”目标目录)来覆盖重要的系统文件。
  • 漏洞利用:通过上传名为 ../../../etc/passwd 的文件,攻击者有可能覆盖或访问到系统关键文件(例如 /etc/passwd),并获取系统敏感信息。

8. 没有防止多次上传相同文件名的机制

  • 描述:如果多个用户上传相同文件名的文件,它们会覆盖原有的文件。这可能导致重要数据丢失,或者攻击者上传恶意文件覆盖合法文件。
  • 漏洞利用:攻击者可以上传一个恶意文件并覆盖原本存在的合法文件,从而执行注入的恶意代码。

9. 文件内容的缺乏验证

  • 描述:文件的内容没有进行任何类型的检查。如果攻击者上传的文件内容包含恶意脚本或其他形式的攻击载体,这些文件可能会对服务器安全构成威胁。
  • 漏洞利用:上传一个图片文件,其中可能包含恶意的 EXIF 元数据或隐藏的 JavaScript 代码,利用服务器中的漏洞进行进一步攻击。

总结

这段代码的主要安全问题包括:

  • 文件类型未验证,攻击者可以上传任意文件。
  • 文件名未消毒处理,可能导致路径穿越、命令注入等问题。
  • 上传目录权限不明确,上传的恶意文件可能被执行。
  • 缺乏文件大小限制,导致可能的资源耗尽攻击。
  • 缺乏错误信息处理,攻击者可能根据错误信息进行反向工程。

通过这些漏洞,攻击者可以实现各种攻击,例如远程代码执行(RCE)、信息泄露、服务拒绝(DoS)或文件覆盖攻击等。

2medium难度下的File Upload漏洞利用

1,如果按low难度的方式去文件上传是失败的,报错信息提示只允许传图片文件

2,这里的思路比较简单,給网站挂上burp suite的proxy,一句话木马文件命名为1.png,上传木马文件并在burp suite截获文件

3,右键发送到repeater模块,然后给filename改为1.php

4,然后就可以看到渲染页面render显示文件上传成功了,并且告诉了路径

5,使用蚁剑进行连接,成功获得网站的webshell

medium难度的靶场源码进行分析

在这段代码上传功能已经做了一些基础的文件类型和大小限制,但仍然存在潜在的漏洞和局限性。

1. 文件类型限制

if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) ) {

有效性:

  • 文件类型检查:代码通过检查文件的 MIME 类型 ($uploaded_type) 来限制上传的文件类型,只允许 JPEG 和 PNG 格式的图片。这是一种防范非图片文件上传的基本手段,可以避免一些常见的攻击(如上传 PHP 文件等)。

局限性:

  • 不可靠的 MIME 类型:$_FILES['uploaded']['type'] 是由客户端传递的,攻击者可以伪造这个值。例如,攻击者可以通过修改请求的 Content-Type 头来上传 PHP 文件,但将 MIME 类型伪装成 image/jpeg 或 image/png,从而绕过该检查。
  • 依赖客户端检测:由于 MIME 类型是客户端发送的,攻击者可以篡改请求头,绕过该限制。PHP 的 $_FILES['uploaded']['type'] 并不总是可信的,因此只能作为一种辅助验证,而不能作为唯一的防线。

2. 文件大小限制

$uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
if( $uploaded_size < 100000 ) {

有效性:

  • 文件大小限制:代码限制了上传文件的最大大小为 100,000 字节(即约 100 KB)。这对于防止上传过大的文件(如高分辨率的图片或视频)是有效的,可以防止攻击者通过上传大型文件耗尽服务器资源。

局限性:

  • 相对宽松的大小限制:虽然 100 KB 对于普通图片文件来说是合理的限制,但对于一些轻量级的恶意文件(如小型的 PHP Web Shell)而言,这个限制可能过于宽松。攻击者仍然可以上传一些小型恶意文件(如包含恶意代码的图片或压缩文件等)。
  • 没有对文件大小的服务器级别限制:尽管在代码中设置了上传文件大小限制,但如果 PHP 的配置文件(php.ini)没有设置上传文件的最大大小,攻击者仍然可以通过服务器的配置绕过此限制。例如,upload_max_filesize 和 post_max_size 配置项的设置可能允许上传比这个限制更大的文件。如果 PHP 配置不当,客户端限制就无法生效。

3. 文件名处理

$target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );

有效性:

  • 使用 basename() 过滤文件路径:通过使用 basename() 函数,代码试图避免路径穿越攻击(例如,上传 ../../etc/passwd 文件)。这可以确保文件名不包含目录路径,防止上传的文件写入其他系统目录。

局限性:

  • 文件名可能存在恶意字符:虽然 basename() 可以防止路径穿越攻击,但它没有对文件名本身进行过滤。如果上传的文件名包含恶意字符(如空格、&、;、$ 等),可能会导致命令注入或其他类型的漏洞。例如,上传文件名为 shell.php; rm -rf / 的文件,可能会导致攻击者通过命令注入控制服务器。
  • 文件扩展名未验证:上传的文件扩展名没有被验证或限制。即使文件名是 image.jpg,但文件的内容可能并不是图像文件。攻击者可能上传一个 PHP 脚本文件,修改扩展名为 .jpg 或 .png,从而绕过文件类型检查。

4. 文件内容验证

  • 没有对文件内容进行有效验证:代码只检查了文件的 MIME 类型和大小,并没有验证文件的实际内容。例如,一个文件可能被伪装成 image/jpeg 类型,但它的实际内容可能是一个包含恶意代码的文件(如嵌入了恶意的 PHP 代码的图片)。

局限性:

  • 缺乏更严格的内容验证:攻击者可以上传伪装成图片的恶意文件,利用文件的隐蔽性执行攻击。例如,通过上传带有恶意 PHP 代码的图片文件,如果上传目录的权限配置不当,恶意代码可能会被执行。
  • 没有使用图像库进行验证:可以使用 PHP 的图像处理函数(如 getimagesize())来验证文件是否真的是图像。即使文件扩展名是 .png 或 .jpg,通过这种方式检查文件内容可以确保文件符合预期的图像格式,而不是伪装的恶意文件。

5. 上传目录权限

  • 上传目录权限未明确控制:尽管代码中指定了目标路径,但没有明确提到该上传目录的权限配置。如果上传目录的权限过于宽松,允许执行 PHP 文件(如 777 权限),攻击者可以上传并执行恶意的 PHP Web Shell,控制服务器。

局限性:

  • 潜在的执行权限问题:如果上传目录没有进行严格的权限控制,上传的文件可能被执行。即使文件本身是图像文件,如果目录配置错误,攻击者仍然可以上传并执行伪装成图像的 PHP 脚本。

总结:有效性与局限性

有效性:

  • 文件类型和大小限制:通过 MIME 类型和文件大小的限制,代码能够有效地阻止部分不符合条件的文件上传(如非图片文件、过大文件等)。
  • 文件名路径防范:通过 basename() 防止路径穿越,确保文件被上传到预定目录。

局限性:

  • 不可信的 MIME 类型:客户端传递的 MIME 类型可以被篡改,无法完全依赖其进行验证。
  • 缺乏对文件内容的严格检查:未对上传的文件内容进行验证,攻击者可以伪装恶意文件绕过上传限制。
  • 上传目录权限不明确:如果上传目录没有严格的权限配置,攻击者可能上传并执行恶意文件。
  • 文件名不安全:文件名可能包含恶意字符,可能导致命令注入或路径执行问题。
  • 大小限制可能过于宽松:虽然设置了文件大小限制,但该限制可能不足以防止一些小型恶意文件上传。

3high难度下的File Upload漏洞利用

1,high难度下对文件上传的限制与过滤更加严格,还是挂上burp suite的proxy,一句话木马文件命名为1.png,上传木马文件并在burp suite截获文件

2,然后送入burp suite模块,尝试使用和medium靶场一样的操作方式

3,上传失败,说明改文件后缀这种简单的绕过方式是无效的。那么这个时候的思路就需要比较开阔,可以通过命令行制作图片木马文件【CTF】图片马制作-CSDN博客

win+R 、 cmd,输入 copy 图片文件名/b+一句话木马文件名/a 制作的图片马文件名

可以使用010editor查看图片木马是否制作成功

上传制作的图片木马文件

4,使用蚁剑根据暴露的上传的文件路径连接图片马,测试连接失败

此时是不能使用蚁剑连接的,因为蚁剑的原理是向上传文件发送包含参数(连接密码)的post请求,通过控制参数来执行不同的命令。这里服务器将木马文件解析成了图片文件,因此向其发送 post 请求时,服务器并不会执行相应命令

5,接下来就需要将这张图片木马当做php来执行,在DVWA靶场里面可以结合File Inclusion文件包含漏洞网站利用,构造 payload:

file://D:/phpstudy_pro/WWW/DVWA-master/hackable/uploads/1.png

一句话木马由此成功被解析,这个时候再使用蚁剑进行连接

6,除了利用该靶场的文件包含漏洞,还可以使用该靶场的命令执行漏洞对文件进行改名,最后再用webshell管理工具蚁剑进行连接

high难度的靶场源码进行分析

有效性:

  1. 文件扩展名检查
    • 代码限制上传文件的扩展名仅为 .jpg, .jpeg, .png,这有效地防止了上传其他类型的文件(如 .php、.html、.exe 等可能含有恶意代码的文件)。
  2. 文件大小限制
    • 代码对上传文件的大小进行了限制,文件必须小于 100 KB。这有助于防止攻击者上传过大的文件,减少对服务器资源的消耗(如磁盘空间和带宽)。
  3. 图像文件验证
    • 使用 getimagesize() 函数检查上传的文件是否为有效的图像文件。即使文件扩展名正确,getimagesize() 仍然可以确保文件的实际内容是图像。这可以防止一些恶意脚本伪装成图片文件上传。

局限性:

  1. 扩展名验证不充分
    • 文件扩展名检查只能防止常见的扩展名伪造攻击(例如 .php 攻击),但是攻击者可以上传其他伪装文件(如 .jpg.php 或 .png.php)。如果文件名后缀包含多个点(例如 evil.jpg.php),就可能绕过扩展名检查。
  2. 图像验证有限
    • getimagesize() 只能验证文件是否为有效的图像文件,但不能确保文件本身不包含恶意代码。例如,攻击者可以上传带有 PHP 代码的图片文件(如通过包含在图片末尾的恶意代码)。如果上传目录具有执行权限,恶意代码可能会被执行。
  3. 缺乏文件名消毒
    • 上传的文件名没有经过严格的消毒处理。虽然使用了 basename() 防止路径穿越攻击(例如 ../../etc/passwd),但文件名仍然可能包含恶意字符(如空格、分号等)并导致其他安全问题(如命令注入)。
  4. 上传目录权限问题
    • 如果上传目录没有严格的权限控制(如不允许执行文件),即使上传的是图像文件,攻击者仍可能通过其他方式上传恶意文件(如上传包含 PHP 代码的图片)。确保目录权限设置为只允许写入且禁止执行是必要的。
  5. 服务器级别的限制未提及
    • 代码中对文件大小做了限制,但如果 PHP 配置(如 upload_max_filesize 和 post_max_size)不当,攻击者仍然可以上传更大的文件,绕过代码中的限制。

四,对high难度的靶场源码进行代码审计,分析其安全性能

1. CSRF 防护

checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

  • 优点
    • 代码使用了 Anti-CSRF token 来防止跨站请求伪造攻击(CSRF)。通过比对用户提交的 token 和服务器存储的 token,能够有效阻止恶意网站通过用户的浏览器发起未经授权的文件上传请求。
  • 潜在风险
    • 需要确保 generateSessionToken() 和 checkToken() 函数的实现是安全的。尤其是生成和验证 token 时,必须确保 token 足够复杂,并且使用 HTTPS 来防止中间人攻击。
    • 如果 token 没有正确保护(如容易被猜测或通过 XSS 漏洞泄露),攻击者仍然可能绕过 CSRF 防护。

2. 文件扩展名和 MIME 类型验证

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 ) )

  • 优点
    • 文件的扩展名、大小、类型都经过了验证,并且使用了 getimagesize() 来确认上传的文件是否为有效的图片。这能有效防止一些常见的上传漏洞,比如上传伪造的 PHP 文件。
  • 潜在问题
    • 扩展名验证不足:仅通过扩展名和 MIME 类型检查文件类型,并不足够强大。攻击者可以尝试上传带有恶意代码的图片文件(例如,PHP Web Shell 伪装成图片),绕过扩展名检查。攻击者还可以上传一个包含 PHP 代码的图片文件(例如 image.php.jpg),并利用文件上传目录的错误配置执行该代码。
    • getimagesize() 限制:getimagesize() 只能检查文件的图像头信息,而不能确保文件内容的安全性。攻击者可以构造一个带有恶意代码的有效图像文件。
    • MIME 类型伪造:$_FILES['uploaded']['type'] 是由客户端提供的,可以被伪造。攻击者可能会通过修改请求中的 MIME 类型来绕过服务器的验证(例如,将文件的 MIME 类型伪造为 image/jpeg)。

3. 文件重命名

$target_file = md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext;

  • 优点
    • 使用 md5() 和 uniqid() 生成唯一的文件名,这样可以有效避免文件名冲突,并防止攻击者通过上传恶意文件并利用文件名攻击(例如文件名包含路径穿越 ../)。
  • 潜在问题
    • MD5 不够安全:虽然 MD5 在这里用来生成文件名,但 MD5 已经被广泛认为不安全,因为它容易碰撞。虽然碰撞攻击在这种简单的场景中不太可能,但使用更安全的哈希算法(如 SHA-256)会更好。

4. 图片重新编码(去除元数据)

imagejpeg( $img, $temp_file, 100);

  • 优点
    • 通过重新编码图片来去除元数据(EXIF、XMP 等),这有助于防止攻击者通过在图片元数据中嵌入恶意代码来进行攻击。
  • 潜在问题
    • 图片处理不完全安全:尽管重新编码图片有助于去除元数据,但如果没有使用更为强大的工具(如 Imagick,而不是 GD),仍然存在一定的风险。GD 库处理图片时的漏洞可能被攻击者利用。
    • 如果图片中嵌入了恶意内容(例如,特殊的图像文件格式漏洞),重新编码并不能完全消除风险。

5. 文件移动和权限控制

if( rename( $temp_file, ( getcwd() . DIRECTORY_SEPARATOR . $target_path . $target_file ) ) )

  • 优点
    • 使用 rename() 将文件从临时目录移动到目标目录,避免了使用 move_uploaded_file(),这减少了某些可能的权限问题。
  • 潜在问题
    • 上传目录权限问题:代码没有明确提到上传目录的权限设置。若上传目录没有适当的权限控制,攻击者可以通过上传的文件执行恶意代码。因此,上传目录应设置为 禁止执行(noexec),并且应限制上传目录的访问权限。
    • 不安全的目录:如果目标目录 (hackable/uploads/) 位于 Web 根目录下且可被直接访问,上传的文件可能会被直接访问和执行(如果是 PHP 脚本或其他可执行文件)。建议将上传目录放在 Web 根目录之外,或者对文件类型进行进一步的检查。

6. 临时文件删除

if( file_exists( $temp_file ) )
    unlink( $temp_file );

  • 优点
    • 在上传操作完成后删除临时文件,这是一个好的做法,确保不留下不必要的文件。
  • 潜在问题
    • 删除失败未处理:如果 unlink() 删除临时文件失败,代码没有处理这个情况。如果出现失败,可能会留下垃圾文件。可以考虑增加错误处理逻辑,确保临时文件始终被清理。

7. 文件大小限制

( $uploaded_size < 100000 )

  • 优点
    • 限制上传文件大小为 100 KB,有助于防止上传过大文件,避免占用服务器过多的资源。
  • 潜在问题
    • PHP 配置问题:这段代码仅限制了文件大小,但 PHP 配置文件(php.ini)中的 upload_max_filesize 和 post_max_size 配置项也必须匹配。如果这些设置较大,攻击者可能绕过代码中的限制。因此,除了代码中的限制,服务器配置也需要严格控制文件大小。

总结:

优点:

  • CSRF 防护:通过 Anti-CSRF token 防止伪造的请求。
  • 文件类型和大小检查:有效限制上传文件的类型和大小。
  • 文件名唯一化:通过哈希值生成唯一文件名,避免文件名冲突和路径穿越问题。
  • 去除元数据:通过重新编码图片去除可能的恶意元数据。

潜在风险:

  • 扩展名和 MIME 类型伪造:仅依赖扩展名和 MIME 类型检查并不足够,攻击者可能伪造文件类型绕过验证。
  • 图像处理不足:尽管重新编码去除了元数据,但仍然存在图像格式漏洞的风险。
  • 文件权限问题:上传目录如果未严格配置权限,上传的文件可能会被执行。
  • MD5 安全性问题:使用 MD5 生成文件名可能存在哈希碰撞的风险,应考虑使用更安全的哈希算法。
  • 临时文件删除问题:临时文件删除失败未处理。

改进建议:

  1. 加强文件类型检查:除了扩展名和 MIME 类型,使用更强的内容验证,如通过 finfo_file() 或 exif_imagetype() 函数进一步验证文件类型。
  2. 目录权限控制:确保上传目录的权限设置为只允许写入,禁止执行文件。
  3. 使用更安全的哈希算法:使用 SHA-256 或其他更强的哈希算法代替 MD5。
  4. 服务器配置:确保 PHP 配置中的文件大小限制与代码中的限制一致,避免绕过。
  5. 图像处理库:考虑使用更强大的图像处理库,如 Imagick,以提高安全性。

相关文章:

DVWA靶场通过——文件上传漏洞

File Upload漏洞 它允许攻击者通过上传恶意文件来执行任意代码、窃取数据、获取服务器权限&#xff0c;甚至完全控制服务器。为了防止文件上传漏洞&#xff0c;开发者需要对文件上传过程进行严格的验证和处理。 1. 文件上传漏洞概述 文件上传漏洞发生在Web应用程序允许用户通过…...

原子类、AtomicLong、AtomicReference、AtomicIntegerFieldUpdater、LongAdder

原子类 JDK提供的原子类&#xff0c;即Atomic*类有很多&#xff0c;大体可做如下分类&#xff1a; 形式类别举例Atomic*基本类型原子类AtomicInteger、AtomicLong、AtomicBooleanAtomic*Array数组类型原子类AtomicIntegerArray、AtomicLongArray、AtomicReferenceArrayAtomic…...

MySQL(8)【聚合函数 | group by分组查询】

阅读导航 引言一、聚合函数1. 简介2. 使用示例&#xff08;1&#xff09;COUNT() 函数&#xff08;2&#xff09;SUM() 函数&#xff08;3&#xff09;AVG() 函数&#xff08;4&#xff09;MAX() 函数&#xff08;5&#xff09;MIN() 函数 二、group by分组查询1. 基本语法2. 按…...

如何监控Elasticsearch集群状态?

大家好&#xff0c;我是锋哥。今天分享关于【如何监控Elasticsearch集群状态&#xff1f;】面试题。希望对大家有帮助&#xff1b; 如何监控Elasticsearch集群状态&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 监控 Elasticsearch 集群的状态对于确保…...

React第七节 组件三大属性之 refs 的用法注意事项

1、定义 React 中refs 是允许我们操作DOM 访问组件实例的一种方案。开发人员可以直接使用 refs 访问操作DOM&#xff0c;而不用自身的数据状态&#xff0c;这种方案在实际开发过程中是有必要的&#xff0c;但是不建议通篇使用refs操作DOM&#xff0c;如果是这样&#xff0c;那…...

全文单词统计

目标&#xff1a;统计词频 import scala.io.Source //知识点 //1.字符串.split("分隔符")&#xff1a;把字符串用指定的分隔符。拆分成多份&#xff0c;保存在数组中 object test1 {def main(args: Array[String]): Unit { //从文件1.txt中读入内容val contentSourc…...

Angular v19 (二):响应式当红实现signal的详细介绍:它擅长做什么、不能做什么?以及与vue、svelte、react等框架的响应式实现对比

本文紧接着Angular v19 新版本来啦&#xff0c;一起瞧瞧新特性吧&#xff01;&#xff0c;主要针对它在v18引入了一项全新的响应式技术——Signal&#xff0c;这引起了开发者社区的广泛关注&#xff0c;最新的v19版本推出了更多的signal工具。Signal的加入旨在优化Angular的响应…...

【数据结构】二叉搜索树(二叉排序树)

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;数据结构 目录 前言 一、什么是二叉搜索树 二、二叉搜索树的实现 节点 属性和接口的声明 插入 查找 删除 拷贝构造 析构 中序遍历 三、二叉搜索树的…...

文件的摘要算法(md5、sm3、sha256、crc)

为了校验文件在传输中保证完整性和准确性&#xff0c;因此需要发送方先对源文件产生一个校验码&#xff0c;并将该值传输给接收方&#xff0c;将附件通过ftph或http方式传输后&#xff0c;由接收方使用相同的算法对接收文件再获取一个新的校验码&#xff0c;将该值和发送方传的…...

Python实现人生重开模拟器

目录 人生重开模拟器介绍 代码实现 打印初始界面 设置初始属性 设置角色性别 设置角色出生点 针对每一岁&#xff0c;生成人生经历 完整代码 人生重开模拟器介绍 人生重开模拟器 是之前比较火的一个小游戏&#xff0c;我们这里使用 Python 实现一个简化版的 人生重开模…...

机器学习(二十五):决策树算法以及决策树和神经网络的对比

一、决策树集合 单一决策树会对训练数据的变化很敏感。例子&#xff1a;输入十个数据&#xff0c;判断是否是猫。只替换其中一个数据&#xff0c;信息增益最高的分裂特征就发生了改变&#xff0c;决策树就发生了变化。 使用决策树集合可以使算法更加健壮。例子&#xff1a;使用…...

k8s运行运行pod报错超出文件描述符表限制

1.问题描述 运行pod超过文件描述符表 unable to allocate file descriptor table - out of memory/opt/COMMAND.sh: line 9: 2.查看设备的文件描述符限制 操作前一定要先查询这个值&#xff0c;2097152这个值即为我们可设置的最大值&#xff0c;超过这个值后将无法登录&am…...

非常简单实用的前后端分离项目-仓库管理系统(Springboot+Vue)part 2

七、创建前端项目 你下载了nodejs吗&#xff1f;从cn官网下载&#xff1a;http://nodejs.cn/download/&#xff0c;或者从一个国外org网站下载&#xff0c;选择自己想要的版本https://nodejs.org/download/release/&#xff0c;双击下载好的安装文件&#xff0c;选择安装路径安…...

开源 AI 智能名片 2 + 1 链动模式 S2B2C 商城小程序源码助力品牌共建:价值、策略与实践

摘要&#xff1a;在当今数字化商业环境下&#xff0c;品牌构建已演变为企业与消费者深度共建的过程。本文聚焦于“开源 AI 智能名片 2 1 链动模式 S2B2C 商城小程序源码”&#xff0c;探讨其如何融入品牌建设&#xff0c;通过剖析品牌价值构成&#xff0c;阐述该技术工具在助力…...

微信小程序中的WXSS与CSS的关系及使用技巧

微信小程序中的WXSS与CSS的关系及使用技巧 引言 在微信小程序的开发中,样式的设计与实现是构建用户友好界面的关键。微信小程序使用WXSS(WeiXin Style Sheets)作为其样式表语言,WXSS在语法上与CSS非常相似,但也有一些独特的特性。本文将深入探讨WXSS与CSS的关系,介绍WX…...

STM32的CAN波特率计算

公式&#xff1a; CAN波特率 APB总线频率 / &#xff08;BRP分频器 1&#xff09;/ (SWJ BS1 BS2) SWJ一般为1。 例如STM32F407的&#xff0c;CAN1和CAN2都在在APB1下&#xff0c;频率是42000000 如果想配置成1M波特率&#xff0c;则计算公式为&#xff1a;...

【LeetCode面试150】——57插入区间

博客昵称&#xff1a;沈小农学编程 作者简介&#xff1a;一名在读硕士&#xff0c;定期更新相关算法面试题&#xff0c;欢迎关注小弟&#xff01; PS&#xff1a;哈喽&#xff01;各位CSDN的uu们&#xff0c;我是你的小弟沈小农&#xff0c;希望我的文章能帮助到你。欢迎大家在…...

活着就好20241128

早晨问候&#xff1a; 亲爱的朋友们&#xff0c;大家早上好&#xff01;今天是2024年11月28日&#xff0c;第48周的第四天&#xff0c;也是十一月的第二十八天&#xff0c;农历甲辰[龙]年十月廿四。在这个即将步入月末、阳光依旧明媚的清晨&#xff0c;愿第一缕阳光轻轻洒落在…...

【kafka03】消息队列与微服务之Kafka 读写数据

Kafka 读写数据 参考文档 Apache Kafka 常见命令 kafka-topics.sh #消息的管理命令 kafka-console-producer.sh #生产者的模拟命令 kafka-console-consumer.sh #消费者的模拟命令 创建 Topic 创建topic名为 chen&#xff0c;partitions(分区)为3&#xff0…...

【Agorversev1.1数据转换】Agorverse高清地图转OpenStreetMap及SUMO路网

文章目录 Agorverse高清地图转OpenStreetMap及SUMO路网1. Agorverse osm转换说明2. 转换源码3. 处理效果4. SUMO-Carla联合仿真 Agorverse高清地图转OpenStreetMap及SUMO路网 1. Agorverse osm转换说明 根据作者的描述&#xff0c;其高清地图的osm文件与标准osm的区别在于以下…...

Vue 3 实现高性能拖拽指令的最佳实践

前言 在现代前端开发中&#xff0c;拖拽功能是增强用户体验的重要手段之一。本文将详细介绍如何在 Vue 3 中封装一个拖拽指令&#xff08;v-draggable&#xff09;&#xff0c;并通过实战例子演示其实现过程。通过这篇教程&#xff0c;您将不仅掌握基础的拖拽功能&#xff0c;…...

AIGC--------AIGC在医疗健康领域的潜力

AIGC在医疗健康领域的潜力 引言 AIGC&#xff08;Artificial Intelligence Generated Content&#xff0c;人工智能生成内容&#xff09;是一种通过深度学习和自然语言处理&#xff08;NLP&#xff09;等技术生成内容的方式。近年来&#xff0c;AIGC在医疗健康领域展现出了极…...

Apache Calcite - calcite jdbc驱动使用场景

前言 在使用Calcite查询数据时通常会用到这些代码获取schema Connection connection DriverManager.getConnection("jdbc:calcite:", info); CalciteConnection calciteConnection connection.unwrap(CalciteConnection.class); SchemaPlus rootSchema calciteC…...

IEC61850实现方案和测试-4-MMS协议

IEC61850实现方案和测试-4作为介绍实现方案和测试的第四篇文章&#xff0c;后续会继续更新&#xff0c;欢迎关注。前三篇如下 第一篇是&#xff1a;IEC61850实现方案和测试-1-CSDN博客 第二篇是&#xff1a;IEC61850实现方案和测试-2-UCA-CSDN博客 第三篇是&#xff1a;IEC6…...

【ubuntu24.04】GTX4700 配置安装cuda

筛选显卡驱动显卡驱动 NVIDIA-Linux-x86_64-550.135.run 而后重启:最新的是12.6 用于ubuntu24.04 ,但是我的4700的显卡驱动要求12.4 cuda...

时间的礼物:如何珍视每一刻

《时间的礼物&#xff1a;如何珍视每一刻》 夫时间者&#xff0c;宇宙之精髓&#xff0c;生命之经纬&#xff0c;悄无声息而流转不息&#xff0c;如织锦之细线&#xff0c;串联古今&#xff0c;贯穿万物。 人生短暂&#xff0c;犹如白驹过隙&#xff0c;倏忽而逝&#xff0c;…...

componentReceivePropsreact class生命周期

componentReceiveProps并不是有props的变化触发&#xff0c;而是由父组件的更新触发的 父组件导致组件重新渲染&#xff0c;即使props没有更改&#xff0c;也会调用componentReceiveProps这个方法&#xff1b;如果只想处理更改&#xff0c;确保当前值与变更值比较--官方 …...

快速理解微服务中Sentinel怎么实现限流

Sentinel是通过动态管理限流规则&#xff0c;根据定义的规则对请求进行限流控制。 一.实现步骤 1.定义资源&#xff1a;在Sentinel中&#xff0c;资源可以是URL、方法等&#xff0c;用于标识需要进行限流的请求&#xff1b;(在Sentinel中&#xff0c;需要我们去告诉Sentinel哪些…...

25.100ASK_T113-PRO 测试摄像头(型号)

1.摄像头 USB2.0 摄像头,支持 UVC协议, 就是V4L2 USB2.0 大概可这样理解吧.这个是2K分辨率. 2.8mm焦距. 开发板还是 100ASK_T113-PRO V1.2版 2.查看摄像头驱动挂载情况 这样接好. 看看设备有没有挂载上 # ls /dev/video* /dev/video0 /dev/video1 这两个就是USB摄像头.说…...

20241127 给typecho文章编辑附件 添加视频 图片预览

Typecho在写文章时&#xff0c;如果一次性上传太多张图片可能分不清哪张&#xff0c;因为附件没有略缩图&#xff0c;无法实时阅览图片&#xff0c;给文章插入图片时很不方便。 编辑admin/file-upload.php 大约十八行的位置 一个while 循环里面,这是在进行html元素更新操作,在合…...

StarRocks-join优化

1、背景 有两个大表&#xff0c;都是6kw级别上下的&#xff0c;通过SR然后包装了一个接口对外提供查询&#xff0c;当前的问题是&#xff0c;这样大的join查询会导致BE直接宕机。并且这个sql很有代表性&#xff0c;我截图如下&#xff1a; 这个表是个单分区&#xff0c;所以直接…...

如何通过ChatGPT提高自己的编程水平

在编程学习的过程中&#xff0c;开发者往往会遇到各种各样的技术难题和学习瓶颈。传统的学习方法依赖书籍、教程、视频等&#xff0c;但随着技术的不断发展&#xff0c;AI助手的崛起为编程学习带来了全新的机遇。ChatGPT&#xff0c;作为一种强大的自然语言处理工具&#xff0c…...

实时数据开发 | checkpoints监控和调优

监控Checkpoints 监控 checkpoint 行为最简单的方法是通过 UI 的 checkpoint 部分。 监控这两个指标: 算子收到第一个 checkpoint barrier 的时间。当触发 checkpoint 的耗费时间一直很高时&#xff0c;这意味着 checkpoint barrier 需要很长时间才能从 source 到达 operator…...

面试手撕题积累

1、实现滑动窗口限流&#xff0c;允许每分钟最多有100个请求 阿里一面题。 核心&#xff1a; 时间窗口管理&#xff1a;滑动窗口会根据时间流逝不断更新&#xff0c;需要记录请求的时间戳&#xff0c;并根据当前时间计算窗口内的请求数量。 限流判断&#xff1a;每次请求到来…...

开发中使用UML的流程_05 PIM-1:分析系统流程

目录 1、概述 2、PIM生成的过程 3、用例叙述格式 4、用例关系 5、执行流程&#xff1a; 6、惯用的编号方式 1、概述 在进入到PIM阶段之后&#xff0c;系统分析员将所有系统用例依相关性分成若干组&#xff0c;以组别方式生成该组系统用例涉及的PIM-1---PIM-4产生结果&am…...

【Go】-go中的锁机制

目录 一、锁的基础知识 1. 互斥量/互斥锁 2. CAS&#xff08;compare and swap&#xff09; 3. 自旋锁 4. 读写锁 5. 乐观锁 & 悲观锁 6. 死锁 二、go中锁机制 1. Mutex-互斥锁 2. RWMutex-读写锁 2.1 RWMutex流程概览 2.2 写锁饥饿问题 2.3. golang的读写锁源…...

Scala学习记录,全文单词统计

package test32 import java.io.PrintWriter import scala.io.Source //知识点 // 字符串.split("分隔符"&#xff1a;把字符串用指定的分隔符&#xff0c;拆分成多个部分&#xff0c;保存在数组中) object test {def main(args: Array[String]): Unit {//从文件1.t…...

重构项目架构

前言 我们上篇文章对整个项目进行一个整体的规划&#xff0c;其中对于APP类规划了类&#xff0c;本篇文章我们就来实现这个规划&#xff1b; class App {//加载页面constructor() {}//获取位置_getPosition() {}//接受位置_loadMap() {}//在地图上点击展现表单_showForm() {}/…...

一个开源轻量级的服务器资源监控平台,支持告警推送

大家好&#xff0c;今天给大家分享一款开源的轻量级服务器资源监控工具Beszel&#xff0c;提供历史数据记录、Docker容器统计信息监控以及多种警报功能&#xff0c;用于监控服务器资源。 项目介绍 Beszel由hub&#xff08;中心服务器端应用&#xff0c;基于PocketBase构建&…...

介绍一下atof(arr);(c基础)

hi , I am 36 适合对象c语言初学者 atof(arr)&#xff1b;是返回浮点数(double型)&#xff0c;浮点数数是arr数组中字符中数字 格式 #include<stdio.h> atof(arr); 返回值arr数组中的数 未改变arr数组 #include<stdio.h> //atof(arr) 返 <stdlib> int…...

基于微信小程序的平价药房管理系统+LW参考示例

1.项目介绍 系统角色&#xff1a;管理员、医生、普通用户功能模块&#xff1a;用户管理、医生管理、药品分类管理、药品信息管理、在线问诊管理、生活常识管理、日常提醒管理、过期处理、订单管理等技术选型&#xff1a;SpringBoot&#xff0c;Vue&#xff0c;uniapp等测试环境…...

什么是 C++ 中的函数对象?它有什么特点?如何定义和使用函数对象?数对象与普通函数有什么区别?

在 C 中&#xff0c;函数对象&#xff08;Function Object&#xff09;也被称为仿函数&#xff08;Functor&#xff09;&#xff0c;是一种可以像函数一样被调用的对象&#xff0c;是一个类的对象&#xff0c;该类重载了函数调用运算符operator()。 函数对象的特点: 与普通函数…...

JAVA篇05 —— 内部类(Local、Anonymous、Member、Static)

欢迎来到我的主页&#xff1a;【一只认真写代码的程序猿】 本篇文章收录于专栏【小小爪哇】 如果这篇文章对你有帮助&#xff0c;希望点赞收藏加关注啦~ 目录 1 内部类Inner Class 1.1 局部内部类 1.2 匿名内部类&#xff08;※※&#xff09; 1.3 匿名类最佳实践&#xf…...

vmware安装ubuntu22.04 复制黏贴 上网

1、ubuntu下载 [Download - 清华镜像站]&#xff1a; 点击 清华大学开源软件镜像站 - Ubuntu 22.04.4 下载 页面中的 ubuntu-22.04.4-desktop-amd64.iso清华大学开源软件镜像站 - Ubuntu 22.04.4 下载 2、安装向导 3、网络设置 sudo netplan try sudo netplan apply4、复制…...

Spring Bean初始化流程

首先&#xff1a; 加载Bean定义(Configuration) 然后对于每个Bean&#xff1a; 1、实例化Bean&#xff08;应该是从Bean方法中获取&#xff0c;Bean方法里面包含new这个类型的代码&#xff09;2、依赖注入&#xff08;所依赖的Bean要经历相同的流程&#xff09;、调用Setter…...

C 语言函数递归探秘:从基础概念到复杂问题求解的进阶之路

我的个人主页 我的专栏&#xff1a;C语言&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01;点赞❤ 收藏❤ 目录 什么是函数递归递归的基本组成递归的工作原理递归的优缺点递归的经典案例 5.1 阶乘计算5.2 斐波那契数列5.3 汉诺塔问题5.4 二分查找 递归的高级…...

【Zookeeper】三,Zookeeper的安装与基本操作

文章目录 安装Zookeeper下载解压解压后的目录结构运行Zookeeper 基本操作 安装Zookeeper 下载 官网下载Zookeeper&#xff0c;会得到一个tar包&#xff0c;如&#xff1a;apache-zookeeper-3.8.4-bin.tar.gz 解压 tar -xvf apache-zookeeper-3.8.4-bin.tar.gz -C /usr/loca…...

STL算法之数值算法<stl_numeric.h>

这一节介绍的算法&#xff0c;统称为数值(numeric)算法。STL规定&#xff0c;欲使用它们&#xff0c;客户端必须包含头文件<numeric>.SGI将它们实现与<stl_numeric.h>文件中。 目录 运用实例 accumulate adjacent_difference inner_product partial_sum pow…...

Git 入门超简单指南

1. 什么是 Git&#xff1f; Git 是一个分布式版本控制系统&#xff0c;由 Linus Torvalds 于 2005 年创建。它的主要目的是帮助开发者有效地管理和跟踪项目的历史版本。通过使用 Git&#xff0c;你可以轻松地记录每一次代码的修改&#xff0c;回滚到以前的版本&#xff0c;以及…...

UE5 和 UE4 中常用的控制台命令总结

调用控制台 按下键盘上的 ~ 键可以调用控制台命令。 技巧 使用键盘的 ↑ 键可以查看之前输入过的指令。控制台指令并不需要打全名&#xff0c;输入空格后跟随指令的部分字符可以进行模糊搜索。按下 Ctrl Shift , 打开 GPUProfile 面板。 命令如下&#xff1a; 调试类 s…...