Files
2023-10-01 16:35:14 -03:00

257 lines
6.2 KiB
Go

package server
import (
"Havoc/pkg/logger"
"encoding/json"
"math/rand"
"time"
"fmt"
"strconv"
"Havoc/pkg/agent"
"Havoc/pkg/events"
"Havoc/pkg/packager"
)
func (t *Teamserver) AgentUpdate(agent *agent.Agent) {
err := t.DB.AgentUpdate(agent)
if err != nil {
logger.Error("Could not update agent: " + err.Error())
}
}
func (t *Teamserver) Died(Agent *agent.Agent) {
Agent.Active = false
t.UnlinkFromAll(Agent)
t.EventAgentMark(Agent.NameID, "Dead")
t.AgentUpdate(Agent)
}
func (t *Teamserver) UnlinkFromAll(Agent *agent.Agent) {
// remove all links from agent
for i := range Agent.Pivots.Links {
t.LinkRemove(Agent, Agent.Pivots.Links[i], false)
Agent.Pivots.Links = append(Agent.Pivots.Links[:i], Agent.Pivots.Links[i+1:]...)
}
// remove agent from parent's link
for _, ParentAgent := range t.Agents.Agents {
if ParentAgent.NameID == Agent.NameID {
continue
}
for i := range ParentAgent.Pivots.Links {
if ParentAgent.Pivots.Links[i].NameID == Agent.NameID {
t.LinkRemove(ParentAgent, Agent, false)
ParentAgent.Pivots.Links = append(ParentAgent.Pivots.Links[:i], ParentAgent.Pivots.Links[i+1:]...)
break
}
}
}
}
func (t *Teamserver) ParentOf(Agent *agent.Agent) (int, error) {
var AgentID, _ = strconv.ParseInt(Agent.NameID, 16, 64)
ID, err := t.DB.ParentOf(int(AgentID))
return ID, err
}
func (t *Teamserver) LinksOf(Agent *agent.Agent) []int {
var AgentID, _ = strconv.ParseInt(Agent.NameID, 16, 64)
return t.DB.LinksOf(int(AgentID))
}
func (t *Teamserver) LinkAdd(ParentAgent *agent.Agent, LinkAgent *agent.Agent) error {
var ParentAgentID, _ = strconv.ParseInt(ParentAgent.NameID, 16, 64)
var LinkAgentID, _ = strconv.ParseInt(LinkAgent.NameID, 16, 64)
err := t.DB.LinkAdd(int(ParentAgentID), int(LinkAgentID))
if err != nil {
logger.Error("Could not add link to database: " + err.Error())
}
return nil
}
func (t *Teamserver) LinkRemove(ParentAgent *agent.Agent, LinkAgent *agent.Agent, UpdateLinks bool) {
var ParentAgentID, _ = strconv.ParseInt(ParentAgent.NameID, 16, 64)
var LinkAgentID, _ = strconv.ParseInt(LinkAgent.NameID, 16, 64)
LinkAgent.Active = false
LinkAgent.Reason = "Disconnected"
if UpdateLinks {
for i := range ParentAgent.Pivots.Links {
if ParentAgent.Pivots.Links[i].NameID == LinkAgent.NameID {
ParentAgent.Pivots.Links = append(ParentAgent.Pivots.Links[:i], ParentAgent.Pivots.Links[i+1:]...)
break
}
}
}
err := t.DB.LinkRemove(int(ParentAgentID), int(LinkAgentID))
if err != nil {
logger.Error("Could not remove link to database: " + err.Error())
}
t.AgentUpdate(LinkAgent)
}
func (t *Teamserver) AgentHasDied(Agent *agent.Agent) bool {
var AgentID, _ = strconv.ParseInt(Agent.NameID, 16, 64)
return t.DB.AgentHasDied(int(AgentID))
}
func (t *Teamserver) AgentAdd(Agent *agent.Agent) []*agent.Agent {
if Agent != nil {
if t.WebHooks != nil {
t.WebHooks.NewAgent(Agent.ToMap())
}
}
err := t.DB.AgentAdd(Agent)
if err != nil {
logger.Error("Could not add agent to database: " + err.Error())
}
return t.Agents.AgentsAppend(Agent)
}
func (t *Teamserver) AgentSendNotify(Agent *agent.Agent) {
var pk packager.Package
/* create a new agent package */
pk = t.EventNewDemon(Agent)
/* append the new agent event */
t.EventAppend(pk)
/* send it to every connected client */
t.EventBroadcast("", pk)
}
func (t *Teamserver) AgentCallbackSize(DemonInstance *agent.Agent, i int) {
var (
Message = make(map[string]string)
pk packager.Package
)
Message["Type"] = "Good"
Message["Message"] = fmt.Sprintf("Send Task to Agent [%v bytes]", i)
OutputJson, _ := json.Marshal(Message)
pk = events.Demons.DemonOutput(DemonInstance.NameID, agent.HAVOC_CONSOLE_MESSAGE, string(OutputJson))
t.EventAppend(pk)
t.EventBroadcast("", pk)
}
func (t *Teamserver) AgentInstance(AgentID int) *agent.Agent {
for _, demon := range t.Agents.Agents {
var NameID, _ = strconv.ParseInt(demon.NameID, 16, 64)
if AgentID == int(NameID) {
return demon
}
}
return nil
}
func (t *Teamserver) AgentLastTimeCalled(AgentID string, LastCallback string, Sleep int, Jitter int, KillDate int64, WorkingHours int32) {
var (
Output = map[string]string{
"Last": LastCallback,
"Sleep": fmt.Sprintf("%d", Sleep),
"Jitter": fmt.Sprintf("%d", Jitter),
"KillDate": fmt.Sprintf("%d", KillDate),
"WorkingHours": fmt.Sprintf("%d", WorkingHours),
}
out, _ = json.Marshal(Output)
pk = events.Demons.DemonOutput(AgentID, agent.COMMAND_NOJOB, string(out))
)
t.EventBroadcast("", pk)
}
func (t *Teamserver) AgentExist(AgentID int) bool {
for _, demon := range t.Agents.Agents {
var NameID, err = strconv.ParseInt(demon.NameID, 16, 64)
if err != nil {
logger.Debug("Failed to convert demon.NameID to int: " + err.Error())
return false
}
if AgentID == int(NameID) {
return true
}
}
return false
}
func (t *Teamserver) AgentConsole(AgentID string, CommandID int, Output map[string]string) {
var (
out, _ = json.Marshal(Output)
pk = events.Demons.DemonOutput(AgentID, CommandID, string(out))
)
t.EventAppend(pk)
t.EventBroadcast("", pk)
}
func (t *Teamserver) PythonModuleCallback(ClientID string, AgentID string, CommandID int, Output map[string]string) {
var (
out, _ = json.Marshal(Output)
pk = events.Demons.DemonOutput(AgentID, CommandID, string(out))
)
err := t.SendEvent(ClientID, pk)
if err != nil {
logger.Error("SendEvent error: ", err)
}
}
func (t *Teamserver) AgentCallback(DemonID string, Time string) {
var (
Output = map[string]string{
"Output": Time,
}
out, _ = json.Marshal(Output)
pk = events.Demons.DemonOutput(DemonID, agent.COMMAND_NOJOB, string(out))
)
t.EventBroadcast("", pk)
}
func (t *Teamserver) SendLogs() bool {
return t.Flags.Server.SendLogs
}
func (t *Teamserver) GetDotNetPipeTemplate() string {
PipeTemplate := t.Profile.Config.Demon.DotNetNamePipe
// https://gist.github.com/realoriginal/d9178c9b071707fec2d6de89a63e4709
PipeTemplates := []string{
"Winsock2\\\\CatalogChangeListener-$#-0",
"mojo.{pid}.{tid}.####################",
"crashpad_{pid}_@@@@@@@@@@@@@@@@",
"chrome.sync.{pid}.{tid}.########",
}
if PipeTemplate == "" {
rand.Seed(time.Now().UnixNano())
index := rand.Intn(len(PipeTemplates))
PipeTemplate = PipeTemplates[index]
}
return PipeTemplate
}