Structural changes and code cleanup

This commit is contained in:
Matias Fernandez
2018-11-20 17:27:20 -03:00
parent f4c77886bd
commit 4add215ecd
13 changed files with 90 additions and 2317 deletions

20
lib/encodings/__init__.py Normal file
View 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

View File

@@ -28,6 +28,8 @@ import random
import zlib import zlib
import numpy as np import numpy as np
from lib.encodings import *
def hexdump(data): def hexdump(data):
str = "" str = ""
for d in data: for d in data:
@@ -98,11 +100,6 @@ else:
class VncServer(): class VncServer():
class ENCODINGS:
raw = 0
zlib = 6 # zlib
cursor = -239 # mouse cursor pseudo encoding
class CONFIG: class CONFIG:
_8bitdither = False _8bitdither = False
@@ -358,7 +355,7 @@ class VncServer():
del screen del screen
self.primaryOrder = "rgb" self.primaryOrder = "rgb"
self.encoding = self.ENCODINGS.raw self.encoding = enc.ENCODINGS.raw
buttonmask = 0 buttonmask = 0
buttons = [0, 0, 0, 0, 0, 0, 0, 0] buttons = [0, 0, 0, 0, 0, 0, 0, 0]
left_pressed = 0 left_pressed = 0
@@ -486,20 +483,21 @@ class VncServer():
data2 = sock.recv(3) data2 = sock.recv(3)
print("Client Message Type: SetEncoding (2)") print("Client Message Type: SetEncoding (2)")
(nencodings,) = unpack("!xH", data2) (nencodings,) = unpack("!xH", data2)
print("SetEncoding: total encodings ", repr(nencodings)) print("SetEncoding: total encodings", repr(nencodings))
data2 = sock.recv(4 * nencodings, socket.MSG_WAITALL) data2 = sock.recv(4 * nencodings, socket.MSG_WAITALL)
print("len", len(data2)) #print("len", len(data2))
self.client_encodings = unpack("!%si" % nencodings, 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") print("Remote cursor encoding present")
self.remotecursor = True self.remotecursor = True
self.cursorchanged = 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") print("Using zlib encoding")
self.encoding = self.ENCODINGS.zlib self.encoding = enc.ENCODINGS.zlib
continue continue
@@ -735,7 +733,7 @@ class VncServer():
sendbuff.extend( image.tobytes() ) 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: if not firstUpdateSent:
firstUpdateSent = True firstUpdateSent = True
compress = zlib.compressobj( compress = zlib.compressobj(
@@ -767,42 +765,9 @@ class VncServer():
sendbuff.extend( l ) # send length sendbuff.extend( l ) # send length
sendbuff.extend( zlibdata ) # send compressed data 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: else:
# send with RAW encoding # send with RAW encoding
rectangles = 1 sendbuff.extend(enc.ENCODINGS.raw_send_image(x, y, w, h, image))
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: else:
print("[!] Unsupported BPP: %s" % self.bpp) print("[!] Unsupported BPP: %s" % self.bpp)

351
server.py
View File

@@ -1,287 +1,20 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import socket, os, sys, wx import pyvncs
from argparse import ArgumentParser
from threading import Thread from threading import Thread
from time import sleep from time import sleep
from struct import *
from pyDes import *
def hexdump(data): import sys
print(" ".join(hex(ord(n)) for n in data)) 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): class ControlThread(Thread):
def __init__(self, threads): def __init__(self, threads):
Thread.__init__(self) Thread.__init__(self)
self.threads = threads self.threads = threads
self.setDaemon(True)
def run(self): def run(self):
# elimina los threads muertos # elimina los threads muertos
@@ -289,51 +22,81 @@ class ControlThread(Thread):
sleep(1) sleep(1)
for t in threads: for t in threads:
if not t.isAlive(): if not t.isAlive():
print("ControlThread removing dead", t)
threads.remove(t) threads.remove(t)
class ClientThread(Thread): class ClientThread(Thread):
def __init__(self, sock, ip, port): def __init__(self, sock, ip, port):
Thread.__init__(self) Thread.__init__(self)
self.ip = ip self.ip = ip
self.port = port self.port = port
self.sock = sock self.sock = sock
self.setDaemon(True)
def __del__(self): def __del__(self):
print("ClientThread died") print("ClientThread died")
def run(self): def run(self):
print("[+] New server socket thread started for " + self.ip + ":" + str(self.port)) 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() status = server.init()
if not status: if not status:
print("Error negotiating client init") print("Error negotiating client init")
return False return False
server.protocol() server.protocol()
# Multithreaded Python server def main(argv):
TCP_IP = '0.0.0.0' global CONFIG, TCP_IP, TCP_PORT, VNC_PASSWORD, threads, controlthread
TCP_PORT = 5901 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 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sockServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sockServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sockServer.bind((TCP_IP, TCP_PORT)) sockServer.bind((TCP_IP, TCP_PORT))
threads = []
controlthread = ControlThread(threads) controlthread = ControlThread(threads)
controlthread.start() 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()
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)

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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
View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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()