Files
maxDcb-C2TeamServer/client/SessionPanel.py
T
2024-11-28 08:31:43 -05:00

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