Structural changes and code cleanup
This commit is contained in:
20
lib/encodings/__init__.py
Normal file
20
lib/encodings/__init__.py
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
# at least, raw encoding is needed by the rfb protocol
|
||||
from . import common as enc
|
||||
from . import raw
|
||||
Binary file not shown.
Binary file not shown.
@@ -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)
|
||||
|
||||
|
||||
337
server.py
337
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))
|
||||
|
||||
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))
|
||||
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
|
||||
@@ -289,47 +22,64 @@ 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()
|
||||
|
||||
app = wx.App(False)
|
||||
# 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))
|
||||
threads = []
|
||||
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()
|
||||
controlthread = ControlThread(threads)
|
||||
controlthread.start()
|
||||
threads.append(controlthread)
|
||||
|
||||
print("Multithreaded Python server : Waiting for connections from TCP clients...")
|
||||
while True:
|
||||
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)
|
||||
@@ -337,3 +87,16 @@ while 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()
|
||||
|
||||
854
server2.py
854
server2.py
@@ -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()
|
||||
821
server3.py
821
server3.py
@@ -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()
|
||||
102
server4.py
102
server4.py
@@ -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()
|
||||
|
||||
49
test.php
49
test.php
@@ -1,49 +0,0 @@
|
||||
#!/usr/bin/php
|
||||
<?php
|
||||
|
||||
function _dump_old($text) {
|
||||
$retval = '';
|
||||
for($i = 0; $i < strlen($text); ++$i) {
|
||||
$retval .= ':'.dechex(ord($text[$i]));
|
||||
}
|
||||
|
||||
return $retval;
|
||||
}
|
||||
|
||||
function _dump($string){
|
||||
$hex = '';
|
||||
for ($i=0; $i<strlen($string); $i++){
|
||||
$ord = ord($string[$i]);
|
||||
$hexCode = dechex($ord);
|
||||
$hex .= '\x' . substr('0'.$hexCode, -2);
|
||||
}
|
||||
return $hex;
|
||||
}
|
||||
|
||||
|
||||
function mirrorBits($k) {
|
||||
$arr = unpack('c*', $k);
|
||||
$ret = '';
|
||||
$cnt = count($arr);
|
||||
if($cnt > 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";
|
||||
15
test.py
15
test.py
@@ -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)
|
||||
|
||||
|
||||
12
test2.py
12
test2.py
@@ -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)
|
||||
43
test3.py
43
test3.py
@@ -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)
|
||||
@@ -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()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user