mirror of
https://github.com/maxDcb/C2TeamServer
synced 2026-06-06 16:14:27 +00:00
214 lines
8.1 KiB
Python
214 lines
8.1 KiB
Python
import sys
|
|
import os
|
|
import time
|
|
from threading import Thread, Lock
|
|
from PyQt5.QtWidgets import *
|
|
from PyQt5.QtGui import *
|
|
from PyQt5.QtCore import *
|
|
|
|
from grpcClient import *
|
|
|
|
|
|
#
|
|
# Sessions
|
|
#
|
|
class Session():
|
|
|
|
def __init__(self, id, listenerHash, beaconHash, hostname, username, arch, privilege, os, lastProofOfLife, killed):
|
|
self.id = id
|
|
self.listenerHash = listenerHash
|
|
self.beaconHash = beaconHash
|
|
self.hostname = hostname
|
|
self.username = username
|
|
self.arch = arch
|
|
self.privilege = privilege
|
|
self.os = os
|
|
self.lastProofOfLife = lastProofOfLife
|
|
self.killed = killed
|
|
|
|
|
|
class Sessions(QWidget):
|
|
|
|
interactWithSession = pyqtSignal(str, str, str, str)
|
|
|
|
idSession = 0
|
|
listSessionObject = []
|
|
|
|
def __init__(self, parent, ip, port, devMode):
|
|
super(QWidget, self).__init__(parent)
|
|
|
|
self.ip = ip
|
|
self.port = port
|
|
self.grpcClient = GrpcClient(ip, port, devMode)
|
|
|
|
widget = QWidget(self)
|
|
self.layout = QGridLayout(widget)
|
|
|
|
self.label = QLabel('Sessions')
|
|
self.layout.addWidget(self.label)
|
|
|
|
# List of sessions
|
|
self.listSession = QTableWidget()
|
|
self.listSession.setShowGrid(False)
|
|
self.listSession.setSelectionBehavior(QTableView.SelectRows)
|
|
self.listSession.setRowCount(0)
|
|
self.listSession.setColumnCount(10)
|
|
self.listSession.cellPressed.connect(self.listSessionClicked)
|
|
self.listSession.verticalHeader().setVisible(False)
|
|
header = self.listSession.horizontalHeader()
|
|
for i in range(10):
|
|
header.setSectionResizeMode(i, QHeaderView.Stretch)
|
|
header.setSectionResizeMode(0, QHeaderView.ResizeToContents)
|
|
header.setSectionResizeMode(1, QHeaderView.ResizeToContents)
|
|
header.setSectionResizeMode(2, QHeaderView.ResizeToContents)
|
|
header.setSectionResizeMode(5, QHeaderView.ResizeToContents)
|
|
header.setSectionResizeMode(6, QHeaderView.ResizeToContents)
|
|
header.setSectionResizeMode(7, QHeaderView.ResizeToContents)
|
|
header.setSectionResizeMode(8, QHeaderView.ResizeToContents)
|
|
header.setSectionResizeMode(9, QHeaderView.ResizeToContents)
|
|
self.layout.addWidget(self.listSession)
|
|
|
|
# Thread to get sessions every second
|
|
# https://realpython.com/python-pyqt-qthread/
|
|
self.thread = QThread()
|
|
self.getSessionsWorker = GetSessionsWorker()
|
|
self.getSessionsWorker.moveToThread(self.thread)
|
|
self.thread.started.connect(self.getSessionsWorker.run)
|
|
self.getSessionsWorker.checkin.connect(self.getSessions)
|
|
self.thread.start()
|
|
|
|
self.setLayout(self.layout)
|
|
|
|
def __del__(self):
|
|
self.getSessionsWorker.quit()
|
|
self.thread.quit()
|
|
self.thread.wait()
|
|
|
|
# interact with session list
|
|
def listSessionClicked(self, row, column):
|
|
self.item = str(self.listSession.item(row, 0).data(0))
|
|
menu = QMenu()
|
|
menu.addAction('Interact')
|
|
menu.addAction('Stop')
|
|
menu.addAction('Delete')
|
|
menu.triggered.connect(self.actionClicked)
|
|
menu.exec_(QCursor.pos())
|
|
|
|
# catch Interact and Stop menu click
|
|
# TODO add remove ?
|
|
def actionClicked(self, action):
|
|
if action.text() == "Interact":
|
|
id = self.item
|
|
for sessionStore in self.listSessionObject:
|
|
if sessionStore.id == int(id):
|
|
self.interactWithSession.emit(sessionStore.beaconHash, sessionStore.listenerHash, sessionStore.hostname, sessionStore.username)
|
|
elif action.text() == "Stop":
|
|
id = self.item
|
|
for sessionStore in self.listSessionObject:
|
|
if sessionStore.id == int(id):
|
|
self.stopSession(sessionStore.beaconHash, sessionStore.listenerHash)
|
|
elif action.text() == "Delete":
|
|
id = self.item
|
|
for ix, sessionStore in enumerate(self.listSessionObject):
|
|
if sessionStore.id == int(id):
|
|
self.listSessionObject.pop(ix)
|
|
self.printSessions()
|
|
|
|
def stopSession(self, beaconHash, listenerHash):
|
|
session = TeamServerApi_pb2.Session(
|
|
beaconHash=beaconHash, listenerHash=listenerHash)
|
|
self.grpcClient.stopSession(session)
|
|
self.getSessions()
|
|
|
|
def getSessions(self):
|
|
responses = self.grpcClient.getSessions()
|
|
|
|
sessions = list()
|
|
for response in responses:
|
|
sessions.append(response)
|
|
|
|
# check for idl sessions
|
|
for ix, item in enumerate(self.listSessionObject):
|
|
runing=False
|
|
for session in sessions:
|
|
if session.beaconHash == item.beaconHash:
|
|
runing=True
|
|
# set idl
|
|
if not runing:
|
|
self.listSessionObject[ix].lastProofOfLife="-1"
|
|
|
|
for session in sessions:
|
|
inStore=False
|
|
for sessionStore in self.listSessionObject:
|
|
#maj
|
|
if session.listenerHash == sessionStore.listenerHash and session.beaconHash == sessionStore.beaconHash:
|
|
#if session.beaconHash == sessionStore.beaconHash:
|
|
inStore=True
|
|
sessionStore.lastProofOfLife=session.lastProofOfLife
|
|
sessionStore.listenerHash=session.listenerHash
|
|
if session.hostname:
|
|
sessionStore.hostname=session.hostname
|
|
if session.username:
|
|
sessionStore.username=session.username
|
|
if session.arch:
|
|
sessionStore.arch=session.arch
|
|
if session.privilege:
|
|
sessionStore.privilege=session.privilege
|
|
if session.os:
|
|
sessionStore.os=session.os
|
|
if session.lastProofOfLife:
|
|
sessionStore.lastProofOfLife=session.lastProofOfLife
|
|
if session.killed:
|
|
sessionStore.killed=session.killed
|
|
# add
|
|
if not inStore:
|
|
self.listSessionObject.append(Session(self.idSession,
|
|
session.listenerHash, session.beaconHash,
|
|
session.hostname, session.username, session.arch,
|
|
session.privilege, session.os, session.lastProofOfLife,
|
|
session.killed))
|
|
self.idSession = self.idSession+1
|
|
|
|
self.printSessions()
|
|
|
|
# don't clear the list each time but just when it's necessary
|
|
def printSessions(self):
|
|
self.listSession.setRowCount(len(self.listSessionObject))
|
|
self.listSession.setHorizontalHeaderLabels(["ID", "Beacon ID", "Listener ID", "Host", "User", "Arch", "Priv", "OS", "POL","Killed"])
|
|
for ix, sessionStore in enumerate(self.listSessionObject):
|
|
id = QTableWidgetItem(str(sessionStore.id))
|
|
self.listSession.setItem(ix, 0, id)
|
|
beaconHash = QTableWidgetItem(sessionStore.beaconHash[0:8])
|
|
self.listSession.setItem(ix, 1, beaconHash)
|
|
listenerHash = QTableWidgetItem(sessionStore.listenerHash[0:8])
|
|
self.listSession.setItem(ix, 2, listenerHash)
|
|
hostname = QTableWidgetItem(sessionStore.hostname)
|
|
self.listSession.setItem(ix, 3, hostname)
|
|
username = QTableWidgetItem(sessionStore.username)
|
|
self.listSession.setItem(ix, 4, username)
|
|
arch = QTableWidgetItem(sessionStore.arch)
|
|
self.listSession.setItem(ix, 5, arch)
|
|
privilege = QTableWidgetItem(sessionStore.privilege)
|
|
self.listSession.setItem(ix, 6, privilege)
|
|
os = QTableWidgetItem(sessionStore.os)
|
|
self.listSession.setItem(ix, 7, os)
|
|
pol = QTableWidgetItem(sessionStore.lastProofOfLife.split(".", 1)[0])
|
|
self.listSession.setItem(ix, 8, pol)
|
|
killed = QTableWidgetItem(str(sessionStore.killed))
|
|
self.listSession.setItem(ix, 9, killed)
|
|
|
|
|
|
class GetSessionsWorker(QObject):
|
|
checkin = pyqtSignal()
|
|
|
|
exit=False
|
|
|
|
def run(self):
|
|
while self.exit==False:
|
|
self.checkin.emit()
|
|
time.sleep(1)
|
|
|
|
def quit(self):
|
|
self.exit=True
|
|
|