initial commit

This commit is contained in:
its-a-feature
2025-01-29 16:08:16 -06:00
commit 1b7ea4a3b2
36 changed files with 5157 additions and 0 deletions
+31
View File
@@ -0,0 +1,31 @@
Copyright (c) 2025, its-a-feature
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of [project] nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
## 3rd Party Licenses
+23
View File
@@ -0,0 +1,23 @@
FROM golang:1.23 AS builder
ARG GITHUB_TOKEN
WORKDIR /Mythic/
COPY [".", "."]
RUN make build
RUN make run_download
FROM alpine
RUN apk add make
COPY --from=builder /main /main
COPY --from=builder /collections /collections
WORKDIR /Mythic/
COPY [".", "."]
CMD make run
+23
View File
@@ -0,0 +1,23 @@
FROM golang:1.23 AS builder
ARG GITHUB_TOKEN
WORKDIR /Mythic/
COPY [".", "."]
RUN make build
RUN make run_download
FROM alpine
RUN apk add make
COPY --from=builder /main /main
COPY --from=builder /collections /collections
WORKDIR /Mythic/
COPY [".", "."]
CMD make run
+46
View File
@@ -0,0 +1,46 @@
BINARY_NAME?=main
DEBUG_LEVEL?="debug"
RABBITMQ_HOST?="127.0.0.1"
RABBITMQ_PASSWORD?="PqR9XJ957sfHqcxj6FsBMj4p"
MYTHIC_SERVER_HOST?="127.0.0.1"
MYTHIC_SERVER_GRPC_PORT?="17444"
WEBHOOK_DEFAULT_URL?=
WEBHOOK_DEFAULT_CHANNEL?=
WEBHOOK_DEFAULT_FEEDBACK_CHANNEL?=
WEBHOOK_DEFAULT_CALLBACK_CHANNEL?=
WEBHOOK_DEFAULT_STARTUP_CHANNEL?=
GITHUB_TOKEN?=
build:
go mod download
go mod tidy
go build -o ${BINARY_NAME} .
cp ${BINARY_NAME} /
run_download:
go mod download
go mod tidy
go build -o ${BINARY_NAME} .
GITHUB_TOKEN=${GITHUB_TOKEN} ./${BINARY_NAME} download
cp -R ./forge/collections /collections
run:
cp /${BINARY_NAME} .
cp -R /collections ./forge
./${BINARY_NAME}
run_custom:
go mod download
go mod tidy
go build -o ${BINARY_NAME} .
DEBUG_LEVEL=${DEBUG_LEVEL} \
RABBITMQ_HOST=${RABBITMQ_HOST} \
RABBITMQ_PASSWORD=${RABBITMQ_PASSWORD} \
MYTHIC_SERVER_HOST=${MYTHIC_SERVER_HOST} \
MYTHIC_SERVER_GRPC_PORT=${MYTHIC_SERVER_GRPC_PORT} \
WEBHOOK_DEFAULT_URL=${WEBHOOK_DEFAULT_URL} \
WEBHOOK_DEFAULT_CHANNEL=${WEBHOOK_DEFAULT_CHANNEL} \
WEBHOOK_DEFAULT_FEEDBACK_CHANNEL=${WEBHOOK_DEFAULT_FEEDBACK_CHANNEL} \
WEBHOOK_DEFAULT_CALLBACK_CHANNEL=${WEBHOOK_DEFAULT_CALLBACK_CHANNEL} \
WEBHOOK_DEFAULT_STARTUP_CHANNEL=${WEBHOOK_DEFAULT_STARTUP_CHANNEL} \
./${BINARY_NAME}
@@ -0,0 +1,2 @@
[
]
@@ -0,0 +1,563 @@
[
{
"name": "ADCSPwn",
"command_name": "ADCSPwn",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# tool to escalate privileges in an active directory network by coercing authenticate from machine accounts and relaying to the certificate service. @bats3c"
},
{
"name": "ADCollector",
"command_name": "ADCollector",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# tool to quickly extract valuable information from the Active Directory environment @dev-2null"
},
{
"name": "ADSearch",
"command_name": "ADSearch",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# tool to help query AD via the LDAP protocol @tomcarver16 (Only NET 4.7)"
},
{
"name": "ADFSDump",
"command_name": "ADFSDump",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "A C# tool to dump all sorts of goodies from AD FS. @FireEye"
},
{
"name": "AtYourService",
"command_name": "AtYourService",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# .NET Assembly for Service Enumeration @mitchmoser"
},
{
"name": "BetterSafetyKatz",
"command_name": "BetterSafetyKatz",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "Fork of SafetyKatz dynamically fetches the latest Mimikatz, runtime patching signatures and PE loads Mimikatz into memory. @Flangvik"
},
{
"name": "Certify",
"command_name": "Certify",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# tool to enumerate and abuse misconfigurations in Active Directory Certificate Services (AD CS). @harmj0y @tifkin_"
},
{
"name": "DeployPrinterNightmare",
"command_name": "DeployPrinterNightmare",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# tool for installing a shared network printer abusing the PrinterNightmare bug to allow other network machines easy privesc @Flangvik"
},
{
"name": "EDD",
"command_name": "EDD",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "Enumerate Domain Data is designed to be similar to PowerView but in .NET @FortyNorthSecurity"
},
{
"name": "ForgeCert",
"command_name": "ForgeCert",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "uses a stolen CA certificate + private key to forge certificates for arbitrary users. @tifkin_"
},
{
"name": "Grouper2",
"command_name": "Grouper2",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# tool to help find security-related misconfigurations in Active Directory Group Policy. @mikeloss"
},
{
"name": "Group3r",
"command_name": "Group3r",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# tool to find vulnerabilities in AD Group Policy, but do it better than Grouper2 did. @mikeloss"
},
{
"name": "KrbRelay",
"command_name": "KrbRelay",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# Framework for Kerberos relaying @cube0x0"
},
{
"name": "KrbRelayUp",
"command_name": "KrbRelayUp",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "universal no-fix local privilege escalation in windows domain environments where LDAP signing is not enforced @dec0ne"
},
{
"name": "Inveigh",
"command_name": "Inveigh",
"repo_url": "https://github.com/Flangvik/SharpCollection"
},
{
"name": "LockLess",
"command_name": "LockLess",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "Allows for the copying of locked files. @GhostPack"
},
{
"name": "Moriarty",
"command_name": "Moriarty",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "Enumerate missing KBs, detect various vulnerabilities, and suggest potential exploits for Privilege Escalation in Windows"
},
{
"name": "PassTheCert",
"command_name": "PassTheCert",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "Proof-of-Concept tool to authenticate to an LDAP/S server with a certificate through Schannel. @AlmondOffSec"
},
{
"name": "PurpleSharp",
"command_name": "PurpleSharp",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# adversary simulation tool that executes adversary techniques with the purpose of generating attack telemetry in monitored Windows environments. @mvelazc0"
},
{
"name": "Rubeus",
"command_name": "Rubeus",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# toolset for raw Kerberos interaction and abuses. @GhostPack"
},
{
"name": "_RunAsCs",
"command_name": "RunAs",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "Csharp and open version of windows builtin runas.exe. @splinter_code"
},
{
"name": "SafetyKatz",
"command_name": "SafetyKatz",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "Combination of slightly modified version of @gentilkiwi's Mimikatz project and @subTee's .NET PE Loader. @GhostPack"
},
{
"name": "SauronEye",
"command_name": "SauronEye",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# search tool find specific files containing specific keywords (.doc, .docx, .xls, .xlsx). @_vivami"
},
{
"name": "SearchOutlook",
"command_name": "SearchOutlook",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# tool to search through a running instance of Outlook for keywords @RedLectroid"
},
{
"name": "Seatbelt",
"command_name": "Seatbelt",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "Performs a number of security oriented host-survey \"safety checks\". @GhostPack"
},
{
"name": "scout",
"command_name": "Scout",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": " A .NET assembly for performing recon against hosts on a network . @jaredhaight"
},
{
"name": "ShadowSpray",
"command_name": "ShadowSpray",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "A tool to spray Shadow Credentials across an entire domain in hopes of abusing long forgotten GenericWrite/GenericAll DACLs over other objects in the domain."
},
{
"name": "SharPersist",
"command_name": "SharPersist",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# persistence toolkit."
},
{
"name": "Sharp-SMBExec",
"command_name": "Sharp-SMBExec",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "A native C# conversion of Kevin Robertsons Invoke-SMBExec powershell script @checkymander"
},
{
"name": "SharpAllowedToAct",
"command_name": "SharpAllowedToAct",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# implementation of a computer object takeover through Resource-Based Constrained Delegation (msDS-AllowedToActOnBehalfOfOtherIdentity) @pkb1s"
},
{
"name": "SharpAppLocker",
"command_name": "SharpAppLocker",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# port of the Get-AppLockerPolicy PS cmdlet with extended features @Flangvik"
},
{
"name": "SharpBlock",
"command_name": "SharpBlock",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "A method of bypassing EDR's active projection DLL's by preventing entry point exection. @CCob"
},
{
"name": "SharpBypassUAC",
"command_name": "SharpBypassUAC",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# tool for UAC bypasses @rodzianko"
},
{
"name": "SharpCOM",
"command_name": "SharpCOM",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# port of Invoke-DCOM @424f424f"
},
{
"name": "SharpChisel",
"command_name": "SharpChisel",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# Chisel Wrapper. @shantanu561993"
},
{
"name": "SharpChrome",
"command_name": "SharpChrome",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "Chrome-specific implementation of SharpDPAPI capable of cookies and logins decryption/triage. @GhostPack"
},
{
"name": "SharpChromium",
"command_name": "SharpChromium",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# Project to retrieve Chromium data, such as cookies, history and saved logins. @djhohnstein"
},
{
"name": "SharpCloud",
"command_name": "SharpCloud",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "Simple C# for checking for the existence of credential files related to AWS, Microsoft Azure, and Google Compute. @chrismaddalena"
},
{
"name": "SharpCookieMonster",
"command_name": "SharpCookieMonster",
"repo_url": "https://github.com/Flangvik/SharpCollection"
},
{
"name": "SharpCrashEventLog",
"command_name": "SharpCrashEventLog",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# port of LogServiceCrash @slyd0g @limbenjamin"
},
{
"name": "SharpDPAPI",
"command_name": "SharpDPAPI",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# port of some Mimikatz DPAPI functionality. @GhostPack"
},
{
"name": "SharpDir",
"command_name": "SharpDir",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# tool to search both local and remote file systems for files. @jnqpblc"
},
{
"name": "SharpDoor",
"command_name": "SharpDoor",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# tool to allow multiple RDP (Remote Desktop) sessions by patching termsrv.dll file. @infosecn1nja"
},
{
"name": "SharpDump",
"command_name": "SharpDump",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "SharpDump is a C# port of PowerSploit's Out-Minidump.ps1 functionality. @GhostPack"
},
{
"name": "SharpEDRChecker",
"command_name": "SharpEDRChecker",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# tool to check for the presence of known defensive products such as AV's, EDR's and logging tools @PwnDexter"
},
{
"name": "SharpExec",
"command_name": "SharpExec",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "SharpExec is an offensive security C# tool designed to aid with lateral movement. @anthemtotheego"
},
{
"name": "SharpFiles",
"command_name": "SharpFiles",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# tool to search for files based on SharpShares output. @fullmetalcache"
},
{
"name": "SharpFinder",
"command_name": "SharpFinder",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "Searches for files matching specific criteria on readable shares within the domain"
},
{
"name": "SharpGPOAbuse",
"command_name": "SharpGPOAbuse",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "SharpGPOAbuse is a .NET application written in C# that can be used to take advantage of a user's edit rights on a Group Policy Object (GPO). @FSecureLABS"
},
{
"name": "SharpHandler",
"command_name": "SharpHandler",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# tool for stealing/duping handles to LSASS @Jean_Maes_1994"
},
{
"name": "SharpHose",
"command_name": "SharpHose",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "Asynchronous Password Spraying Tool in C# for Windows Environments . @ustayready"
},
{
"name": "SharpHound",
"command_name": "SharpHound",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# 2022 version of the BloodHound 4.x Ingestor. @BloodHoundAD"
},
{
"name": "SharpKatz",
"command_name": "SharpKatz",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "PURE C# port of significant MimiKatz functionality such as logonpasswords, dcsync, etc. @b4rtik"
},
{
"name": "SharpKiller",
"command_name": "SharpKiller",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "Lifetime AMSI bypass by @ZeroMemoryEx ported to .NET Framework 4.8 @S1lky_1337"
},
{
"name": "SharpLAPS",
"command_name": "SharpLAPS",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "A C# tool to retrieve LAPS passwords from LDAP @pentest_swissky"
},
{
"name": "SharpMapExec",
"command_name": "SharpMapExec",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# version of @byt3bl33d3r's tool CrackMapExec @cube0x0"
},
{
"name": "SharpMiniDump",
"command_name": "SharpMiniDump",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# tool to Create a minidump of the LSASS process from memory @b4rtik"
},
{
"name": "SharpNoPSExec",
"command_name": "SharpNoPSExec",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# tool allowing file less command execution for lateral movement. @juliourena"
},
{
"name": "SharpMove",
"command_name": "SharpMove",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# tool for performing lateral movement techniques @0xthirteen"
},
{
"name": "SharpPrinter",
"command_name": "SharpPrinter",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# tool for discovering Printers on an network @424f424f"
},
{
"name": "SharpRDP",
"command_name": "SharpRDP",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# Remote Desktop Protocol Console Application for Authenticated Command Execution @0xthirteen"
},
{
"name": "SharpNamedPipePTH",
"command_name": "SharpNamedPipePTH",
"repo_url": "https://github.com/Flangvik/SharpCollection"
},
{
"name": "SharpReg",
"command_name": "SharpReg",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# tool to interact with the Remote Registry service api. @jnqpblc"
},
{
"name": "SharpSQLPwn",
"command_name": "SharpSQLPwn",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# tool to identify and exploit weaknesses within MSSQL instances in Active Directory environments. @lefayjey"
},
{
"name": "SharpSearch",
"command_name": "SharpSearch",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# Project to quickly filter through a file share for targeted files for desired information. @djhohnstein"
},
{
"name": "SharpSecDump",
"command_name": "SharpSecDump",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# port of the remote SAM + LSA Secrets dumping functionality of impacket's secretsdump.py @G0ldenGunSec"
},
{
"name": "SharpSCCM",
"command_name": "SharpSCCM",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# utility for interacting with SCCM @_Mayyhem"
},
{
"name": "SharpShares",
"command_name": "SharpShares",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "Enumerate all network shares in the current domain. @djhohnstein"
},
{
"name": "SharpSphere",
"command_name": "SharpSphere",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# SharpSphere has the ability to interact with the guest operating systems of virtual machines managed by vCenter. @jkcoote & @grzryc"
},
{
"name": "SharpSniper",
"command_name": "SharpSniper",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "SharpSniper is a simple tool to find the IP address of these users so that you can target their box. @hunniccyber"
},
{
"name": "SharpSpray",
"command_name": "SharpSpray",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# tool to perform a password spraying attack against all users of a domain using LDAP. @jnqpblc"
},
{
"name": "SharpStay",
"command_name": "SharpStay",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": ".NET project for installing Persistence. @0xthirteen"
},
{
"name": "SharpSvc",
"command_name": "SharpSvc",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# tool to interact with the SC Manager API. @jnqpblc (Only NET 4.7)"
},
{
"name": "SharpTask",
"command_name": "SharpTask",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# tool to interact with the Task Scheduler service api. @jnqpblc"
},
{
"name": "SharpTokenFinder",
"command_name": "SharpTokenFinder",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# implementation of TokenFinder. Steal M365 access tokens from Office Desktop apps"
},
{
"name": "SharpUp",
"command_name": "SharpUp",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# port of various PowerUp functionality. @GhostPack"
},
{
"name": "SharpView",
"command_name": "SharpView",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# implementation of harmj0y's PowerView. @tevora-threat"
},
{
"name": "SharpWMI",
"command_name": "SharpWMI",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# implementation of various WMI functionality. @GhostPack"
},
{
"name": "SharpWebServer",
"command_name": "SharpWebServer",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "A Red Team oriented simple HTTP & WebDAV server written in C# with functionality to capture Net-NTLM hashes. @mariuszbit"
},
{
"name": "SharpWifiGrabber",
"command_name": "SharpWifiGrabber",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "Sharp Wifi Password Grabber retrieves in clear-text the Wi-Fi Passwords from all WLAN Profiles saved on a workstation. @r3n_hat"
},
{
"name": "SharpZeroLogon",
"command_name": "SharpZeroLogon",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# port of CVE-2020-1472 , a.k.a. Zerologon. @buffaloverflow"
},
{
"name": "Shhmon",
"command_name": "Shhmon",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "Neutering Sysmon via driver unload. @Shhmon"
},
{
"name": "Snaffler",
"command_name": "Snaffler",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# tool for pentesters to help find delicious candy. @l0ss and @Sh3r4"
},
{
"name": "SqlClient",
"command_name": "SqlClient",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# .NET mssql client for accessing database data through beacon. @FortyNorthSecurity"
},
{
"name": "Standin",
"command_name": "Standin",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# based small AD post-compromise toolkit. @FuzzySec"
},
{
"name": "StickyNotesExtract",
"command_name": "StickyNotesExtract",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# tool that extracts data from the Windows Sticky Notes database. @V1V1"
},
{
"name": "SweetPotato",
"command_name": "SweetPotato",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "Local Service to SYSTEM privilege escalation from Windows 7 to Windows 10 / Server 2019 . @CCob"
},
{
"name": "ThunderFox",
"command_name": "ThunderFox",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# Retrieves data (contacts, emails, history, cookies and credentials) from Thunderbird and Firefox. @V1V1"
},
{
"name": "TruffleSnout",
"command_name": "TruffleSnout",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# based iterative AD discovery toolkit for offensive operators. @dsnezhkov"
},
{
"name": "TokenStomp",
"command_name": "TokenStomp",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# implementation of the token privilege removal flaw discovered by @GabrielLandau / Elastic. @Mrtn9"
},
{
"name": "WMIReg",
"command_name": "WMIReg",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "C# PoC to interact with local/remote registry hives through WMI. @airzero24"
},
{
"name": "Watson",
"command_name": "Watson",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "Enumerate missing KBs and suggest exploits for useful Privilege Escalation vulnerabilities . @rasta-mouse"
},
{
"name": "winPEAS",
"command_name": "winPEAS",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "PEASS - Privilege Escalation Awesome Scripts (winPEAS). @carlospolop"
},
{
"name": "Whisker",
"command_name": "Whisker",
"repo_url": "https://github.com/Flangvik/SharpCollection",
"description": "Whisker is a C# tool for taking over Active Directory user and computer accounts by manipulating their msDS-KeyCredentialLink attribute. @elad_shamir"
}
]
@@ -0,0 +1,2 @@
[
]
@@ -0,0 +1,914 @@
[
{
"name": "Nano Dump",
"command_name": "nanodump",
"repo_url": "https://github.com/sliverarmory/nanodump",
"public_key": "RWRftt+kvCADbGXc9qe8q1OAkGy5C8lWVrzUVoT3DCH0hJ6uCuzmc0fk"
},
{
"name": "CredMan",
"command_name": "credman",
"repo_url": "https://github.com/sliverarmory/CredManBOF",
"public_key": "RWTGTuUsXkcGbS26sLXUP4TSF/2DdWVdWC1+qb9P9bX+zO5N+A4i5us4"
},
{
"name": "Inject ETW Bypass",
"command_name": "inject-etw-bypass",
"repo_url": "https://github.com/sliverarmory/InjectEtwBypass",
"public_key": "RWSF8tXGXrAzwUcjXE5eFFMj8bdGftD/rY+eWc/eQKUTeS99jBCThRgr"
},
{
"name": "Inject AMSI Bypass",
"command_name": "inject-amsi-bypass",
"repo_url": "https://github.com/sliverarmory/InjectAmsiBypass",
"public_key": "RWTPC+E0Btp82ARPNT5GjCJW/Xy+8N+ey4eUTL+D36dctLz99tIdeUQj"
},
{
"name": "Find Module",
"command_name": "find-module",
"repo_url": "https://github.com/sliverarmory/FindObjects-BOF",
"public_key": "RWTKjKbbO8eamcTsYl0lEnBv8oobkfWG/TYSIDPRx/9JFxLRnbEtbHi1"
},
{
"name": "Find Proc Handle",
"command_name": "find-proc-handle",
"repo_url": "https://github.com/sliverarmory/FindObjects-BOF",
"public_key": "RWTKjKbbO8eamcTsYl0lEnBv8oobkfWG/TYSIDPRx/9JFxLRnbEtbHi1"
},
{
"name": "BOF Roast",
"command_name": "bof-roast",
"repo_url": "https://github.com/sliverarmory/BofRoast",
"public_key": "RWRgRJAS+Nae5U5ThhqgFdedx+Fpfm+eYCXkx9gHCzd0em1djrupBaEg"
},
{
"name": "ADCS Enum",
"command_name": "sa-adcs-enum",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "ADCS Enum COM",
"command_name": "sa-adcs-enum-com",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "ADCS Enum COM2",
"command_name": "sa-adcs-enum-com2",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Adv Audit Policies",
"command_name": "sa-adv-audit-policies",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "ARP",
"command_name": "sa-arp",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Cacls",
"command_name": "sa-cacls",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Driver Sigs",
"command_name": "sa-driversigs",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Enum Filter Driver",
"command_name": "sa-enum-filter-driver",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Enum Local Sessions",
"command_name": "sa-enum-local-sessions",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Find Loaded Module",
"command_name": "sa-find-loaded-module",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Get Password Policy",
"command_name": "sa-get-password-policy",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Get NetSession",
"command_name": "sa-get-netsession",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "IP Config",
"command_name": "sa-ipconfig",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "LDAP Search",
"command_name": "sa-ldapsearch",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "List DNS",
"command_name": "sa-listdns",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "List Modules",
"command_name": "sa-listmods",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Net Group",
"command_name": "sa-netgroup",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Net Local Group",
"command_name": "sa-netlocalgroup",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Net Shares",
"command_name": "sa-netshares",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Net Stat",
"command_name": "sa-netstat",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Net View",
"command_name": "sa-netview",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Nslookup",
"command_name": "sa-nslookup",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Reg Query",
"command_name": "sa-reg-query",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Routeprint",
"command_name": "sa-routeprint",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Sc Enum",
"command_name": "sa-sc-enum",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Sc Qc",
"command_name": "sa-sc-qc",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Sc Qdescription",
"command_name": "sa-sc-qdescription",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Sc Qfailure",
"command_name": "sa-sc-qfailure",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Sc Qtriggerinfo",
"command_name": "sa-sc-qtriggerinfo",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Sc Query",
"command_name": "sa-sc-query",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "schtasksenum",
"command_name": "sa-schtasksenum",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "schtasksquery",
"command_name": "sa-schtasksquery",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Tasklist",
"command_name": "sa-tasklist",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Uptime",
"command_name": "sa-uptime",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Vssenum",
"command_name": "sa-vssenum",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Whoami",
"command_name": "sa-whoami",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Windowlist",
"command_name": "sa-windowlist",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "Wmi Query",
"command_name": "sa-wmi-query",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "sa-env",
"command_name": "sa-env",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "sa-get-netsession2",
"command_name": "sa-get-netsession2",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "sa-list_firewall_rules",
"command_name": "sa-list_firewall_rules",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "sa-locale",
"command_name": "sa-locale",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "sa-netlocalgroup2",
"command_name": "sa-netlocalgroup2",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "sa-netloggedon",
"command_name": "sa-netloggedon",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "sa-netloggedon2",
"command_name": "sa-netloggedon2",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "sa-nettime",
"command_name": "sa-nettime",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "sa-netuptime",
"command_name": "sa-netuptime",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "sa-ldapsearch",
"command_name": "sa-ldapsearch",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "sa-notepad",
"command_name": "sa-notepad",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "sa-probe",
"command_name": "sa-probe",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "sa-dir",
"command_name": "sa-dir",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "sa-netuse",
"command_name": "sa-netuse",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "sa-netuser",
"command_name": "sa-netuser",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "sa-netuserenum",
"command_name": "sa-netuserenum",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "sa-regsession",
"command_name": "sa-regsession",
"repo_url": "https://github.com/sliverarmory/CS-Situational-Awareness-BOF",
"public_key": "RWSN1vDbbpNFEi3pKpeoMPIAHIvlOM502TK4zA8zTP5Jn0//+SXJboyQ"
},
{
"name": "ChromiumKeyDump",
"command_name": "chromiumkeydump",
"repo_url": "https://github.com/sliverarmory/bof-collection",
"public_key": "RWSN/EmkY2pASCHFwyP7aS0fO7sb6cq7KP3NNHWRq/bzKF0jZABv8BvA"
},
{
"name": "HandleKatz_BOF",
"command_name": "handlekatz",
"repo_url": "https://github.com/sliverarmory/HandleKatz_BOF",
"public_key": "RWRf3fkrlfYhjX/yAw0bsDDX6KQUOfiqmfPMqxJ0o0EfMVqSrQJcw8QQ"
},
{
"name": "LdapSignCheck",
"command_name": "ldapsigncheck",
"repo_url": "https://github.com/sliverarmory/LdapSignCheck",
"public_key": "RWQYjHn4JYThXQE7N13FstjBzDERt/Hhd72hV/hFuPG4RAZZteOttf1o"
},
{
"name": "Unhook BOF",
"command_name": "unhook-bof",
"repo_url": "https://github.com/sliverarmory/unhook-bof",
"public_key": "RWTfJUbkhmANsG740AhAuvsBY1hGaiMQYPq3DxZcT2zYQZ1sMbRnDsP+"
},
{
"name": "hollow",
"command_name": "hollow",
"repo_url": "https://github.com/sliverarmory/hollow",
"public_key": "RWQPThFN80cr30q2UqF99+YJFZBOH1DoWi9PewURBIp1KD/A37IT8S7W"
},
{
"name": "secinject",
"command_name": "secinject",
"repo_url": "https://github.com/sliverarmory/secinject",
"public_key": "RWTuSv5qvs1adchtXS0stvDeORK3wXVo3dAInfcAxNdsJ6ix2pPB0hMD"
},
{
"name": "Delegation BOF",
"command_name": "delegationbof",
"repo_url": "https://github.com/sliverarmory/DelegationBOF",
"public_key": "RWSzonsCJJ38uhlR4jbMa6B7LhHZ315JkOG0Jsw5V94NM5iv6m/qTQCm"
},
{
"name": "C2-Tool-Collection Askcreds BOF",
"command_name": "c2tc-askcreds",
"repo_url": "https://github.com/sliverarmory/C2-Tool-Collection",
"public_key": "RWRk3J0Rkgy1659ur/iwOKJX5MvUXzl5gXlPyN0uH2RDwMYI/09RT/wj"
},
{
"name": "C2-Tool-Collection Kerberoast BOF",
"command_name": "c2tc-kerberoast",
"repo_url": "https://github.com/sliverarmory/C2-Tool-Collection",
"public_key": "RWRk3J0Rkgy1659ur/iwOKJX5MvUXzl5gXlPyN0uH2RDwMYI/09RT/wj"
},
{
"name": "C2-Tool-Collection Psw BOF",
"command_name": "c2tc-psw",
"repo_url": "https://github.com/sliverarmory/C2-Tool-Collection",
"public_key": "RWRk3J0Rkgy1659ur/iwOKJX5MvUXzl5gXlPyN0uH2RDwMYI/09RT/wj"
},
{
"name": "C2-Tool-Collection Smbinfo BOF",
"command_name": "c2tc-smbinfo",
"repo_url": "https://github.com/sliverarmory/C2-Tool-Collection",
"public_key": "RWRk3J0Rkgy1659ur/iwOKJX5MvUXzl5gXlPyN0uH2RDwMYI/09RT/wj"
},
{
"name": "C2-Tool-Collection Winver BOF",
"command_name": "c2tc-winver",
"repo_url": "https://github.com/sliverarmory/C2-Tool-Collection",
"public_key": "RWRk3J0Rkgy1659ur/iwOKJX5MvUXzl5gXlPyN0uH2RDwMYI/09RT/wj"
},
{
"name": "C2-Tool-Collection AddMachineAccount BOF",
"command_name": "c2tc-addmachineaccount",
"repo_url": "https://github.com/sliverarmory/C2-Tool-Collection",
"public_key": "RWRk3J0Rkgy1659ur/iwOKJX5MvUXzl5gXlPyN0uH2RDwMYI/09RT/wj"
},
{
"name": "C2-Tool-Collection Lapsdump BOF",
"command_name": "c2tc-lapsdump",
"repo_url": "https://github.com/sliverarmory/C2-Tool-Collection",
"public_key": "RWRk3J0Rkgy1659ur/iwOKJX5MvUXzl5gXlPyN0uH2RDwMYI/09RT/wj"
},
{
"name": "C2-Tool-Collection PetitPotam BOF",
"command_name": "c2tc-petitpotam",
"repo_url": "https://github.com/sliverarmory/C2-Tool-Collection",
"public_key": "RWRk3J0Rkgy1659ur/iwOKJX5MvUXzl5gXlPyN0uH2RDwMYI/09RT/wj"
},
{
"name": "C2-Tool-Collection Domaininfo BOF",
"command_name": "c2tc-domaininfo",
"repo_url": "https://github.com/sliverarmory/C2-Tool-Collection",
"public_key": "RWRk3J0Rkgy1659ur/iwOKJX5MvUXzl5gXlPyN0uH2RDwMYI/09RT/wj"
},
{
"name": "C2-Tool-Collection KerbHash BOF",
"command_name": "c2tc-kerbhash",
"repo_url": "https://github.com/sliverarmory/C2-Tool-Collection",
"public_key": "RWRk3J0Rkgy1659ur/iwOKJX5MvUXzl5gXlPyN0uH2RDwMYI/09RT/wj"
},
{
"name": "C2-Tool-Collection Psc BOF",
"command_name": "c2tc-psc",
"repo_url": "https://github.com/sliverarmory/C2-Tool-Collection",
"public_key": "RWRk3J0Rkgy1659ur/iwOKJX5MvUXzl5gXlPyN0uH2RDwMYI/09RT/wj"
},
{
"name": "C2-Tool-Collection Psk BOF",
"command_name": "c2tc-psk",
"repo_url": "https://github.com/sliverarmory/C2-Tool-Collection",
"public_key": "RWRk3J0Rkgy1659ur/iwOKJX5MvUXzl5gXlPyN0uH2RDwMYI/09RT/wj"
},
{
"name": "C2-Tool-Collection Psm BOF",
"command_name": "c2tc-psm",
"repo_url": "https://github.com/sliverarmory/C2-Tool-Collection",
"public_key": "RWRk3J0Rkgy1659ur/iwOKJX5MvUXzl5gXlPyN0uH2RDwMYI/09RT/wj"
},
{
"name": "C2-Tool-Collection Psx BOF",
"command_name": "c2tc-psx",
"repo_url": "https://github.com/sliverarmory/C2-Tool-Collection",
"public_key": "RWRk3J0Rkgy1659ur/iwOKJX5MvUXzl5gXlPyN0uH2RDwMYI/09RT/wj"
},
{
"name": "C2-Tool-Collection SprayAD BOF",
"command_name": "c2tc-spray-ad",
"repo_url": "https://github.com/sliverarmory/C2-Tool-Collection",
"public_key": "RWRk3J0Rkgy1659ur/iwOKJX5MvUXzl5gXlPyN0uH2RDwMYI/09RT/wj"
},
{
"name": "C2-Tool-Collection StartWebClient BOF",
"command_name": "c2tc-startwebclient",
"repo_url": "https://github.com/sliverarmory/C2-Tool-Collection",
"public_key": "RWRk3J0Rkgy1659ur/iwOKJX5MvUXzl5gXlPyN0uH2RDwMYI/09RT/wj"
},
{
"name": "C2-Tool-Collection WdToggle BOF",
"command_name": "c2tc-wdtoggle",
"repo_url": "https://github.com/sliverarmory/C2-Tool-Collection",
"public_key": "RWRk3J0Rkgy1659ur/iwOKJX5MvUXzl5gXlPyN0uH2RDwMYI/09RT/wj"
},
{
"name": "C2-Tool-Collection Klist BOF",
"command_name": "c2tc-klist",
"repo_url": "https://github.com/sliverarmory/C2-Tool-Collection",
"public_key": "RWRk3J0Rkgy1659ur/iwOKJX5MvUXzl5gXlPyN0uH2RDwMYI/09RT/wj"
},
{
"name": "tgtdelegation",
"command_name": "tgtdelegation",
"repo_url": "https://github.com/sliverarmory/tgtdelegation",
"public_key": "RWRkoeERRaeV81FHsxqwHvz9AFJ/GrX7Km1EPoEtXmCdOYUyELtdpVIE"
},
{
"name": "scshell",
"command_name": "scshell",
"repo_url": "https://github.com/sliverarmory/SCShell",
"public_key": "RWQQ/PVOzVMSOYt2bASGJyuLXqpPJQ4VhL8ZGcYn9tBx6mu3/L9osdEs"
},
{
"name": "bof-servicemove",
"command_name": "bof-servicemove",
"repo_url": "https://github.com/sliverarmory/ServiceMove-BOF",
"public_key": "RWRkGH1ddtfCXPyrJi1iCVQdS7kw6+QRekp1zKu7Su/KMzEDj0/DzeTE"
},
{
"name": "Syscalls Shellcode Inject",
"command_name": "syscalls_shinject",
"repo_url": "https://github.com/sliverarmory/BOFs",
"public_key": "RWS3pUfl/3Kb6A3F69YmQe3SmhSU1s5+wt3Z3tgX1IiDHpIMqKjY8/Qu"
},
{
"name": "InlineExecute-Assembly",
"command_name": "inline-execute-assembly",
"repo_url": "https://github.com/sliverarmory/InlineExecute-Assembly",
"public_key": "RWRtW3fCRENY2BQ664A0Ko76/Jlh6ZLZvA3bbt20ky1TuLWlh41QQCF1"
},
{
"name": "remote-adcs-request",
"command_name": "remote-adcs-request",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-chrome-key",
"command_name": "remote-chrome-key",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-enable-user",
"command_name": "remote-enable-user",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-process-destroy",
"command_name": "remote-process-destroy",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-process-list-handles",
"command_name": "remote-process-list-handles",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-reg-delete",
"command_name": "remote-reg-delete",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-reg-save",
"command_name": "remote-reg-save",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-schtasks-delete",
"command_name": "remote-schtasks-delete",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-schtasks-stop",
"command_name": "remote-schtasks-stop",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-sc-config",
"command_name": "remote-sc-config",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-sc-create",
"command_name": "remote-sc-create",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-sc-delete",
"command_name": "remote-sc-delete",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-sc-description",
"command_name": "remote-sc-description",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-sc-start",
"command_name": "remote-sc-start",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-sc-stop",
"command_name": "remote-sc-stop",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-setuserpass",
"command_name": "remote-setuserpass",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-adduser",
"command_name": "remote-adduser",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-addusertogroup",
"command_name": "remote-addusertogroup",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-lastpass",
"command_name": "remote-lastpass",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-office-tokens",
"command_name": "remote-office-tokens",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-procdump",
"command_name": "remote-procdump",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-reg-set",
"command_name": "remote-reg-set",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-schtaskscreate",
"command_name": "remote-schtaskscreate",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-schtasksrun",
"command_name": "remote-schtasksrun",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-shspawnas",
"command_name": "remote-shspawnas",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-suspendresume",
"command_name": "remote-suspendresume",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-unexpireuser",
"command_name": "remote-unexpireuser",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-get_priv",
"command_name": "remote-get_priv",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-ghost_task",
"command_name": "remote-ghost_task",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-sc_failure",
"command_name": "remote-sc_failure",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-slack_cookie",
"command_name": "remote-slack_cookie",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-adcs_request_on_behalf",
"command_name": "remote-adcs_request_on_behalf",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-global_unprotect",
"command_name": "remote-global_unprotect",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-make_token_cert",
"command_name": "remote-make_token_cert",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "remote-slackKey",
"command_name": "remote-slackKey",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "inject-tooltip",
"command_name": "inject-tooltip",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "inject-kernelcallbacktable",
"command_name": "inject-kernelcallbacktable",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "inject-uxsubclassinfo",
"command_name": "inject-uxsubclassinfo",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "inject-ntcreatethread",
"command_name": "inject-ntcreatethread",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "inject-dde",
"command_name": "inject-dde",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "inject-ntqueueapcthread",
"command_name": "inject-ntqueueapcthread",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "inject-conhost",
"command_name": "inject-conhost",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "inject-svcctrl",
"command_name": "inject-svcctrl",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "inject-ctray",
"command_name": "inject-ctray",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "inject-createremotethread",
"command_name": "inject-createremotethread",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "inject-setthreadcontext",
"command_name": "inject-setthreadcontext",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "inject-clipboard",
"command_name": "inject-clipboard",
"repo_url": "https://github.com/sliverarmory/CS-Remote-OPs-BOF",
"public_key": "RWRm8i4sFCLvcgeDadZwq/nrHrioIm81PN3nejwhty6yjaomlfjACk8r"
},
{
"name": "Keylogger",
"command_name": "raw-keylogger",
"repo_url": "https://github.com/sliverarmory/SliverKeylogger",
"public_key": "RWSSZAU2J83hqtNtSZigjU4PWcII3XYLP8KCvCJbxJUO8ax1GWTsdHYK"
},
{
"name": "winrm",
"command_name": "winrm",
"repo_url": "https://github.com/sliverarmory/winrmdll-sliver",
"public_key": "RWSJ7R+SWl07CHFJc0/EISI13VYDIWbgU+caunVW9sIZfZZHJAjIsbS0"
},
{
"name": "hashdump",
"command_name": "hashdump",
"repo_url": "https://github.com/sliverarmory/hashdump",
"public_key": "RWTh1yHjC7SqdX88YUPr0mwyWQpJPJf45rnquCfLl5McmSoxX1JMHvOG"
},
{
"name": "patchit",
"command_name": "patchit",
"repo_url": "https://github.com/sliverarmory/BOF-patchit",
"public_key": "RWQhRUp9UkE8nXlKTw+hpTg8fm0kJQpNDXy0gTpS/3Uw6+TPjM6jlxhy"
},
{
"name": "threadless-inject",
"command_name": "threadless-inject",
"repo_url": "https://github.com/sliverarmory/ThreadlessInject-BOF",
"public_key": "RWQb8kihJmahzcrXdqyTgIzOlKOGkMy41Jw99LgbLIPP/fumtFxN5nGc"
},
{
"name": "kerbrute",
"command_name": "kerbrute",
"repo_url": "https://github.com/sliverarmory/kerbrute",
"public_key": "RWR8t1Bebp515aKBZV5NILvxDf0eENlEbM1lSBfeKzfpS+kQDpCynmSY"
},
{
"name": "mimikatz",
"command_name": "mimikatz",
"repo_url": "https://github.com/sliverarmory/mimikatz",
"public_key": "RWQoTq429Swu8XK1KoKvcI4YDByEdI+QMMh+ZIdZha8qR/1sGewzJwPW"
},
{
"name": "jump-wmiexec",
"command_name": "jump-wmiexec",
"repo_url": "https://github.com/sliverarmory/HavocFrameworkModules",
"public_key": "RWQK7+ZMIJIoyU+LbkVETsqj6aTT9cvJG5pk4J9hY50Isfzcf9zsEFrn"
},
{
"name": "jump-psexec",
"command_name": "jump-psexec",
"repo_url": "https://github.com/sliverarmory/HavocFrameworkModules",
"public_key": "RWQK7+ZMIJIoyU+LbkVETsqj6aTT9cvJG5pk4J9hY50Isfzcf9zsEFrn"
},
{
"name": "nanorobeus",
"command_name": "nanorobeus",
"repo_url": "https://github.com/sliverarmory/HavocFrameworkModules",
"public_key": "RWQK7+ZMIJIoyU+LbkVETsqj6aTT9cvJG5pk4J9hY50Isfzcf9zsEFrn"
},
{
"name": "go-cookie-monster",
"command_name": "go-cookie-monster",
"repo_url": "https://github.com/sliverarmory/go-cookie-monster",
"public_key": "RWT9dnd+uf1FED1AkJO9jToTcmDChfq9KQpcBLjQtAhbOXTzAp29uWKD"
},
{
"name": "chisel",
"command_name": "chisel",
"repo_url": "https://github.com/sliverarmory/chisel",
"public_key": "RWQprtN3AKNuWbfXIGnCza43DUTy7ePrn1qJkOvuNGIIQbCv7UsK24Z6"
},
{
"name": "portbender",
"command_name": "portbender",
"repo_url": "https://github.com/sliverarmory/Sliver-PortBender",
"public_key": "RWSt+JnLbkQac67EF+VhPhZUxKwvRYxc2W/WInI/UtYC4KiuGdzwHC8p"
}
]
@@ -0,0 +1,10 @@
[
{
"name": "SharpCollection",
"type": "assembly"
},
{
"name": "SliverArmory",
"type": "bof"
}
]
@@ -0,0 +1,299 @@
package agentfunctions
import (
"encoding/json"
"errors"
"fmt"
agentstructs "github.com/MythicMeta/MythicContainer/agent_structs"
"github.com/MythicMeta/MythicContainer/logging"
"github.com/MythicMeta/MythicContainer/utils/sharedStructs"
"os"
"path/filepath"
)
const version = "0.0.1"
const CollectionSources = "collection_sources.json"
const PayloadTypeSupportFilename = "payload_type_support.json"
const BofPrefix = "forge_bof_"
const AssemblyPrefix = "forge_net_"
const PayloadTypeName = "forge"
type collectionSource struct {
Name string `json:"name"`
Type string `json:"type"`
SourceFilename string `json:"-"`
CommandsFilename string `json:"-"`
}
var collectionSourceNotFoundError = errors.New("collection source not found")
func getCollectionSourceNameOptions() []string {
assemblyCommandsFile, err := getOrCreateFile(CollectionSources)
if err != nil {
logging.LogError(err, "Failed to read collection sources file")
return []string{}
}
sources := []collectionSource{}
err = json.Unmarshal(assemblyCommandsFile, &sources)
if err != nil {
logging.LogError(err, "failed to parse collection sources")
return []string{}
}
sourceNames := make([]string, len(sources))
for i, source := range sources {
sourceNames[i] = source.Name
}
return sourceNames
}
func addCollectionSource(source collectionSource) error {
collectionFile, err := getOrCreateFile(CollectionSources)
if err != nil {
logging.LogError(err, "Failed to read collection sources file")
return err
}
sources := []collectionSource{}
err = json.Unmarshal(collectionFile, &sources)
if err != nil {
logging.LogError(err, "failed to parse collection sources")
return err
}
found := false
for i, _ := range sources {
if sources[i].Name == source.Name {
sources[i] = source
found = true
}
}
if !found {
sources = append(sources, source)
}
collectionFile, err = json.MarshalIndent(sources, "", "\t")
if err != nil {
logging.LogError(err, "failed to parse collection sources")
return err
}
err = os.WriteFile(CollectionSources, collectionFile, 0644)
return err
}
func getCollectionSource(name string) (collectionSource, error) {
collection := collectionSource{
Name: name,
SourceFilename: fmt.Sprintf("%s_sources.json", name),
CommandsFilename: fmt.Sprintf("%s_commands.json", name),
}
collectionFile, err := getOrCreateFile(CollectionSources)
if err != nil {
logging.LogError(err, "Failed to read collection sources file")
return collection, err
}
sources := []collectionSource{}
err = json.Unmarshal(collectionFile, &sources)
if err != nil {
logging.LogError(err, "failed to parse collection sources")
return collection, err
}
for i, _ := range sources {
sources[i].SourceFilename = fmt.Sprintf("%s_sources.json", sources[i].Name)
sources[i].CommandsFilename = fmt.Sprintf("%s_commands.json", sources[i].Name)
}
for _, source := range sources {
if source.Name == name {
return source, nil
}
}
return collection, collectionSourceNotFoundError
}
func getCollectionSources() []collectionSource {
sources := []collectionSource{}
collectionFile, err := getOrCreateFile(CollectionSources)
if err != nil {
logging.LogError(err, "Failed to read collection sources file")
return sources
}
err = json.Unmarshal(collectionFile, &sources)
if err != nil {
logging.LogError(err, "failed to parse collection sources")
return sources
}
for i, _ := range sources {
sources[i].SourceFilename = fmt.Sprintf("%s_sources.json", sources[i].Name)
sources[i].CommandsFilename = fmt.Sprintf("%s_commands.json", sources[i].Name)
}
return sources
}
func getOrCreateFile(filename string) ([]byte, error) {
commandsFileBytes, err := os.ReadFile(filename)
if errors.Is(err, os.ErrNotExist) {
newFile, err := os.Create(filename)
if err != nil {
return nil, err
}
newFile.Write([]byte("[]"))
newFile.Close()
return []byte("[]"), nil
}
if err != nil {
return nil, err
}
return commandsFileBytes, nil
}
type collectionSourceCommandData struct {
Name string `json:"name"`
CommandName string `json:"command_name"`
Description string `json:"description"`
RepoURL string `json:"repo_url"`
CustomDownloadURL string `json:"custom_download_url"`
CustomVersion string `json:"custom_version"`
customAssemblyFileID string
customBofFileIDs []string
customBofExtensionFileID string
Registered bool `json:"registered"`
Downloadable bool `json:"downloadable"`
CollectionName string `json:"collection_name"`
}
type agentDefinition struct {
Agent string `json:"agent"`
BofCommand string `json:"bof_command"`
BofFileParameterName string `json:"bof_file_parameter_name"`
BofArgumentArrayParameterName string `json:"bof_argument_array_parameter_name"`
BofEntryPointParameterName string `json:"bof_entrypoint_parameter_name"`
InlineAssemblyCommand string `json:"inline_assembly_command"`
InlineAssemblyFileParameterName string `json:"inline_assembly_file_parameter_name"`
InlineAssemblyArgumentParameterName string `json:"inline_assembly_argument_parameter_name"`
ExecuteAssemblyCommand string `json:"execute_assembly_command"`
ExecuteAssemblyFileParameterName string `json:"execute_assembly_file_parameter_name"`
ExecuteAssemblyArgumentParameterName string `json:"execute_assembly_argument_parameter_name"`
}
type bofCommand struct {
CommandName string `json:"command_name"`
CollectionType string `json:"collection_type"`
CollectionCommandName string `json:"collection_command_name"`
}
type assemblyCommand struct {
CommandName string `json:"command_name"`
CollectionType string `json:"collection_type"`
CollectionCommandName string `json:"collection_command_name"`
}
var payloadDefinition = agentstructs.PayloadType{
Name: PayloadTypeName,
FileExtension: "bin",
Author: "@its_a_feature_",
SupportedOS: []string{agentstructs.SUPPORTED_OS_WINDOWS},
Wrapper: false,
CanBeWrappedByTheFollowingPayloadTypes: []string{},
SupportsDynamicLoading: true,
Description: fmt.Sprintf("A collection of bofs/assemblies and their associated commands to be shared across agents.\nVersion %s\nNeeds Mythic 3.3.0+", version),
SupportedC2Profiles: []string{},
MythicEncryptsData: true,
AgentType: agentstructs.AgentTypeCommandAugment,
BuildParameters: []agentstructs.BuildParameter{},
BuildSteps: []agentstructs.BuildStep{},
OnContainerStartFunction: func(message sharedStructs.ContainerOnStartMessage) sharedStructs.ContainerOnStartMessageResponse {
response := sharedStructs.ContainerOnStartMessageResponse{}
collectionSources := getCollectionSources()
for _, source := range collectionSources {
commandsFile, err := getOrCreateFile(source.CommandsFilename)
if err != nil {
logging.LogError(err, "Failed to read commands file")
response.EventLogErrorMessage = "Failed to read commands file"
return response
}
switch source.Type {
case "assembly":
registeredCommands := []assemblyCommand{}
err = json.Unmarshal(commandsFile, &registeredCommands)
if err != nil {
logging.LogError(err, "failed to parse assembly commands into struct")
response.EventLogErrorMessage = "failed to parse assembly commands into struct"
return response
}
sourceCommandFile, err := getOrCreateFile(source.SourceFilename)
if err != nil {
logging.LogError(err, "Failed to read commands file")
response.EventLogErrorMessage = "Failed to read commands file"
return response
}
sourceCommands := []collectionSourceCommandData{}
err = json.Unmarshal(sourceCommandFile, &sourceCommands)
if err != nil {
logging.LogError(err, "failed to parse assembly commands into struct")
response.EventLogErrorMessage = "failed to parse assembly commands into struct"
return response
}
for _, registeredCommand := range registeredCommands {
for _, sourceCommand := range sourceCommands {
if registeredCommand.CollectionCommandName == sourceCommand.Name {
newCommand := createAssemblyCommand(sourceCommand, source, false)
agentstructs.AllPayloadData.Get(PayloadTypeName).AddCommand(newCommand)
}
}
}
case "bof":
registeredCommands := []bofCommand{}
err = json.Unmarshal(commandsFile, &registeredCommands)
if err != nil {
logging.LogError(err, "failed to parse assembly commands into struct")
response.EventLogErrorMessage = "failed to parse assembly commands into struct"
return response
}
sourceCommandFile, err := getOrCreateFile(source.SourceFilename)
if err != nil {
logging.LogError(err, "Failed to read commands file")
response.EventLogErrorMessage = "Failed to read commands file"
return response
}
sourceCommands := []collectionSourceCommandData{}
err = json.Unmarshal(sourceCommandFile, &sourceCommands)
if err != nil {
logging.LogError(err, "failed to parse assembly commands into struct")
response.EventLogErrorMessage = "failed to parse assembly commands into struct"
return response
}
for _, registeredCommand := range registeredCommands {
for _, sourceCommand := range sourceCommands {
if registeredCommand.CollectionCommandName == sourceCommand.Name {
newCommand, err := createBofCommand(sourceCommand, source, false)
if err != nil {
logging.LogError(err, "failed to create bof command")
continue
}
agentstructs.AllPayloadData.Get(PayloadTypeName).AddCommand(newCommand)
}
}
}
default:
}
}
return response
},
CheckIfCallbacksAliveFunction: func(message agentstructs.PTCheckIfCallbacksAliveMessage) agentstructs.PTCheckIfCallbacksAliveMessageResponse {
response := agentstructs.PTCheckIfCallbacksAliveMessageResponse{Success: true, Callbacks: make([]agentstructs.PTCallbacksToCheckResponse, 0)}
return response
},
}
func Initialize() {
agentFileData, err := getOrCreateFile(PayloadTypeSupportFilename)
if err != nil {
logging.LogError(err, "Failed to read payload file")
} else {
supportedAgents := []agentDefinition{}
err = json.Unmarshal(agentFileData, &supportedAgents)
if err != nil {
logging.LogError(err, "failed to parse payload file")
} else {
supportedAgentNames := make([]string, len(supportedAgents))
for i, agent := range supportedAgents {
supportedAgentNames[i] = agent.Agent
}
payloadDefinition.CommandAugmentSupportedAgents = supportedAgentNames
}
}
// do this to pre-load the existing commands before we sync for the first time
payloadDefinition.OnContainerStartFunction(sharedStructs.ContainerOnStartMessage{})
agentstructs.AllPayloadData.Get(PayloadTypeName).AddPayloadDefinition(payloadDefinition)
agentstructs.AllPayloadData.Get(PayloadTypeName).AddIcon(filepath.Join(".", PayloadTypeName, "agentfunctions", PayloadTypeName+".svg"))
agentstructs.AllPayloadData.Get(PayloadTypeName).AddDarkModeIcon(filepath.Join(".", PayloadTypeName, "agentfunctions", PayloadTypeName+".svg"))
}
@@ -0,0 +1,74 @@
package agentfunctions
import (
"encoding/json"
"github.com/MythicMeta/MythicContainer/logging"
"sync"
)
func DownloadEverything() {
collections := getCollectionSources()
wg := sync.WaitGroup{}
for _, collectionSourceData := range collections {
commandSources := []collectionSourceCommandData{}
commandSourcesFileData, err := getOrCreateFile(collectionSourceData.SourceFilename)
err = json.Unmarshal(commandSourcesFileData, &commandSources)
if err != nil {
logging.LogError(err, "failed to unmarshal contents of collection source file")
continue
}
for _, commandSource := range commandSources {
wg.Add(1)
go func() {
defer wg.Done()
switch collectionSourceData.Type {
case "assembly":
if commandSource.CustomDownloadURL != "" {
logging.LogInfo("[*] Starting download", "source", collectionSourceData.Name,
"command", commandSource.Name, "version", commandSource.CustomVersion)
err = downloadAssemblyFile(commandSource, commandSource.CustomVersion, collectionSourceData, nil)
if err != nil {
logging.LogError(err, "[!] failed to download assembly file", "source", collectionSourceData.Name,
"command", commandSource.Name, "version", commandSource.CustomVersion)
} else {
logging.LogInfo("[*] Successfully downloaded", "source", collectionSourceData.Name, "command", commandSource.Name, "version", commandSource.CustomVersion)
}
} else {
atLeastOneSuccess := false
if commandSource.RepoURL == "" {
logging.LogError(nil, "[!] No custom url and now repo url", "source", collectionSourceData.Name, "command", commandSource.Name)
return
}
for _, assemblyVersion := range assemblyVersions {
logging.LogInfo("[*] Starting download", "source", collectionSourceData.Name,
"command", commandSource.Name, "version", assemblyVersion)
err = downloadAssemblyFile(commandSource, assemblyVersion, collectionSourceData, nil)
if err == nil {
atLeastOneSuccess = true
logging.LogInfo("[*] Successfully downloaded", "source", collectionSourceData.Name, "command", commandSource.Name, "version", assemblyVersion)
} else {
logging.LogError(err, "[!] failed to download assembly file", "source", collectionSourceData.Name,
"command", commandSource.Name, "version", assemblyVersion)
}
}
if !atLeastOneSuccess {
logging.LogError(err, "[!] failed to download assembly file", "source", collectionSourceData.Name,
"command", commandSource.Name)
}
}
case "bof":
logging.LogInfo("[*] Starting download", "source", collectionSourceData.Name,
"command", commandSource.Name, "version", "bof")
err = downloadBofFile(commandSource, collectionSourceData, nil)
if err != nil {
logging.LogError(err, "[!] failed to download bof file", "source", collectionSourceData.Name,
"command", commandSource.Name)
} else {
logging.LogInfo("[*] Successfully downloaded", "source", collectionSourceData.Name, "command", commandSource.Name, "version", "bof")
}
}
}()
}
}
wg.Wait()
}
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="128" height="128">
<path d="M0 0 C-0.3125 1.875 -0.3125 1.875 -1 4 C-1.99 4.66 -2.98 5.32 -4 6 C6.89 6 17.78 6 29 6 C27.35 5.01 25.7 4.02 24 3 C24 2.01 24 1.02 24 0 C27.02346601 -0.2519555 28.6402007 -0.20421041 31.3125 1.3125 C33 3 33 3 33 6 C33.85549438 6.03758423 33.85549438 6.03758423 34.72827148 6.07592773 C37.29826157 6.19156549 39.86785527 6.31443624 42.4375 6.4375 C43.33533203 6.47681641 44.23316406 6.51613281 45.15820312 6.55664062 C46.01220703 6.59853516 46.86621094 6.64042969 47.74609375 6.68359375 C48.53685303 6.72025146 49.3276123 6.75690918 50.14233398 6.79467773 C52 7 52 7 53 8 C53.14115161 10.67058851 53.04247107 13.32432238 53 16 C57.62 16 62.24 16 67 16 C67 22.6 67 29.2 67 36 C59 40 59 40 56.125 40.75 C53.85726768 41.78994425 53.85726768 41.78994425 53.25390625 43.8984375 C52.74201328 45.91070643 52.36272144 47.95557005 52 50 C48.04 50 44.08 50 40 50 C40 56.27 40 62.54 40 69 C42.6915625 68.9690625 42.6915625 68.9690625 45.4375 68.9375 C47.29166122 68.9161878 49.14712498 68.92773498 51 69 C52 70 52 70 52.1328125 72.6875 C52.13023438 73.780625 52.12765625 74.87375 52.125 76 C52.12886719 77.6396875 52.12886719 77.6396875 52.1328125 79.3125 C52 82 52 82 51 83 C48.97505769 83.09409479 46.9468013 83.11743122 44.91967773 83.11352539 C42.96776772 83.11341209 42.96776772 83.11341209 40.97642517 83.11329651 C39.54548098 83.10818909 38.11453718 83.10297308 36.68359375 83.09765625 C35.2277074 83.09579203 33.77182043 83.09436815 32.31593323 83.09336853 C28.47720621 83.08954365 24.63851681 83.07971364 20.79980469 83.06866455 C16.88542184 83.05844978 12.97103294 83.05387077 9.05664062 83.04882812 C1.37107657 83.03809134 -6.31445645 83.02101529 -14 83 C-14.02685938 80.85423363 -14.04633088 78.70837355 -14.0625 76.5625 C-14.07410156 75.36753906 -14.08570313 74.17257813 -14.09765625 72.94140625 C-14 70 -14 70 -13 69 C-9.3308423 68.85689713 -5.67284559 68.95778338 -2 69 C-2 62.73 -2 56.46 -2 50 C-5.96 50 -9.92 50 -14 50 C-14.061875 48.618125 -14.12375 47.23625 -14.1875 45.8125 C-14.5745171 43.26613088 -14.5745171 43.26613088 -16 41 C-20.24349661 38.60173998 -24.28915445 37.43172757 -29 36 C-29 29.07 -29 22.14 -29 15 C-24.38 15 -19.76 15 -15 15 C-15 12.69 -15 10.38 -15 8 C-14.030625 7.7525 -13.06125 7.505 -12.0625 7.25 C-11.051875 6.8375 -10.04125 6.425 -9 6 C-8.33820153 4.01954441 -8.33820153 4.01954441 -8 2 C-5.06004981 -0.02755186 -3.72295997 0 0 0 Z " fill="#020202" transform="translate(40,45)"/>
<path d="M0 0 C19.8 0 39.6 0 60 0 C60 11.88 60 23.76 60 36 C40.2 36 20.4 36 0 36 C0 24.12 0 12.24 0 0 Z " fill="#7C8B91" transform="translate(29,55)"/>
<path d="M0 0 C1.44207941 2.88415883 1.09394887 5.41721528 1.0625 8.625 C1.05347656 9.81351563 1.04445313 11.00203125 1.03515625 12.2265625 C1.02355469 13.14179688 1.01195313 14.05703125 1 15 C1.60499329 14.99111755 2.20998657 14.98223511 2.83331299 14.9730835 C9.12722328 14.88462407 15.42095713 14.82427158 21.71533203 14.78027344 C24.06468884 14.76015186 26.41399554 14.73285149 28.76318359 14.69824219 C32.13912315 14.6497496 35.51440086 14.62703643 38.890625 14.609375 C39.94179504 14.58872986 40.99296509 14.56808472 42.07598877 14.54681396 C49.35677436 14.54457101 49.35677436 14.54457101 52.66333008 16.88574219 C54.19644077 19.31071727 54.51076642 20.64749405 54.4375 23.5 C54.43621094 24.2528125 54.43492188 25.005625 54.43359375 25.78125 C53.88211404 28.60323625 52.96959605 29.91024345 51 32 C48.74104309 32.48101807 48.74104309 32.48101807 46.06958008 32.45410156 C45.06876907 32.45379944 44.06795807 32.45349731 43.03681946 32.45318604 C41.95861435 32.43254089 40.88040924 32.41189575 39.76953125 32.390625 C38.66397385 32.38496521 37.55841644 32.37930542 36.4193573 32.37347412 C32.88330036 32.35105795 29.34825141 32.30084996 25.8125 32.25 C23.41733233 32.22994187 21.02214879 32.21168991 18.62695312 32.1953125 C12.75095733 32.151176 6.87555067 32.08421128 1 32 C1.02320312 32.91523437 1.04640625 33.83046875 1.0703125 34.7734375 C1.09738281 36.55621094 1.09738281 36.55621094 1.125 38.375 C1.14820312 39.55835938 1.17140625 40.74171875 1.1953125 41.9609375 C1 45 1 45 -1 47 C-3.03125 47.25878906 -3.03125 47.25878906 -5.5 47.265625 C-6.386875 47.26820312 -7.27375 47.27078125 -8.1875 47.2734375 C-9.115625 47.26570313 -10.04375 47.25796875 -11 47.25 C-11.928125 47.25773437 -12.85625 47.26546875 -13.8125 47.2734375 C-15.1428125 47.26957031 -15.1428125 47.26957031 -16.5 47.265625 C-17.3146875 47.26336914 -18.129375 47.26111328 -18.96875 47.25878906 C-21 47 -21 47 -23 45 C-25.09387008 33.30735764 -25.34755157 19.90811384 -18.83422852 9.66796875 C-18.27018311 8.89066406 -17.7061377 8.11335937 -17.125 7.3125 C-16.5899585 6.5596875 -16.05491699 5.806875 -15.50366211 5.03125 C-10.94749479 -0.49826532 -6.92953813 -0.91968788 0 0 Z " fill="#040200" transform="translate(63,0)"/>
<path d="M0 0 C0.02464705 5.67830078 0.04283462 11.35657069 0.05493164 17.03491211 C0.05997256 18.96818585 0.06680519 20.90145576 0.07543945 22.8347168 C0.08751565 25.60726872 0.09323057 28.37977041 0.09765625 31.15234375 C0.10281754 32.02213364 0.10797882 32.89192352 0.11329651 33.78807068 C0.11349185 35.85905814 0.06208168 37.92994324 0 40 C-1 41 -1 41 -4.59765625 41.09765625 C-6.08596867 41.0909822 -7.57426432 41.07902183 -9.0625 41.0625 C-10.20041992 41.05573242 -10.20041992 41.05573242 -11.36132812 41.04882812 C-13.24091871 41.0370068 -15.12046899 41.01907078 -17 41 C-19.09351772 15.23070009 -19.09351772 15.23070009 -10.44018555 4.01538086 C-7.03773786 0.14252227 -4.97569198 -0.2616967 0 0 Z " fill="#7E572A" transform="translate(61,3)"/>
<path d="M0 0 C11.88 0 23.76 0 36 0 C36 4.29 36 8.58 36 13 C24.12 13 12.24 13 0 13 C0 8.71 0 4.42 0 0 Z " fill="#495053" transform="translate(41,101)"/>
<path d="M0 0 C19.14 0 38.28 0 58 0 C58 2.64 58 5.28 58 8 C38.86 8 19.72 8 0 8 C0 5.36 0 2.72 0 0 Z " fill="#5F7C8A" transform="translate(30,117)"/>
<path d="M0 0 C11.55 0 23.1 0 35 0 C35 3.63 35 7.26 35 11 C23.45 11 11.9 11 0 11 C0 7.37 0 3.74 0 0 Z " fill="#FA9401" transform="translate(64,18)"/>
<path d="M0 0 C3.96 0 7.92 0 12 0 C12 6.27 12 12.54 12 19 C7.39942914 18.07988583 4.20327441 16.89559434 0 15 C0 10.05 0 5.1 0 0 Z " fill="#5E7A88" transform="translate(14,63)"/>
<path d="M0 0 C3.96 0 7.92 0 12 0 C12 4.95 12 9.9 12 15 C2.25 19 2.25 19 0 19 C0 12.73 0 6.46 0 0 Z " fill="#5F7B89" transform="translate(92,64)"/>
<path d="M0 0 C11.88 0 23.76 0 36 0 C36 1.65 36 3.3 36 5 C24.12 5 12.24 5 0 5 C0 3.35 0 1.7 0 0 Z " fill="#676E70" transform="translate(41,94)"/>
<path d="M0 0 C17.16 0 34.32 0 52 0 C52 0.66 52 1.32 52 2 C35.83 2 19.66 2 3 2 C3 10.25 3 18.5 3 27 C2.01 26.67 1.02 26.34 0 26 C0 17.42 0 8.84 0 0 Z " fill="#030404" transform="translate(33,60)"/>
<path d="M0 0 C1.423125 -0.061875 2.84625 -0.12375 4.3125 -0.1875 C5.51326172 -0.23970703 5.51326172 -0.23970703 6.73828125 -0.29296875 C9 0 9 0 10.80859375 1.28515625 C12 3 12 3 11.75 6.625 C11 10 11 10 10 11 C6.66381769 11.14257189 3.34024394 11.04228157 0 11 C0 7.37 0 3.74 0 0 Z " fill="#F6AD43" transform="translate(102,18)"/>
<path d="M0 0 C0.99 0 1.98 0 3 0 C3 4.95 3 9.9 3 15 C2.01 15.33 1.02 15.66 0 16 C0 10.72 0 5.44 0 0 Z " fill="#140D06" transform="translate(47,24)"/>
<path d="M0 0 C2.97 0 5.94 0 9 0 C9 1.32 9 2.64 9 4 C6.03 4 3.06 4 0 4 C0 2.68 0 1.36 0 0 Z " fill="#000000" transform="translate(66,40)"/>
<path d="M0 0 C2.64 0 5.28 0 8 0 C8 1.32 8 2.64 8 4 C5.03 4 2.06 4 -1 4 C-0.67 2.68 -0.34 1.36 0 0 Z " fill="#000000" transform="translate(30,40)"/>
</svg>

