The Fix

seteuid()

One of the ways to fix this TOCTOU bug is to add just one line of instruction after access() (before fopen() is called) to manually set the effective UID of the process as the actual UID of the process.

You can do this using the following system call: seteuid(getuid());

Task 12

TASK 12: Modify vulnerable_root_prog.c to add that one line of code above right under:

if (!access(fileName, W_OK))
{
   ...

Then:

  1. Login as root and recompile with make inside /FilesForRoot/.
  2. Login back as your original user account, and cd to /User/ again, and run exploit.sh.
  3. Observe the result
  4. Press ctrl+c to cancel the script (yes, this change will cause step 2 to run in infinite loop).

Disable SUID

Of course another way is to disable the SUID bit of vulnerable_root_prog altogether, however in practice sometimes this might not be ideal since there might be other parts of the program that requires execution with elevated privilege, temporarily.

Task 13

TASK 13: Run exploit.sh with root_prog_nosuid.

Open exploit.sh and replace vulnerable_root_prog with root_prog_nosuid, and run the script again (while logged in as user account).

Summary

Ensure that you have answered all questions in edimension corresponding to each task in this handout. No other separate code submission is needed.

By the end of this lab, we hope that you have learned:

  • What SUID bit does, and how can it be utilised to gain elevated privileges to access protected files
  • The differences between root and normal user
  • The meaning of file permission. Although we do not go through explicitly on how it is set, you can read about it here and experiment how to do it using the chmod command.
  • How race condition happens and how it can be used as an attack
  • How to fix the TOCTOU bug

TL;DR

  1. Clone the repository:
    git clone https://github.com/natalieagus/lab_toctou
    
  2. Set root’s password, and login as root:
    sudo passwd root
    su root 
    
  3. Create other users (while logged in as root). Use a good password, like LDcwzD&#6JKr:
    adduser test-user-0
    adduser test-user-0 sudo
    adduser test-user-1
    adduser test-user-1 sudo
    adduser test-user-2
    adduser test-user-2 sudo
    
  4. make inside /FilesForRoot/ folder (while logged in as root):
    cd FilesForRoot
    make
    
  5. Log in back to your regular user account:
    su <username>
    
  6. Change to /User/ directory, make, then exploit:
    cd ../User
    make
    ./exploit.sh
    
  7. Once exploit.sh succeeds, login to test-user-0 with password 00000. This proves that the attack has been successfully launched.