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 65bdec7..3206e87 100644 Binary files a/pyvncs/__pycache__/__init__.cpython-36.pyc and b/pyvncs/__pycache__/__init__.cpython-36.pyc differ diff --git a/pyvncs/__pycache__/server.cpython-36.pyc b/pyvncs/__pycache__/server.cpython-36.pyc index 44b0a05..96d4937 100644 Binary files a/pyvncs/__pycache__/server.cpython-36.pyc and b/pyvncs/__pycache__/server.cpython-36.pyc differ 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() - -