After

Width:  |  Height:  |  Size: 7.4 KiB

@@ -0,0 +1,166 @@
package agentfunctions
import (
"encoding/json"
"fmt"
agentstructs "github.com/MythicMeta/MythicContainer/agent_structs"
"github.com/MythicMeta/MythicContainer/logging"
"github.com/MythicMeta/MythicContainer/mythicrpc"
"path/filepath"
)
func init() {
agentstructs.AllPayloadData.Get(PayloadTypeName).AddCommand(agentstructs.Command{
Name: fmt.Sprintf("%s_collections", PayloadTypeName),
Description: fmt.Sprintf("Interact with the %s container to view available commands.", PayloadTypeName),
HelpString: fmt.Sprintf("%s_collections", PayloadTypeName),
Version: 1,
Author: "@its_a_feature_",
MitreAttackMappings: []string{},
SupportedUIFeatures: []string{},
ScriptOnlyCommand: true,
AssociatedBrowserScript: &agentstructs.BrowserScript{
ScriptPath: filepath.Join(".", PayloadTypeName, "browserscripts", fmt.Sprintf("%s_collections.js", PayloadTypeName)),
Author: "@its_a_feature_",
},
CommandAttributes: agentstructs.CommandAttribute{
SupportedOS: []string{agentstructs.SUPPORTED_OS_WINDOWS},
CommandIsBuiltin: true,
},
CommandParameters: []agentstructs.CommandParameter{
{
Name: "collectionName",
ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_CHOOSE_ONE_CUSTOM,
Description: "Choose which collection to query",
ModalDisplayName: "Collection Name to Query",
DynamicQueryFunction: func(message agentstructs.PTRPCDynamicQueryFunctionMessage) []string {
return getCollectionSourceNameOptions()
},
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: true,
},
},
},
},
TaskFunctionCreateTasking: func(taskData *agentstructs.PTTaskMessageAllData) agentstructs.PTTaskCreateTaskingMessageResponse {
response := agentstructs.PTTaskCreateTaskingMessageResponse{
Success: true,
TaskID: taskData.Task.ID,
}
collection, err := taskData.Args.GetChooseOneArg("collectionName")
if err != nil {
logging.LogError(err, "failed to get collection name")
response.Success = false
response.Error = err.Error()
return response
}
displayParams := fmt.Sprintf("-collectionName %s", collection)
response.DisplayParams = &displayParams
collectionSourceData, err := getCollectionSource(collection)
if err != nil {
logging.LogError(err, "failed to get collection source")
response.Success = false
response.Error = err.Error()
return response
}
fileContents, err := getOrCreateFile(collectionSourceData.SourceFilename)
if err != nil {
logging.LogError(err, "failed to get collection source file contents")
response.Success = false
response.Error = err.Error()
return response
}
commandSources := []collectionSourceCommandData{}
err = json.Unmarshal(fileContents, &commandSources)
if err != nil {
logging.LogError(err, "failed to unmarshal collection source file contents")
response.Success = false
response.Error = err.Error()
return response
}
commandNames := make([]string, len(commandSources))
for i, _ := range commandSources {
switch collectionSourceData.Type {
case "assembly":
commandNames[i] = fmt.Sprintf("%s%s", AssemblyPrefix, commandSources[i].CommandName)
case "bof":
commandNames[i] = fmt.Sprintf("%s%s", BofPrefix, commandSources[i].CommandName)
}
}
commandSearchResp, err := mythicrpc.SendMythicRPCCallbackSearchCommand(mythicrpc.MythicRPCCallbackSearchCommandMessage{
CallbackID: &taskData.Callback.ID,
SearchCommandNames: &commandNames,
})
if err != nil {
logging.LogError(err, "failed to send search for commands commands")
response.Success = false
response.Error = err.Error()
return response
}
if !commandSearchResp.Success {
logging.LogError(err, "got error message back from command search from Mythic")
response.Success = false
response.Error = commandSearchResp.Error
return response
}
for i, _ := range commandSources {
commandSources[i].CollectionName = collection
if commandSources[i].RepoURL != "" || commandSources[i].CustomDownloadURL != "" {
commandSources[i].Downloadable = true
}
switch collectionSourceData.Type {
case "assembly":
commandSources[i].CommandName = fmt.Sprintf("%s%s", AssemblyPrefix, commandSources[i].CommandName)
case "bof":
commandSources[i].CommandName = fmt.Sprintf("%s%s", BofPrefix, commandSources[i].CommandName)
}
for _, registeredCommand := range commandSearchResp.Commands {
switch collectionSourceData.Type {
case "assembly":
if commandSources[i].CommandName == registeredCommand.Name {
commandSources[i].Registered = true
break
}
case "bof":
if commandSources[i].CommandName == registeredCommand.Name {
commandSources[i].Registered = true
break
}
}
}
}
commandOptionBytes, err := json.Marshal(&commandSources)
if err != nil {
logging.LogError(err, "failed to marshal updated command sources back to bytes")
response.Success = false
response.Error = err.Error()
return response
}
resp, err := mythicrpc.SendMythicRPCResponseCreate(mythicrpc.MythicRPCResponseCreateMessage{
TaskID: taskData.Task.ID,
Response: commandOptionBytes,
})
if err != nil {
response.Success = false
response.Error = err.Error()
return response
}
if !resp.Success {
response.Success = false
response.Error = resp.Error
return response
}
return response
},
TaskFunctionParseArgDictionary: func(args *agentstructs.PTTaskMessageArgsData, input map[string]interface{}) error {
return args.LoadArgsFromDictionary(input)
},
TaskFunctionParseArgString: func(args *agentstructs.PTTaskMessageArgsData, input string) error {
return args.LoadArgsFromJSONString(input)
},
})
}
@@ -0,0 +1,363 @@
package agentfunctions
import (
"encoding/json"
"errors"
"fmt"
agentstructs "github.com/MythicMeta/MythicContainer/agent_structs"
"github.com/MythicMeta/MythicContainer/logging"
"github.com/MythicMeta/MythicContainer/mythicrpc"
"github.com/MythicMeta/MythicContainer/rabbitmq"
"os"
)
const assemblyGroup = "Create New .NET Assembly Command"
const bofGroup = "Create New BOF Command"
func init() {
agentstructs.AllPayloadData.Get(PayloadTypeName).AddCommand(agentstructs.Command{
Name: fmt.Sprintf("%s_create", PayloadTypeName),
Description: "Create brand new .NET or BOF commands to be available across all supported agent types.",
HelpString: fmt.Sprintf("%s_create", PayloadTypeName),
Version: 1,
Author: "@its_a_feature_",
MitreAttackMappings: []string{},
SupportedUIFeatures: []string{fmt.Sprintf("%s:create", PayloadTypeName)},
ScriptOnlyCommand: true,
CommandAttributes: agentstructs.CommandAttribute{
SupportedOS: []string{agentstructs.SUPPORTED_OS_WINDOWS},
CommandIsBuiltin: true,
},
CommandParameters: []agentstructs.CommandParameter{
{
Name: "collectionName",
ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_CHOOSE_ONE_CUSTOM,
Description: "Choose which collection to associate this new command with",
ModalDisplayName: "Collection Name",
DynamicQueryFunction: func(message agentstructs.PTRPCDynamicQueryFunctionMessage) []string {
return getCollectionSourceNameOptions()
},
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: true,
GroupName: assemblyGroup,
UIModalPosition: 1,
},
{
ParameterIsRequired: true,
GroupName: bofGroup,
UIModalPosition: 1,
},
},
},
{
Name: "commandName",
ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_STRING,
Description: "Specify which command to create",
ModalDisplayName: "Command Name to Register",
DefaultValue: "",
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: true,
GroupName: assemblyGroup,
UIModalPosition: 2,
},
{
ParameterIsRequired: true,
GroupName: bofGroup,
UIModalPosition: 2,
},
},
},
{
Name: "description",
ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_STRING,
Description: "Description of the new command",
ModalDisplayName: "Command Description",
DefaultValue: "",
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: false,
GroupName: assemblyGroup,
UIModalPosition: 3,
},
{
ParameterIsRequired: false,
GroupName: bofGroup,
UIModalPosition: 3,
},
},
},
{
Name: "commandFileAssembly",
ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_FILE,
Description: "Upload the .net to execute for this command version",
ModalDisplayName: "The assembly file to execute",
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: true,
GroupName: assemblyGroup,
UIModalPosition: 4,
},
},
},
{
Name: "commandVersion",
ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_CHOOSE_ONE_CUSTOM,
Description: "What version is this assembly",
ModalDisplayName: "Version",
DefaultValue: "4.7_Any",
DynamicQueryFunction: func(message agentstructs.PTRPCDynamicQueryFunctionMessage) []string {
return assemblyVersions
},
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: false,
GroupName: assemblyGroup,
UIModalPosition: 5,
},
},
},
{
Name: "commandFilesBof",
ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_FILE_MULTIPLE,
Description: "Upload the .o files to execute for this command",
ModalDisplayName: "The bof .o files to execute",
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: true,
GroupName: bofGroup,
UIModalPosition: 4,
},
},
},
{
Name: "extensionFile",
ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_FILE,
Description: "The extension.json file that describes this bof command",
ModalDisplayName: "Sliver Armory style extension.json file",
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: true,
GroupName: bofGroup,
UIModalPosition: 5,
},
},
},
},
TaskFunctionCreateTasking: func(taskData *agentstructs.PTTaskMessageAllData) agentstructs.PTTaskCreateTaskingMessageResponse {
response := agentstructs.PTTaskCreateTaskingMessageResponse{
Success: true,
TaskID: taskData.Task.ID,
}
parameterGroup, err := taskData.Args.GetParameterGroupName()
if err != nil {
logging.LogError(err, "failed to get parameterGroup")
response.Success = false
response.Error = err.Error()
return response
}
collection, err := taskData.Args.GetStringArg("collectionName")
if err != nil {
logging.LogError(err, "failed to get collection name")
response.Success = false
response.Error = err.Error()
return response
}
commandName, err := taskData.Args.GetStringArg("commandName")
if err != nil {
logging.LogError(err, "failed to get commandName")
response.Success = false
response.Error = err.Error()
return response
}
description, err := taskData.Args.GetStringArg("description")
if err != nil {
logging.LogError(err, "failed to get commandName")
response.Success = false
response.Error = err.Error()
return response
}
collectionSourceData, err := getCollectionSource(collection)
if errors.Is(err, collectionSourceNotFoundError) {
if parameterGroup == assemblyGroup {
collectionSourceData.Type = "assembly"
} else {
collectionSourceData.Type = "bof"
}
err = addCollectionSource(collectionSourceData)
if err != nil {
logging.LogError(err, "failed to add collection source")
response.Success = false
response.Error = err.Error()
return response
}
} else if err != nil {
logging.LogError(err, "failed to get collection source by name")
response.Success = false
response.Error = err.Error()
return response
}
fileContents, err := getOrCreateFile(collectionSourceData.SourceFilename)
if err != nil {
logging.LogError(err, "failed to get contents of collection sources file")
response.Success = false
response.Error = err.Error()
return response
}
commandSources := []collectionSourceCommandData{}
err = json.Unmarshal(fileContents, &commandSources)
if err != nil {
logging.LogError(err, "failed to unmarshal contents of collection source file")
response.Success = false
response.Error = err.Error()
return response
}
displayParams := fmt.Sprintf("-collectionName %s -commandName %s", collection, commandName)
response.DisplayParams = &displayParams
if (collectionSourceData.Type == "assembly" && parameterGroup == bofGroup) ||
(collectionSourceData.Type == "bof" && parameterGroup == assemblyGroup) {
response.Success = false
response.Error = fmt.Sprintf("This collection is of type %s, but you're trying to create a command of the wrong type.\nCreate a new collection or create a new command of the right type", collectionSourceData.Type)
return response
}
commandIndex := -1
newCommandSource := collectionSourceCommandData{
Name: commandName,
CommandName: commandName,
Description: description,
}
for i, commandSource := range commandSources {
if commandSource.CommandName == commandName {
if commandSource.RepoURL != "" || commandSource.CustomDownloadURL != "" {
// trying to upload commandX when one already exists with a URL, not good
response.Success = false
response.Error = "Can't create new commandX when one already exists that references a remote URL"
return response
}
// we already have this command name, but there's no remote url, so it was created like this
// this is ok to update
commandIndex = i
newCommandSource = commandSource
newCommandSource.Description = description
}
}
var prefixedCommandName string
if parameterGroup == assemblyGroup {
commandFileID, err := taskData.Args.GetFileArg("commandFileAssembly")
if err != nil {
logging.LogError(err, "failed to get commandFile")
response.Success = false
response.Error = err.Error()
return response
}
commandVersion, err := taskData.Args.GetStringArg("commandVersion")
if err != nil {
logging.LogError(err, "failed to get version")
response.Success = false
response.Error = err.Error()
return response
}
prefixedCommandName = fmt.Sprintf("%s%s", AssemblyPrefix, commandName)
newCommandSource.customAssemblyFileID = commandFileID
newCommandSource.CustomVersion = commandVersion
err = downloadAssemblyFile(newCommandSource, commandVersion, collectionSourceData, taskData)
if err != nil {
logging.LogError(err, "failed to download file to container")
response.Success = false
response.Error = err.Error()
return response
}
mythicrpc.SendMythicRPCResponseCreate(mythicrpc.MythicRPCResponseCreateMessage{
TaskID: taskData.Task.ID,
Response: []byte(fmt.Sprintf("Registering new command %s\n", prefixedCommandName)),
})
newCommand := createAssemblyCommand(newCommandSource, collectionSourceData, true)
agentstructs.AllPayloadData.Get(PayloadTypeName).AddCommand(newCommand)
} else {
commandFileIDs, err := taskData.Args.GetArrayArg("commandFilesBof")
if err != nil {
logging.LogError(err, "failed to get commandFile")
response.Success = false
response.Error = err.Error()
return response
}
extensionFileID, err := taskData.Args.GetFileArg("extensionFile")
if err != nil {
logging.LogError(err, "failed to get version")
response.Success = false
response.Error = err.Error()
return response
}
if len(commandFileIDs) == 0 {
response.Error = "No command files specified"
response.Success = false
return response
}
if extensionFileID == "" {
response.Error = "No extension file specified"
response.Success = false
return response
}
prefixedCommandName = fmt.Sprintf("%s%s", BofPrefix, commandName)
mythicrpc.SendMythicRPCResponseCreate(mythicrpc.MythicRPCResponseCreateMessage{
TaskID: taskData.Task.ID,
Response: []byte(fmt.Sprintf("Registering new command %s\n", prefixedCommandName)),
})
newCommandSource.customBofExtensionFileID = extensionFileID
newCommandSource.customBofFileIDs = commandFileIDs
err = downloadBofFile(newCommandSource, collectionSourceData, taskData)
if err != nil {
logging.LogError(err, "failed to download files to container")
response.Success = false
response.Error = err.Error()
return response
}
newCommand, err := createBofCommand(newCommandSource, collectionSourceData, true)
if err != nil {
response.Success = false
response.Error = err.Error()
return response
}
agentstructs.AllPayloadData.Get(PayloadTypeName).AddCommand(newCommand)
}
rabbitmq.SyncPayloadData(&payloadDefinition.Name, false)
response.Success = true
// add / update command in sources file
if commandIndex == -1 {
commandSources = append(commandSources, newCommandSource)
} else {
commandSources[commandIndex] = newCommandSource
}
commandBytes, err := json.MarshalIndent(commandSources, "", "\t")
if err != nil {
logging.LogError(err, "failed to marshal command sources")
response.Success = false
response.Error = err.Error()
return response
}
err = os.WriteFile(collectionSourceData.SourceFilename, commandBytes, os.ModePerm)
if err != nil {
logging.LogError(err, "failed to marshal command sources")
response.Success = false
response.Error = err.Error()
return response
}
mythicrpc.SendMythicRPCResponseCreate(mythicrpc.MythicRPCResponseCreateMessage{
TaskID: taskData.Task.ID,
Response: []byte(fmt.Sprintf("Command Registered for use!\n")),
})
return response
},
TaskFunctionParseArgDictionary: func(args *agentstructs.PTTaskMessageArgsData, input map[string]interface{}) error {
return args.LoadArgsFromDictionary(input)
},
TaskFunctionParseArgString: func(args *agentstructs.PTTaskMessageArgsData, input string) error {
if len(input) > 0 {
return args.LoadArgsFromJSONString(input)
}
return nil
},
})
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,334 @@
package agentfunctions
import (
"encoding/json"
"errors"
"fmt"
agentstructs "github.com/MythicMeta/MythicContainer/agent_structs"
"github.com/MythicMeta/MythicContainer/logging"
"github.com/MythicMeta/MythicContainer/mythicrpc"
"github.com/MythicMeta/MythicContainer/rabbitmq"
"os"
)
func removeCommandFromFile(commandSource collectionSourceCommandData, collectionSourceData collectionSource) error {
assemblyCommandsFile, err := getOrCreateFile(collectionSourceData.CommandsFilename)
if err != nil {
logging.LogError(err, "Failed to read assembly commands file")
return err
}
if collectionSourceData.Type == "assembly" {
commands := []assemblyCommand{}
err = json.Unmarshal(assemblyCommandsFile, &commands)
if err != nil {
logging.LogError(err, "failed to parse assembly commands into struct")
return err
}
for i, _ := range commands {
if commands[i].CommandName == fmt.Sprintf("%s%s", AssemblyPrefix, commandSource.CommandName) {
// we found the one to remove
commands = append(commands[:i], commands[i+1:]...)
newAssemblyCommandsBytes, err := json.MarshalIndent(commands, "", "\t")
if err != nil {
logging.LogError(err, "failed to marshal commands into JSON")
return err
}
err = os.WriteFile(collectionSourceData.CommandsFilename, newAssemblyCommandsBytes, os.ModePerm)
if err != nil {
logging.LogError(err, "failed to write out new commands to file")
return err
}
return nil
}
}
// never found the command, so it's essentially removed
return nil
} else if collectionSourceData.Type == "bof" {
commands := []bofCommand{}
err = json.Unmarshal(assemblyCommandsFile, &commands)
if err != nil {
logging.LogError(err, "failed to parse assembly commands into struct")
return err
}
for i, _ := range commands {
if commands[i].CommandName == fmt.Sprintf("%s%s", BofPrefix, commandSource.CommandName) {
// we found the one to remove
commands = append(commands[:i], commands[i+1:]...)
newAssemblyCommandsBytes, err := json.MarshalIndent(commands, "", "\t")
if err != nil {
logging.LogError(err, "failed to marshal commands into JSON")
return err
}
err = os.WriteFile(collectionSourceData.CommandsFilename, newAssemblyCommandsBytes, os.ModePerm)
if err != nil {
logging.LogError(err, "failed to write out new commands to file")
return err
}
return nil
}
}
// never found the command, so it's essentially removed
return nil
}
return errors.New("unknown source type")
}
func init() {
agentstructs.AllPayloadData.Get(PayloadTypeName).AddCommand(agentstructs.Command{
Name: fmt.Sprintf("%s_register", PayloadTypeName),
Description: "Register existing possible commands to be available across all supported agent types.",
HelpString: fmt.Sprintf("%s_register -collectionName SharpCollection -commandName Rubeus", PayloadTypeName),
Version: 1,
Author: "@its_a_feature_",
MitreAttackMappings: []string{},
SupportedUIFeatures: []string{fmt.Sprintf("%s:register", PayloadTypeName)},
ScriptOnlyCommand: true,
CommandAttributes: agentstructs.CommandAttribute{
SupportedOS: []string{agentstructs.SUPPORTED_OS_WINDOWS},
CommandIsBuiltin: true,
},
CommandParameters: []agentstructs.CommandParameter{
{
Name: "collectionName",
ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_CHOOSE_ONE_CUSTOM,
Description: "Choose which collection to query",
ModalDisplayName: "Collection Name to Query",
DynamicQueryFunction: func(message agentstructs.PTRPCDynamicQueryFunctionMessage) []string {
return getCollectionSourceNameOptions()
},
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: true,
},
},
},
{
Name: "commandName",
ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_STRING,
Description: "Specify which command to register",
ModalDisplayName: "Command Name to Register",
DefaultValue: "",
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: true,
},
},
},
{
Name: "remove",
ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_BOOLEAN,
Description: "Unregister the command across all callbacks",
ModalDisplayName: "Unregister the command across all callbacks",
DefaultValue: false,
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: true,
},
},
},
},
TaskFunctionCreateTasking: func(taskData *agentstructs.PTTaskMessageAllData) agentstructs.PTTaskCreateTaskingMessageResponse {
response := agentstructs.PTTaskCreateTaskingMessageResponse{
Success: true,
TaskID: taskData.Task.ID,
}
collection, err := taskData.Args.GetChooseOneArg("collectionName")
if err != nil {
logging.LogError(err, "failed to get collection name")
response.Success = false
response.Error = err.Error()
return response
}
commandName, err := taskData.Args.GetStringArg("commandName")
if err != nil {
logging.LogError(err, "failed to get commandName")
response.Success = false
response.Error = err.Error()
return response
}
remove, err := taskData.Args.GetBooleanArg("remove")
if err != nil {
logging.LogError(err, "failed to get commandName")
response.Success = false
response.Error = err.Error()
return response
}
displayParams := fmt.Sprintf("-collectionName %s -commandName %s", collection, commandName)
if remove {
displayParams += " -remove"
}
response.DisplayParams = &displayParams
collectionSourceData, err := getCollectionSource(collection)
if err != nil {
logging.LogError(err, "failed to get collection source by name")
response.Success = false
response.Error = err.Error()
return response
}
fileContents, err := getOrCreateFile(collectionSourceData.SourceFilename)
if err != nil {
logging.LogError(err, "failed to get contents of collection sources file")
response.Success = false
response.Error = err.Error()
return response
}
commandSources := []collectionSourceCommandData{}
err = json.Unmarshal(fileContents, &commandSources)
if err != nil {
logging.LogError(err, "failed to unmarshal contents of collection source file")
response.Success = false
response.Error = err.Error()
return response
}
var prefixedCommandName string
for _, commandSource := range commandSources {
if commandSource.Name == commandName {
switch collectionSourceData.Type {
case "assembly":
prefixedCommandName = fmt.Sprintf("%s%s", AssemblyPrefix, commandSource.CommandName)
if remove {
mythicrpc.SendMythicRPCResponseCreate(mythicrpc.MythicRPCResponseCreateMessage{
TaskID: taskData.Task.ID,
Response: []byte(fmt.Sprintf("Removing command %s\n", prefixedCommandName)),
})
err = removeCommandFromFile(commandSource, collectionSourceData)
if err != nil {
logging.LogError(err, "failed to remove command")
response.Success = false
response.Error = err.Error()
}
agentstructs.AllPayloadData.Get(PayloadTypeName).RemoveCommand(agentstructs.Command{Name: prefixedCommandName})
} else {
mythicrpc.SendMythicRPCResponseCreate(mythicrpc.MythicRPCResponseCreateMessage{
TaskID: taskData.Task.ID,
Response: []byte(fmt.Sprintf("Registering new command %s\n", prefixedCommandName)),
})
newCommand := createAssemblyCommand(commandSource, collectionSourceData, true)
agentstructs.AllPayloadData.Get(PayloadTypeName).AddCommand(newCommand)
}
case "bof":
prefixedCommandName = fmt.Sprintf("%s%s", BofPrefix, commandSource.CommandName)
if remove {
mythicrpc.SendMythicRPCResponseCreate(mythicrpc.MythicRPCResponseCreateMessage{
TaskID: taskData.Task.ID,
Response: []byte(fmt.Sprintf("Removing command %s\n", prefixedCommandName)),
})
err = removeCommandFromFile(commandSource, collectionSourceData)
if err != nil {
logging.LogError(err, "failed to remove command")
response.Success = false
response.Error = err.Error()
}
agentstructs.AllPayloadData.Get(PayloadTypeName).RemoveCommand(agentstructs.Command{Name: prefixedCommandName})
} else {
mythicrpc.SendMythicRPCResponseCreate(mythicrpc.MythicRPCResponseCreateMessage{
TaskID: taskData.Task.ID,
Response: []byte(fmt.Sprintf("Registering new command %s\n", prefixedCommandName)),
})
newCommand, err := createBofCommand(commandSource, collectionSourceData, true)
if err != nil {
response.Success = false
response.Error = err.Error()
return response
}
agentstructs.AllPayloadData.Get(PayloadTypeName).AddCommand(newCommand)
}
default:
}
rabbitmq.SyncPayloadData(&payloadDefinition.Name, false)
response.Success = true
if remove {
// now to remove this command from all associated callbacks
payloadtypesFileContents, err := getOrCreateFile(PayloadTypeSupportFilename)
if err != nil {
logging.LogError(err, "failed to read payloadtype support file")
response.Success = false
response.Error = err.Error()
return response
}
payloadTypes := []agentDefinition{}
err = json.Unmarshal(payloadtypesFileContents, &payloadTypes)
if err != nil {
logging.LogError(err, "failed to read unmarshal payloadtypes file")
response.Success = false
response.Error = err.Error()
return response
}
payloadTypeNames := make([]string, len(payloadTypes))
for i, payloadType := range payloadTypes {
payloadTypeNames[i] = payloadType.Agent
}
callbacksSearchResp, err := mythicrpc.SendMythicRPCCallbackSearch(mythicrpc.MythicRPCCallbackSearchMessage{
AgentCallbackID: taskData.Callback.ID,
SearchCallbackPayloadTypes: &payloadTypeNames,
})
if err != nil {
logging.LogError(err, "failed to send mythicrpc message to mythic to search for callbacks")
response.Success = false
response.Error = err.Error()
return response
}
if !callbacksSearchResp.Success {
logging.LogError(nil, "mythicrpc returned error", "error", callbacksSearchResp.Error)
response.Success = false
response.Error = callbacksSearchResp.Error
return response
}
callbackIDs := make([]int, len(callbacksSearchResp.Results))
for i, callback := range callbacksSearchResp.Results {
callbackIDs[i] = callback.ID
}
callbacksRemoveCommandResp, err := mythicrpc.SendMythicRPCCallbackRemoveCommand(mythicrpc.MythicRPCCallbackRemoveCommandMessage{
TaskID: taskData.Task.ID,
PayloadType: PayloadTypeName,
CallbackIDs: callbackIDs,
Commands: []string{
prefixedCommandName,
},
})
if err != nil {
logging.LogError(err, "failed to send mythicrpc message to mythic to remove commands")
response.Success = false
response.Error = err.Error()
return response
}
if !callbacksRemoveCommandResp.Success {
logging.LogError(nil, "mythicrpc returned error", "error", callbacksSearchResp.Error)
response.Success = false
response.Error = callbacksSearchResp.Error
return response
}
mythicrpc.SendMythicRPCResponseCreate(mythicrpc.MythicRPCResponseCreateMessage{
TaskID: taskData.Task.ID,
Response: []byte(fmt.Sprintf("Command Removed from use!\n")),
})
} else {
mythicrpc.SendMythicRPCResponseCreate(mythicrpc.MythicRPCResponseCreateMessage{
TaskID: taskData.Task.ID,
Response: []byte(fmt.Sprintf("Command Registered for use!\n")),
})
}
return response
}
}
response.Success = false
response.Error = "Failed to find that command in " + collectionSourceData.SourceFilename
return response
},
TaskFunctionParseArgDictionary: func(args *agentstructs.PTTaskMessageArgsData, input map[string]interface{}) error {
return args.LoadArgsFromDictionary(input)
},
TaskFunctionParseArgString: func(args *agentstructs.PTTaskMessageArgsData, input string) error {
if len(input) > 0 {
return args.LoadArgsFromJSONString(input)
}
return nil
},
})
}
@@ -0,0 +1,306 @@
package agentfunctions
import (
"encoding/json"
"fmt"
agentstructs "github.com/MythicMeta/MythicContainer/agent_structs"
"github.com/MythicMeta/MythicContainer/logging"
"github.com/MythicMeta/MythicContainer/mythicrpc"
"github.com/MythicMeta/MythicContainer/rabbitmq"
"os"
)
func init() {
agentstructs.AllPayloadData.Get(PayloadTypeName).AddCommand(agentstructs.Command{
Name: fmt.Sprintf("%s_support", PayloadTypeName),
Description: fmt.Sprintf("Add, remove, or update support for a payload type with %s", PayloadTypeName),
HelpString: fmt.Sprintf("%s_support", PayloadTypeName),
Version: 1,
Author: "@its_a_feature_",
MitreAttackMappings: []string{},
SupportedUIFeatures: []string{},
ScriptOnlyCommand: true,
CommandAttributes: agentstructs.CommandAttribute{
SupportedOS: []string{agentstructs.SUPPORTED_OS_WINDOWS},
CommandIsBuiltin: true,
},
CommandParameters: []agentstructs.CommandParameter{
{
Name: "payload_type",
CLIName: "payloadType",
ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_CHOOSE_ONE_CUSTOM,
Description: "Choose which payload type to modify support for",
ModalDisplayName: "Payload Type",
DefaultValue: "",
DynamicQueryFunction: func(message agentstructs.PTRPCDynamicQueryFunctionMessage) []string {
supportedAgentsFile, err := getOrCreateFile(PayloadTypeSupportFilename)
if err != nil {
logging.LogError(err, "failed to get supported payload types file")
return []string{}
}
supportedAgents := []agentDefinition{}
err = json.Unmarshal(supportedAgentsFile, &supportedAgents)
if err != nil {
logging.LogError(err, "failed to unmarshal supported payload types file")
return []string{}
}
supportedAgentNames := make([]string, len(supportedAgents))
for i, agent := range supportedAgents {
supportedAgentNames[i] = agent.Agent
}
return supportedAgentNames
},
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: true,
UIModalPosition: 0,
},
},
},
{
Name: "bof_command",
CLIName: "bofCommand",
ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_STRING,
Description: "Name of the bof command for this agent",
ModalDisplayName: "BOF Command",
DefaultValue: "",
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: true,
UIModalPosition: 1,
},
},
},
{
Name: "bof_file_parameter_name",
CLIName: "bofFileParameterName",
ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_STRING,
Description: "Name of the parameter that specifies the bof file UUID",
ModalDisplayName: "BOF File Parameter Name",
DefaultValue: "",
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: true,
UIModalPosition: 2,
},
},
},
{
Name: "bof_argument_array_parameter_name",
CLIName: "bofArgumentArrayParameterName",
ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_STRING,
Description: "Name of the parameter that specifies array of BOF arguments",
ModalDisplayName: "BOF Arguments Array Parameter Name",
DefaultValue: "",
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: true,
UIModalPosition: 3,
},
},
},
{
Name: "bof_entrypoint_parameter_name",
CLIName: "bofEntrypointParameterName",
ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_STRING,
Description: "Name of the parameter that specifies the bof entrypoint function name",
ModalDisplayName: "BOF Entrypoint Parameter Name",
DefaultValue: "go",
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: true,
UIModalPosition: 4,
},
},
},
{
Name: "inline_assembly_command",
CLIName: "inlineAssemblyCommand",
ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_STRING,
Description: "Name of the command that runs assemblies inline",
ModalDisplayName: "Inline Assembly Command Name",
DefaultValue: "inline_assembly",
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: true,
UIModalPosition: 5,
},
},
},
{
Name: "inline_assembly_file_parameter_name",
CLIName: "inlineAssemblyFileParameterName",
ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_STRING,
Description: "Name of the parameter that specifies the assembly file UUID",
ModalDisplayName: "Inline Assembly File Parameter Name",
DefaultValue: "",
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: true,
UIModalPosition: 6,
},
},
},
{
Name: "inline_assembly_argument_parameter_name",
CLIName: "inlineAssemblyArgumentParameterName",
ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_STRING,
Description: "Name of the parameter that specifies the assembly argument string",
ModalDisplayName: "Inline Assembly argument string Parameter Name",
DefaultValue: "",
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: true,
UIModalPosition: 7,
},
},
},
{
Name: "execute_assembly_command",
CLIName: "executeAssemblyCommand",
ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_STRING,
Description: "Name of the command that runs assemblies in fork-and-run",
ModalDisplayName: "Execute Assembly Command Name",
DefaultValue: "execute_assembly",
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: true,
UIModalPosition: 8,
},
},
},
{
Name: "execute_assembly_file_parameter_name",
CLIName: "executeAssemblyFileParameterName",
ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_STRING,
Description: "Name of the parameter that specifies the assembly file UUID",
ModalDisplayName: "Execute Assembly File Parameter Name",
DefaultValue: "",
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: true,
UIModalPosition: 9,
},
},
},
{
Name: "execute_assembly_argument_parameter_name",
CLIName: "executeAssemblyArgumentParameterName",
ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_STRING,
Description: "Name of the parameter that specifies the assembly argument string",
ModalDisplayName: "Execute Assembly argument string Parameter Name",
DefaultValue: "",
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: true,
UIModalPosition: 10,
},
},
},
{
Name: "remove_support",
CLIName: "remove",
ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_BOOLEAN,
Description: "Remove this agent from the supported list",
ModalDisplayName: "Remove Support",
DefaultValue: false,
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: true,
UIModalPosition: 11,
},
},
},
},
TaskFunctionCreateTasking: func(taskData *agentstructs.PTTaskMessageAllData) agentstructs.PTTaskCreateTaskingMessageResponse {
response := agentstructs.PTTaskCreateTaskingMessageResponse{
Success: true,
TaskID: taskData.Task.ID,
}
inputAgent, _ := taskData.Args.GetStringArg("payload_type")
inputBofCommand, _ := taskData.Args.GetStringArg("bof_command")
inputBofFileParameterName, _ := taskData.Args.GetStringArg("bof_file_parameter_name")
inputBofArgumentArrayParameterName, _ := taskData.Args.GetStringArg("bof_argument_array_parameter_name")
inputBofEntrypointParameterName, _ := taskData.Args.GetStringArg("bof_entrypoint_parameter_name")
inputInlineAssemblyCommand, _ := taskData.Args.GetStringArg("inline_assembly_command")
inputInlineAssemblyFileParameterName, _ := taskData.Args.GetStringArg("inline_assembly_file_parameter_name")
inputInlineAssemblyArgumentParameterName, _ := taskData.Args.GetStringArg("inline_assembly_argument_parameter_name")
inputExecuteAssemblyCommand, _ := taskData.Args.GetStringArg("execute_assembly_command")
inputExecuteAssemblyFileParameterName, _ := taskData.Args.GetStringArg("execute_assembly_file_parameter_name")
inputExecuteAssemblyArgumentParameterName, _ := taskData.Args.GetStringArg("execute_assembly_argument_parameter_name")
remove, _ := taskData.Args.GetBooleanArg("remove_support")
supportedAgentsFile, err := getOrCreateFile(PayloadTypeSupportFilename)
if err != nil {
response.Success = false
response.Error = err.Error()
return response
}
newDefinition := agentDefinition{
Agent: inputAgent,
BofCommand: inputBofCommand,
BofFileParameterName: inputBofFileParameterName,
BofArgumentArrayParameterName: inputBofArgumentArrayParameterName,
BofEntryPointParameterName: inputBofEntrypointParameterName,
InlineAssemblyCommand: inputInlineAssemblyCommand,
InlineAssemblyFileParameterName: inputInlineAssemblyFileParameterName,
InlineAssemblyArgumentParameterName: inputInlineAssemblyArgumentParameterName,
ExecuteAssemblyCommand: inputExecuteAssemblyCommand,
ExecuteAssemblyFileParameterName: inputExecuteAssemblyFileParameterName,
ExecuteAssemblyArgumentParameterName: inputExecuteAssemblyArgumentParameterName,
}
supportedAgents := []agentDefinition{}
err = json.Unmarshal(supportedAgentsFile, &supportedAgents)
if err != nil {
response.Success = false
response.Error = err.Error()
return response
}
found := false
for i, agent := range supportedAgents {
if agent.Agent == newDefinition.Agent {
supportedAgents[i] = newDefinition
found = true
if remove {
supportedAgents = append(supportedAgents[:i], supportedAgents[i+1:]...)
}
break
}
}
if !found {
supportedAgents = append(supportedAgents, newDefinition)
}
supportedAgentBytes, err := json.MarshalIndent(supportedAgents, "", "\t")
if err != nil {
response.Success = false
response.Error = err.Error()
return response
}
err = os.WriteFile(PayloadTypeSupportFilename, supportedAgentBytes, os.ModePerm)
if err != nil {
response.Success = false
response.Error = err.Error()
return response
}
Initialize()
rabbitmq.SyncPayloadData(&payloadDefinition.Name, false)
if remove {
mythicrpc.SendMythicRPCResponseCreate(mythicrpc.MythicRPCResponseCreateMessage{
TaskID: taskData.Task.ID,
Response: []byte(fmt.Sprintf("Successfully removed support for %s", inputAgent)),
})
} else {
mythicrpc.SendMythicRPCResponseCreate(mythicrpc.MythicRPCResponseCreateMessage{
TaskID: taskData.Task.ID,
Response: []byte(fmt.Sprintf("Successfully added support for %s", inputAgent)),
})
}
return response
},
TaskFunctionParseArgDictionary: func(args *agentstructs.PTTaskMessageArgsData, input map[string]interface{}) error {
return args.LoadArgsFromDictionary(input)
},
TaskFunctionParseArgString: func(args *agentstructs.PTTaskMessageArgsData, input string) error {
return args.LoadArgsFromJSONString(input)
},
})
}
@@ -0,0 +1,52 @@
function(task, responses){
if(responses.length === 0){
return {"plaintext": "No response yet from agent..."};
}
if(task.status.includes("error")){
return {"plaintext": responses.join("\n")};
}
try{
let collection = JSON.parse(responses[0]);
let headers = [
{"plaintext": "DL", "type": "button", "width": 50, "disableSort": true},
{"plaintext": "Reg", "type": "button", "width": 50, "disableSort": true},
{"plaintext": "Name", "type": "string", "fillWidth": true},
{"plaintext": "Command", "type": "string", "fillWidth": true},
{"plaintext": "Description", "type": "string", "fillWidth": true}
];
let rows = [];
for(let i = 0; i < collection.length; i++){
rows.push({
"DL": {"button":{
"name": "",
"type": "task",
"ui_feature": "forge:download",
"hoverText": collection[i]["downloadable"] ? "Re-download latest from GitHub and register command" : "No url associated with this source, so it can't be re downloaded",
"startIcon": "download",
"disabled": !collection[i]["downloadable"],
"startIconColor": "green",
"parameters": {"collectionName": collection[i]["collection_name"], "commandName": collection[i]["name"]}
}},
"Reg": {"button": {
"name": "",
"type": "task",
"ui_feature": "forge:register",
"hoverText": collection[i]["registered"] ? "Remove Command": "Register command",
"startIcon": collection[i]["registered"] ? "kill": "list",
"startIconColor": collection[i]["registered"] ? "red": "",
"parameters": {"collectionName": collection[i]["collection_name"], "commandName": collection[i]["name"], "remove": collection[i]["registered"]}
}},
"Name": {"plaintext": collection[i]["name"]},
"Command": {"plaintext": collection[i]["command_name"]},
"Description": {"plaintext": collection[i]["description"]}
});
}
return {"table": [{
"headers": headers,
"rows": rows
}]}
}catch(error){
console.log(error)
return {"plaintext": responses.join("\n")};
}
}
+39
View File
@@ -0,0 +1,39 @@
module community_collections
go 1.23.4
replace github.com/MythicMeta/MythicContainer => ../../../../MythicMeta/MythicContainer
require github.com/MythicMeta/MythicContainer v1.4.13
require (
github.com/fsnotify/fsnotify v1.8.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/magiconair/properties v1.8.9 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
github.com/rabbitmq/amqp091-go v1.10.0 // indirect
github.com/rs/zerolog v1.33.0 // indirect
github.com/sagikazarmark/locafero v0.7.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.12.0 // indirect
github.com/spf13/cast v1.7.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.19.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c // indirect
golang.org/x/net v0.34.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/text v0.21.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287 // indirect
google.golang.org/grpc v1.70.0 // indirect
google.golang.org/protobuf v1.36.4 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
+106
View File
@@ -0,0 +1,106 @@
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM=
github.com/magiconair/properties v1.8.9/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw=
github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo=
github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k=
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs=
github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4=
github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U=
go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg=
go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M=
go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8=
go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4=
go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU=
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM=
go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c h1:KL/ZBHXgKGVmuZBZ01Lt57yE5ws8ZPSkkihmEyq7FXc=
golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU=
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287 h1:J1H9f+LEdWAfHcez/4cvaVBox7cOYT+IU6rgqj5x++8=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk=
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+22
View File
@@ -0,0 +1,22 @@
package main
import (
"community_collections/forge/agentfunctions"
"github.com/MythicMeta/MythicContainer"
"github.com/MythicMeta/MythicContainer/logging"
"os"
)
func main() {
agentfunctions.Initialize()
if len(os.Args) > 1 {
if os.Args[1] == "download" {
logging.UpdateLogToStdout("debug")
agentfunctions.DownloadEverything()
return
}
}
MythicContainer.StartAndRunForever([]MythicContainer.MythicServices{
MythicContainer.MythicServicePayload,
})
}
@@ -0,0 +1,15 @@
[
{
"agent": "apollo",
"bof_command": "execute_coff",
"bof_file_parameter_name": "bof_file",
"bof_argument_array_parameter_name": "coff_arguments",
"bof_entrypoint_parameter_name": "function_name",
"inline_assembly_command": "inline_assembly",
"inline_assembly_file_parameter_name": "assembly_file",
"inline_assembly_argument_parameter_name": "assembly_arguments",
"execute_assembly_command": "execute_assembly",
"execute_assembly_file_parameter_name": "assembly_file",
"execute_assembly_argument_parameter_name": "assembly_arguments"
}
]
+39
View File
@@ -0,0 +1,39 @@
# Forge
<p align="center">
<img alt="Forge Logo" src="agent_icons/forge.svg" height="30%" width="30%">
</p>
Forge is a "Command Augmentation" Payload Type for Mythic that brings in @Flangvik's [SharpCollection](https://github.com/Flangvik/SharpCollection) and Sliver's [Armory](https://github.com/sliverarmory/armory/blob/master/armory.json).
Forge itself doesn't build and isn't deployed to a target host; instead, it provides "alias" type commands for BOF execution and .NET execution that are then passed to another Payload Type's commands.
For example, a `forge_net_Rubeus` command might get passed to Apollo's `execute_assembly` command for execution.
Forge comes preconfigured for `Apollo`, but new agent support can always be added on the fly with the `forge_support` command (only needs to happen once per Mythic instance) or by modifying the `payload_type_support.json` file on disk and restarting the container.
## Forge's Icon
poseidon's icon made by Iconic Panda from [flaticon.com](https://www.flaticon.com/free-icons/forge)
## How to install an agent in this format within Mythic
When it's time for you to test out your install or for another user to install your agent, it's pretty simple. Within Mythic you can run the `mythic-cli` binary to install this in one of three ways:
* `sudo ./mythic-cli install github https://github.com/user/repo` to install the main branch
* `sudo ./mythic-cli install github https://github.com/user/repo branchname` to install a specific branch of that repo
* `sudo ./mythic-cli install folder /path/to/local/folder/cloned/from/github` to install from an already cloned down version of an agent repo
Now, you might be wondering _when_ should you or a user do this to properly add your agent to their Mythic instance. There's no wrong answer here, just depends on your preference. The three options are:
* Mythic is already up and going, then you can run the install script and just direct that agent's containers to start (i.e. `sudo ./mythic-cli start agentName` and if that agent has its own special C2 containers, you'll need to start them too via `sudo ./mythic-cli start c2profileName`).
* Mythic is already up and going, but you want to minimize your steps, you can just install the agent and run `sudo ./mythic-cli start`. That script will first _stop_ all of your containers, then start everything back up again. This will also bring in the new agent you just installed.
* Mythic isn't running, you can install the script and just run `sudo ./mythic-cli start`.
## Documentation
The Poseidon documentation source code can be found in the `documenation-payload/forge` directory.
View the rendered documentation by clicking on **Docs -> Agent Documentation** in the upper right-hand corner of the Mythic
interface.
## Building Outside of Mythic
If you want to build outside of Mythic, you can use the `Makefile` included in the project's `Payload_Type/forge` directory. You will need to modify the variables at the top of the Makefile to match the information for connecting to Mythic.
+14
View File
@@ -0,0 +1,14 @@
{
"os": ["Windows"],
"languages": ["go", ".net", "c++"] ,
"features": {
"mythic": [],
"custom": []
},
"payload_output": ["exe", "o"],
"architectures": ["x86_64"],
"c2": [],
"mythic_version": "3.3.0",
"agent_version": "0.0.1",
"supported_wrappers": []
}
+18
View File
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="128" height="128">
<path d="M0 0 C-0.3125 1.875 -0.3125 1.875 -1 4 C-1.99 4.66 -2.98 5.32 -4 6 C6.89 6 17.78 6 29 6 C27.35 5.01 25.7 4.02 24 3 C24 2.01 24 1.02 24 0 C27.02346601 -0.2519555 28.6402007 -0.20421041 31.3125 1.3125 C33 3 33 3 33 6 C33.85549438 6.03758423 33.85549438 6.03758423 34.72827148 6.07592773 C37.29826157 6.19156549 39.86785527 6.31443624 42.4375 6.4375 C43.33533203 6.47681641 44.23316406 6.51613281 45.15820312 6.55664062 C46.01220703 6.59853516 46.86621094 6.64042969 47.74609375 6.68359375 C48.53685303 6.72025146 49.3276123 6.75690918 50.14233398 6.79467773 C52 7 52 7 53 8 C53.14115161 10.67058851 53.04247107 13.32432238 53 16 C57.62 16 62.24 16 67 16 C67 22.6 67 29.2 67 36 C59 40 59 40 56.125 40.75 C53.85726768 41.78994425 53.85726768 41.78994425 53.25390625 43.8984375 C52.74201328 45.91070643 52.36272144 47.95557005 52 50 C48.04 50 44.08 50 40 50 C40 56.27 40 62.54 40 69 C42.6915625 68.9690625 42.6915625 68.9690625 45.4375 68.9375 C47.29166122 68.9161878 49.14712498 68.92773498 51 69 C52 70 52 70 52.1328125 72.6875 C52.13023438 73.780625 52.12765625 74.87375 52.125 76 C52.12886719 77.6396875 52.12886719 77.6396875 52.1328125 79.3125 C52 82 52 82 51 83 C48.97505769 83.09409479 46.9468013 83.11743122 44.91967773 83.11352539 C42.96776772 83.11341209 42.96776772 83.11341209 40.97642517 83.11329651 C39.54548098 83.10818909 38.11453718 83.10297308 36.68359375 83.09765625 C35.2277074 83.09579203 33.77182043 83.09436815 32.31593323 83.09336853 C28.47720621 83.08954365 24.63851681 83.07971364 20.79980469 83.06866455 C16.88542184 83.05844978 12.97103294 83.05387077 9.05664062 83.04882812 C1.37107657 83.03809134 -6.31445645 83.02101529 -14 83 C-14.02685938 80.85423363 -14.04633088 78.70837355 -14.0625 76.5625 C-14.07410156 75.36753906 -14.08570313 74.17257813 -14.09765625 72.94140625 C-14 70 -14 70 -13 69 C-9.3308423 68.85689713 -5.67284559 68.95778338 -2 69 C-2 62.73 -2 56.46 -2 50 C-5.96 50 -9.92 50 -14 50 C-14.061875 48.618125 -14.12375 47.23625 -14.1875 45.8125 C-14.5745171 43.26613088 -14.5745171 43.26613088 -16 41 C-20.24349661 38.60173998 -24.28915445 37.43172757 -29 36 C-29 29.07 -29 22.14 -29 15 C-24.38 15 -19.76 15 -15 15 C-15 12.69 -15 10.38 -15 8 C-14.030625 7.7525 -13.06125 7.505 -12.0625 7.25 C-11.051875 6.8375 -10.04125 6.425 -9 6 C-8.33820153 4.01954441 -8.33820153 4.01954441 -8 2 C-5.06004981 -0.02755186 -3.72295997 0 0 0 Z " fill="#020202" transform="translate(40,45)"/>
<path d="M0 0 C19.8 0 39.6 0 60 0 C60 11.88 60 23.76 60 36 C40.2 36 20.4 36 0 36 C0 24.12 0 12.24 0 0 Z " fill="#7C8B91" transform="translate(29,55)"/>
<path d="M0 0 C1.44207941 2.88415883 1.09394887 5.41721528 1.0625 8.625 C1.05347656 9.81351563 1.04445313 11.00203125 1.03515625 12.2265625 C1.02355469 13.14179688 1.01195313 14.05703125 1 15 C1.60499329 14.99111755 2.20998657 14.98223511 2.83331299 14.9730835 C9.12722328 14.88462407 15.42095713 14.82427158 21.71533203 14.78027344 C24.06468884 14.76015186 26.41399554 14.73285149 28.76318359 14.69824219 C32.13912315 14.6497496 35.51440086 14.62703643 38.890625 14.609375 C39.94179504 14.58872986 40.99296509 14.56808472 42.07598877 14.54681396 C49.35677436 14.54457101 49.35677436 14.54457101 52.66333008 16.88574219 C54.19644077 19.31071727 54.51076642 20.64749405 54.4375 23.5 C54.43621094 24.2528125 54.43492188 25.005625 54.43359375 25.78125 C53.88211404 28.60323625 52.96959605 29.91024345 51 32 C48.74104309 32.48101807 48.74104309 32.48101807 46.06958008 32.45410156 C45.06876907 32.45379944 44.06795807 32.45349731 43.03681946 32.45318604 C41.95861435 32.43254089 40.88040924 32.41189575 39.76953125 32.390625 C38.66397385 32.38496521 37.55841644 32.37930542 36.4193573 32.37347412 C32.88330036 32.35105795 29.34825141 32.30084996 25.8125 32.25 C23.41733233 32.22994187 21.02214879 32.21168991 18.62695312 32.1953125 C12.75095733 32.151176 6.87555067 32.08421128 1 32 C1.02320312 32.91523437 1.04640625 33.83046875 1.0703125 34.7734375 C1.09738281 36.55621094 1.09738281 36.55621094 1.125 38.375 C1.14820312 39.55835938 1.17140625 40.74171875 1.1953125 41.9609375 C1 45 1 45 -1 47 C-3.03125 47.25878906 -3.03125 47.25878906 -5.5 47.265625 C-6.386875 47.26820312 -7.27375 47.27078125 -8.1875 47.2734375 C-9.115625 47.26570313 -10.04375 47.25796875 -11 47.25 C-11.928125 47.25773437 -12.85625 47.26546875 -13.8125 47.2734375 C-15.1428125 47.26957031 -15.1428125 47.26957031 -16.5 47.265625 C-17.3146875 47.26336914 -18.129375 47.26111328 -18.96875 47.25878906 C-21 47 -21 47 -23 45 C-25.09387008 33.30735764 -25.34755157 19.90811384 -18.83422852 9.66796875 C-18.27018311 8.89066406 -17.7061377 8.11335937 -17.125 7.3125 C-16.5899585 6.5596875 -16.05491699 5.806875 -15.50366211 5.03125 C-10.94749479 -0.49826532 -6.92953813 -0.91968788 0 0 Z " fill="#040200" transform="translate(63,0)"/>
<path d="M0 0 C0.02464705 5.67830078 0.04283462 11.35657069 0.05493164 17.03491211 C0.05997256 18.96818585 0.06680519 20.90145576 0.07543945 22.8347168 C0.08751565 25.60726872 0.09323057 28.37977041 0.09765625 31.15234375 C0.10281754 32.02213364 0.10797882 32.89192352 0.11329651 33.78807068 C0.11349185 35.85905814 0.06208168 37.92994324 0 40 C-1 41 -1 41 -4.59765625 41.09765625 C-6.08596867 41.0909822 -7.57426432 41.07902183 -9.0625 41.0625 C-10.20041992 41.05573242 -10.20041992 41.05573242 -11.36132812 41.04882812 C-13.24091871 41.0370068 -15.12046899 41.01907078 -17 41 C-19.09351772 15.23070009 -19.09351772 15.23070009 -10.44018555 4.01538086 C-7.03773786 0.14252227 -4.97569198 -0.2616967 0 0 Z " fill="#7E572A" transform="translate(61,3)"/>
<path d="M0 0 C11.88 0 23.76 0 36 0 C36 4.29 36 8.58 36 13 C24.12 13 12.24 13 0 13 C0 8.71 0 4.42 0 0 Z " fill="#495053" transform="translate(41,101)"/>
<path d="M0 0 C19.14 0 38.28 0 58 0 C58 2.64 58 5.28 58 8 C38.86 8 19.72 8 0 8 C0 5.36 0 2.72 0 0 Z " fill="#5F7C8A" transform="translate(30,117)"/>
<path d="M0 0 C11.55 0 23.1 0 35 0 C35 3.63 35 7.26 35 11 C23.45 11 11.9 11 0 11 C0 7.37 0 3.74 0 0 Z " fill="#FA9401" transform="translate(64,18)"/>
<path d="M0 0 C3.96 0 7.92 0 12 0 C12 6.27 12 12.54 12 19 C7.39942914 18.07988583 4.20327441 16.89559434 0 15 C0 10.05 0 5.1 0 0 Z " fill="#5E7A88" transform="translate(14,63)"/>
<path d="M0 0 C3.96 0 7.92 0 12 0 C12 4.95 12 9.9 12 15 C2.25 19 2.25 19 0 19 C0 12.73 0 6.46 0 0 Z " fill="#5F7B89" transform="translate(92,64)"/>
<path d="M0 0 C11.88 0 23.76 0 36 0 C36 1.65 36 3.3 36 5 C24.12 5 12.24 5 0 5 C0 3.35 0 1.7 0 0 Z " fill="#676E70" transform="translate(41,94)"/>
<path d="M0 0 C17.16 0 34.32 0 52 0 C52 0.66 52 1.32 52 2 C35.83 2 19.66 2 3 2 C3 10.25 3 18.5 3 27 C2.01 26.67 1.02 26.34 0 26 C0 17.42 0 8.84 0 0 Z " fill="#030404" transform="translate(33,60)"/>
<path d="M0 0 C1.423125 -0.061875 2.84625 -0.12375 4.3125 -0.1875 C5.51326172 -0.23970703 5.51326172 -0.23970703 6.73828125 -0.29296875 C9 0 9 0 10.80859375 1.28515625 C12 3 12 3 11.75 6.625 C11 10 11 10 10 11 C6.66381769 11.14257189 3.34024394 11.04228157 0 11 C0 7.37 0 3.74 0 0 Z " fill="#F6AD43" transform="translate(102,18)"/>
<path d="M0 0 C0.99 0 1.98 0 3 0 C3 4.95 3 9.9 3 15 C2.01 15.33 1.02 15.66 0 16 C0 10.72 0 5.44 0 0 Z " fill="#140D06" transform="translate(47,24)"/>
<path d="M0 0 C2.97 0 5.94 0 9 0 C9 1.32 9 2.64 9 4 C6.03 4 3.06 4 0 4 C0 2.68 0 1.36 0 0 Z " fill="#000000" transform="translate(66,40)"/>
<path d="M0 0 C2.64 0 5.28 0 8 0 C8 1.32 8 2.64 8 4 C5.03 4 2.06 4 -1 4 C-0.67 2.68 -0.34 1.36 0 0 Z " fill="#000000" transform="translate(30,40)"/>
</svg>

After

Width:  |  Height:  |  Size: 7.4 KiB

+7
View File
@@ -0,0 +1,7 @@
{
"exclude_payload_type": false,
"exclude_c2_profiles": false,
"exclude_documentation_payload": false,
"exclude_documentation_c2": false,
"exclude_agent_icons": false
}
+140
View File
@@ -0,0 +1,140 @@
+++
title = "forge"
chapter = false
weight = 5
+++
![logo](/agents/forge/forge.svg?width=200px)
## Summary
Forge is a "Command Augmentation" payload type that provides a few functions for downloading/creating BOF/.NET commands as new, tab-completable commands within a variety of other payload type's callbacks.
Forge itself can't be "built"; instead, it offers Mythic-side commands that can then be passed down to various callbacks for execution.
These forge commands are automatically injected into all Windows callbacks based on payload types listed in the [payload_type_support.json](#payload_type_support.json) file (more on that further down).
Forge offers three kinds of execution for supported payload types:
* BOF
* Execute Assembly
* Inline Assembly
The forge container comes with @Flangvik's [SharpCollection](https://github.com/Flangvik/SharpCollection) and Sliver's [Armory](https://github.com/sliverarmory/armory/blob/master/armory.json) installed.
## Supporting Files
### payload_type_support.json
This file identifies which payload types are supported and how to pass execution from forge to them.
This takes the following format:
```json
[
{
"agent": "apollo",
"bof_command": "execute_coff",
"bof_file_parameter_name": "bof_file",
"bof_argument_array_parameter_name": "coff_arguments",
"bof_entrypoint_parameter_name": "function_name",
"inline_assembly_command": "inline_assembly",
"inline_assembly_file_parameter_name": "assembly_file",
"inline_assembly_argument_parameter_name": "assembly_arguments",
"execute_assembly_command": "execute_assembly",
"execute_assembly_file_parameter_name": "assembly_file",
"execute_assembly_argument_parameter_name": "assembly_arguments"
}
]
```
This is an array of entries, one for each agent that's supported. If you want to add your agent as a supported agent, then just modify this file to add your own entry to the list. Then run the following commands:
```bash
sudo ./mythic-cli build forge
```
This file allows you to indicate, for each supported payload type, what parameter names things should get passed down as.
#### bof
BOF commands created as part of Forge are first-order commands within supported callbacks. For example, if the bof is "sa-netgroup", then the corresponding command that will be registered is `forge_bof_sa-netgroup`.
This allows you to easily group `forge*` commands together and identify if a command is a BOF or .NET executable. If this BOF takes two arguments, `group` and `server`, then they'll be exposed to the operator like
`forge_bof_sa-netgroup -server 127.0.0.1 -group Administrators`. You don't need to worry about the order or types of values, that'll be handled for you based on the backing bof's `extension.json` file (the same as the SliverArmory format).
This command then needs to be passed down to your callback for your payload type to actually execute the BOF. There are four fields that help identify how this works in your payload_type_support.json:
* "bof_command": "execute_coff"
* which command in your agent should we pass control to. Control goes right to that command's `create_go_tasking` function and continues from there like normal.
* "bof_file_parameter_name": "bof_file"
* every bof is backed by a file, this is identifying the name of your BOF command's parameter that expects the file. The value passed to this parameter is the file's UUID (just like if it was type File)
* "bof_argument_array_parameter_name": "coff_arguments"
* in Mythic, the ideal way to handle a BOF's arguments is with a parameter type of TypedArray. This allows us to specify the type of data (int, short, widestring, string, etc) in addition to the data itself in a standard format. Data will be passed along in this stnadard format with standard BOF notations.
* For example: `[ ["i", 5], ["Z", "Administrator"] ]`. Your command's typed array parser will get called with this data.
* "bof_entrypoint_parameter_name": "function_name"
* BOFs identy the entrypoint for the program. The vast majority of the time this is `go`, but doesn't technically have to be. This is passed into your payload type's command and fetched from this BOF's backing `extension.json` file.
#### net
.NET commands created as part of Forge are first-order commands within supported callbacks. For example, if the .NET is "Rubeus", then the corresponding command that will be registered is `forge_net_Rubeus`.
This allows you to easily group `forge*` commands together and identify if a command is a BOF or .NET executable. Due to the nature of how assemblies are largely used within the offensive community,
these new commands take in a few specific parameters:
* args
* this is the entire args string that's passed to the assembly. We can't easily break this up into named parameters because most assemblies just expect a single string as if they were run on the command line.
* version
* this is the version of the assembly you want to execute. This defaults to `4.7_Any`, but you can set it to any of the versions associated with @Flangvik's SharpCollection repository.
* execution
* This identifies the execution method you want to use with the assembly - execute_assembly (fork-and-run) or inline_assembly (inside your process)
### collection_sources.json
This file identifies all the collections that are available along with what kind of commands they are. The initial file looks like this:
```json
[
{
"name": "SharpCollection",
"type": "assembly"
},
{
"name": "SliverArmory",
"type": "bof"
}
]
```
This tells forge that there's two collections; `SharpCollection` which has `assembly` commands and `SliverArmory` which has `bof` commands.
Forge processes this file and then looks for their associated sources files, `SharpCollection_sources.json` and `SliverArmory_sources.json` files respectively.
### *_sources.json
This file outlines the original sources of all the commands that are available under a specific collection. This is an array of entries, where each one has the following fields:
```json
{
"name": "Nano Dump",
"command_name": "nanodump",
"description": "",
"repo_url": "https://github.com/sliverarmory/nanodump",
"custom_download_url": "",
"custom_version": ""
}
```
* "name":
* This is the name of the command overall (see this with `forge_community` command)
* "command_name":
* This is the name of the command that gets added to `forge_bof_` or `forge_net_`
* "description":
* This is the description of the command and is displayed in the modal UI and help
* "repo_url":
* assemblies
* This points to a SharpCollection-like repository for assemblies
* bof
* repo that has a tagged release with a command.tar.gz file that contains the extension.json and .o files
* "custom_download_url":
* This can be the url of a specific file to download instead of using the SharpCollection or SliverArmory release formats
* assemblies
* This points to the specific download url of the .exe file
* bof
* This points to a specific download url of the command.tar.gz file with the extension.json and .o files
* "custom_version":
* This can be used to specify a custom version to associate with a .NET execution instead of using one of the versions associated with SharpCollection's formats
## Authors
- @its_a_feature_
@@ -0,0 +1,6 @@
+++
title = "Commands"
chapter = true
weight = 15
pre = "<b>2. </b>"
+++
@@ -0,0 +1,34 @@
+++
title = "forge_collections"
chapter = false
weight = 100
hidden = false
+++
## Summary
List out the available commands for a given collections source. The resulting table in the UI will show if a command is already registered or not and give an option to unregister the command.
- Needs Admin: False
- Version: 1
- Author: @its_a_feature_
### Arguments
#### collectionName
- Description: the name of the collection to query
- Required Value: True
- Default Value: None
## Usage
```
forge_collections -collectionName SharpCollection
```
## MITRE ATT&CK Mapping
## Detailed Summary
For a given collection, X, this reads the `X_sources.json` file to populate the data in the UI.
@@ -0,0 +1,68 @@
+++
title = "forge_create"
chapter = false
weight = 103
hidden = false
+++
## Summary
Create an entirely new command by uploading your own BOFs, extension.json, or .NET files. This can be as part of a new "collection" or an existing one.
If there's something in a collection's source of available commands already, you can simply register or download it for use within your callbacks.
This is specifically for uploading your own local data.
- Needs Admin: False
- Version: 1
- Author: @its_a_feature_
### Arguments
#### collectionName
- Description: The name of the collection that this command belongs to
- Required Value: True
- Default Value:
#### commandName
- Description: The name of the command to register
- Required Value: True
- Default Value:
#### description
- Description: The description of the command
- Required Value: False
- Default Value:
#### commandFileAssembly
- Description: If creating an assembly command, this is the actual exe to run
- Required Value: True
- Default Value:
#### commandVersion
- Description: If creating an assembly command, this is the .net version of the exe
- Required Value: True
- Default Value:
#### commandFilesBof
- Description: If creating a bof command, these are all the .o files to use
- Required Value: True
- Default Value:
#### extensionFile
- Description: If creating a bof command, this is the extension.json file that describes the bof arguments
- Required Value: True
- Default Value:
## Usage
```
forge_create
```
## Detailed Summary
@@ -0,0 +1,38 @@
+++
title = "forge_download"
chapter = false
weight = 101
hidden = false
+++
## Summary
Download the necessary files for a specific command from a specific collection and register that command in this and all supported callbacks.
- Needs Admin: False
- Version: 1
- Author: @its_a_feature_
### Arguments
#### collectionName
- Description: The name of the collection where this command exists
- Required Value: True
- Default Value: None
#### commandName
- Description: The name of the command
- Required Value: True
- Default Value: None
## Usage
```
forge_download -collectionName SharpCollection -commandName Rubeus
```
## MITRE ATT&CK Mapping
## Detailed Summary
@@ -0,0 +1,46 @@
+++
title = "forge_register"
chapter = false
weight = 101
hidden = false
+++
## Summary
Register a command from a collection with the assumption that the backing .o and exe files already exist in the container.
If `remove` is specified, then remove that command from this callback and all callbacks.
- Needs Admin: False
- Version: 1
- Author: @its_a_feature_
### Arguments
#### collectionName
- Description: The name of the collection that contains this command
- Required Value: True
- Default Value: None
#### commandName
- Description: The name of the specific command to register
- Required Value: True
- Default Value: None
#### remove
- Description: If the command is already registered, remove it from this callback and all callbacks
- Required Value: False
- Default Value: False
## Usage
```
forge_register -collectionName SharpCollection -commandName Rubeus
forge_register -collectionName SharpCollection -commandName Rubeus -remove
```
## MITRE ATT&CK Mapping
## Detailed Summary
@@ -0,0 +1,98 @@
+++
title = "forge_support"
chapter = false
weight = 101
hidden = false
+++
## Summary
Add, remove, or update support for a payload type for use with forge.
- Needs Admin: False
- Version: 1
- Author: @its_a_feature_
### Arguments
#### payload_type
- Description: Choose which payload type to modify support for
- Required Value: True
- Default Value: None
#### bof_command
- Description: Name of the bof command for this agent
- Required Value: True
- Default Value: None
#### bof_file_parameter_name
- Description: Name of the parameter that specifies the bof file UUID
- Required Value: True
- Default Value: None
#### bof_argument_array_parameter_name
- Description: Name of the parameter that specifies array of BOF arguments
- Required Value: True
- Default Value: None
#### bof_entrypoint_parameter_name
- Description: Name of the parameter that specifies the bof entrypoint function name
- Required Value: True
- Default Value: None
#### inline_assembly_command
- Description: Name of the command that runs assemblies inline
- Required Value: True
- Default Value: None
#### inline_assembly_file_parameter_name
- Description: Name of the parameter that specifies the assembly file UUID
- Required Value: True
- Default Value: None
#### inline_assembly_argument_parameter_name
- Description: Name of the parameter that specifies the assembly argument string
- Required Value: True
- Default Value: None
#### execute_assembly_command
- Description: Name of the command that runs assemblies in fork-and-run
- Required Value: True
- Default Value: None
#### execute_assembly_file_parameter_name
- Description: Name of the parameter that specifies the assembly file UUID
- Required Value: True
- Default Value: None
#### execute_assembly_argument_parameter_name
- Description: Name of the parameter that specifies the assembly argument string
- Required Value: True
- Default Value: None
#### remove_support
- Description: Remove this agent from the supported list
- Required Value: True
- Default Value: False
## Usage
```
forge_support
```
## MITRE ATT&CK Mapping
## Detailed Summary
@@ -0,0 +1,11 @@
+++
title = "Development"
chapter = false
weight = 20
pre = "<b>3. </b>"
+++
## Development Environment
For command development, please use golang v1.23+
+18
View File
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="128" height="128">
<path d="M0 0 C-0.3125 1.875 -0.3125 1.875 -1 4 C-1.99 4.66 -2.98 5.32 -4 6 C6.89 6 17.78 6 29 6 C27.35 5.01 25.7 4.02 24 3 C24 2.01 24 1.02 24 0 C27.02346601 -0.2519555 28.6402007 -0.20421041 31.3125 1.3125 C33 3 33 3 33 6 C33.85549438 6.03758423 33.85549438 6.03758423 34.72827148 6.07592773 C37.29826157 6.19156549 39.86785527 6.31443624 42.4375 6.4375 C43.33533203 6.47681641 44.23316406 6.51613281 45.15820312 6.55664062 C46.01220703 6.59853516 46.86621094 6.64042969 47.74609375 6.68359375 C48.53685303 6.72025146 49.3276123 6.75690918 50.14233398 6.79467773 C52 7 52 7 53 8 C53.14115161 10.67058851 53.04247107 13.32432238 53 16 C57.62 16 62.24 16 67 16 C67 22.6 67 29.2 67 36 C59 40 59 40 56.125 40.75 C53.85726768 41.78994425 53.85726768 41.78994425 53.25390625 43.8984375 C52.74201328 45.91070643 52.36272144 47.95557005 52 50 C48.04 50 44.08 50 40 50 C40 56.27 40 62.54 40 69 C42.6915625 68.9690625 42.6915625 68.9690625 45.4375 68.9375 C47.29166122 68.9161878 49.14712498 68.92773498 51 69 C52 70 52 70 52.1328125 72.6875 C52.13023438 73.780625 52.12765625 74.87375 52.125 76 C52.12886719 77.6396875 52.12886719 77.6396875 52.1328125 79.3125 C52 82 52 82 51 83 C48.97505769 83.09409479 46.9468013 83.11743122 44.91967773 83.11352539 C42.96776772 83.11341209 42.96776772 83.11341209 40.97642517 83.11329651 C39.54548098 83.10818909 38.11453718 83.10297308 36.68359375 83.09765625 C35.2277074 83.09579203 33.77182043 83.09436815 32.31593323 83.09336853 C28.47720621 83.08954365 24.63851681 83.07971364 20.79980469 83.06866455 C16.88542184 83.05844978 12.97103294 83.05387077 9.05664062 83.04882812 C1.37107657 83.03809134 -6.31445645 83.02101529 -14 83 C-14.02685938 80.85423363 -14.04633088 78.70837355 -14.0625 76.5625 C-14.07410156 75.36753906 -14.08570313 74.17257813 -14.09765625 72.94140625 C-14 70 -14 70 -13 69 C-9.3308423 68.85689713 -5.67284559 68.95778338 -2 69 C-2 62.73 -2 56.46 -2 50 C-5.96 50 -9.92 50 -14 50 C-14.061875 48.618125 -14.12375 47.23625 -14.1875 45.8125 C-14.5745171 43.26613088 -14.5745171 43.26613088 -16 41 C-20.24349661 38.60173998 -24.28915445 37.43172757 -29 36 C-29 29.07 -29 22.14 -29 15 C-24.38 15 -19.76 15 -15 15 C-15 12.69 -15 10.38 -15 8 C-14.030625 7.7525 -13.06125 7.505 -12.0625 7.25 C-11.051875 6.8375 -10.04125 6.425 -9 6 C-8.33820153 4.01954441 -8.33820153 4.01954441 -8 2 C-5.06004981 -0.02755186 -3.72295997 0 0 0 Z " fill="#020202" transform="translate(40,45)"/>
<path d="M0 0 C19.8 0 39.6 0 60 0 C60 11.88 60 23.76 60 36 C40.2 36 20.4 36 0 36 C0 24.12 0 12.24 0 0 Z " fill="#7C8B91" transform="translate(29,55)"/>
<path d="M0 0 C1.44207941 2.88415883 1.09394887 5.41721528 1.0625 8.625 C1.05347656 9.81351563 1.04445313 11.00203125 1.03515625 12.2265625 C1.02355469 13.14179688 1.01195313 14.05703125 1 15 C1.60499329 14.99111755 2.20998657 14.98223511 2.83331299 14.9730835 C9.12722328 14.88462407 15.42095713 14.82427158 21.71533203 14.78027344 C24.06468884 14.76015186 26.41399554 14.73285149 28.76318359 14.69824219 C32.13912315 14.6497496 35.51440086 14.62703643 38.890625 14.609375 C39.94179504 14.58872986 40.99296509 14.56808472 42.07598877 14.54681396 C49.35677436 14.54457101 49.35677436 14.54457101 52.66333008 16.88574219 C54.19644077 19.31071727 54.51076642 20.64749405 54.4375 23.5 C54.43621094 24.2528125 54.43492188 25.005625 54.43359375 25.78125 C53.88211404 28.60323625 52.96959605 29.91024345 51 32 C48.74104309 32.48101807 48.74104309 32.48101807 46.06958008 32.45410156 C45.06876907 32.45379944 44.06795807 32.45349731 43.03681946 32.45318604 C41.95861435 32.43254089 40.88040924 32.41189575 39.76953125 32.390625 C38.66397385 32.38496521 37.55841644 32.37930542 36.4193573 32.37347412 C32.88330036 32.35105795 29.34825141 32.30084996 25.8125 32.25 C23.41733233 32.22994187 21.02214879 32.21168991 18.62695312 32.1953125 C12.75095733 32.151176 6.87555067 32.08421128 1 32 C1.02320312 32.91523437 1.04640625 33.83046875 1.0703125 34.7734375 C1.09738281 36.55621094 1.09738281 36.55621094 1.125 38.375 C1.14820312 39.55835938 1.17140625 40.74171875 1.1953125 41.9609375 C1 45 1 45 -1 47 C-3.03125 47.25878906 -3.03125 47.25878906 -5.5 47.265625 C-6.386875 47.26820312 -7.27375 47.27078125 -8.1875 47.2734375 C-9.115625 47.26570313 -10.04375 47.25796875 -11 47.25 C-11.928125 47.25773437 -12.85625 47.26546875 -13.8125 47.2734375 C-15.1428125 47.26957031 -15.1428125 47.26957031 -16.5 47.265625 C-17.3146875 47.26336914 -18.129375 47.26111328 -18.96875 47.25878906 C-21 47 -21 47 -23 45 C-25.09387008 33.30735764 -25.34755157 19.90811384 -18.83422852 9.66796875 C-18.27018311 8.89066406 -17.7061377 8.11335937 -17.125 7.3125 C-16.5899585 6.5596875 -16.05491699 5.806875 -15.50366211 5.03125 C-10.94749479 -0.49826532 -6.92953813 -0.91968788 0 0 Z " fill="#040200" transform="translate(63,0)"/>
<path d="M0 0 C0.02464705 5.67830078 0.04283462 11.35657069 0.05493164 17.03491211 C0.05997256 18.96818585 0.06680519 20.90145576 0.07543945 22.8347168 C0.08751565 25.60726872 0.09323057 28.37977041 0.09765625 31.15234375 C0.10281754 32.02213364 0.10797882 32.89192352 0.11329651 33.78807068 C0.11349185 35.85905814 0.06208168 37.92994324 0 40 C-1 41 -1 41 -4.59765625 41.09765625 C-6.08596867 41.0909822 -7.57426432 41.07902183 -9.0625 41.0625 C-10.20041992 41.05573242 -10.20041992 41.05573242 -11.36132812 41.04882812 C-13.24091871 41.0370068 -15.12046899 41.01907078 -17 41 C-19.09351772 15.23070009 -19.09351772 15.23070009 -10.44018555 4.01538086 C-7.03773786 0.14252227 -4.97569198 -0.2616967 0 0 Z " fill="#7E572A" transform="translate(61,3)"/>
<path d="M0 0 C11.88 0 23.76 0 36 0 C36 4.29 36 8.58 36 13 C24.12 13 12.24 13 0 13 C0 8.71 0 4.42 0 0 Z " fill="#495053" transform="translate(41,101)"/>
<path d="M0 0 C19.14 0 38.28 0 58 0 C58 2.64 58 5.28 58 8 C38.86 8 19.72 8 0 8 C0 5.36 0 2.72 0 0 Z " fill="#5F7C8A" transform="translate(30,117)"/>
<path d="M0 0 C11.55 0 23.1 0 35 0 C35 3.63 35 7.26 35 11 C23.45 11 11.9 11 0 11 C0 7.37 0 3.74 0 0 Z " fill="#FA9401" transform="translate(64,18)"/>
<path d="M0 0 C3.96 0 7.92 0 12 0 C12 6.27 12 12.54 12 19 C7.39942914 18.07988583 4.20327441 16.89559434 0 15 C0 10.05 0 5.1 0 0 Z " fill="#5E7A88" transform="translate(14,63)"/>
<path d="M0 0 C3.96 0 7.92 0 12 0 C12 4.95 12 9.9 12 15 C2.25 19 2.25 19 0 19 C0 12.73 0 6.46 0 0 Z " fill="#5F7B89" transform="translate(92,64)"/>
<path d="M0 0 C11.88 0 23.76 0 36 0 C36 1.65 36 3.3 36 5 C24.12 5 12.24 5 0 5 C0 3.35 0 1.7 0 0 Z " fill="#676E70" transform="translate(41,94)"/>
<path d="M0 0 C17.16 0 34.32 0 52 0 C52 0.66 52 1.32 52 2 C35.83 2 19.66 2 3 2 C3 10.25 3 18.5 3 27 C2.01 26.67 1.02 26.34 0 26 C0 17.42 0 8.84 0 0 Z " fill="#030404" transform="translate(33,60)"/>
<path d="M0 0 C1.423125 -0.061875 2.84625 -0.12375 4.3125 -0.1875 C5.51326172 -0.23970703 5.51326172 -0.23970703 6.73828125 -0.29296875 C9 0 9 0 10.80859375 1.28515625 C12 3 12 3 11.75 6.625 C11 10 11 10 10 11 C6.66381769 11.14257189 3.34024394 11.04228157 0 11 C0 7.37 0 3.74 0 0 Z " fill="#F6AD43" transform="translate(102,18)"/>
<path d="M0 0 C0.99 0 1.98 0 3 0 C3 4.95 3 9.9 3 15 C2.01 15.33 1.02 15.66 0 16 C0 10.72 0 5.44 0 0 Z " fill="#140D06" transform="translate(47,24)"/>
<path d="M0 0 C2.97 0 5.94 0 9 0 C9 1.32 9 2.64 9 4 C6.03 4 3.06 4 0 4 C0 2.68 0 1.36 0 0 Z " fill="#000000" transform="translate(66,40)"/>
<path d="M0 0 C2.64 0 5.28 0 8 0 C8 1.32 8 2.64 8 4 C5.03 4 2.06 4 -1 4 C-0.67 2.68 -0.34 1.36 0 0 Z " fill="#000000" transform="translate(30,40)"/>
</svg>

After

Width:  |  Height:  |  Size: 7.4 KiB

+6
View File
@@ -0,0 +1,6 @@
+++
title = "OPSEC"
chapter = false
weight = 10
pre = "<b>1. </b>"
+++