I am willing to log keystrokes from a list of processes that I wish to. There is a script shellsnoop.d (at brenden''s blog and in DTrace Toolkit), which captures all key strokes within the shell. But, it works because the arg0 of write/read syscalls is either 0,1 or 2 for the shell/terminal. For other processes, it varies and it isn''t 0,1 or 2. Please suggest me a way to either extend the shellsnoop, or to use different providers/probes to log keystrokes only (not all events e.g. mouse clicks). Thanks. -- This message posted from opensolaris.org
Salman Jamali wrote:> I am willing to log keystrokes from a list of processes that I wish to.Faisal Mansoor wrote: > I am trying to write a keylogger using dtrace for all kinds of applications. School project?
Yes, it''s my work and I thought it to be an interesting (mis)use of DTrace so moved along :) However, it''s dragging me into the OpenSolaris implementation. So, I''ll appreciate any sort of input that may help me to stay focused.. Thanks. -- This message posted from opensolaris.org
Brendan Gregg - Sun Microsystems
2008-Mar-18 03:05 UTC
[dtrace-discuss] logging keystrokes
G''Day Folks, On Mon, Mar 17, 2008 at 03:06:00PM -0700, Dan Mick wrote:> Salman Jamali wrote: > > I am willing to log keystrokes from a list of processes that I wish to. > > Faisal Mansoor wrote: > > > I am trying to write a keylogger using dtrace for all kinds of applications. > > School project?:) It is a topic that can lead you through some interesting OS internals, and also a sensational example of DTrace''s systemic observability. It should make for a computer science assignment that students would enjoy. Is this for keystrokes from the locally attached keyboard, or for keyboards on remote clients who are running software on the server? The approach is different for each; here I''ll quickly describe locally attached keyboards, whose codepath of keystroke events would be something like this: keyboard driver | stream I/O | syscalls | libc | Xorg | syscalls | socket | X11 library | application (eg, gnome-terminal) | syscalls | child library (eg, libc) | child application (eg, bash) ... Everything is observable using DTrace - pick a layer and start tracing. Finding keystroke events is much easier than most things, as it is easy to inject known workloads (hit the "a" key 23 times) and frequency count which probes fired. Examples of tracing keyboard events can be found in typewriter-0.75 (http://www.brendangregg.com/dtrace.html - which I haven''t updated in a long time. (If anyone has trouble hearing sound properly, try changing "cat file > /dev/audio &" to "audioplay file &", which seems to make it work much better for x86/amd64 audio drivers.)) In typewriter.d I simply hardcoded the keycode for the enter key. There are many better ways to get this if you are interested in the entire keymap, such as we are for keyboard sniffing. Here is one technique: ---------------- #!/usr/sbin/dtrace -s #pragma D option quiet #pragma D option switchrate=10 BEGIN { trace("Tracing... Hit Ctrl-C to end.\n"); } fbt::kbtrans_keyreleased:entry /self->seen == 0/ { this->key = args[0]->kbtrans_lower.kbtrans_keyboard->k_normal[arg1]; printf("%Y %s: %#x \"%c\"\n", walltimestamp, probefunc, this->key, this->key); self->seen = 1; } fbt::kbtrans_keyreleased:return { self->seen = 0; } ---------------- Example output: # ./keysniffer.d Tracing... Hit Ctrl-C to end. 2008 Mar 18 02:43:38 kbtrans_keyreleased: 0x79 y 2008 Mar 18 02:43:38 kbtrans_keyreleased: 0x6f o 2008 Mar 18 02:43:38 kbtrans_keyreleased: 0x75 u 2008 Mar 18 02:43:39 kbtrans_keyreleased: 0x20 2008 Mar 18 02:43:39 kbtrans_keyreleased: 0x68 h 2008 Mar 18 02:43:39 kbtrans_keyreleased: 0x61 a 2008 Mar 18 02:43:39 kbtrans_keyreleased: 0x76 v 2008 Mar 18 02:43:39 kbtrans_keyreleased: 0x65 e 2008 Mar 18 02:43:40 kbtrans_keyreleased: 0x20 2008 Mar 18 02:43:40 kbtrans_keyreleased: 0x62 b 2008 Mar 18 02:43:40 kbtrans_keyreleased: 0x65 e 2008 Mar 18 02:43:40 kbtrans_keyreleased: 0x65 e 2008 Mar 18 02:43:40 kbtrans_keyreleased: 0x6e n 2008 Mar 18 02:43:40 kbtrans_keyreleased: 0x20 2008 Mar 18 02:43:41 kbtrans_keyreleased: 0x30 0 2008 Mar 18 02:43:41 kbtrans_keyreleased: 0x77 w 2008 Mar 18 02:43:42 kbtrans_keyreleased: 0x6e n 2008 Mar 18 02:43:42 kbtrans_keyreleased: 0x33 3 2008 Mar 18 02:43:42 kbtrans_keyreleased: 0x64 d ^C That''s just one way to do it, from many DTrace makes available. Hitting up Xorg, as Alan said, may be better - as you get to see it after xmodmap translations (for those of us using dvorak keyboards ;). When writing such tools, I''d suggest people to write a disclaimer similar to what I put at the top of shellsnoop: # This program sounds somewhat dangerous (snooping keystrokes), but is # no more so than /usr/bin/truss, and both need root or dtrace privileges to # run. In fact, less dangerous, as we only print visible text (not password # text, for example). Having said that, it goes without saying that this # program shouldn''t be used for breeching privacy of other users. DTrace can be used for some alarming security attacks - but other tools could be used for the same attacks. We don''t want IT departments to ban DTrace based on security misunderstandings, rather, to understand that the actual issue is that of root privilege delegation - as it is with other tools. :-) Finally, if someone is reading this thread because they are interested in "logging" keystrokes (from the subject) - be aware that dtrace can drop events when under heavy load (safety valve). This behaviour would need to be carefully understood before an auditing framework could be successful. Brendan -- Brendan [CA, USA]
Thanks a lot. I still have 2 problems, For almost the same script, I typed "you have been 0wn3d", but I got this result: 2008 Mar 20 12:18:14 kbtrans_keyreleased: 0x5d "]" & scancode 28 2008 Mar 20 12:18:14 kbtrans_keyreleased: 0x77 "w" & scancode 18 2008 Mar 20 12:18:14 kbtrans_keyreleased: 0x69 "i" & scancode 24 2008 Mar 20 12:18:15 kbtrans_keyreleased: 0x102 "" & scancode 44 2008 Mar 20 12:18:15 kbtrans_keyreleased: 0x30 "0" & scancode 11 2008 Mar 20 12:18:16 kbtrans_keyreleased: 0x33 "3" & scancode 4 2008 Mar 20 12:18:16 kbtrans_keyreleased: 0x6f "o" & scancode 25 2008 Mar 20 12:18:16 kbtrans_keyreleased: 0x37 "7" & scancode 8 2008 Mar 20 12:18:17 kbtrans_keyreleased: 0x102 "" & scancode 44 2008 Mar 20 12:18:17 kbtrans_keyreleased: 0x34 "4" & scancode 5 2008 Mar 20 12:18:17 kbtrans_keyreleased: 0x37 "7" & scancode 8 2008 Mar 20 12:18:18 kbtrans_keyreleased: 0x37 "7" & scancode 8 2008 Mar 20 12:18:18 kbtrans_keyreleased: 0x71 "q" & scancode 17 2008 Mar 20 12:18:18 kbtrans_keyreleased: 0x102 "" & scancode 44 2008 Mar 20 12:18:19 kbtrans_keyreleased: 0x6c "l" & scancode 39 2008 Mar 20 12:18:20 kbtrans_keyreleased: 0x70 "p" & scancode 26 2008 Mar 20 12:18:20 kbtrans_keyreleased: 0x71 "q" & scancode 17 2008 Mar 20 12:18:20 kbtrans_keyreleased: 0x73 "s" & scancode 32 2008 Mar 20 12:18:21 kbtrans_keyreleased: 0x36 "6" & scancode 7 However, the scancodes are consistent with key mapping of keyboard controller, which I got through the dumpkeys command. For example, when I type ''a'', I get [b]2008 Mar 20 12:18:16 kbtrans_keyreleased: 0x33 "3" & scancode 4 [/b] Where, the scancode 4 is that of ''a''. But, "3" retrieved by the script is inconsistent. Secondly, I still need to associate the key pressed with the process that has the keyboard focus. Is there some sort of documentation of the related code describing the structures and functions at a higher level beside the code comments? Please suggest something, also, I am using Dell Inspiron e1505. Thanks. -- This message posted from opensolaris.org
BEGIN { trace("Tracing... Hit Ctrl-C to end.\n"); self->count = 0; } fbt::kbtrans_keyreleased:entry { self->count = self->count + 1; } fbt::kbtrans_keyreleased:entry /self->count == 2/ { this->key = args[0]->kbtrans_lower.kbtrans_keyboard->k_normal[arg1]; printf("%d %s %Y %s: %#x \"%c\" & scancode %d \n", pid, execname, walltimestamp, probefunc, this->key, this->key, arg1); self->count = 0; } This script resolved the problem which I mentioned earlier. The new output is: # dtrace -s keySniff.d Tracing... Hit Ctrl-C to end. 0 sched 2008 Mar 23 18:36:19 kbtrans_keyreleased: 0x73 "s" & scancode 22 0 sched 2008 Mar 23 18:36:19 kbtrans_keyreleased: 0x61 "a" & scancode 4 0 sched 2008 Mar 23 18:36:19 kbtrans_keyreleased: 0x6c "l" & scancode 15 0 sched 2008 Mar 23 18:36:20 kbtrans_keyreleased: 0x6d "m" & scancode 16 0 sched 2008 Mar 23 18:36:20 kbtrans_keyreleased: 0x61 "a" & scancode 4 0 sched 2008 Mar 23 18:36:20 kbtrans_keyreleased: 0x6e "n" & scancode 17 The 0 and sched is junk. Now, I need to work this out so that these are replaced by the pid and execname of the process that has the current keyboard focus. -- This message posted from opensolaris.org
On Mon, Mar 17, 2008 at 10:05 PM, Brendan Gregg - Sun Microsystems <brendan at sun.com> wrote:> # ./keysniffer.d > Tracing... Hit Ctrl-C to end. > 2008 Mar 18 02:43:38 kbtrans_keyreleased: 0x79 y > 2008 Mar 18 02:43:38 kbtrans_keyreleased: 0x6f o > 2008 Mar 18 02:43:38 kbtrans_keyreleased: 0x75 u > 2008 Mar 18 02:43:39 kbtrans_keyreleased: 0x20 > 2008 Mar 18 02:43:39 kbtrans_keyreleased: 0x68 h > 2008 Mar 18 02:43:39 kbtrans_keyreleased: 0x61 a > 2008 Mar 18 02:43:39 kbtrans_keyreleased: 0x76 v > 2008 Mar 18 02:43:39 kbtrans_keyreleased: 0x65 eI started down the path of using a similar technique some time ago (ssh sessions, not X) and found that I could not get proper ordering of the keystroke logging if I typed sufficiently fast. I suspect that the magnitude of this problem increases with the number of CPUs and workload on the system. If memory serves, I was on a lightly loaded T2000. My thoughts were to log a high resolution timer (ticks?) along with the tty and keystroke for reassembly later. -- Mike Gerdts http://mgerdts.blogspot.com/
Brendan Gregg - Sun Microsystems
2008-Mar-24 00:06 UTC
[dtrace-discuss] logging keystrokes
On Sun, Mar 23, 2008 at 06:22:32PM -0500, Mike Gerdts wrote:> On Mon, Mar 17, 2008 at 10:05 PM, Brendan Gregg - Sun Microsystems > <brendan at sun.com> wrote: > > # ./keysniffer.d > > Tracing... Hit Ctrl-C to end. > > 2008 Mar 18 02:43:38 kbtrans_keyreleased: 0x79 y > > 2008 Mar 18 02:43:38 kbtrans_keyreleased: 0x6f o > > 2008 Mar 18 02:43:38 kbtrans_keyreleased: 0x75 u > > 2008 Mar 18 02:43:39 kbtrans_keyreleased: 0x20 > > 2008 Mar 18 02:43:39 kbtrans_keyreleased: 0x68 h > > 2008 Mar 18 02:43:39 kbtrans_keyreleased: 0x61 a > > 2008 Mar 18 02:43:39 kbtrans_keyreleased: 0x76 v > > 2008 Mar 18 02:43:39 kbtrans_keyreleased: 0x65 e > > I started down the path of using a similar technique some time ago > (ssh sessions, not X) and found that I could not get proper ordering > of the keystroke logging if I typed sufficiently fast. I suspect that > the magnitude of this problem increases with the number of CPUs and > workload on the system. If memory serves, I was on a lightly loaded > T2000.Just add "#pragma D option switchrate=100" to sshkeysnoop.d and it should work in most conditions: http://www.brendangregg.com/DTrace/sshkeysnoop.d> My thoughts were to log a high resolution timer (ticks?) along with > the tty and keystroke for reassembly later.Why use ticks when there is ''timestamp''? Tracing ''pid'' and proc:::exit should be sufficient instead of tty. Brendan -- Brendan [CA, USA]