Skip to content

Commit

Permalink
more x11 progress, now working on screenshots, WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
h00die committed Feb 26, 2024
1 parent 5e42df8 commit 453f8bb
Show file tree
Hide file tree
Showing 14 changed files with 541 additions and 117 deletions.
98 changes: 91 additions & 7 deletions documentation/modules/auxiliary/gather/x11_keyboard_spy.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,92 @@
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.
This module binds to an open X11 host to log keystrokes. The X11 service can accept
connections from any users when misconfigured with the command `xhost +`.
This module is a close copy of the old xspy c program which has been on Kali for a long time.
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 (especially before
the repeat delay is hit). To combat printing multiple characters for a single key
press, repeat characters are ignored.

### Ubuntu 10.04

1. `sudo nano /etc/gdm/gdm.schemas`
2. Find:

```
<schema>
<key>security/DisallowTCP</key>
<signature>b</signature>
<default>true</default>
</schema>
```
- Change `true` to `false`

3. logout or reboot
4. Verification: ```sudo netstat -antp | grep 6000```

```
tcp 0 0 0.0.0.0:6000 0.0.0.0:* LISTEN 1806/X
```

5. Now, to verify you allow ANYONE to get on X11, type: `xhost +`

### Ubuntu 12.04, 14.04

1. `sudo nano /etc/lightdm/lightdm.conf`
2. Under the `[SeatDefaults]` area, add:

```
xserver-allow-tcp=true
allow-guest=true
```

3. logout or reboot
4. Verification: ```sudo netstat -antp | grep 6000```

```
tcp 0 0 0.0.0.0:6000 0.0.0.0:* LISTEN 1806/X
```

5. Now, to verify you allow ANYONE to get on X11, type: `xhost +`

### Ubuntu 16.04

Use the Ubuntu 12.04 instructions, however change `SeatDefaults` to `Seat:*`

### Fedora 15

1. `vi /etc/gdm/custom.conf`
2. Under the `[security]` area, add:

```
DisallowTCP=false
```

3. logout/reboot
4. Now, to verify you allow ANYONE to get on X11, type: `xhost +`

### Solaris 10

1. `svccfg -s svc:/application/x11/x11-server setprop options/tcp_listen = true`
2. `svc disable cde-login`
3. `svc enable cde-login`
4. `xhost +`

### Ubuntu 22.04

#### Server

Getting X11 to listen on a TCP port is rather taxing, so we use socat to facilitate instead.

1. `sudo apt-get install ubuntu-desktop socat` # overkill but it gets everything we need
2. `sudo reboot` # prob a good idea since so much was installed
3. `sudo xhost +` # must be done through gui, not through SSH
4. `socat -d -d TCP-LISTEN:6000,fork,bind=<IP to listen to here> UNIX-CONNECT:/tmp/.X11-unix/X0`

