| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- #!/usr/bin/env python3
- import json
- import os
- import signal
- import socket
- import subprocess
- import sys
- import time
- import websocket
- DEBUG = True
- DEBUG = False
- def log(s):
- if not DEBUG:
- return
- print(s)
- def sendmsg(msg):
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- ret = None
- try:
- s.connect(('localhost', 9999))
- tosend = msg + "\r\n"
- encoded_msg = tosend.encode("ascii")
- s.sendall(encoded_msg)
- ret = s.recv(4096)
- s.close()
- except Exception as e:
- log(e)
- return None
- log("[nc output] %s " % ret)
- return ret
- class PManager:
- ws = websocket.WebSocket()
- ip = "ws://192.168.1.208:9001"
- p_list = {}
- ptable = {}
- log_list = {}
- name = ""
- def __init__(self, name, ptable):
- self.ptable = ptable
- self.conn(self.ip)
- self.name = name
- signal.signal(signal.SIGINT, self.sighandler)
- signal.signal(signal.SIGCHLD, signal.SIG_IGN) #To kill zombies
- while True:
- try:
- data = self.ws.recv()
- except Exception as e:
- log(e)
- self.conn(self.ip)
- continue
- try:
- j = json.loads(data)
- except Exception as e:
- log(e)
- log("Invalid json?")
- continue
-
- if ("type" not in j or "command" not in j or
- "key" not in j or j["type"] != "snowmix"):
- log("Dropping: %s" % j)
- continue
-
- #log(j)
- if j["command"] == "oneshot":
- opts = None
- if "options" in j:
- opts = j["options"]
- self.oneshot(j["key"], opts)
- if j["command"] == "launch":
- opts = None
- if "options" in j:
- opts = j["options"]
- self.launch(j["key"], opts)
-
- if j["command"] == "kill":
- self.stop(j["key"])
-
- if j["command"] == "netcat":
- sendmsg(j["key"])
- if j["command"] == "status": #and j["key"] == self.name:
- self.sendstatus()
- def sendstatus(self):
- self.send({"type": "snowmix", "subtype": "statusreport", "name": self.name, "data":self.p_list})
- def send(self, data):
- try:
- if type(data) is dict:
- data = json.dumps(data)
- print(data)
- self.ws.send(data)
- except Exception as e:
- print(e)
- def conn(self, target):
- if self.ws is None:
- self.ws = websocket.WebSocket()
- try:
- self.ws.connect(target)
- except Exception as e:
- log(e)
- time.sleep(2)
- self.conn(target) #keep trying you basterd
-
-
- def close(self):
- if self.ws is None:
- return
- self.ws.close()
-
- def sighandler(self, sig, frame):
- log("\rExiting!")
- self.close()
- log("Bye!")
- sys.exit(0)
-
- def stop(self, key):
- if key not in self.p_list:
- log("key %s doesn't exist! not killing!" % (key))
- return
- try:
- os.killpg(os.getpgid(self.p_list[key]), signal.SIGTERM)
- except Exception as e:
- log("This process (%d) can't be killed! Why?" % self.p_list[key])
- log(e)
-
- try:
- self.log_list[key].close()
- except Exception as e:
- log("ex file: %s" % e)
-
- if key in self.log_list:
- del self.log_list[key]
-
- del self.p_list[key]
- self.sendstatus()
-
- def oneshot(self, key, options=None):
- if key not in self.ptable:
- log("This process (%s) is not on my table!" % key)
- return
- log("Oneshotting! key: %s" % key)
- tolaunch = self.ptable[key]
- if options is not None:
- options = [ o for o in options if type(o) is str ]
- tolaunch = tolaunch + options
- log(tolaunch)
- try:
- proc = subprocess.Popen(tolaunch, preexec_fn=os.setsid)
- except Exception as e:
- log(e)
- def launch(self, key, options=None):
- if key in self.p_list:
- log("key %s exist! not running!" % (key))
- return
-
- if key not in self.ptable:
- log("This process (%s) is not on my table!" % key)
- return
-
- log("Launching! key: %s, opts: %s" % (key, options))
- tolaunch = self.ptable[key]
- if options is not None:
- options = [ o for o in options if type(o) is str ]
- tolaunch = tolaunch + options
-
- log(tolaunch)
- self.log_list[key] = open("/tmp/%s" % key, "w")
- try:
- proc = subprocess.Popen(tolaunch, preexec_fn=os.setsid, stdout=self.log_list[key])
- #Le doy su propio grupo al subproceso
- except Exception as e:
- log(e)
- sys.exit(1)
- self.p_list[key] = proc.pid
- self.sendstatus()
- return proc.pid
- if __name__ == "__main__":
- if len(sys.argv) != 2:
- print("Usage: ./%s <file.json>" % (sys.argv[0]))
- sys.exit(1)
- try:
- data = json.loads(open(sys.argv[1]).read())
- except Exception as e:
- print(e)
- sys.exit(2)
-
- ptable = data["data"]
- name = data["name"]
- m = PManager(name, ptable)
|