diff --git a/ctrlsrv.py b/ctrlsrv.py deleted file mode 100755 index cd7fcd3..0000000 --- a/ctrlsrv.py +++ /dev/null @@ -1,327 +0,0 @@ -#!/usr/bin/env python3 -# 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 . - -import pyvncs -from lib import log -from lib import common -from argparse import ArgumentParser -from threading import Thread -import time -import sys -import socket -import signal -import readline -import traceback - -#_debug = log.debug -_debug = print - -if common.isWindows(): - _debug("Wintendo...") - import win32ts - import win32security - import win32con - import win32api - import ntsecuritycon - import win32process - import win32event - -def signal_handler(signal, frame): - _debug("Exiting on signal %s..." % signal) - sys.exit(0) - -signal.signal(signal.SIGINT, signal_handler) - -config = { -} - -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: - time.sleep(1) - for t in threads: - if not t.isAlive(): - _debug("ControlThread removing dead", t) - threads.remove(t) - -class VNCThread(Thread): - def __init__(self, port, password): - Thread.__init__(self) - self.ip = None - self.port = port - self.sock = None - self.password = password - self.setDaemon(True) - - def __del__(self): - _debug("VNCThread died") - - - def run(self): - - TCP_IP = '0.0.0.0' - _debug("[+] Listen...") - self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - self.sock.bind((TCP_IP, int(self.port))) - self.sock.listen(4) - (conn, (ip,port)) = self.sock.accept() - - _debug("[+] New server socket started for " + ip + ":" + str(port)) - #_debug("Thread", self) - server = pyvncs.server.VncServer(conn, self.password) - #server.CONFIG._8bitdither = CONFIG._8bitdither - status = server.init() - - if not status: - _debug("Error negotiating client init") - return False - server.protocol() - - -class ClientThread(Thread): - def __init__(self, sock, ip, port, config): - Thread.__init__(self) - self.ip = ip - self.port = port - self.sock = sock - self.setDaemon(True) - self.config = config - - def __del__(self): - _debug("ClientThread died") - - def run(self): - #_debug("[+] New server socket thread started for " + self.ip + ":" + str(self.port)) - #_debug("Thread", self) - f = self.sock.makefile('rw') - - f.write("AUTH:>") - f.flush() - passwd = f.readline().strip("\n") - if passwd != config["PASSWORD"]: - time.sleep(1) - f.write("!NO AUTH") - f.flush() - _debug("NO AUTH '%s' != '%s'" % (passwd, config["PASSWORD"])) - self.sock.close() - return - - while True: - f.write("OK:>") - f.flush() - try: - data = f.readline() - cmd = data.strip() - if not data: break - - if cmd == "_DEBUG": - sys.stdout = sys.stderr = f - f.write("OK\n") - - elif cmd == "PING": - f.write("PONG\n") - - elif cmd == "QUIT": - f.write("BYE\n") - self.sock.close() - return - - elif cmd.startswith("STARTVNC"): - params = cmd.split() - if len(params) != 3: - f.write("!NOT_PARAMS\n") - f.flush() - continue - _debug("START VNC !!!") - newthread = VNCThread(params[1], params[2]) - newthread.setDaemon(True) - newthread.start() - - elif cmd == "_WINSESSIONS" and common.isWindows(): - winsessions = win32ts.WTSEnumerateSessions(win32ts.WTS_CURRENT_SERVER_HANDLE) - print(winsessions, file=f) - - elif cmd == "_WINCONSOLE" and common.isWindows(): - winsessions = win32ts.WTSEnumerateSessions(win32ts.WTS_CURRENT_SERVER_HANDLE) - print(winsessions, file=f) - active = win32ts.WTSGetActiveConsoleSessionId() - print(active, file=f) - token = win32ts.WTSQueryUserToken(active) - print(token, file=f) - duplicated = win32security.DuplicateTokenEx(token, win32con.MAXIMUM_ALLOWED, win32con.NULL, win32security.TokenPrimary, win32security.SECURITY_ATTRIBUTES()) - print("duplicated", token, file=f) - - elif cmd == "_TEST" and common.isWindows(): - winsessions = win32ts.WTSEnumerateSessions(win32ts.WTS_CURRENT_SERVER_HANDLE) - print(winsessions, file=f) - active = win32ts.WTSGetActiveConsoleSessionId() - print(active, file=f) - token = win32ts.WTSQueryUserToken(active) - print("token", token, file=f) - ntoken = win32security.DuplicateTokenEx(token, 3 , win32con.MAXIMUM_ALLOWED , win32security.TokenPrimary , win32security.SECURITY_ATTRIBUTES() ) - print("ntoken", ntoken, file=f) - #th = win32security.OpenProcessToken(win32api.GetCurrentProcess(), win32con.MAXIMUM_ALLOWED) - #print("th", th, file=f) - shell_as2(ntoken, True, "cmd") - - elif cmd == "_EVAL": - while True: - f.write("EV:>") - f.flush() - data = f.readline() - cmd = data.strip() - if cmd == "": continue - if cmd == "_QUIT": break - if not data: break - - try: - eval(data) - except: - print("ERROR:", sys.exc_info()[0], file=f) - print(traceback.format_exc(), file=f) - f.flush() - - _debug("eval:", cmd.strip()) - f.flush() - - elif cmd == "_ERROR": - a = 1/0 - - else: - f.write("!NO_CMD %s\n" % cmd) - - _debug("command:", cmd.strip()) - f.flush() - except: - print("ERROR:", sys.exc_info()[0], file=f) - print(traceback.format_exc(), file=f) - f.flush() - -def get_all_privs(th): - # Try to give ourselves some extra privs (only works if we're admin): - # SeBackupPrivilege - so we can read anything - # SeDebugPrivilege - so we can find out about other processes (otherwise OpenProcess will fail for some) - # SeSecurityPrivilege - ??? what does this do? - - # Problem: Vista+ support "Protected" processes, e.g. audiodg.exe. We can't see info about these. - # Interesting post on why Protected Process aren't really secure anyway: http://www.alex-ionescu.com/?p=34 - - privs = win32security.GetTokenInformation(th, ntsecuritycon.TokenPrivileges) - for privtuple in privs: - privs2 = win32security.GetTokenInformation(th, ntsecuritycon.TokenPrivileges) - newprivs = [] - for privtuple2 in privs2: - if privtuple2[0] == privtuple[0]: - newprivs.append((privtuple2[0], 2)) # SE_PRIVILEGE_ENABLED - else: - newprivs.append((privtuple2[0], privtuple2[1])) - - # Adjust privs - privs3 = tuple(newprivs) - win32security.AdjustTokenPrivileges(th, False, privs3) -def shell_as(th, enable_privs = 0): - #t = thread(th) - #print(t.as_text()) - new_tokenh = win32security.DuplicateTokenEx(th, 3 , win32con.MAXIMUM_ALLOWED , win32security.TokenPrimary , win32security.SECURITY_ATTRIBUTES() ) - print("new_tokenh: %s" % new_tokenh) - print("Impersonating...") - if enable_privs: - get_all_privs(new_tokenh) - commandLine = "cmd" - si = win32process.STARTUPINFO() - print("pysecdump: Starting shell with required privileges...") - (hProcess, hThread, dwProcessId, dwThreadId) = win32process.CreateProcessAsUser( - new_tokenh, - None, # AppName - commandLine, # Command line - None, # Process Security - None, # ThreadSecurity - 1, # Inherit Handles? - win32process.NORMAL_PRIORITY_CLASS, - None, # New environment - None, # Current directory - si) # startup info. - win32event.WaitForSingleObject( hProcess, win32event.INFINITE ); - print("pysecdump: Quitting") - -def shell_as2(new_tokenh, enable_privs = 0, commandLine = "cmd"): - print("new_tokenh: %s" % new_tokenh) - print("Impersonating...") - if enable_privs: - get_all_privs(new_tokenh) - si = win32process.STARTUPINFO() - print("pysecdump: Starting shell with required privileges...") - (hProcess, hThread, dwProcessId, dwThreadId) = win32process.CreateProcessAsUser( - new_tokenh, - None, # AppName - commandLine, # Command line - None, # Process Security - None, # ThreadSecurity - 1, # Inherit Handles? - win32process.NORMAL_PRIORITY_CLASS, - None, # New environment - None, # Current directory - si) # startup info. - win32event.WaitForSingleObject( hProcess, win32event.INFINITE ) - print("pysecdump: Quitting") - -def main(argv): - global threads, config - 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" % ("5899"), type=int, required=False, default='5899') - parser.add_argument("-P", "--password", help="Sets password", required=True, dest="PASSWORD") - - args = parser.parse_args() - - config["PASSWORD"] = args.PASSWORD - config["PORT"] = args.TCP_PORT - - sockServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sockServer.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - sockServer.bind((args.TCP_IP, args.TCP_PORT)) - - controlthread = ControlThread(threads) - controlthread.start() - threads.append(controlthread) - - #_debug("Multithreaded Python server : Waiting for connections from TCP clients...") - _debug("Runing on:", sys.platform) - while True: - sockServer.listen(4) - (conn, (ip,port)) = sockServer.accept() - newthread = ClientThread(conn, ip, port, config) - newthread.setDaemon(True) - newthread.start() - threads.append(newthread) - #print(threads) - - - -if __name__ == "__main__": - threads = [] - main(sys.argv)