Use /dev/ptmx to measure inter-keystroke timing (CVE-2013-0160)

As a reminder, the "/dev/ptmx" character device is used to create a pseudo-terminal master and slave pair. When a process opens this file, it gets a file descriptor for a pseudo-terminal master (PTM), and a pseudo-terminal slave (PTS) device is created in the /dev/pts directory. See pts(4) for more information.

The master is a file descriptor pointing to "/dev/ptmx" itself and thanks to a multiplexing mechanism, data written into it is provided to the process connected to the slave.

For instance, in an interactive bash session opened with an application that use pseudo-terminal (ssh or terminal emulator such as xterm, urxvt, etc.), we have (here in xterm):

# ps -o comm= -p $PPID,$$
xterm
bash

# ls -l /proc/$PPID/fd
[...]
lrwx------ 1 root root 64  6 janv. 16:19 4 -> /dev/ptmx    // PTM (fd=4)    

# ls -l /proc/$$/fd
lrwx------ 1 root root 64  6 janv. 16:18 0 -> /dev/pts/4   // PTS
[...]

While using those applications, data is sent through PTM each time a keystroke is pressed:

# strace -e write -p <xterm pid>
Process 10572 attached - interrupt to quit
write(4, "l", 1)                        = 1
write(4, "s", 1)                        = 1
write(4, "\r", 1)                       = 1

It means that the "/dev/ptmx" file is modified each time a user (even root) presses a keystroke while in a PTY.

By using the Inotify API with the IN_MODIFY bit, a local user can see real-time updates of this file, and thus can measure latency between keystrokes. Several articles ([1] for instance), demonstrate that inter-keystroke timing (also called latency), is considered sufficient to determine what information is being typed on a keyboard.

The first PoC [2] displays the time difference between two key presses (inter-keystroke timing) while another user is typing in a PTY:

$ ./ptmx-keystroke-latency
[+] PoC to disclose latency between keystrokes
[+] Wait for someone to type in a PTY
21:39:49 (+5739 ms)
21:39:50 (+97 ms)
21:39:50 (+449 ms)
[...]

The second PoC [3] discloses password length when a user runs "su -". It can be updated to target other applications that re-quire a password input (such as ssh, gpg, etc.):

$ ./ptmx-su-pwdlen.sh 
[*] Wait for someone to run "su -"
[+] su detected, full command: su -
[+] password len is 7

Timeline:


References:


Greetz to: