CyberChef 11.2.0 on AWS User Guide
Overview
This guide covers launching and using the CyberChef 11.2.0 on Ubuntu 24.04 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg security operations tools listing on AWS Marketplace; you pick it as the software version when you subscribe and launch.
CyberChef, originally created by GCHQ, is known as "the Cyber Swiss Army Knife". It has more than 400 operations for analysts, incident responders and developers: Base64, hex, URL and character set encoding and decoding, hashes and checksums, AES, DES and other ciphers, Gzip, Bzip2, LZMA and Zip, regular expressions, extracting and defanging indicators such as URLs, IP addresses and domains, parsing X.509 certificates and network data, QR codes, OCR and much more. You chain operations into a recipe and CyberChef runs it as you type. Every operation runs in your browser: what you paste in is processed on the page and is never sent to the server.
Upstream CyberChef is a public web page with no login. The cloudimg image makes it a private tool for your team:
- HTTPS from the first boot. nginx serves CyberChef on port 443 with a certificate generated on your instance's first boot. Port 80 redirects to HTTPS.
- A password unique to your instance. HTTP Basic Auth is required for the user
admin. The password is generated on first boot and written to/root/cyberchef-credentials.txt(root only); nginx stores only a SHA-512 crypt hash of it. No password is baked into the image. - Fail closed. nginx refuses to start until first boot has generated the certificate and the password, so CyberChef is never served without a login.
- A Content Security Policy built for the page. The browser may run only the scripts served by your instance (plus the two small scripts inside the page, allowed by their hashes) and may not connect to any other site, so pasted data cannot be sent elsewhere by the page. Requests for host names the instance does not serve are dropped, only
GETandHEADare accepted, cross site requests are refused, nginx is blocked from the instance metadata service and the AMI requires IMDSv2. - The official release, verified. The CyberChef 11.2.0 release bundle is checked against a pinned SHA-256 checksum before it is installed.
- Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.
What is on the image: CyberChef 11.2.0 (the official static release in /var/www/cyberchef, licence in /usr/share/doc/cyberchef), nginx, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent.
Default user: ubuntu · Architecture: x86_64 · Recommended instance type: m5.large
Prerequisites
- An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet with a route to the internet (or a private route you use for management).
- A security group that allows TCP 22 (SSH), TCP 443 (CyberChef) and TCP 80 (redirects to HTTPS) from your own networks only.
Step 1: Launch the instance
In the AWS Marketplace listing choose Continue to Subscribe, then Continue to Configuration, pick CyberChef 11.2.0 on Ubuntu 24.04 as the software version and your Region, then Launch through EC2. Choose m5.large (the server itself needs very little, because the work happens in your users' browsers), your key pair, and a security group as above.
With the AWS CLI (replace the values in angle brackets):
aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
--instance-type m5.large --key-name <your-key-pair> \
--security-group-ids <your-security-group> --subnet-id <your-subnet> \
--metadata-options HttpTokens=required,HttpEndpoint=enabled \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=cyberchef}]'
Step 2: Connect to your instance
| Version | SSH user |
|---|---|
| CyberChef 11.2.0 on Ubuntu 24.04 | ubuntu |
ssh -i <your-key.pem> ubuntu@<public-ip>
Step 3: Check the services
First boot generates the certificate and the password, then nginx starts:
systemctl is-active nginx cyberchef-firstboot
sudo test -f /var/lib/cloudimg/cyberchef-firstboot.done && echo FIRSTBOOT_DONE
Both units are active and the first boot marker is present:
active
active
FIRSTBOOT_DONE
Only SSH and nginx listen on the network (the local DNS resolver listens on loopback only):
sudo ss -lntp | awk 'NR>1 {print $4, $6}' | sed -E 's/pid=[0-9]+,fd=[0-9]+/.../g' | sort
0.0.0.0:22 users:(("sshd",...),("systemd",...))
0.0.0.0:443 users:(("nginx",...),("nginx",...),("nginx",...))
0.0.0.0:80 users:(("nginx",...),("nginx",...),("nginx",...))
127.0.0.53%lo:53 users:(("systemd-resolve",...))
127.0.0.54:53 users:(("systemd-resolve",...))
[::]:22 users:(("sshd",...),("systemd",...))
[::]:443 users:(("nginx",...),("nginx",...),("nginx",...))
[::]:80 users:(("nginx",...),("nginx",...),("nginx",...))
Step 4: Get your URL and password
sudo cat /root/cyberchef-credentials.txt
The file is readable by root only and holds the URL, the user name and this instance's password:
CYBERCHEF_URL=https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/
CYBERCHEF_USERNAME=admin
CYBERCHEF_PASSWORD=<CYBERCHEF_PASSWORD>
The URL uses the instance's public DNS name from EC2 instance metadata. The certificate also names the public and private IP addresses, so https://<public-ip>/ works too. To serve CyberChef under your own DNS name, see Step 8.
Step 5: Sign in from your browser
Open the CYBERCHEF_URL in your browser. The certificate is self signed, so your browser asks you to confirm it the first time (or install your own certificate, Step 8). Sign in as admin with the password from Step 4; the browser remembers the login for the session.
CyberChef has four areas: the Operations list on the left (search it, or open a category such as Encryption / Encoding, Public Key, Networking or Data format), the Recipe you build by dragging operations into it, the Input pane and the Output pane. With Auto Bake ticked the output updates as you type. Here From Base64 decodes a Base64 string:

