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:
- 2013/01/07 - Started discussion on oss-security (post)
- 2013/01/08 - CVE-2013-0160 was assigned
- 2013/01/08 - RedHat bug report (#892983)
- 2013/01/09 - Patch provided by the grsecurity project (for grsecurity patched kernels) (patch)
- 2013/01/09 - Ubuntu bug report (#1097680)
- 2013/02/15 - Patch provided by Jiri Slaby to the LKML list (post)
References:
- [1] Timing Analysis of Keystrokes and Timing Attacks on SSH
- [2] PoC to display latency between keystrokes: ptmx-keystroke-latency.c
- [3] PoC to target "su -" and disclose password length: ptmx-su-pwdlen.sh
Greetz to:
- larry for review.