## Verification Steps
Example steps in this format (is also in the PR):
Expand Down Expand Up @@ -42,3 +122,7 @@ msf > use module_name
msf auxiliary(module_name) > set POWERLEVEL >9000
msf auxiliary(module_name) > exploit
```

## Confirming

To keylog the remote host, we use a tool called [xspy](http://tools.kali.org/sniffingspoofing/xspy)
15 changes: 13 additions & 2 deletions lib/msf/core/exploit/remote/x11.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module Msf::Exploit::Remote::X11
include Msf::Exploit::Remote::X11::Extensions
include Msf::Exploit::Remote::X11::Xkeyboard
include Msf::Exploit::Remote::X11::Keysymdef
include Msf::Exploit::Remote::X11::Window

class X11GETPROPERTYRESPONSE < BinData::Record
endian :little
Expand All @@ -33,7 +34,7 @@ class X11GETPROPERTY < BinData::Record
uint8 :delete_field, initial_value: 0 # \x00 false, assuming \x01 true?
uint16 :request_length, value: -> { num_bytes / 4 }
uint32 :window # X11CONNECTION.screen_root
uint32 :property, value: 23 # "\x17\x00\x00\x00" RESOURCE_MANAGER
uint32 :property, initial_value: 23 # "\x17\x00\x00\x00" RESOURCE_MANAGER
uint32 :get_property_type, value: 31 # "\x1f\x00\x00\x00" # get-property-type (31 = string)
uint32 :long_offset, value: 0
uint32 :content_length, value: 100_000_000 # "\x00\xe1\xf5\x05"
Expand Down Expand Up @@ -116,4 +117,14 @@ class X11GETINPUTFOCUSREQUEST < BinData::Record
uint8 :unused
uint16 :request_length, value: -> { num_bytes / 4 }
end
end

class X11INTERNATOM < BinData::Record
endian :little
uint8 :opcode, value: 16 #InternAtom
uint8 :only_if_exists, initial_value: 0 # 0 false, 1 true?
uint16 :request_length, value: -> { num_bytes / 4 }
uint16 :name_length, value: -> { name.to_s.length }
uint16 :unused, initial_value: 0
string :name, trim_padding: true
end
end
2 changes: 1 addition & 1 deletion lib/msf/core/exploit/remote/x11/connect.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,4 @@ class X11CONNECTIONREQUEST < BinData::Record
uint16 :authorization_protocol_data_length, value: 0
uint16 :unused2, value: 0
end
end
end
2 changes: 1 addition & 1 deletion lib/msf/core/exploit/remote/x11/extensions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,4 @@ def versions?
wanted_major.nonzero? || wanted_minor.nonzero?
end
end
end
end
4 changes: 2 additions & 2 deletions lib/msf/core/exploit/remote/x11/keysymdef.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ module Msf::Exploit::Remote::X11::Keysymdef
65500 => '[F31]', # XK_F31
65501 => '[F32]', # XK_F32
65502 => '[F33]', # XK_F33
65503 => '[F34]', # XK_F34
65503 => '[F34]', # XK_F34
65504 => '[F35]', # XK_F35
65505 => '[Shift_L]', # XK_Shift_L
65506 => '[Shift_R]', # XK_Shift_R
Expand All @@ -128,4 +128,4 @@ module Msf::Exploit::Remote::X11::Keysymdef
65517 => '[Hyper_L]', # XK_Hyper_L
65518 => '[Hyper_R]' # XK_Hyper_R
}
end
end
77 changes: 77 additions & 0 deletions lib/msf/core/exploit/remote/x11/window.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# -*- coding: binary -*-

#
# This mixin is a simplistic implementation of X11 extensions protocol
#
# Wireshark dissector: https://wiki.wireshark.org/X11
#

module Msf::Exploit::Remote::X11::Window
class GETREQUEST < BinData::Record
endian :little
uint8 :opcode # 3 = GetWindowAttributes, 14 = GetGeometry
uint8 :unused # XXX seems to be increasing counter...
uint16 :request_length, value: -> { num_bytes / 4 }
uint32 :window
end

class GETWINDOWATTRIBUTESRESPONSE < BinData::Record
endian :little

uint8 :depth
uint16 :visual_id
uint8 :class_name
uint8 :bit_gravity
uint8 :win_gravity
uint32 :backing_planes
uint32 :backing_pixel
uint8 :save_under
uint8 :map_is_installed
uint8 :map_state
uint8 :override_redirect
uint32 :colormap
uint32 :all_event_masks
uint32 :your_event_mask
uint16 :do_not_propagate_mask
end

class GetGeometryResponse < BinData::Record
endian :little

uint8 :depth
uint32 :root
uint16 :x
uint16 :y
uint16 :width
uint16 :height
uint16 :border_width
end

class TRANSLATECOORDINATESREQUEST < BinData::Record
endian :little
uint8 :opcode, value: 40 # TranslateCoordinates
uint8 :unused # XXX seems to be increasing counter...
uint16 :request_length, value: -> { num_bytes / 4 }
uint32 :src_window
uint32 :dst_window
uint16 :src_x
uint16 :src_y
end

class QUERYTREEREQUEST < BinData::Record
endian :little
uint8 :opcode, value: 15 # QueryTree
uint8 :unused, value: 1 # XXX counter?
uint16 :request_length, value: -> { num_bytes / 4 }
uint32 :drawable
end

class QUERYTREERESPONSE < BinData::Record
endian :little
uint8 :root
uint8 :parent_id
uint16 :n_children
array :children, type: :uint32le, initial_length: :n_children
array :tree, type: :uint8, read_until: :eof
end
end
53 changes: 36 additions & 17 deletions lib/msf/core/exploit/remote/x11/xkeyboard.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,37 @@
#

module Msf::Exploit::Remote::X11::Xkeyboard
class X11XKBKEYMODMAP < BinData::Record
class KEYMODMAP < BinData::Record
endian :little
uint8 :keycode
uint8 :mods # bit array, shift, lock, control, 1, 2, 3, 4, 5
end

class X11XKBSYM < BinData::Record
class SYM < BinData::Record
endian :little
uint32 :syms
end

class X11XKBKEYSYMENTRY < BinData::Record
class KEYSYMENTRY < BinData::Record
endian :little
uint32 :kt_index
uint8 :group_info
uint8 :width
uint16 :n_syms
# next we have a list of syms, length is n_syms
array :key_sym_array,
type: :X11XKBSYM,
type: :SYM,
initial_length: :n_syms
end

class X11XKBMODDEF < BinData::Record
class MODDEF < BinData::Record
endian :little
uint8 :mask
uint8 :real_mods
uint16 :vmods
end

class X11XKBKEYMAPENTRY < BinData::Record
class KEYMAPENTRY < BinData::Record
endian :little
uint8 :active
uint8 :mods_mask # bit array, shift, lock, control, 1, 2, 3, 4, 5
Expand All @@ -47,7 +47,7 @@ class X11XKBKEYMAPENTRY < BinData::Record
uint16 :unused
end

class X11XKBKEYTYPE < BinData::Record
class KEYTYPE < BinData::Record
endian :little
uint8 :mods_mask
uint8 :mods_mods
Expand All @@ -56,13 +56,13 @@ class X11XKBKEYTYPE < BinData::Record
uint8 :n_map_entries
uint8 :has_preserve # 8bit boolean, \x01 == true \x00 == false
uint8 :unused
# next we have a list of X11XKBKEYMAPENTRY, length is :n_map_entries
# next we have a list of KEYMAPENTRY, length is :n_map_entries
array :key_map_array,
type: :X11XKBKEYMAPENTRY,
type: :KEYMAPENTRY,
initial_length: :n_map_entries
# not sure how to tell how many of these there are
array :key_mods_array,
type: :X11XKBMODDEF,
type: :MODDEF,
initial_length: :n_map_entries,
onlyif: -> { has_preserve == 1 }
end
Expand Down Expand Up @@ -177,17 +177,17 @@ class GETMAPREPLY < BinData::Record
uint8 :total_vmod_map_key
uint8 :unused1
uint16 :virtual_mods # bit array
# next we have a list of X11XKBKEYTYPE, length is :total_types
# next we have a list of KEYTYPE, length is :total_types
array :key_types_array,
type: :X11XKBKEYTYPE,
type: :KEYTYPE,
initial_length: :n_types
# next we have a list of X11XKBKEYSYMENTRY
# next we have a list of KEYSYMENTRY
array :key_map_array,
type: :X11XKBKEYSYMENTRY,
type: :KEYSYMENTRY,
initial_length: :n_key_sym
# next we have a list of X11XKBKEYMODMAP
# next we have a list of KEYMODMAP
array :key_mod_map_array,
type: :X11XKBKEYMODMAP,
type: :KEYMODMAP,
initial_length: :total_mod_map_key
uint16 :unused2, onlyif: :padding? # this onlyif may be wrong, its a guess for the time being

Expand Down Expand Up @@ -357,4 +357,23 @@ class QUERYKEYMAPREPLY < BinData::Record
type: :uint8,
read_until: :eof
end
end

class BELLREQUEST < BinData::Record
endian :little
uint8 :xkeyboard_id # opcode
uint8 :extension_minor, value: 3 # Bell
uint16 :request_length, value: -> { num_bytes / 4 }
uint16 :device_spec, value: 256 # XXX does this come from elsewhere?
uint16 :bell_class, value: 768
uint16 :bell_id, value: 1024
uint8 :percent, initial_value: 50 # xxx do we want to change this?
uint8 :force_sound, initial_value: 0 # 0 = false, 1 true?
uint8 :sound_only, initial_value: 0 # 0 = false, 1 true?
uint8 :unused
uint16 :pitch, initial_value: 0
uint16 :duration, initial_value: 0
uint16 :unused2
uint32 :name, initial_value: 816 # XXX do we see this elsewhere?
uint32 :window
end
end
Loading

0 comments on commit 453f8bb

Please sign in to comment.