Step 6: Use CyberChef
Extract and defang indicators. Paste a suspicious email or log excerpt, then chain Extract URLs and Defang URL. CyberChef pulls out every link and rewrites it (hxxps[://]...[.]com) so it can be pasted into a ticket or a chat without becoming clickable. Extract IP addresses, Extract domains and Extract email addresses work the same way:

Hashes and checksums. Add SHA2 (size 256) and type into the Input pane; the digest is computed in your browser. Here the SHA-256 of hello is 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824, as expected. MD5, SHA1, SHA3, BLAKE2, CRC, HMAC and many others are in the Hashing category:

Encryption. AES Encrypt and AES Decrypt take a key and IV in hex, UTF-8, Latin1 or Base64, and support CBC, CTR, GCM, ECB and other modes. DES, Triple DES, Blowfish, RC4 and ChaCha are next to them:

Use the save icon above the recipe to store a recipe in your browser, or copy the page address: CyberChef keeps the recipe and input in the URL, so you can bookmark a recipe or share it with a colleague (they sign in with the same password, or their own, Step 9).
Step 7: Check the security posture from the command line
Without a login CyberChef is refused, port 80 redirects to HTTPS, the health check stays open for load balancers, and a request for a host name the instance does not serve is dropped without an answer:
H=$(sudo grep '^CYBERCHEF_URL=' /root/cyberchef-credentials.txt | sed -E 's#^CYBERCHEF_URL=https://([^/]+)/.*#\1#')
curl -s -o /dev/null -w 'http:// -> %{http_code} %{redirect_url}\n' --resolve "$H:80:127.0.0.1" "http://$H/"
curl -sk -o /dev/null -w 'no login -> HTTP %{http_code}\n' --resolve "$H:443:127.0.0.1" "https://$H/"
curl -sk -o /dev/null -w 'health -> HTTP %{http_code}\n' --resolve "$H:443:127.0.0.1" "https://$H/healthz"
curl -sk -o /dev/null -w 'unknown host -> %{http_code}\n' --resolve "evil.example:443:127.0.0.1" "https://evil.example/" || true
http:// -> 301 https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/
no login -> HTTP 401
health -> HTTP 200
unknown host -> 000
000 means nginx closed the connection without answering, which is how it treats any host name it does not serve.
With the password, CyberChef is served, together with its Content Security Policy. The password is passed to curl on standard input, so it never appears in the process list or your shell history:
sudo bash -c '
F=/root/cyberchef-credentials.txt
P=$(grep "^CYBERCHEF_PASSWORD=" $F | cut -d= -f2-)
H=$(grep "^CYBERCHEF_URL=" $F | sed -E "s#^CYBERCHEF_URL=https://([^/]+)/.*#\1#")
auth() { printf "user = \"admin:%s\"\n" "$P"; }
auth | curl -K - -sk --resolve "$H:443:127.0.0.1" -o /dev/null -w "with login -> HTTP %{http_code}\n" "https://$H/"
auth | curl -K - -sk --compressed --resolve "$H:443:127.0.0.1" "https://$H/" | grep -o "<title>[^<]*</title>"
auth | curl -K - -sk --resolve "$H:443:127.0.0.1" -o /dev/null -D - "https://$H/" | tr -d "\r" | grep -i "^content-security-policy:" | tr ";" "\n" | sed "s/^ *//" | grep -E "^(content-security-policy: default-src|script-src|connect-src|object-src|frame-ancestors)" | sed -E "s/sha256-[A-Za-z0-9+\/=]+/sha256-.../g"
'
with login -> HTTP 200
<title>CyberChef</title>
content-security-policy: default-src 'self'
script-src 'self' 'sha256-...' 'sha256-...' 'unsafe-eval' 'wasm-unsafe-eval'
connect-src 'self' data: blob:
object-src 'none'
frame-ancestors 'none'
script-src allows only scripts from your instance and the two inline scripts of the CyberChef page (by their SHA-256 hashes). 'unsafe-eval' and 'wasm-unsafe-eval' are needed by operations such as Bzip2, Argon2 and OCR, whose libraries generate code or run WebAssembly in the browser. connect-src 'self' stops the page from sending anything to another site; this also means the HTTP request operation can only reach your own instance. CyberChef shows a small animation while a long operation runs; plugins are disabled by the policy, so that animation is not shown, and nothing else changes.
nginx keeps only a SHA-512 crypt hash of the password; the plain text is in the root only credentials file:
sudo sed -E 's/^(admin:\$6\$).*/\1<sha512-crypt-hash>/' /etc/nginx/.cyberchef-htpasswd
sudo stat -c '%a %U:%G %n' /etc/nginx/.cyberchef-htpasswd /root/cyberchef-credentials.txt
admin:$6$<sha512-crypt-hash>
640 root:www-data /etc/nginx/.cyberchef-htpasswd
600 root:root /root/cyberchef-credentials.txt
The certificate was generated on this instance and names its own addresses:
H=$(sudo grep '^CYBERCHEF_URL=' /root/cyberchef-credentials.txt | sed -E 's#^CYBERCHEF_URL=https://([^/]+)/.*#\1#')
echo | openssl s_client -connect 127.0.0.1:443 -servername "$H" 2>/dev/null | openssl x509 -noout -subject -ext subjectAltName
subject=CN = ec2-<public-ip-dashed>.<region>.compute.amazonaws.com, O = cloudimg
X509v3 Subject Alternative Name:
DNS:ec2-<public-ip-dashed>.<region>.compute.amazonaws.com, IP Address:<public-ip>, IP Address:<private-ip>, IP Address:127.0.0.1, DNS:localhost
nginx cannot reach the instance metadata service, and it will not start until first boot has finished and a per instance password is in place:
systemctl show nginx -p IPAddressDeny | grep 169.254.169.254
systemctl cat nginx | grep -E '^ExecStartPre=/usr/(bin/test|local/sbin)'
IPAddressDeny=fd00:ec2::254/128 169.254.169.254/32 168.63.129.16/32
ExecStartPre=/usr/bin/test -f /var/lib/cloudimg/cyberchef-firstboot.done
ExecStartPre=/usr/local/sbin/cyberchef-auth-guard
nginx also refuses a request whose Origin is another web site (HTTP 403), because browsers resend Basic Auth credentials on cross site requests:
H=$(sudo grep '^CYBERCHEF_URL=' /root/cyberchef-credentials.txt | sed -E 's#^CYBERCHEF_URL=https://([^/]+)/.*#\1#')
curl -sk --resolve "$H:443:127.0.0.1" -H 'Origin: https://evil.example' -d x=1 "https://$H/" | grep -o '403 Forbidden' | head -1
403 Forbidden
Step 8: Your own DNS name and certificate
Point a DNS record at the instance, then set the name CyberChef is served as. This mints a new self signed certificate for the name, updates nginx and the URL in the credentials file, and keeps the name across reboots:
sudo cyberchef-set-hostname <your-domain>
To use a certificate from your own certificate authority instead, copy it over the generated pair and reload nginx (running cyberchef-set-hostname again replaces it with a self signed one):
sudo install -m 0644 <your-domain>.crt /etc/ssl/cyberchef/cyberchef.crt
sudo install -m 0600 <your-domain>.key /etc/ssl/cyberchef/cyberchef.key
sudo nginx -t && sudo systemctl reload nginx
Step 9: Change the password or add users
cyberchef-set-password manages the Basic Auth file. Run it with no arguments to generate a new random password for admin; it is written to /root/cyberchef-credentials.txt. To choose the password yourself, hand it over on standard input (printf is a shell builtin, so the password never appears in the process list; start the line with a space so most shells keep it out of your history):
printf '%s\n' '<new-password>' | sudo cyberchef-set-password --stdin
To give a colleague their own login, add --user <name>; remove it again with --delete <name>. Passwords are 12 to 128 printable characters without spaces or :. nginx reads the file on every request, so no reload is needed:
printf '%s\n' '<new-password>' | sudo cyberchef-set-password --user alice --stdin
sudo cyberchef-set-password --delete alice
Step 10: Server components
| Component | Path |
|---|---|
| CyberChef static release | /var/www/cyberchef |
| Licence and source note | /usr/share/doc/cyberchef/ |
| nginx site | /etc/nginx/sites-available/cloudimg-cyberchef |
| Content Security Policy | /etc/nginx/cyberchef-csp.conf (generated by cyberchef-csp) |
| Basic Auth file | /etc/nginx/.cyberchef-htpasswd (SHA-512 crypt) |
| Certificate and key | /etc/ssl/cyberchef/ |
| First boot script | /usr/local/sbin/cyberchef-firstboot.sh |
| Host name and password helpers | /usr/local/sbin/cyberchef-set-hostname, /usr/local/sbin/cyberchef-set-password |
| Credentials | /root/cyberchef-credentials.txt (mode 0600) |
ls -1 /var/www/cyberchef
du -sh /var/www/cyberchef
ls -l /usr/share/doc/cyberchef | awk 'NR>1{print $1,$5,$9}'
nginx -v 2>&1
ChefWorker.js.LICENSE.txt
CyberChef_v11.2.0.html
DishWorker.js.LICENSE.txt
InputWorker.js.LICENSE.txt
LoaderWorker.js.LICENSE.txt
ZipWorker.js.LICENSE.txt
assets
images
index.html
index.html.br
index.html.gz
modules
72M /var/www/cyberchef
-rw-r--r-- 11357 LICENSE
-rw-r--r-- 434 README.cloudimg.txt
nginx version: nginx/1.24.0 (Ubuntu)
Step 11: Updating CyberChef
CyberChef keeps no data on the server, so there is nothing to back up. To move to a newer release, download the official release zip from the CyberChef releases page, check its checksum, extract it into /var/www/cyberchef, copy its CyberChef_v<version>.html to index.html, then regenerate the Content Security Policy (the page's inline script hashes change with each release) and reload nginx:
sudo cyberchef-csp --write
sudo nginx -t && sudo systemctl reload nginx
Step 12: Security recommendations
- Allow ports 22, 80 and 443 in the security group from your own networks only.
- Keep the per instance password secret, rotate it if it may have been shared, and give each colleague their own login (Step 9).
- Use your own DNS name and a certificate your clients trust (Step 8).
- Keep the operating system patched; unattended security upgrades are on, and
sudo apt-get update && sudo apt-get upgradeapplies everything else.
Support and licensing
CyberChef is Crown Copyright and open source under the Apache License 2.0; there is no per user or per CPU licence fee. The licence is in /usr/share/doc/cyberchef/. cloudimg is not affiliated with or endorsed by GCHQ. The AMI price covers cloudimg's hardening, first boot setup and support.
- Email: support@cloudimg.co.uk
- Website: https://www.cloudimg.co.uk
- Support: 24/7, with a 24 hour response SLA