From 4add215ecddbce5644788e8cb3bb10b2d6b03d82 Mon Sep 17 00:00:00 2001 From: Matias Fernandez Date: Tue, 20 Nov 2018 17:27:20 -0300 Subject: [PATCH] Structural changes and code cleanup --- lib/encodings/__init__.py | 20 + pyvncs/__pycache__/__init__.cpython-36.pyc | Bin 202 -> 203 bytes pyvncs/__pycache__/server.cpython-36.pyc | Bin 15820 -> 15348 bytes pyvncs/server.py | 61 +- server.py | 351 ++------- server2.py | 854 --------------------- server3.py | 821 -------------------- server4.py | 102 --- test.php | 49 -- test.py | 15 - test2.py | 12 - test3.py | 43 -- testtkinker.py | 79 -- 13 files changed, 90 insertions(+), 2317 deletions(-) create mode 100644 lib/encodings/__init__.py delete mode 100755 server2.py delete mode 100755 server3.py delete mode 100644 server4.py delete mode 100755 test.php delete mode 100644 test.py delete mode 100755 test2.py delete mode 100755 test3.py delete mode 100644 testtkinker.py diff --git a/lib/encodings/__init__.py b/lib/encodings/__init__.py new file mode 100644 index 0000000..4d4f35d --- /dev/null +++ b/lib/encodings/__init__.py @@ -0,0 +1,20 @@ +# coding=utf-8 +# pyvncs +# Copyright (C) 2017-2018 Matias Fernandez +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . + +# at least, raw encoding is needed by the rfb protocol +from . import common as enc +from . import raw diff --git a/pyvncs/__pycache__/__init__.cpython-36.pyc b/pyvncs/__pycache__/__init__.cpython-36.pyc index 65bdec779b1b8f39732359767d5e61fdce8c8bf4..3206e8763127ba45272d16151cf98cab65bfb748 100644 GIT binary patch delta 43 zcmX@bc$$&Jn3tDpN!8ovi5#`!2Ku4JsYS*5MTsey75XWuWvMy&1*t_7XX^t1Kqe28 delta 42 xcmX@jc#4t3n3tC;OE4*FB1f&5zJ6$NYEiL%QDRDFg?@f{o^wuqY0AVo`Tz>Y4d(y= diff --git a/pyvncs/__pycache__/server.cpython-36.pyc b/pyvncs/__pycache__/server.cpython-36.pyc index 44b0a052f4ecbf66e5d015a2d627b5d5cb2b9ec8..96d4937f7aa1c789b6849ac1fdd3d1cd5a87e147 100644 GIT binary patch delta 3655 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 diff --git a/pyvncs/server.py b/pyvncs/server.py index 6bf81a5..da7d137 100644 --- a/pyvncs/server.py +++ b/pyvncs/server.py @@ -28,6 +28,8 @@ import random import zlib import numpy as np +from lib.encodings import * + def hexdump(data): str = "" for d in data: @@ -98,11 +100,6 @@ else: class VncServer(): - class ENCODINGS: - raw = 0 - zlib = 6 # zlib - cursor = -239 # mouse cursor pseudo encoding - class CONFIG: _8bitdither = False @@ -358,7 +355,7 @@ class VncServer(): del screen self.primaryOrder = "rgb" - self.encoding = self.ENCODINGS.raw + self.encoding = enc.ENCODINGS.raw buttonmask = 0 buttons = [0, 0, 0, 0, 0, 0, 0, 0] left_pressed = 0 @@ -486,20 +483,21 @@ class VncServer(): data2 = sock.recv(3) print("Client Message Type: SetEncoding (2)") (nencodings,) = unpack("!xH", data2) - print("SetEncoding: total encodings ", repr(nencodings)) + print("SetEncoding: total encodings", repr(nencodings)) data2 = sock.recv(4 * nencodings, socket.MSG_WAITALL) - print("len", len(data2)) + #print("len", len(data2)) self.client_encodings = unpack("!%si" % nencodings, data2) - print("data", repr(self.client_encodings), len(self.client_encodings)) + #print("data", repr(self.client_encodings), len(self.client_encodings)) - if self.ENCODINGS.cursor in self.client_encodings: + if hasattr(enc.ENCODINGS, "cursor") and enc.ENCODINGS.cursor in self.client_encodings: print("Remote cursor encoding present") self.remotecursor = True self.cursorchanged = True - - if self.ENCODINGS.zlib in self.client_encodings: + + if hasattr(enc.ENCODINGS, "zlib") and enc.ENCODINGS.zlib in self.client_encodings: print("Using zlib encoding") - self.encoding = self.ENCODINGS.zlib + self.encoding = enc.ENCODINGS.zlib + continue @@ -735,7 +733,7 @@ class VncServer(): sendbuff.extend( image.tobytes() ) - if self.encoding == self.ENCODINGS.zlib - 9998: + if hasattr(enc.ENCODINGS, "zlib") and self.encoding == enc.ENCODINGS.zlib - 9998: if not firstUpdateSent: firstUpdateSent = True compress = zlib.compressobj( @@ -767,42 +765,9 @@ class VncServer(): sendbuff.extend( l ) # send length sendbuff.extend( zlibdata ) # send compressed data - if self.encoding == self.ENCODINGS.zlib: - rectangles = 1 - sendbuff.extend(pack("!BxH", 0, rectangles)) - sendbuff.extend(pack("!HHHH", x, y, w, h)) - sendbuff.extend(pack(">i", self.encoding)) - - print("Compressing...") - - - if not firstUpdateSent: - firstUpdateSent = True - zlibdata = zlib.compress( image.tobytes() )[2:] - print("FIRSTTTTTTTTTTTTTTTTTTTTTTTTTT") - else: - zlibdata = zlib.compress( image.tobytes() )[2:-4] - - #zlibdata = zlib.compress( image.tobytes() )[2:-4] # no header and checksum - #zlibdata = zlib.compress( image.tobytes() )[:-4] # no checksum - #zlibdata = zlib.compress( image.tobytes() ) - - l = pack("!I", len(zlibdata) ) - sendbuff.extend( l ) # send length - sendbuff.extend( zlibdata ) # send compressed data - #sendbuff.extend( pack("!B", 0) ) - - #inf = inflate(zlibdata, winsize=-15) - - del zlibdata, l else: # send with RAW encoding - rectangles = 1 - sendbuff.extend(pack("!BxH", 0, rectangles)) - sendbuff.extend(pack("!HHHH", x, y, w, h)) - sendbuff.extend(pack(">i", self.encoding)) - sendbuff.extend( image.tobytes() ) - + sendbuff.extend(enc.ENCODINGS.raw_send_image(x, y, w, h, image)) else: print("[!] Unsupported BPP: %s" % self.bpp) diff --git a/server.py b/server.py index aa1420d..0a6afa2 100755 --- a/server.py +++ b/server.py @@ -1,287 +1,20 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -import socket, os, sys, wx +import pyvncs +from argparse import ArgumentParser from threading import Thread from time import sleep -from struct import * -from pyDes import * -def hexdump(data): - print(" ".join(hex(ord(n)) for n in data)) +import sys +import socket -class VncServer(): - def __init__(self, socket, ip, port): - self.initmsg = "RFB 003.008\n" - self.socket = socket - - self.sectypes = [ - 2, # VNC auth - 19 # VeNCrypt - ] - - def __del__(self): - print("VncServer died") - - def encrypt(self, key, data): - k = des(key, ECB, "\0\0\0\0\0\0\0\0", pad=None, padmode=PAD_PKCS5) - d = k.encrypt(data) - return d - - def decrypt(self, challenge, data): - k = des(challenge, ECB, "\0\0\0\0\0\0\0\0", pad=None, padmode=PAD_PKCS5) - return k.decrypt(data) - - def mirrorBits(self, key): - newkey = [] - for ki in range(len(key)): - bsrc = key[ki] - btgt = 0 - for i in range(8): - if ord(bsrc) & (1 << i): - btgt = btgt | (1 << 7-i) - newkey.append(btgt) - - return newkey - - def sendmessage(self, message): - ''' sends a RFB message, usually an error message ''' - sock = self.socket - message = bytes(message, 'iso8859-1') - # 4 bytes lenght and string - buff = pack("I%ds" % (len(message),), len(message), message) - sock.send(message) - - def getbuff(self, timeout): - sock = self.socket - sock.settimeout(timeout) - - try: - data = sock.recv(1024) - except socket.timeout: - data = None - print("getbuff() timeout") - - return data - - def init(self): - sock = self.socket - sock.send(self.initmsg.encode()) - - # RFB version handshake - data = self.getbuff(30) - - print("init received: '%s'" % data) - if data == self.initmsg.encode(): - print("init OK") - else: - print("init NOT OK!! '%s' '%s'" % (data, self.initmsg.encode())) - sock.send(pack("BB", 1, 0)) - self.sendmessage("RFB protocol not supported") - sock.close() - return False - - # security types handshake - sendbuff = pack("B", len(self.sectypes)) # number of security types - sendbuff += pack('%sB' % len(self.sectypes), *self.sectypes) # send available sec types - sock.send(sendbuff) - - data = self.getbuff(30) - try: - sectype = unpack("B", data)[0] - except: - sectype = None - - if sectype not in self.sectypes: - print("Incompatible security type: %s" % data) - sock.send(pack("B", 1)) # failed handshake - self.sendmessage("Incompatible security type") - sock.close() - return False - - print("sec type data: %s" % data) - - # VNC Auth - if sectype == 2: - # el cliente encripta el challenge con la contraseña ingresada como key - pw = (VNC_PASSWORD + '\0' * 8)[:8] - challenge = os.urandom(16) # challenge - sock.send(challenge) # send challenge - # obtener desde el cliente el dato encritado - data = self.getbuff(30) - # la encriptacion de challenge, con pw como key debe dar data - - k = des(self.mirrorBits(pw)) - crypted = k.encrypt(challenge) - - if data == crypted: - # Handshake successful - sock.send(pack("I", 0)) - print("Auth OK") - else: - print("Invalid auth") - return False - - #unsupported VNC auth type - else: - return False - - # get ClientInit - data = self.getbuff(30) - print("Clientinit (shared flag)", repr(data)) - - # ServerInit - screen = wx.ScreenDC() - print("screen", repr(screen)) - size = screen.GetSize() - print("size", repr(size)) - - width = size[0] - height = size[1] - bpp = 32 # FIXME: get real bpp - depth = 24 # FIXME: get real depth - self.depth = depth - self.bpp = 32 - bigendian = 0 - truecolor = 1 - red_maximum = 255 - green_maximum = 255 - blue_maximum = 255 - red_shift = 16 - self.red_shift = red_shift - green_shift = 8 - self.green_shift = green_shift - blue_shift = 0 - self.blue_shift = blue_shift - padding1 = 0 - padding2 = 0 - padding3 = 0 - - sendbuff = pack("!HH", width, height) - sendbuff += pack("!BBBB", bpp, depth, bigendian, truecolor) - sendbuff += pack("!HHHBBB", red_maximum, green_maximum, blue_maximum, red_shift, green_shift, blue_shift) - sendbuff += pack("!BBB", padding1, padding2, padding3) - - desktop_name = "Test VNC" - desktop_name_len = len(desktop_name) - - sendbuff += pack("!I", desktop_name_len) - sendbuff += desktop_name.encode() - - print("width", repr(width)) - print("height", repr(height)) - - sock.send(sendbuff) - - return True - - - def protocol(self): - sock = self.socket - sock.settimeout(1) # set nonblocking socket - - screen = wx.ScreenDC() - size = screen.GetSize() - width = size[0] - height = size[1] - - while True: - try: - data = sock.recv(1) # read first byte - except socket.timeout: - #print("timeout") - continue - except Exception as e: - print("exception '%s'" % e) - sock.close() - break - - if not data: - # clinet disconnected - sock.close() - break - - if data[0] == 0: # SetPixelFormat - data2 = sock.recv(19) - print("Client Message Type: Set Pixel Format (0)") - (self.bpp, self.depth, self.bigendian, self.truecolor, self.red_maximum, - self.green_maximum, self.blue_maximum, self.red_shift, self.green_shift, - self.blue_shift) = unpack("!xxxBBBBHHHBBBxxx", data2) - print("bpp", self.bpp) - print("depth", self.depth) - - if data[0] == 2: # SetEncoding - data2 = sock.recv(3) - print("Client Message Type: SetEncoding (2)") - h = unpack("xH", data2) - print("h", repr(h)) - data2 = sock.recv(4096) - - else: - data2 = sock.recv(4096) - print("RAW Server received data:", data+data2) - - #sleep(0.1) - #self.RAWSendRectangles(sock, 0, 0, width, height) - - def GetRectangle(self, x, y, w, h): - screen = wx.ScreenDC() - size = screen.GetSize() - bmp = wx.Bitmap(size[0], size[1], self.depth) - mem = wx.MemoryDC() - mem.SelectObject(bmp) - mem.Blit(0, 0, size[0], size[1], screen, 0, 0) - mem.SelectObject(wx.NullBitmap) - - rect = bmp.GetSubBitmap(wx.Rect(x, y, w, h)) - image = wx.Bitmap.ConvertToImage(rect) - - del mem - del bmp - del rect - - return image - - def RAWSendRectangles(self, sock, x, y, w, h): - image = self.GetRectangle(x, y, w, h) - pixelData = image.GetData() - - sendbuff = pack("!BBH", 0, 0, 1) - sendbuff += pack("!HHHH", x, y, w, h) - sendbuff += pack("!i", 0) - sock.send(sendbuff) - - sendbuff = bytearray() - print("Start...") - for b in range(0, len(pixelData), 3): - red = (pixelData[b] & 0x000000FF) >> self.red_shift - green = (pixelData[b+1] & 0x000000FF) >> self.green_shift - blue = (pixelData[b+2] & 0x000000FF) >> self.blue_shift - sendbuff.extend( pack("!BBBx", pixelData[b], pixelData[b+1], pixelData[b+2]) ) - #sendbuff += pack("BBBx", pixelData[b], pixelData[b+1], pixelData[b+2]) - #print(".", end='', flush=True) - - print("End...") - sock.sendall(sendbuff) - - #c = 0 - #for d in pixelData: - # if c == 3: - # c=0 - # sock.send( pack("x") ) - - # sock.send( pack("B", d)) - # c += 1 - - #sock.sendall(pack( "B" , pixelData)) - #print("Supossed data len:", w * h * self.depth) - #print("Real data len: ", len(pixelData)) - class ControlThread(Thread): def __init__(self, threads): Thread.__init__(self) self.threads = threads + self.setDaemon(True) def run(self): # elimina los threads muertos @@ -289,51 +22,81 @@ class ControlThread(Thread): sleep(1) for t in threads: if not t.isAlive(): + print("ControlThread removing dead", t) threads.remove(t) - class ClientThread(Thread): def __init__(self, sock, ip, port): Thread.__init__(self) self.ip = ip self.port = port self.sock = sock + self.setDaemon(True) def __del__(self): print("ClientThread died") def run(self): print("[+] New server socket thread started for " + self.ip + ":" + str(self.port)) - server = VncServer(self.sock, self.ip, self.port) + #print("Thread", self) + server = pyvncs.server.VncServer(self.sock, VNC_PASSWORD) + server.CONFIG._8bitdither = CONFIG._8bitdither status = server.init() + if not status: print("Error negotiating client init") return False server.protocol() -# Multithreaded Python server -TCP_IP = '0.0.0.0' -TCP_PORT = 5901 +def main(argv): + global CONFIG, TCP_IP, TCP_PORT, VNC_PASSWORD, threads, controlthread + class CONFIG: + _8bitdither = False -VNC_PASSWORD='kaka80' + parser = ArgumentParser() + parser.add_argument("-l", "--listen-address", dest="TCP_IP", + help="Listen in this address, default: %s" % ("0.0.0.0"), required=False, default='0.0.0.0') + parser.add_argument("-p", "--port", dest="TCP_PORT", + help="Listen in this port, default: %s" % ("5901"), type=int, required=False, default='5901') + parser.add_argument("-P", "--password", help="Sets password", required=True, dest="VNC_PASSWORD") + parser.add_argument("-8", "--8bitdither", help="Enable 8 bit dithering", required=False, action='store_true', dest="dither") + args = parser.parse_args() + + # Multithreaded Python server + TCP_IP = '0.0.0.0' if not hasattr(args,"TCP_IP") else args.TCP_IP + TCP_PORT = '0.0.0.0' if not hasattr(args,"TCP_PORT") else args.TCP_PORT + VNC_PASSWORD = args.VNC_PASSWORD + CONFIG._8bitdither = args.dither -app = wx.App(False) + sockServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sockServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + sockServer.bind((TCP_IP, TCP_PORT)) + + controlthread = ControlThread(threads) + controlthread.start() + threads.append(controlthread) -sockServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM) -sockServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) -sockServer.bind((TCP_IP, TCP_PORT)) -threads = [] + print("Multithreaded Python server : Waiting for connections from TCP clients...") + print("Runing on:", sys.platform) + while True: + sockServer.listen(4) + (conn, (ip,port)) = sockServer.accept() + newthread = ClientThread(conn, ip, port) + newthread.setDaemon(True) + newthread.start() + threads.append(newthread) + #print(threads) -controlthread = ControlThread(threads) -controlthread.start() -print("Multithreaded Python server : Waiting for connections from TCP clients...") -while True: - sockServer.listen(4) - (conn, (ip,port)) = sockServer.accept() - newthread = ClientThread(conn, ip, port) - newthread.setDaemon(True) - newthread.start() - threads.append(newthread) - #print(threads) +if __name__ == "__main__": + try: + threads = [] + main(sys.argv) + except KeyboardInterrupt: + # quit + print("Exiting on ctrl+c...") + #for t in threads: + # print("Killing", t) + sys.exit() + \ No newline at end of file diff --git a/server2.py b/server2.py deleted file mode 100755 index 05bc2a0..0000000 --- a/server2.py +++ /dev/null @@ -1,854 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -import socket, select, os, sys, random, zlib -from threading import Thread -from time import sleep -from struct import * -from pyDes import * -from argparse import ArgumentParser - -from pymouse import PyMouse -from pykeyboard import PyKeyboard - -import numpy as np - -from PIL import Image, ImageChops, ImageDraw, ImagePalette -if sys.platform == "linux" or sys.platform == "linux2": - from Xlib import display, X - # take screen images, that's not the best way, so here - # we use directly use xlib to take the screenshot. - class ImageGrab(): - def grab(): - dsp = display.Display() - root = dsp.screen().root - geom = root.get_geometry() - w = geom.width - h = geom.height - raw = root.get_image(0, 0, w ,h, X.ZPixmap, 0xffffffff) - image = Image.frombytes("RGB", (w, h), raw.data, "raw", "BGRX") - return image - -elif sys.platform == "darwin": - import Quartz.CoreGraphics as CG - class ImageGrab(): - def grab(): - screenshot = CG.CGWindowListCreateImage(CG.CGRectInfinite, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault) - width = CG.CGImageGetWidth(screenshot) - height = CG.CGImageGetHeight(screenshot) - bytesperrow = CG.CGImageGetBytesPerRow(screenshot) - - pixeldata = CG.CGDataProviderCopyData(CG.CGImageGetDataProvider(screenshot)) - - i = Image.frombytes("RGBA", (width, height), pixeldata) - (b, g, r, x) = i.split() - i = Image.merge("RGBX", (r, g, b, x)) - - return i - -else: - from PIL import ImageGrab - - -def selfRestart(): - try: - p = psutil.Process(os.getpid()) - for handler in p.get_open_files() + p.connections(): - os.close(handler.fd) - except Exception as e: - print(e) - - python = sys.executable - os.execl(python, python, *sys.argv) - -def hexdump(data): - str = "" - for d in data: - str += hex(d) - str += "(%s) " % d - return str - -def quantizetopalette(silf, palette, dither=False): - """Convert an RGB or L mode image to use a given P image's palette.""" - - silf.load() - - # use palette from reference image - palette.load() - if palette.mode != "P": - raise ValueError("bad mode for palette image") - if silf.mode != "RGB" and silf.mode != "L": - raise ValueError( - "only RGB or L mode images can be quantized to a palette" - ) - im = silf.im.convert("P", 1 if dither else 0, palette.im) - # the 0 above means turn OFF dithering - - # Later versions of Pillow (4.x) rename _makeself to _new - try: - return silf._new(im) - except AttributeError: - return silf._makeself(im) - - -def deflate(data, compresslevel=9, method=zlib.DEFLATED, winsize=-zlib.MAX_WBITS, memlevel=zlib.DEF_MEM_LEVEL, strategy=0): - compress = zlib.compressobj( - compresslevel, # level: 0-9 - method, # method: must be DEFLATED - winsize, # window size in bits: - # -15..-8: negate, suppress header - # 8..15: normal - # 16..30: subtract 16, gzip header - memlevel, # mem level: 1..8/9 - strategy # strategy: - # 0 = Z_DEFAULT_STRATEGY - # 1 = Z_FILTERED - # 2 = Z_HUFFMAN_ONLY - # 3 = Z_RLE - # 4 = Z_FIXED - ) - deflated = compress.compress(data) - deflated += compress.flush() - return deflated - -def inflate(data, winsize=-zlib.MAX_WBITS): - decompress = zlib.decompressobj( - winsize # see above - ) - inflated = decompress.decompress(data) - inflated += decompress.flush() - return inflated - -def getDictByValue(d, val): - try: - return [k for k,v in d.items() if v==val][0] - except: - return False - -RFB_VERSION = '003.008' -RFB_SECTYPES = [ - 2, # VNC auth - 19 # VeNCrypt - ] - -class VncServer(): - - class ENCODINGS: - raw = 0 - zlib = -6 # disabled - - def __init__(self, socket, ip, port): - self.initmsg = ("RFB %s\n" % RFB_VERSION) - self.socket = socket - self.framebuffer = None - - self.sectypes = RFB_SECTYPES - - self.BGR233 = [0, 0, 0, 0, 0, 85, 0, 0, 170, 0, 0, 255, 36, 0, 0, 36, 0, 85, 36, 0, 170, 36, 0, 255, 73, 0, 0, 73, 0, 85, 73, 0, 170, 73, 0, 255, 109, 0, 0, 109, 0, 85, 109, 0, 170, 109, 0, 255, 146, 0, 0, 146, 0, 85, 146, 0, 170, 146, 0, 255, 182, 0, 0, 182, 0, 85, 182, 0, 170, 182, 0, 255, 219, 0, 0, 219, 0, 85, 219, 0, 170, 219, 0, 255, 255, 0, 0, 255, 0, 85, 255, 0, 170, 255, 0, 255, 0, 36, 0, 0, 36, 85, 0, 36, 170, 0, 36, 255, 36, 36, 0, 36, 36, 85, 36, 36, 170, 36, 36, 255, 73, 36, 0, 73, 36, 85, 73, 36, 170, 73, 36, 255, 109, 36, 0, 109, 36, 85, 109, 36, 170, 109, 36, 255, 146, 36, 0, 146, 36, 85, 146, 36, 170, 146, 36, 255, 182, 36, 0, 182, 36, 85, 182, 36, 170, 182, 36, 255, 219, 36, 0, 219, 36, 85, 219, 36, 170, 219, 36, 255, 255, 36, 0, 255, 36, 85, 255, 36, 170, 255, 36, 255, 0, 73, 0, 0, 73, 85, 0, 73, 170, 0, 73, 255, 36, 73, 0, 36, 73, 85, 36, 73, 170, 36, 73, 255, 73, 73, 0, 73, 73, 85, 73, 73, 170, 73, 73, 255, 109, 73, 0, 109, 73, 85, 109, 73, 170, 109, 73, 255, 146, 73, 0, 146, 73, 85, 146, 73, 170, 146, 73, 255, 182, 73, 0, 182, 73, 85, 182, 73, 170, 182, 73, 255, 219, 73, 0, 219, 73, 85, 219, 73, 170, 219, 73, 255, 255, 73, 0, 255, 73, 85, 255, 73, 170, 255, 73, 255, 0, 109, 0, 0, 109, 85, 0, 109, 170, 0, 109, 255, 36, 109, 0, 36, 109, 85, 36, 109, 170, 36, 109, 255, 73, 109, 0, 73, 109, 85, 73, 109, 170, 73, 109, 255, 109, 109, 0, 109, 109, 85, 109, 109, 170, 109, 109, 255, 146, 109, 0, 146, 109, 85, 146, 109, 170, 146, 109, 255, 182, 109, 0, 182, 109, 85, 182, 109, 170, 182, 109, 255, 219, 109, 0, 219, 109, 85, 219, 109, 170, 219, 109, 255, 255, 109, 0, 255, 109, 85, 255, 109, 170, 255, 109, 255, 0, 146, 0, 0, 146, 85, 0, 146, 170, 0, 146, 255, 36, 146, 0, 36, 146, 85, 36, 146, 170, 36, 146, 255, 73, 146, 0, 73, 146, 85, 73, 146, 170, 73, 146, 255, 109, 146, 0, 109, 146, 85, 109, 146, 170, 109, 146, 255, 146, 146, 0, 146, 146, 85, 146, 146, 170, 146, 146, 255, 182, 146, 0, 182, 146, 85, 182, 146, 170, 182, 146, 255, 219, 146, 0, 219, 146, 85, 219, 146, 170, 219, 146, 255, 255, 146, 0, 255, 146, 85, 255, 146, 170, 255, 146, 255, 0, 182, 0, 0, 182, 85, 0, 182, 170, 0, 182, 255, 36, 182, 0, 36, 182, 85, 36, 182, 170, 36, 182, 255, 73, 182, 0, 73, 182, 85, 73, 182, 170, 73, 182, 255, 109, 182, 0, 109, 182, 85, 109, 182, 170, 109, 182, 255, 146, 182, 0, 146, 182, 85, 146, 182, 170, 146, 182, 255, 182, 182, 0, 182, 182, 85, 182, 182, 170, 182, 182, 255, 219, 182, 0, 219, 182, 85, 219, 182, 170, 219, 182, 255, 255, 182, 0, 255, 182, 85, 255, 182, 170, 255, 182, 255, 0, 219, 0, 20, 219, 85, 0, 219, 170, 0, 219, 255, 36, 219, 0, 36, 219, 85, 36, 219, 170, 36, 219, 255, 73, 219, 0, 73, 219, 85, 73, 219, 170, 73, 219, 255, 109, 219, 0, 109, 219, 85, 109, 219, 170, 109, 219, 255, 146, 219, 0, 146, 219, 85, 146, 219, 170, 146, 219, 255, 182, 219, 0, 182, 219, 85, 182, 219, 170, 182, 219, 255, 219, 219, 0, 219, 219, 85, 219, 219, 170, 219, 219, 255, 255, 219, 0, 255, 219, 85, 255, 219, 170, 255, 219, 255, 0, 255, 0, 0, 255, 85, 0, 255, 170, 0, 255, 255, 36, 255, 0, 36, 255, 85, 36, 255, 170, 36, 255, 255, 73, 255, 0, 73, 255, 85, 73, 255, 170, 73, 255, 255, 109, 255, 0, 109, 255, 85, 109, 255, 170, 109, 255, 255, 146, 255, 0, 146, 255, 85, 146, 255, 170, 146, 255, 255, 182, 255, 0, 182, 255, 85, 182, 255, 170, 182, 255, 255, 219, 255, 0, 219, 255, 85, 219, 255, 170, 219, 255, 255, 255, 255, 0, 255, 255, 85, 255, 255, 170, 255, 255, 255] - - def __del__(self): - print("VncServer died") - - def encrypt(self, key, data): - k = des(key, ECB, "\0\0\0\0\0\0\0\0", pad=None, padmode=PAD_PKCS5) - d = k.encrypt(data) - return d - - def decrypt(self, challenge, data): - k = des(challenge, ECB, "\0\0\0\0\0\0\0\0", pad=None, padmode=PAD_PKCS5) - return k.decrypt(data) - - def mirrorBits(self, key): - newkey = [] - for ki in range(len(key)): - bsrc = key[ki] - btgt = 0 - for i in range(8): - if ord(bsrc) & (1 << i): - btgt = btgt | (1 << 7-i) - newkey.append(btgt) - - return newkey - - def sendmessage(self, message): - ''' sends a RFB message, usually an error message ''' - sock = self.socket - message = bytes(message, 'iso8859-1') - # 4 bytes lenght and string - buff = pack("I%ds" % (len(message),), len(message), message) - sock.send(message) - - def getbuff(self, timeout): - sock = self.socket - sock.settimeout(timeout) - - try: - data = sock.recv(1024) - except socket.timeout: - data = None - print("getbuff() timeout") - - return data - - def init(self): - sock = self.socket - sock.send(self.initmsg.encode()) - - # RFB version handshake - data = self.getbuff(30) - - print("init received: '%s'" % data) - server_version = float(RFB_VERSION) - try: - client_version = float(data[4:11]) - except: - print("Error parsing client version") - return False - - print("client, server:", client_version, server_version) - - # security types handshake - sendbuff = pack("B", len(self.sectypes)) # number of security types - sendbuff += pack('%sB' % len(self.sectypes), *self.sectypes) # send available sec types - sock.send(sendbuff) - - data = self.getbuff(30) - try: - sectype = unpack("B", data)[0] - except: - sectype = None - - if sectype not in self.sectypes: - print("Incompatible security type: %s" % data) - sock.send(pack("B", 1)) # failed handshake - self.sendmessage("Incompatible security type") - sock.close() - return False - - print("sec type data: %s" % data) - - # VNC Auth - if sectype == 2: - # el cliente encripta el challenge con la contraseña ingresada como key - pw = (VNC_PASSWORD + '\0' * 8)[:8] - challenge = os.urandom(16) # challenge - sock.send(challenge) # send challenge - # obtener desde el cliente el dato encritado - data = self.getbuff(30) - # la encriptacion de challenge, con pw como key debe dar data - - k = des(self.mirrorBits(pw)) - crypted = k.encrypt(challenge) - - if data == crypted: - # Handshake successful - sock.send(pack("I", 0)) - print("Auth OK") - else: - print("Invalid auth") - return False - - #unsupported VNC auth type - else: - return False - - # get ClientInit - data = self.getbuff(30) - print("Clientinit (shared flag)", repr(data)) - - self.ServerInit() - - return True - - def ServerInit(self): - # ServerInit - - sock = self.socket - screen = ImageGrab.grab() - print("screen", repr(screen)) - size = screen.size - print("size", repr(size)) - del screen - - width = size[0] - self.width = width - height = size[1] - self.height = height - bpp = 32 # FIXME: get real bpp - depth = 32 # FIXME: get real depth - self.depth = depth - self.bpp = bpp - bigendian = 0 - truecolor = 1 - red_maximum = 255 - self.red_maximum = red_maximum - green_maximum = 255 - self.green_maximum = green_maximum - blue_maximum = 255 - self.blue_maximum = blue_maximum - red_shift = 16 - self.red_shift = red_shift - green_shift = 8 - self.green_shift = green_shift - blue_shift = 0 - self.blue_shift = blue_shift - - sendbuff = pack("!HH", width, height) - sendbuff += pack("!BBBB", bpp, depth, bigendian, truecolor) - sendbuff += pack("!HHHBBB", red_maximum, green_maximum, blue_maximum, red_shift, green_shift, blue_shift) - sendbuff += pack("!xxx") # padding - - desktop_name = "Test VNC" - desktop_name_len = len(desktop_name) - - sendbuff += pack("!I", desktop_name_len) - sendbuff += desktop_name.encode() - - print("width", repr(width)) - print("height", repr(height)) - - sock.send(sendbuff) - - - def protocol(self): - self.socket.settimeout(None) # set nonblocking socket - - screen = ImageGrab.grab() - size = screen.size - width = size[0] - height = size[1] - del screen - - self.primaryOrder = "rgb" - self.encoding = self.ENCODINGS.raw - buttonmask = 0 - buttons = [0, 0, 0, 0, 0, 0, 0, 0] - left_pressed = 0 - right_pressed = 0 - middle_pressed = 0 - - kdbmap = { - "KEY_BackSpace": 0xff08, - "KEY_Tab": 0xff09, - "KEY_Return": 0xff0d, - "KEY_Escape": 0xff1b, - "KEY_Insert": 0xff63, - "KEY_Delete": 0xffff, - "KEY_Home": 0xff50, - "KEY_End": 0xff57, - "KEY_PageUp": 0xff55, - "KEY_PageDown": 0xff56, - "KEY_Left": 0xff51, - "KEY_Up": 0xff52, - "KEY_Right": 0xff53, - "KEY_Down": 0xff54, - "KEY_F1": 0xffbe, - "KEY_F2": 0xffbf, - "KEY_F3": 0xffc0, - "KEY_F4": 0xffc1, - "KEY_F5": 0xffc2, - "KEY_F6": 0xffc3, - "KEY_F7": 0xffc4, - "KEY_F8": 0xffc5, - "KEY_F9": 0xffc6, - "KEY_F10": 0xffc7, - "KEY_F11": 0xffc8, - "KEY_F12": 0xffc9, - "KEY_F13": 0xFFCA, - "KEY_F14": 0xFFCB, - "KEY_F15": 0xFFCC, - "KEY_F16": 0xFFCD, - "KEY_F17": 0xFFCE, - "KEY_F18": 0xFFCF, - "KEY_F19": 0xFFD0, - "KEY_F20": 0xFFD1, - "KEY_ShiftLeft": 0xffe1, - "KEY_ShiftRight": 0xffe2, - "KEY_ControlLeft": 0xffe3, - "KEY_ControlRight": 0xffe4, - "KEY_MetaLeft": 0xffe7, - "KEY_MetaRight": 0xffe8, - "KEY_AltLeft": 0xffe9, - "KEY_AltRight": 0xffea, - "KEY_Scroll_Lock": 0xFF14, - "KEY_Sys_Req": 0xFF15, - "KEY_Num_Lock": 0xFF7F, - "KEY_Caps_Lock": 0xFFE5, - "KEY_Pause": 0xFF13, - "KEY_Super_L": 0xFFEB, - "KEY_Super_R": 0xFFEC, - "KEY_Hyper_L": 0xFFED, - "KEY_Hyper_R": 0xFFEE, - "KEY_KP_0": 0xFFB0, - "KEY_KP_1": 0xFFB1, - "KEY_KP_2": 0xFFB2, - "KEY_KP_3": 0xFFB3, - "KEY_KP_4": 0xFFB4, - "KEY_KP_5": 0xFFB5, - "KEY_KP_6": 0xFFB6, - "KEY_KP_7": 0xFFB7, - "KEY_KP_8": 0xFFB8, - "KEY_KP_9": 0xFFB9, - "KEY_KP_Enter": 0xFF8D, - "KEY_ForwardSlash": 0x002F, - "KEY_BackSlash": 0x005C, - "KEY_SpaceBar": 0x0020 - } - - # key mapping per SO (windows, osx, linux) - # FIXME: OSX maping - if sys.platform == "darwin": - keyboard.control_key = keyboard.key_code_translate_table['control'] - - - mapping = { - "KEY_ControlLeft" : [keyboard.control_key, "Control", keyboard.control_l_key], - "KEY_ControlRight" : [keyboard.control_key, "Control", keyboard.control_r_key], - "KEY_AltLeft": [keyboard.alt_l_key, "Alternate", keyboard.alt_l_key], - "KEY_AltRight": [keyboard.alt_r_key, "Alternate", keyboard.alt_r_key], - "KEY_ShiftLeft": [keyboard.shift_l_key, "shift", keyboard.shift_l_key], - "KEY_ShiftRight": [keyboard.shift_r_key, "shift", keyboard.shift_r_key], - "KEY_Up": [keyboard.up_key, "Up", keyboard.up_key], - "KEY_Down": [keyboard.down_key, "Down", keyboard.down_key], - "KEY_Left": [keyboard.left_key, "Left", keyboard.left_key], - "KEY_Right": [keyboard.right_key, "Right", keyboard.right_key], - "KEY_Delete": [keyboard.delete_key, "delete", keyboard.delete_key], - "KEY_Insert": [keyboard.insert_key, "insert", keyboard.insert_key], - "KEY_Home": [keyboard.home_key, "home", keyboard.home_key], - "KEY_End": [keyboard.end_key, "end", keyboard.end_key], - "KEY_PageUp": [keyboard.page_up_key, "PageUp", keyboard.page_up_key], - "KEY_PageDown": [keyboard.page_down_key, "PageDown", keyboard.page_down_key], - } - - # function keys mapping - for i in range(1,20): - mapping.update( { ("KEY_F%s" % i): [keyboard.function_keys[i], ("F%s" % i) , keyboard.function_keys[i]] } ) - - - while True: - #print(".", end='', flush=True) - r,_,_ = select.select([self.socket],[],[],0) - if r == []: - #no data - sleep(0.1) - continue - - sock = r[0] - try: - data = sock.recv(1) # read first byte - except socket.timeout: - #print("timeout") - continue - except Exception as e: - print("exception '%s'" % e) - sock.close() - break - - if not data: - # clinet disconnected - sock.close() - break - - if data[0] == 0: # client SetPixelFormat - data2 = sock.recv(19, socket.MSG_WAITALL) - print("Client Message Type: Set Pixel Format (0)") - (self.bpp, self.depth, self.bigendian, self.truecolor, self.red_maximum, - self.green_maximum, self.blue_maximum, - self.red_shift, self.green_shift, self.blue_shift - ) = unpack("!xxxBBBBHHHBBBxxx", data2) - print("IMG bpp, depth, endian, truecolor", self.bpp, self.depth, self.bigendian, self.truecolor) - print("SHIFTS", self.red_shift, self.green_shift, self.blue_shift) - print("MAXS", self.red_maximum, self.green_maximum, self.blue_maximum) - - if self.red_shift > self.blue_shift: - self.primaryOrder = "rgb" - else: - self.primaryOrder = "bgr" - print("Using order: ", self.primaryOrder) - - continue - - if data[0] == 2: # SetEncoding - data2 = sock.recv(3) - print("Client Message Type: SetEncoding (2)") - (nencodings,) = unpack("!xH", data2) - print("SetEncoding: total encodings ", repr(nencodings)) - data2 = sock.recv(4 * nencodings, socket.MSG_WAITALL) - print("len", len(data2)) - self.client_encodings = unpack("!%si" % nencodings, data2) - print("data", repr(self.client_encodings), len(self.client_encodings)) - - if self.ENCODINGS.zlib in self.client_encodings: - print("Using zlib encoding") - self.encoding = self.ENCODINGS.zlib - continue - - if data[0] == 3: # FBUpdateRequest - data2 = sock.recv(9, socket.MSG_WAITALL) - #print("Client Message Type: FBUpdateRequest (3)") - #print(len(data2)) - (incremental, x, y, w, h) = unpack("!BHHHH", data2) - #print("RFBU:", incremental, x, y, w, h) - self.SendRectangles(sock, x, y, w, h, incremental) - continue - - if data[0] == 4: - kbdkey = '' - data2 = sock.recv(7) - # B = U8, L = U32 - (downflag, key) = unpack("!BxxL", data2) - print("KeyEvent", downflag, hex(key)) - spKey = getDictByValue(kdbmap, key) - - if not spKey: - try: - kbdkey = chr(key) - except: - kbdkey = key - else: - kbdkey = key - - if downflag: - func = getattr(keyboard, "press_key") - else: - func = getattr(keyboard, "release_key") - - # dynamic keyboard mapping according to "mapping" obj - if spKey in mapping: - print("mapping:", mapping[spKey]) - if sys.platform == "win32" or sys.platform == "win64" and 0 in mapping[spKey]: - kbdkey = mapping[spKey][0] - if sys.platform == "darwin" and 1 in mapping[spKey]: - kbdkey = mapping[spKey][1] - if sys.platform == "linux" and 2 in mapping[spKey]: - kbdkey = mapping[spKey][2] - - print("getDictByValue", getDictByValue(kdbmap, key)) - - func(kbdkey) - - continue - - if data[0] == 5: # PointerEvent - data2 = sock.recv(5, socket.MSG_WAITALL) - (buttonmask, x, y) = unpack("!BHH", data2) - mouse.move(x, y) - buttons[0] = buttonmask & int("0000001", 2) # left button - buttons[1] = buttonmask & int("0000010", 2) # middle button - buttons[2] = buttonmask & int("0000100", 2) # right button - buttons[3] = buttonmask & int("0001000", 2) # scroll up - buttons[4] = buttonmask & int("0010000", 2) # scroll down - - if buttons[0] and not left_pressed: - print("LEFT PRESSED") - mouse.press(x, y, 1) - left_pressed = 1 - elif not buttons[0] and left_pressed: - print("LEFT RELEASED") - mouse.release(x, y, 1) - left_pressed = 0 - - if buttons[1] and not middle_pressed: - print("MIDDLE PRESSED") - mouse.press(x, y, 3) - middle_pressed = 1 - elif not buttons[1] and middle_pressed: - print("MIDDLE RELEASED") - mouse.release(x, y, 3) - middle_pressed = 0 - - if buttons[2] and not right_pressed: - print("RIGHT PRESSED") - mouse.press(x, y, 2) - right_pressed = 1 - elif not buttons[2] and right_pressed: - print("RIGHT RELEASED") - mouse.release(x, y, 2) - right_pressed = 0 - - if buttons[3]: - print("SCROLLUP PRESSED") - mouse.scroll(vertical=1) - - if buttons[4]: - print("SCROLLDOWN PRESSED") - mouse.scroll(vertical=-1) - - #print("PointerEvent", buttonmask, x, y) - continue - - else: - data2 = sock.recv(4096) - print("RAW Server received data:", repr(data[0]) , data+data2) - - - def GetRectangle(self, x, y, w, h): - try: - scr = ImageGrab.grab() - except: - return False - (scr_width, scr_height) = scr.size - - if scr.mode != "RGB": - img = scr.convert("RGB") - else: - img = scr - - del scr - - crop = img.crop((x, y, w, h)) - del img - - return crop - - def SendRectangles(self, sock, x, y, w, h, incremental=0): - # send FramebufferUpdate to client - - #print("start SendRectangles") - rectangle = self.GetRectangle(x, y, w, h) - if not rectangle: - rectangle = Image.new("RGB", [w, h], (0,0,0)) - - lastshot = rectangle - sendbuff = bytearray() - - # try to send only the actual changes - if self.framebuffer != None and incremental == 1: - diff = ImageChops.difference(rectangle, self.framebuffer) - if diff.getbbox() is None: - rectangles = 0 - sendbuff.extend(pack("!BxH", 0, rectangles)) - sock.sendall(sendbuff) - sleep(0.3) - return - - if diff.getbbox() is not None: - if hasattr(diff, "getbbox"): - rectangle = rectangle.crop(diff.getbbox()) - (x, y, _, _) = diff.getbbox() - w = rectangle.width - h = rectangle.height - #print("XYWH:", x,y,w,h, "diff", repr(diff.getbbox())) - - stimeout = sock.gettimeout() - sock.settimeout(None) - - if self.bpp == 32 or self.bpp == 8: - if rectangle.mode is not "RGB": - image = rectangle.convert("RGB") - else: - image = rectangle - - b = np.asarray(image) - a = b.copy() - del b - - if self.bpp == 32: - redBits = 8 - greenBits = 8 - blueBits = 8 - elif self.bpp == 8: - redBits = 4 - greenBits = 4 - blueBits = 4 - - #redMask = ((1 << redBits) - 1) << self.red_shift - #greenMask = ((1 << greenBits) - 1) << self.green_shift - #blueMask = ((1 << blueBits) - 1) << self.blue_shift - #print("redMask", redMask, greenMask, blueMask) - - if self.primaryOrder == "bgr": - self.blue_shift = 0 - blueMask = (1 << blueBits) - 1 - self.green_shift = blueBits - greenMask = ((1 << greenBits) - 1) << self.green_shift - self.red_shift = self.green_shift + greenBits - redMask = ((1 << redBits) - 1) << self.red_shift - - else: # RGB - self.red_shift = 0 - redMask = (1 << redBits) - 1 - self.green_shift = redBits - greenMask = ((1 << greenBits) - 1) << self.green_shift - self.blue_shift = self.green_shift + greenBits - blueMask = ((1 << blueBits) - 1) << self.blue_shift - - a[..., 0] = ( a[..., 0] ) & redMask >> self.red_shift - a[..., 1] = ( a[..., 1] ) & greenMask >> self.green_shift - a[..., 2] = ( a[..., 2] ) & blueMask >> self.blue_shift - - image = Image.fromarray(a) - del a - - if self.primaryOrder == "rgb": - (b, g, r) = image.split() - image = Image.merge("RGB", (r, g, b)) - del b,g,r - - if self.bpp == 32: - image = image.convert("RGBX") - elif self.bpp == 8: - image = image.convert("P") - #image = image.convert("RGB") - #p = Image.new("P",(16,16)) - #p.putpalette(self.BGR233) - #image = quantizetopalette(image, p, dither=CONFIG._8bitdither) - #image.putpalette(self.BGR233) - #del p - - #print(image) - if self.encoding == self.ENCODINGS.zlib: - rectangles = 1 - sendbuff.extend(pack("!BxH", 0, rectangles)) - sendbuff.extend(pack("!HHHH", x, y, w, h)) - sendbuff.extend(pack(">i", self.encoding)) - - print("Compressing...") - #zlibdata = zlib.compress( image.tobytes() )[2:-4] # no header and checksum - #zlibdata = zlib.compress( image.tobytes() )[:-4] # no checksum - zlibdata = zlib.compress( image.tobytes() ) - - l = pack("!I", len(zlibdata) ) - print("LEN:", hexdump(l), len(zlibdata) ) - sendbuff.extend( l ) # send length - print("ZLIB HEAD:", hexdump(zlibdata[0:2]) ) - chksum = zlibdata[-4:] - print("ZLIB CHECKSUM:", hexdump(chksum) ) - sendbuff.extend( zlibdata ) # send compressed data - - #inf = inflate(zlibdata, winsize=-15) - - del zlibdata, l - else: - # send with RAW encoding - rectangles = 1 - sendbuff.extend(pack("!BxH", 0, rectangles)) - sendbuff.extend(pack("!HHHH", x, y, w, h)) - sendbuff.extend(pack(">i", self.encoding)) - sendbuff.extend( image.tobytes() ) - - elif self.bpp == -8: - print("8BPP routines!") - if rectangle.mode is not "RGB": - image = rectangle.convert("RGB") - else: - image = rectangle - - (r, g, b) = image.split() - image = Image.merge("RGB", (g, r, b)) - del b,g,r - - p = Image.new("P",(16,16)) - p.putpalette(self.BGR233) - image = quantizetopalette(image, p, dither=CONFIG._8bitdither) - image.putpalette(self.BGR233) - del p - rectangles = 1 - sendbuff.extend(pack("!BxH", 0, rectangles)) - sendbuff.extend(pack("!HHHH", x, y, w, h)) - sendbuff.extend(pack(">i", self.encoding)) - sendbuff.extend( image.tobytes() ) - - else: - print("[!] Unsupported BPP: %s" % self.bpp) - - self.framebuffer = lastshot - sock.sendall(sendbuff) - sock.settimeout(stimeout) - #print("end SendRectangles") - - -class ControlThread(Thread): - def __init__(self, threads): - Thread.__init__(self) - self.threads = threads - self.setDaemon(True) - - def run(self): - # elimina los threads muertos - while True: - sleep(1) - for t in threads: - if not t.isAlive(): - print("ControlThread removing dead", t) - threads.remove(t) - - -class ClientThread(Thread): - def __init__(self, sock, ip, port): - Thread.__init__(self) - self.ip = ip - self.port = port - self.sock = sock - self.setDaemon(True) - - def __del__(self): - print("ClientThread died") - - def run(self): - print("[+] New server socket thread started for " + self.ip + ":" + str(self.port)) - #print("Thread", self) - server = VncServer(self.sock, self.ip, self.port) - status = server.init() - - if not status: - print("Error negotiating client init") - return False - server.protocol() - - -def main(argv): - global CONFIG, TCP_IP, TCP_PORT, VNC_PASSWORD, mouse, keyboard, threads, controlthread - - class CONFIG: - _8bitdither = False - - parser = ArgumentParser() - parser.add_argument("-l", "--listen-address", dest="TCP_IP", - help="Listen in this address, default: %s" % ("0.0.0.0"), required=False, default='0.0.0.0') - parser.add_argument("-p", "--port", dest="TCP_PORT", - help="Listen in this port, default: %s" % ("5901"), type=int, required=False, default='5901') - parser.add_argument("-P", "--password", help="Sets password", required=True, dest="VNC_PASSWORD") - - parser.add_argument("-8", "--8bitdither", help="Enable 8 bit dithering", required=False, action='store_true', dest="dither") - - args = parser.parse_args() - - # Multithreaded Python server - TCP_IP = '0.0.0.0' if not hasattr(args,"TCP_IP") else args.TCP_IP - TCP_PORT = '0.0.0.0' if not hasattr(args,"TCP_PORT") else args.TCP_PORT - VNC_PASSWORD = args.VNC_PASSWORD - CONFIG._8bitdither = args.dither - - mouse = PyMouse() - keyboard = PyKeyboard() - - sockServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sockServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - sockServer.bind((TCP_IP, TCP_PORT)) - - controlthread = ControlThread(threads) - controlthread.start() - threads.append(controlthread) - - print("Multithreaded Python server : Waiting for connections from TCP clients...") - print("Runing on:", sys.platform) - while True: - sockServer.listen(4) - (conn, (ip,port)) = sockServer.accept() - newthread = ClientThread(conn, ip, port) - newthread.setDaemon(True) - newthread.start() - threads.append(newthread) - #print(threads) - -if __name__ == "__main__": - try: - threads = [] - main(sys.argv) - except KeyboardInterrupt: - # quit - print("Exiting on ctrl+c...") - #for t in threads: - # print("Killing", t) - sys.exit() diff --git a/server3.py b/server3.py deleted file mode 100755 index 72d86c9..0000000 --- a/server3.py +++ /dev/null @@ -1,821 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -import socket, select, os, sys, random, zlib -from threading import Thread -from time import sleep -from struct import * -from pyDes import * -from argparse import ArgumentParser - -from pynput import mouse, keyboard - -import numpy as np - -from PIL import Image, ImageChops, ImageDraw, ImagePalette -if sys.platform == "linux" or sys.platform == "linux2": - from Xlib import display, X - # take screen images, that's not the best way, so here - # we use directly use xlib to take the screenshot. - class ImageGrab(): - def grab(): - dsp = display.Display() - root = dsp.screen().root - geom = root.get_geometry() - w = geom.width - h = geom.height - raw = root.get_image(0, 0, w ,h, X.ZPixmap, 0xffffffff) - image = Image.frombytes("RGB", (w, h), raw.data, "raw", "BGRX") - return image - -elif sys.platform == "darwin": - import Quartz.CoreGraphics as CG - class ImageGrab(): - def grab(): - screenshot = CG.CGWindowListCreateImage(CG.CGRectInfinite, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault) - width = CG.CGImageGetWidth(screenshot) - height = CG.CGImageGetHeight(screenshot) - bytesperrow = CG.CGImageGetBytesPerRow(screenshot) - - pixeldata = CG.CGDataProviderCopyData(CG.CGImageGetDataProvider(screenshot)) - - i = Image.frombytes("RGBA", (width, height), pixeldata) - (b, g, r, x) = i.split() - i = Image.merge("RGBX", (r, g, b, x)) - - return i - -else: - from PIL import ImageGrab - - -def selfRestart(): - try: - p = psutil.Process(os.getpid()) - for handler in p.get_open_files() + p.connections(): - os.close(handler.fd) - except Exception as e: - print(e) - - python = sys.executable - os.execl(python, python, *sys.argv) - -def hexdump(data): - str = "" - for d in data: - str += hex(d) - str += "(%s) " % d - return str - -def quantizetopalette(silf, palette, dither=False): - """Convert an RGB or L mode image to use a given P image's palette.""" - - silf.load() - - # use palette from reference image - palette.load() - if palette.mode != "P": - raise ValueError("bad mode for palette image") - if silf.mode != "RGB" and silf.mode != "L": - raise ValueError( - "only RGB or L mode images can be quantized to a palette" - ) - im = silf.im.convert("P", 1 if dither else 0, palette.im) - # the 0 above means turn OFF dithering - - # Later versions of Pillow (4.x) rename _makeself to _new - try: - return silf._new(im) - except AttributeError: - return silf._makeself(im) - - -def deflate(data, compresslevel=9, method=zlib.DEFLATED, winsize=-zlib.MAX_WBITS, memlevel=zlib.DEF_MEM_LEVEL, strategy=0): - compress = zlib.compressobj( - compresslevel, # level: 0-9 - method, # method: must be DEFLATED - winsize, # window size in bits: - # -15..-8: negate, suppress header - # 8..15: normal - # 16..30: subtract 16, gzip header - memlevel, # mem level: 1..8/9 - strategy # strategy: - # 0 = Z_DEFAULT_STRATEGY - # 1 = Z_FILTERED - # 2 = Z_HUFFMAN_ONLY - # 3 = Z_RLE - # 4 = Z_FIXED - ) - deflated = compress.compress(data) - deflated += compress.flush() - return deflated - -def inflate(data, winsize=-zlib.MAX_WBITS): - decompress = zlib.decompressobj( - winsize # see above - ) - inflated = decompress.decompress(data) - inflated += decompress.flush() - return inflated - -def getDictByValue(d, val): - try: - return [k for k,v in d.items() if v==val][0] - except: - return False - -RFB_VERSION = '003.008' -RFB_SECTYPES = [ - 2, # VNC auth - 19 # VeNCrypt - ] - -class VncServer(): - - class ENCODINGS: - raw = 0 - zlib = -6 # disabled - - def __init__(self, socket, ip, port): - self.initmsg = ("RFB %s\n" % RFB_VERSION) - self.socket = socket - self.framebuffer = None - - self.sectypes = RFB_SECTYPES - - self.BGR233 = [0, 0, 0, 0, 0, 85, 0, 0, 170, 0, 0, 255, 36, 0, 0, 36, 0, 85, 36, 0, 170, 36, 0, 255, 73, 0, 0, 73, 0, 85, 73, 0, 170, 73, 0, 255, 109, 0, 0, 109, 0, 85, 109, 0, 170, 109, 0, 255, 146, 0, 0, 146, 0, 85, 146, 0, 170, 146, 0, 255, 182, 0, 0, 182, 0, 85, 182, 0, 170, 182, 0, 255, 219, 0, 0, 219, 0, 85, 219, 0, 170, 219, 0, 255, 255, 0, 0, 255, 0, 85, 255, 0, 170, 255, 0, 255, 0, 36, 0, 0, 36, 85, 0, 36, 170, 0, 36, 255, 36, 36, 0, 36, 36, 85, 36, 36, 170, 36, 36, 255, 73, 36, 0, 73, 36, 85, 73, 36, 170, 73, 36, 255, 109, 36, 0, 109, 36, 85, 109, 36, 170, 109, 36, 255, 146, 36, 0, 146, 36, 85, 146, 36, 170, 146, 36, 255, 182, 36, 0, 182, 36, 85, 182, 36, 170, 182, 36, 255, 219, 36, 0, 219, 36, 85, 219, 36, 170, 219, 36, 255, 255, 36, 0, 255, 36, 85, 255, 36, 170, 255, 36, 255, 0, 73, 0, 0, 73, 85, 0, 73, 170, 0, 73, 255, 36, 73, 0, 36, 73, 85, 36, 73, 170, 36, 73, 255, 73, 73, 0, 73, 73, 85, 73, 73, 170, 73, 73, 255, 109, 73, 0, 109, 73, 85, 109, 73, 170, 109, 73, 255, 146, 73, 0, 146, 73, 85, 146, 73, 170, 146, 73, 255, 182, 73, 0, 182, 73, 85, 182, 73, 170, 182, 73, 255, 219, 73, 0, 219, 73, 85, 219, 73, 170, 219, 73, 255, 255, 73, 0, 255, 73, 85, 255, 73, 170, 255, 73, 255, 0, 109, 0, 0, 109, 85, 0, 109, 170, 0, 109, 255, 36, 109, 0, 36, 109, 85, 36, 109, 170, 36, 109, 255, 73, 109, 0, 73, 109, 85, 73, 109, 170, 73, 109, 255, 109, 109, 0, 109, 109, 85, 109, 109, 170, 109, 109, 255, 146, 109, 0, 146, 109, 85, 146, 109, 170, 146, 109, 255, 182, 109, 0, 182, 109, 85, 182, 109, 170, 182, 109, 255, 219, 109, 0, 219, 109, 85, 219, 109, 170, 219, 109, 255, 255, 109, 0, 255, 109, 85, 255, 109, 170, 255, 109, 255, 0, 146, 0, 0, 146, 85, 0, 146, 170, 0, 146, 255, 36, 146, 0, 36, 146, 85, 36, 146, 170, 36, 146, 255, 73, 146, 0, 73, 146, 85, 73, 146, 170, 73, 146, 255, 109, 146, 0, 109, 146, 85, 109, 146, 170, 109, 146, 255, 146, 146, 0, 146, 146, 85, 146, 146, 170, 146, 146, 255, 182, 146, 0, 182, 146, 85, 182, 146, 170, 182, 146, 255, 219, 146, 0, 219, 146, 85, 219, 146, 170, 219, 146, 255, 255, 146, 0, 255, 146, 85, 255, 146, 170, 255, 146, 255, 0, 182, 0, 0, 182, 85, 0, 182, 170, 0, 182, 255, 36, 182, 0, 36, 182, 85, 36, 182, 170, 36, 182, 255, 73, 182, 0, 73, 182, 85, 73, 182, 170, 73, 182, 255, 109, 182, 0, 109, 182, 85, 109, 182, 170, 109, 182, 255, 146, 182, 0, 146, 182, 85, 146, 182, 170, 146, 182, 255, 182, 182, 0, 182, 182, 85, 182, 182, 170, 182, 182, 255, 219, 182, 0, 219, 182, 85, 219, 182, 170, 219, 182, 255, 255, 182, 0, 255, 182, 85, 255, 182, 170, 255, 182, 255, 0, 219, 0, 20, 219, 85, 0, 219, 170, 0, 219, 255, 36, 219, 0, 36, 219, 85, 36, 219, 170, 36, 219, 255, 73, 219, 0, 73, 219, 85, 73, 219, 170, 73, 219, 255, 109, 219, 0, 109, 219, 85, 109, 219, 170, 109, 219, 255, 146, 219, 0, 146, 219, 85, 146, 219, 170, 146, 219, 255, 182, 219, 0, 182, 219, 85, 182, 219, 170, 182, 219, 255, 219, 219, 0, 219, 219, 85, 219, 219, 170, 219, 219, 255, 255, 219, 0, 255, 219, 85, 255, 219, 170, 255, 219, 255, 0, 255, 0, 0, 255, 85, 0, 255, 170, 0, 255, 255, 36, 255, 0, 36, 255, 85, 36, 255, 170, 36, 255, 255, 73, 255, 0, 73, 255, 85, 73, 255, 170, 73, 255, 255, 109, 255, 0, 109, 255, 85, 109, 255, 170, 109, 255, 255, 146, 255, 0, 146, 255, 85, 146, 255, 170, 146, 255, 255, 182, 255, 0, 182, 255, 85, 182, 255, 170, 182, 255, 255, 219, 255, 0, 219, 255, 85, 219, 255, 170, 219, 255, 255, 255, 255, 0, 255, 255, 85, 255, 255, 170, 255, 255, 255] - - def __del__(self): - print("VncServer died") - - def encrypt(self, key, data): - k = des(key, ECB, "\0\0\0\0\0\0\0\0", pad=None, padmode=PAD_PKCS5) - d = k.encrypt(data) - return d - - def decrypt(self, challenge, data): - k = des(challenge, ECB, "\0\0\0\0\0\0\0\0", pad=None, padmode=PAD_PKCS5) - return k.decrypt(data) - - def mirrorBits(self, key): - newkey = [] - for ki in range(len(key)): - bsrc = key[ki] - btgt = 0 - for i in range(8): - if ord(bsrc) & (1 << i): - btgt = btgt | (1 << 7-i) - newkey.append(btgt) - - return newkey - - def sendmessage(self, message): - ''' sends a RFB message, usually an error message ''' - sock = self.socket - message = bytes(message, 'iso8859-1') - # 4 bytes lenght and string - buff = pack("I%ds" % (len(message),), len(message), message) - sock.send(message) - - def getbuff(self, timeout): - sock = self.socket - sock.settimeout(timeout) - - try: - data = sock.recv(1024) - except socket.timeout: - data = None - print("getbuff() timeout") - - return data - - def init(self): - sock = self.socket - sock.send(self.initmsg.encode()) - - # RFB version handshake - data = self.getbuff(30) - - print("init received: '%s'" % data) - server_version = float(RFB_VERSION) - try: - client_version = float(data[4:11]) - except: - print("Error parsing client version") - return False - - print("client, server:", client_version, server_version) - - # security types handshake - sendbuff = pack("B", len(self.sectypes)) # number of security types - sendbuff += pack('%sB' % len(self.sectypes), *self.sectypes) # send available sec types - sock.send(sendbuff) - - data = self.getbuff(30) - try: - sectype = unpack("B", data)[0] - except: - sectype = None - - if sectype not in self.sectypes: - print("Incompatible security type: %s" % data) - sock.send(pack("B", 1)) # failed handshake - self.sendmessage("Incompatible security type") - sock.close() - return False - - print("sec type data: %s" % data) - - # VNC Auth - if sectype == 2: - # el cliente encripta el challenge con la contraseña ingresada como key - pw = (VNC_PASSWORD + '\0' * 8)[:8] - challenge = os.urandom(16) # challenge - sock.send(challenge) # send challenge - # obtener desde el cliente el dato encritado - data = self.getbuff(30) - # la encriptacion de challenge, con pw como key debe dar data - - k = des(self.mirrorBits(pw)) - crypted = k.encrypt(challenge) - - if data == crypted: - # Handshake successful - sock.send(pack("I", 0)) - print("Auth OK") - else: - print("Invalid auth") - return False - - #unsupported VNC auth type - else: - return False - - # get ClientInit - data = self.getbuff(30) - print("Clientinit (shared flag)", repr(data)) - - self.ServerInit() - - return True - - def ServerInit(self): - # ServerInit - - sock = self.socket - screen = ImageGrab.grab() - print("screen", repr(screen)) - size = screen.size - print("size", repr(size)) - del screen - - width = size[0] - self.width = width - height = size[1] - self.height = height - bpp = 32 # FIXME: get real bpp - depth = 32 # FIXME: get real depth - self.depth = depth - self.bpp = bpp - bigendian = 0 - truecolor = 1 - red_maximum = 255 - self.red_maximum = red_maximum - green_maximum = 255 - self.green_maximum = green_maximum - blue_maximum = 255 - self.blue_maximum = blue_maximum - red_shift = 16 - self.red_shift = red_shift - green_shift = 8 - self.green_shift = green_shift - blue_shift = 0 - self.blue_shift = blue_shift - - sendbuff = pack("!HH", width, height) - sendbuff += pack("!BBBB", bpp, depth, bigendian, truecolor) - sendbuff += pack("!HHHBBB", red_maximum, green_maximum, blue_maximum, red_shift, green_shift, blue_shift) - sendbuff += pack("!xxx") # padding - - desktop_name = "Test VNC" - desktop_name_len = len(desktop_name) - - sendbuff += pack("!I", desktop_name_len) - sendbuff += desktop_name.encode() - - print("width", repr(width)) - print("height", repr(height)) - - sock.send(sendbuff) - - - def protocol(self): - self.socket.settimeout(None) # set nonblocking socket - - screen = ImageGrab.grab() - size = screen.size - width = size[0] - height = size[1] - del screen - - self.primaryOrder = "rgb" - self.encoding = self.ENCODINGS.raw - buttonmask = 0 - buttons = [0, 0, 0, 0, 0, 0, 0, 0] - left_pressed = 0 - right_pressed = 0 - middle_pressed = 0 - - - kbdmap = { - 0xff08: keyboard.Key.backspace, - 0xff09: keyboard.Key.tab, - 0xff0d: keyboard.Key.enter, - 0xff1b: keyboard.Key.esc, - 0xff63: keyboard.Key.insert if hasattr(keyboard.Key, "insert") else None, - 0xffff: keyboard.Key.delete, - 0xff50: keyboard.Key.home, - 0xff57: keyboard.Key.end, - 0xff55: keyboard.Key.page_up, - 0xff56: keyboard.Key.page_down, - 0xff51: keyboard.Key.left, - 0xff52: keyboard.Key.up, - 0xff53: keyboard.Key.right, - 0xff54: keyboard.Key.down, - 0xffbe: keyboard.Key.f1, - 0xffbf: keyboard.Key.f2, - 0xffc0: keyboard.Key.f3, - 0xffc1: keyboard.Key.f4, - 0xffc2: keyboard.Key.f5, - 0xffc3: keyboard.Key.f6, - 0xffc4: keyboard.Key.f7, - 0xffc5: keyboard.Key.f8, - 0xffc6: keyboard.Key.f9, - 0xffc7: keyboard.Key.f10, - 0xffc8: keyboard.Key.f11, - 0xffc9: keyboard.Key.f12, - 0xffca: keyboard.Key.f13, - 0xffcb: keyboard.Key.f14, - 0xffcc: keyboard.Key.f15, - 0xffcd: keyboard.Key.f16, - 0xffce: keyboard.Key.f17, - 0xffcf: keyboard.Key.f18, - 0xffd0: keyboard.Key.f19, - 0xffd1: keyboard.Key.f20, - 0xffe1: keyboard.Key.shift_l, - 0xffe2: keyboard.Key.shift_r, - 0xffe3: keyboard.Key.ctrl_l, - 0xffe4: keyboard.Key.ctrl_r, - 0xffe7: None, # "KEY_MetaLeft" - 0xffe8: None, # "KEY_MetaRight" - 0xffe9: keyboard.Key.cmd_l, - 0xffea: keyboard.Key.alt_gr, # "KEY_AltRight" - 0xff14: keyboard.Key.scroll_lock if hasattr(keyboard.Key, "scroll_lock") else None, - 0xff15: keyboard.Key.print_screen if hasattr(keyboard.Key, "print_screen") else None, # "KEY_Sys_Req" - 0xff7f: keyboard.Key.num_lock if hasattr(keyboard.Key, "num_lock") else None, - 0xffe5: keyboard.Key.caps_lock, - 0xff13: keyboard.Key.pause if hasattr(keyboard.Key, "pause") else None, - 0xffeb: keyboard.Key.cmd_r, # "KEY_Super_L" - 0xffec: keyboard.Key.cmd_r, # "KEY_Super_R" - 0xffed: None, # "KEY_Hyper_L" - 0xffee: None, # "KEY_Hyper_R" - 0xffb0: None, # "KEY_KP_0" - 0xffb1: None, # "KEY_KP_1" - 0xffb2: None, # "KEY_KP_2" - 0xffb3: None, # "KEY_KP_3" - 0xffb4: None, # "KEY_KP_4" - 0xffb5: None, # "KEY_KP_5" - 0xffb6: None, # "KEY_KP_6" - 0xffb7: None, # "KEY_KP_7" - 0xffb8: None, # "KEY_KP_8" - 0xffb9: None, # "KEY_KP_9" - 0xff8d: None, # "KEY_KP_Enter" - 0x002f: "/", # KEY_ForwardSlash - 0x005c: "\\", # KEY_BackSlash - 0x0020: keyboard.Key.space, # "KEY_SpaceBar" - 0xff7e: keyboard.Key.alt_gr, # altgr, at least on a mac (?) - 0xfe03: keyboard.Key.alt_l, - } - - if sys.platform == "darwin": - kbdmap[0xffe2] = keyboard.Key.shift - - while True: - #print(".", end='', flush=True) - r,_,_ = select.select([self.socket],[],[],0) - if r == []: - #no data - sleep(0.1) - continue - - sock = r[0] - try: - data = sock.recv(1) # read first byte - except socket.timeout: - #print("timeout") - continue - except Exception as e: - print("exception '%s'" % e) - sock.close() - break - - if not data: - # clinet disconnected - sock.close() - break - - if data[0] == 0: # client SetPixelFormat - data2 = sock.recv(19, socket.MSG_WAITALL) - print("Client Message Type: Set Pixel Format (0)") - (self.bpp, self.depth, self.bigendian, self.truecolor, self.red_maximum, - self.green_maximum, self.blue_maximum, - self.red_shift, self.green_shift, self.blue_shift - ) = unpack("!xxxBBBBHHHBBBxxx", data2) - print("IMG bpp, depth, endian, truecolor", self.bpp, self.depth, self.bigendian, self.truecolor) - print("SHIFTS", self.red_shift, self.green_shift, self.blue_shift) - print("MAXS", self.red_maximum, self.green_maximum, self.blue_maximum) - - if self.red_shift > self.blue_shift: - self.primaryOrder = "rgb" - else: - self.primaryOrder = "bgr" - print("Using order: ", self.primaryOrder) - - continue - - if data[0] == 2: # SetEncoding - data2 = sock.recv(3) - print("Client Message Type: SetEncoding (2)") - (nencodings,) = unpack("!xH", data2) - print("SetEncoding: total encodings ", repr(nencodings)) - data2 = sock.recv(4 * nencodings, socket.MSG_WAITALL) - print("len", len(data2)) - self.client_encodings = unpack("!%si" % nencodings, data2) - print("data", repr(self.client_encodings), len(self.client_encodings)) - - if self.ENCODINGS.zlib in self.client_encodings: - print("Using zlib encoding") - self.encoding = self.ENCODINGS.zlib - continue - - if data[0] == 3: # FBUpdateRequest - data2 = sock.recv(9, socket.MSG_WAITALL) - #print("Client Message Type: FBUpdateRequest (3)") - #print(len(data2)) - (incremental, x, y, w, h) = unpack("!BHHHH", data2) - #print("RFBU:", incremental, x, y, w, h) - self.SendRectangles(sock, x, y, w, h, incremental) - continue - - if data[0] == 4: - kbdkey = '' - data2 = sock.recv(7) - # B = U8, L = U32 - (downflag, key) = unpack("!BxxL", data2) - print("KeyEvent", downflag, hex(key)) - - # special key - if key in kbdmap: - kbdkey = kbdmap[key] - else: # normal key - try: - kbdkey = keyboard.KeyCode.from_char(chr(key)) - except: - kbdkey = None - - try: - print("KEY:", kbdkey) - except: - print("KEY: (unprintable)") - - try: - if downflag: - keyboard.Controller().press(kbdkey) - else: - keyboard.Controller().release(kbdkey) - except: - print("Error sending key") - - continue - - if data[0] == 5: # PointerEvent - data2 = sock.recv(5, socket.MSG_WAITALL) - (buttonmask, x, y) = unpack("!BHH", data2) - buttons[0] = buttonmask & int("0000001", 2) # left button - buttons[1] = buttonmask & int("0000010", 2) # middle button - buttons[2] = buttonmask & int("0000100", 2) # right button - buttons[3] = buttonmask & int("0001000", 2) # scroll up - buttons[4] = buttonmask & int("0010000", 2) # scroll down - - mouse.Controller().position = (x, y) - - if buttons[0] and not left_pressed: - print("LEFT PRESSED") - mouse.Controller().press(mouse.Button.left) - left_pressed = 1 - elif not buttons[0] and left_pressed: - print("LEFT RELEASED") - mouse.Controller().release(mouse.Button.left) - left_pressed = 0 - - if buttons[1] and not middle_pressed: - print("MIDDLE PRESSED") - mouse.Controller().press(mouse.Button.middle) - middle_pressed = 1 - elif not buttons[1] and middle_pressed: - print("MIDDLE RELEASED") - mouse.Controller().release(mouse.Button.middle) - middle_pressed = 0 - - if buttons[2] and not right_pressed: - print("RIGHT PRESSED") - mouse.Controller().press(mouse.Button.right) - right_pressed = 1 - elif not buttons[2] and right_pressed: - print("RIGHT RELEASED") - mouse.Controller().release(mouse.Button.right) - right_pressed = 0 - - if buttons[3]: - print("SCROLLUP PRESSED") - mouse.Controller().scroll(0, 2) - - if buttons[4]: - print("SCROLLDOWN PRESSED") - mouse.Controller().scroll(0, -2) - - #print("PointerEvent", buttonmask, x, y) - continue - - else: - data2 = sock.recv(4096) - print("RAW Server received data:", repr(data[0]) , data+data2) - - - def GetRectangle(self, x, y, w, h): - try: - scr = ImageGrab.grab() - except: - return False - (scr_width, scr_height) = scr.size - - if scr.mode != "RGB": - img = scr.convert("RGB") - else: - img = scr - - del scr - - crop = img.crop((x, y, w, h)) - del img - - return crop - - def SendRectangles(self, sock, x, y, w, h, incremental=0): - # send FramebufferUpdate to client - - #print("start SendRectangles") - rectangle = self.GetRectangle(x, y, w, h) - if not rectangle: - rectangle = Image.new("RGB", [w, h], (0,0,0)) - - lastshot = rectangle - sendbuff = bytearray() - - # try to send only the actual changes - if self.framebuffer != None and incremental == 1: - diff = ImageChops.difference(rectangle, self.framebuffer) - if diff.getbbox() is None: - rectangles = 0 - sendbuff.extend(pack("!BxH", 0, rectangles)) - sock.sendall(sendbuff) - sleep(0.3) - return - - if diff.getbbox() is not None: - if hasattr(diff, "getbbox"): - rectangle = rectangle.crop(diff.getbbox()) - (x, y, _, _) = diff.getbbox() - w = rectangle.width - h = rectangle.height - #print("XYWH:", x,y,w,h, "diff", repr(diff.getbbox())) - - stimeout = sock.gettimeout() - sock.settimeout(None) - - if self.bpp == 32 or self.bpp == 8: - if rectangle.mode is not "RGB": - image = rectangle.convert("RGB") - else: - image = rectangle - - b = np.asarray(image) - a = b.copy() - del b - - if self.bpp == 32: - redBits = 8 - greenBits = 8 - blueBits = 8 - elif self.bpp == 8: - redBits = 4 - greenBits = 4 - blueBits = 4 - - #redMask = ((1 << redBits) - 1) << self.red_shift - #greenMask = ((1 << greenBits) - 1) << self.green_shift - #blueMask = ((1 << blueBits) - 1) << self.blue_shift - #print("redMask", redMask, greenMask, blueMask) - - if self.primaryOrder == "bgr": - self.blue_shift = 0 - blueMask = (1 << blueBits) - 1 - self.green_shift = blueBits - greenMask = ((1 << greenBits) - 1) << self.green_shift - self.red_shift = self.green_shift + greenBits - redMask = ((1 << redBits) - 1) << self.red_shift - - else: # RGB - self.red_shift = 0 - redMask = (1 << redBits) - 1 - self.green_shift = redBits - greenMask = ((1 << greenBits) - 1) << self.green_shift - self.blue_shift = self.green_shift + greenBits - blueMask = ((1 << blueBits) - 1) << self.blue_shift - - a[..., 0] = ( a[..., 0] ) & redMask >> self.red_shift - a[..., 1] = ( a[..., 1] ) & greenMask >> self.green_shift - a[..., 2] = ( a[..., 2] ) & blueMask >> self.blue_shift - - image = Image.fromarray(a) - del a - - if self.primaryOrder == "rgb": - (b, g, r) = image.split() - image = Image.merge("RGB", (r, g, b)) - del b,g,r - - if self.bpp == 32: - image = image.convert("RGBX") - elif self.bpp == 8: - image = image.convert("P") - #image = image.convert("RGB") - #p = Image.new("P",(16,16)) - #p.putpalette(self.BGR233) - #image = quantizetopalette(image, p, dither=CONFIG._8bitdither) - #image.putpalette(self.BGR233) - #del p - - #print(image) - if self.encoding == self.ENCODINGS.zlib: - rectangles = 1 - sendbuff.extend(pack("!BxH", 0, rectangles)) - sendbuff.extend(pack("!HHHH", x, y, w, h)) - sendbuff.extend(pack(">i", self.encoding)) - - print("Compressing...") - #zlibdata = zlib.compress( image.tobytes() )[2:-4] # no header and checksum - #zlibdata = zlib.compress( image.tobytes() )[:-4] # no checksum - zlibdata = zlib.compress( image.tobytes() ) - - l = pack("!I", len(zlibdata) ) - print("LEN:", hexdump(l), len(zlibdata) ) - sendbuff.extend( l ) # send length - print("ZLIB HEAD:", hexdump(zlibdata[0:2]) ) - chksum = zlibdata[-4:] - print("ZLIB CHECKSUM:", hexdump(chksum) ) - sendbuff.extend( zlibdata ) # send compressed data - - #inf = inflate(zlibdata, winsize=-15) - - del zlibdata, l - else: - # send with RAW encoding - rectangles = 1 - sendbuff.extend(pack("!BxH", 0, rectangles)) - sendbuff.extend(pack("!HHHH", x, y, w, h)) - sendbuff.extend(pack(">i", self.encoding)) - sendbuff.extend( image.tobytes() ) - - elif self.bpp == -8: - print("8BPP routines!") - if rectangle.mode is not "RGB": - image = rectangle.convert("RGB") - else: - image = rectangle - - (r, g, b) = image.split() - image = Image.merge("RGB", (g, r, b)) - del b,g,r - - p = Image.new("P",(16,16)) - p.putpalette(self.BGR233) - image = quantizetopalette(image, p, dither=CONFIG._8bitdither) - image.putpalette(self.BGR233) - del p - rectangles = 1 - sendbuff.extend(pack("!BxH", 0, rectangles)) - sendbuff.extend(pack("!HHHH", x, y, w, h)) - sendbuff.extend(pack(">i", self.encoding)) - sendbuff.extend( image.tobytes() ) - - else: - print("[!] Unsupported BPP: %s" % self.bpp) - - self.framebuffer = lastshot - sock.sendall(sendbuff) - sock.settimeout(stimeout) - #print("end SendRectangles") - - -class ControlThread(Thread): - def __init__(self, threads): - Thread.__init__(self) - self.threads = threads - self.setDaemon(True) - - def run(self): - # elimina los threads muertos - while True: - sleep(1) - for t in threads: - if not t.isAlive(): - print("ControlThread removing dead", t) - threads.remove(t) - - -class ClientThread(Thread): - def __init__(self, sock, ip, port): - Thread.__init__(self) - self.ip = ip - self.port = port - self.sock = sock - self.setDaemon(True) - - def __del__(self): - print("ClientThread died") - - def run(self): - print("[+] New server socket thread started for " + self.ip + ":" + str(self.port)) - #print("Thread", self) - server = VncServer(self.sock, self.ip, self.port) - status = server.init() - - if not status: - print("Error negotiating client init") - return False - server.protocol() - - -def main(argv): - global CONFIG, TCP_IP, TCP_PORT, VNC_PASSWORD, mouse, keyboard, threads, controlthread - - class CONFIG: - _8bitdither = False - - parser = ArgumentParser() - parser.add_argument("-l", "--listen-address", dest="TCP_IP", - help="Listen in this address, default: %s" % ("0.0.0.0"), required=False, default='0.0.0.0') - parser.add_argument("-p", "--port", dest="TCP_PORT", - help="Listen in this port, default: %s" % ("5901"), type=int, required=False, default='5901') - parser.add_argument("-P", "--password", help="Sets password", required=True, dest="VNC_PASSWORD") - - parser.add_argument("-8", "--8bitdither", help="Enable 8 bit dithering", required=False, action='store_true', dest="dither") - - args = parser.parse_args() - - # Multithreaded Python server - TCP_IP = '0.0.0.0' if not hasattr(args,"TCP_IP") else args.TCP_IP - TCP_PORT = '0.0.0.0' if not hasattr(args,"TCP_PORT") else args.TCP_PORT - VNC_PASSWORD = args.VNC_PASSWORD - CONFIG._8bitdither = args.dither - - sockServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sockServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - sockServer.bind((TCP_IP, TCP_PORT)) - - controlthread = ControlThread(threads) - controlthread.start() - threads.append(controlthread) - - print("Multithreaded Python server : Waiting for connections from TCP clients...") - print("Runing on:", sys.platform) - while True: - sockServer.listen(4) - (conn, (ip,port)) = sockServer.accept() - newthread = ClientThread(conn, ip, port) - newthread.setDaemon(True) - newthread.start() - threads.append(newthread) - #print(threads) - -if __name__ == "__main__": - try: - threads = [] - main(sys.argv) - except KeyboardInterrupt: - # quit - print("Exiting on ctrl+c...") - #for t in threads: - # print("Killing", t) - sys.exit() diff --git a/server4.py b/server4.py deleted file mode 100644 index 0a6afa2..0000000 --- a/server4.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -import pyvncs -from argparse import ArgumentParser -from threading import Thread -from time import sleep - -import sys -import socket - - -class ControlThread(Thread): - def __init__(self, threads): - Thread.__init__(self) - self.threads = threads - self.setDaemon(True) - - def run(self): - # elimina los threads muertos - while True: - sleep(1) - for t in threads: - if not t.isAlive(): - print("ControlThread removing dead", t) - threads.remove(t) - -class ClientThread(Thread): - def __init__(self, sock, ip, port): - Thread.__init__(self) - self.ip = ip - self.port = port - self.sock = sock - self.setDaemon(True) - - def __del__(self): - print("ClientThread died") - - def run(self): - print("[+] New server socket thread started for " + self.ip + ":" + str(self.port)) - #print("Thread", self) - server = pyvncs.server.VncServer(self.sock, VNC_PASSWORD) - server.CONFIG._8bitdither = CONFIG._8bitdither - status = server.init() - - if not status: - print("Error negotiating client init") - return False - server.protocol() - - -def main(argv): - global CONFIG, TCP_IP, TCP_PORT, VNC_PASSWORD, threads, controlthread - class CONFIG: - _8bitdither = False - - parser = ArgumentParser() - parser.add_argument("-l", "--listen-address", dest="TCP_IP", - help="Listen in this address, default: %s" % ("0.0.0.0"), required=False, default='0.0.0.0') - parser.add_argument("-p", "--port", dest="TCP_PORT", - help="Listen in this port, default: %s" % ("5901"), type=int, required=False, default='5901') - parser.add_argument("-P", "--password", help="Sets password", required=True, dest="VNC_PASSWORD") - parser.add_argument("-8", "--8bitdither", help="Enable 8 bit dithering", required=False, action='store_true', dest="dither") - args = parser.parse_args() - - # Multithreaded Python server - TCP_IP = '0.0.0.0' if not hasattr(args,"TCP_IP") else args.TCP_IP - TCP_PORT = '0.0.0.0' if not hasattr(args,"TCP_PORT") else args.TCP_PORT - VNC_PASSWORD = args.VNC_PASSWORD - CONFIG._8bitdither = args.dither - - sockServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sockServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - sockServer.bind((TCP_IP, TCP_PORT)) - - controlthread = ControlThread(threads) - controlthread.start() - threads.append(controlthread) - - print("Multithreaded Python server : Waiting for connections from TCP clients...") - print("Runing on:", sys.platform) - while True: - sockServer.listen(4) - (conn, (ip,port)) = sockServer.accept() - newthread = ClientThread(conn, ip, port) - newthread.setDaemon(True) - newthread.start() - threads.append(newthread) - #print(threads) - - -if __name__ == "__main__": - try: - threads = [] - main(sys.argv) - except KeyboardInterrupt: - # quit - print("Exiting on ctrl+c...") - #for t in threads: - # print("Killing", t) - sys.exit() - \ No newline at end of file diff --git a/test.php b/test.php deleted file mode 100755 index c0fb01b..0000000 --- a/test.php +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/php - 8){ - $cnt = 8; - } - - for($i=1; $i<=$cnt; $i++){ - $s = $arr[$i]; - $s = (($s >> 1) & 0x55) | (($s << 1) & 0xaa); - $s = (($s >> 2) & 0x33) | (($s << 2) & 0xcc); - $s = (($s >> 4) & 0x0f) | (($s << 4) & 0xf0); - $ret = $ret . chr($s); - } - return $ret; -} - -$passwd="kaka80\0\0"; -$data = "1234567890123456"; - -$iv = mcrypt_create_iv(mcrypt_get_iv_size (MCRYPT_DES, MCRYPT_MODE_ECB), MCRYPT_RAND); -$crypted = mcrypt_encrypt(MCRYPT_DES, mirrorBits($passwd), $data, MCRYPT_MODE_ECB, $iv); - -echo "Crypted: " . base64_encode($crypted); -echo "\n"; diff --git a/test.py b/test.py deleted file mode 100644 index a05e776..0000000 --- a/test.py +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -from pynput import mouse, keyboard - -keyboard.Controller().press(keyboard.Key.shift) -keyboard.Controller().press('a') - -#keyboard.Controller().modifiers(keyboard.Key().shift) -#print("Shift:", keyboard.Controller().shift_pressed) -#keyboard.Controller().press('a') -#keyboard.Controller().release('a') -#keyboard.Controller().release(keyboard.Key.shift_r) - - diff --git a/test2.py b/test2.py deleted file mode 100755 index 0cec203..0000000 --- a/test2.py +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -zlibHeader = bytearray() -zlibLength = 300309 - -zlibHeader.append( (zlibLength>>24) & 0xFF ) -zlibHeader.append( (zlibLength>>16) & 0xFF ) -zlibHeader.append( (zlibLength>>8) & 0xFF ) -zlibHeader.append( zlibLength & 0xFF ) - -print(zlibHeader) diff --git a/test3.py b/test3.py deleted file mode 100755 index c78f157..0000000 --- a/test3.py +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -from PIL import Image, ImageChops, ImageDraw - -def quantizetopalette(silf, palette, dither=False): - """Convert an RGB or L mode image to use a given P image's palette.""" - - silf.load() - - # use palette from reference image - palette.load() - if palette.mode != "P": - raise ValueError("bad mode for palette image") - if silf.mode != "RGB" and silf.mode != "L": - raise ValueError( - "only RGB or L mode images can be quantized to a palette" - ) - im = silf.im.convert("P", 1 if dither else 0, palette.im) - # the 0 above means turn OFF dithering - - # Later versions of Pillow (4.x) rename _makeself to _new - try: - return silf._new(im) - except AttributeError: - return silf._makeself(im) - - -BGR233 = [0, 0, 0, 0, 0, 85, 0, 0, 170, 0, 0, 255, 36, 0, 0, 36, 0, 85, 36, 0, 170, 36, 0, 255, 73, 0, 0, 73, 0, 85, 73, 0, 170, 73, 0, 255, 109, 0, 0, 109, 0, 85, 109, 0, 170, 109, 0, 255, 146, 0, 0, 146, 0, 85, 146, 0, 170, 146, 0, 255, 182, 0, 0, 182, 0, 85, 182, 0, 170, 182, 0, 255, 219, 0, 0, 219, 0, 85, 219, 0, 170, 219, 0, 255, 255, 0, 0, 255, 0, 85, 255, 0, 170, 255, 0, 255, 0, 36, 0, 0, 36, 85, 0, 36, 170, 0, 36, 255, 36, 36, 0, 36, 36, 85, 36, 36, 170, 36, 36, 255, 73, 36, 0, 73, 36, 85, 73, 36, 170, 73, 36, 255, 109, 36, 0, 109, 36, 85, 109, 36, 170, 109, 36, 255, 146, 36, 0, 146, 36, 85, 146, 36, 170, 146, 36, 255, 182, 36, 0, 182, 36, 85, 182, 36, 170, 182, 36, 255, 219, 36, 0, 219, 36, 85, 219, 36, 170, 219, 36, 255, 255, 36, 0, 255, 36, 85, 255, 36, 170, 255, 36, 255, 0, 73, 0, 0, 73, 85, 0, 73, 170, 0, 73, 255, 36, 73, 0, 36, 73, 85, 36, 73, 170, 36, 73, 255, 73, 73, 0, 73, 73, 85, 73, 73, 170, 73, 73, 255, 109, 73, 0, 109, 73, 85, 109, 73, 170, 109, 73, 255, 146, 73, 0, 146, 73, 85, 146, 73, 170, 146, 73, 255, 182, 73, 0, 182, 73, 85, 182, 73, 170, 182, 73, 255, 219, 73, 0, 219, 73, 85, 219, 73, 170, 219, 73, 255, 255, 73, 0, 255, 73, 85, 255, 73, 170, 255, 73, 255, 0, 109, 0, 0, 109, 85, 0, 109, 170, 0, 109, 255, 36, 109, 0, 36, 109, 85, 36, 109, 170, 36, 109, 255, 73, 109, 0, 73, 109, 85, 73, 109, 170, 73, 109, 255, 109, 109, 0, 109, 109, 85, 109, 109, 170, 109, 109, 255, 146, 109, 0, 146, 109, 85, 146, 109, 170, 146, 109, 255, 182, 109, 0, 182, 109, 85, 182, 109, 170, 182, 109, 255, 219, 109, 0, 219, 109, 85, 219, 109, 170, 219, 109, 255, 255, 109, 0, 255, 109, 85, 255, 109, 170, 255, 109, 255, 0, 146, 0, 0, 146, 85, 0, 146, 170, 0, 146, 255, 36, 146, 0, 36, 146, 85, 36, 146, 170, 36, 146, 255, 73, 146, 0, 73, 146, 85, 73, 146, 170, 73, 146, 255, 109, 146, 0, 109, 146, 85, 109, 146, 170, 109, 146, 255, 146, 146, 0, 146, 146, 85, 146, 146, 170, 146, 146, 255, 182, 146, 0, 182, 146, 85, 182, 146, 170, 182, 146, 255, 219, 146, 0, 219, 146, 85, 219, 146, 170, 219, 146, 255, 255, 146, 0, 255, 146, 85, 255, 146, 170, 255, 146, 255, 0, 182, 0, 0, 182, 85, 0, 182, 170, 0, 182, 255, 36, 182, 0, 36, 182, 85, 36, 182, 170, 36, 182, 255, 73, 182, 0, 73, 182, 85, 73, 182, 170, 73, 182, 255, 109, 182, 0, 109, 182, 85, 109, 182, 170, 109, 182, 255, 146, 182, 0, 146, 182, 85, 146, 182, 170, 146, 182, 255, 182, 182, 0, 182, 182, 85, 182, 182, 170, 182, 182, 255, 219, 182, 0, 219, 182, 85, 219, 182, 170, 219, 182, 255, 255, 182, 0, 255, 182, 85, 255, 182, 170, 255, 182, 255, 0, 219, 0, 20, 219, 85, 0, 219, 170, 0, 219, 255, 36, 219, 0, 36, 219, 85, 36, 219, 170, 36, 219, 255, 73, 219, 0, 73, 219, 85, 73, 219, 170, 73, 219, 255, 109, 219, 0, 109, 219, 85, 109, 219, 170, 109, 219, 255, 146, 219, 0, 146, 219, 85, 146, 219, 170, 146, 219, 255, 182, 219, 0, 182, 219, 85, 182, 219, 170, 182, 219, 255, 219, 219, 0, 219, 219, 85, 219, 219, 170, 219, 219, 255, 255, 219, 0, 255, 219, 85, 255, 219, 170, 255, 219, 255, 0, 255, 0, 0, 255, 85, 0, 255, 170, 0, 255, 255, 36, 255, 0, 36, 255, 85, 36, 255, 170, 36, 255, 255, 73, 255, 0, 73, 255, 85, 73, 255, 170, 73, 255, 255, 109, 255, 0, 109, 255, 85, 109, 255, 170, 109, 255, 255, 146, 255, 0, 146, 255, 85, 146, 255, 170, 146, 255, 255, 182, 255, 0, 182, 255, 85, 182, 255, 170, 182, 255, 255, 219, 255, 0, 219, 255, 85, 219, 255, 170, 219, 255, 255, 255, 255, 0, 255, 255, 85, 255, 255, 170, 255, 255, 255] - -im = Image.open("/Users/radix/Downloads/IMG_20170929_185311.jpg") -print(im) - -p = Image.new("P",(16,16)) -p.putpalette(BGR233) - -#im2 = im.quantize(palette=p) - -im2 = quantizetopalette(im, p, dither=False) - -im2.show() - -print(im2.getpalette() == BGR233) \ No newline at end of file diff --git a/testtkinker.py b/testtkinker.py deleted file mode 100644 index 7f56386..0000000 --- a/testtkinker.py +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -import sys - -from PIL import Image, ImageChops, ImageDraw, ImagePalette -if sys.platform == "linux" or sys.platform == "linux2": - from Xlib import display, X - # take screen images, that's not the best way, so here - # we use directly use xlib to take the screenshot. - class ImageGrab(): - def grab(): - dsp = display.Display() - root = dsp.screen().root - geom = root.get_geometry() - w = geom.width - h = geom.height - raw = root.get_image(0, 0, w ,h, X.ZPixmap, 0xffffffff) - image = Image.frombytes("RGB", (w, h), raw.data, "raw", "BGRX") - return image - -elif sys.platform == "darwin": - import Quartz.CoreGraphics as CG - class ImageGrab(): - def grab(): - screenshot = CG.CGWindowListCreateImage(CG.CGRectInfinite, CG.kCGWindowListOptionOnScreenOnly, CG.kCGNullWindowID, CG.kCGWindowImageDefault) - width = CG.CGImageGetWidth(screenshot) - height = CG.CGImageGetHeight(screenshot) - bytesperrow = CG.CGImageGetBytesPerRow(screenshot) - - pixeldata = CG.CGDataProviderCopyData(CG.CGImageGetDataProvider(screenshot)) - - i = Image.frombytes("RGBA", (width, height), pixeldata) - (b, g, r, x) = i.split() - i = Image.merge("RGBX", (r, g, b, x)) - - return i - -else: - from PIL import ImageGrab - - - -thickarrow_strings = ( #sized 24x24 - "XX ", - "XXX ", - "XXXX ", - "XX.XX ", - "XX..XX ", - "XX...XX ", - "XX....XX ", - "XX.....XX ", - "XX......XX ", - "XX.......XX ", - "XX........XX ", - "XX........XXX ", - "XX......XXXXX ", - "XX.XXX..XX ", - "XXXX XX..XX ", - "XX XX..XX ", - " XX..XX ", - " XX..XX ", - " XX..XX ", - " XXXX ", - " XX ", - " ", - " ", - " ") - - -buf = "" -for x in thickarrow_strings: - buf += x - -i = Image.frombytes("I", (24,24), str.encode(buf)) -print(i) -i.show() - -