| # | Name | Time | Type | |
|---|---|---|---|---|
| 1 | "Saint John": what is writing to this log file? | 10 m | Fix No Registration |
"Saint John": what is writing to this log file?Scenario: "Saint John": what is writing to this log file? Level: Easy Type: Fix Access: Public Description: A developer created a testing program that is continuously writing to a log file /var/log/bad.log and filling up disk. You can check for example with tail -f /var/log/bad.log. Test: The log file size doesn't change (within a time interval bigger than the rate of change of the log file). Time to Solve: 10 minutes. |
| 2 | "Saskatoon": counting IPs. | 15 m | Do |
"Saskatoon": counting IPs.Scenario: "Saskatoon": counting IPs. Level: Easy Type: Do Access: Email Description: There's a web server access log file at /home/admin/access.log. The file consists of one line per HTTP request, with the requester's IP address at the beginning of each line (first column). Test: The SHA1 checksum of the IP address sha1sum /home/admin/highestip.txt is 6ef426c40652babc0d081d438b9f353709008e93 (just a way to verify the solution without giving it away, we also accept the right IP with no ending newline in the file.) Time to Solve: 15 minutes. |
| 3 | "The Command Line Murders" | 20 m | Do No Registration |
"The Command Line Murders"Scenario: "The Command Line Murders" Level: Easy Type: Do Access: Public Description: This is the Command Line Murders with a small twist as in the solution is different Test: md5sum ~/mysolution returns 9bba101c7369f49ca890ea96aa242dd5 Time to Solve: 20 minutes. |
| 4 | "Taipei": Come a-knocking | 15 m | Hack |
"Taipei": Come a-knockingScenario: "Taipei": Come a-knocking Level: Easy Type: Hack Access: Email Description: There is a web server on port :80 protected with Port Knocking. Find the one "knock" needed (sending a SYN to a single port, not a sequence) so you can curl localhost. Test: Executing curl localhost returns a message with md5sum fe474f8e1c29e9f412ed3b726369ab65. (Note: the resulting md5sum includes the new line terminator: echo $(curl localhost)) Time to Solve: 15 minutes. |
| 5 | "Resumable Server": Linux Upskill Challenge | 30 m | Do |
"Resumable Server": Linux Upskill ChallengeScenario: "Resumable Server": Linux Upskill Challenge Level: Easy Type: Do Access: Email Description: This is a Debian 11 server without a challenge; it's for you to do as you please. Test: None Time to Solve: 30 minutes. |
| 6 | "Lhasa": Easy Math | 15 m | Do |
"Lhasa": Easy MathScenario: "Lhasa": Easy Math Level: Easy Type: Do Access: Email Description: There's a file /home/admin/scores.txt with two columns (the first number is a line number and the second one is a test score for example). Test: md5sum /home/admin/solution returns 6d4832eb963012f6d8a71a60fac77168 solution Time to Solve: 15 minutes. |
| 7 | "Bucharest": Connecting to Postgres | 10 m | Fix |
"Bucharest": Connecting to PostgresScenario: "Bucharest": Connecting to Postgres Level: Easy Type: Fix Access: Email Description: A web application relies on the PostgreSQL 13 database present on this server. However, the connection to the database is not working. Your task is to identify and resolve the issue causing this connection failure. The application connects to a database named app1 with the user app1user and the password app1user. Test: Running PGPASSWORD=app1user psql -h 127.0.0.1 -d app1 -U app1user -c '\q' succeeds (does not return an error). Time to Solve: 10 minutes. |
| 8 | "Bilbao": Basic Kubernetes Problems | 10 m | Fix |
"Bilbao": Basic Kubernetes ProblemsScenario: "Bilbao": Basic Kubernetes Problems Level: Easy Type: Fix Access: Email Description: There's a Kubernetes Deployment with an Nginx pod and a Load Balancer declared in the manifest.yml file. The pod is not coming up. Fix it so that you can access the Nginx container through the Load Balancer. Test: Running curl 10.43.216.196 returns the default Nginx Welcome page. Time to Solve: 10 minutes. |
| 9 | "Apia": Needle in a Haystack | 20 m | Do Pro |
"Apia": Needle in a HaystackScenario: "Apia": Needle in a Haystack Level: Easy Type: Do Access: Paid Description: In a directory /home/admin/data, there are multiple files, all of them with same content. One of these files has been modified, a word was added. You need to identify which word it is and put it in the solution file (both newline terminated or not are accepted). Test: md5sum /home/admin/solution should return 55aba155290288b58e9b778c8f616560 or 2eeefea9fc4b16ea624bed5c67a49d80 Time to Solve: 20 minutes. |
| 10 | "Gitega": Find the Bad Git Commit | 15 m | Do Pro |
"Gitega": Find the Bad Git CommitScenario: "Gitega": Find the Bad Git Commit Level: Easy Type: Do Access: Paid Description: The directory at /home/admin/git has a Git repository with a Golang program and a test for it. Test: Doing md5sum /home/admin/solution returns f7db1bb6b7bfcd66a4eb66782804b39d. Time to Solve: 15 minutes. |
| 11 | "Minneapolis": Break a CSV file | 10 m | Do |
"Minneapolis": Break a CSV fileScenario: "Minneapolis": Break a CSV file Level: Easy Type: Do Access: Email Description: Break the Comma Separated Valued (CSV) file data.csv in the /home/admin/ directory into exactly 10 smaller files of about the same size named data-00.csv, data-01.csv, ... , data-09.csv files in the same directory. All the files should have the same header (first line with column names) as data.csv. None of the smaller files should be bigger than 32KB. Test: The "Check My Solution" button runs the script /home/admin/agent/check.sh, which you can see and execute. Time to Solve: 10 minutes. |
| 12 | "Saint Paul": Merge Many CSVs files | 15 m | Do |
"Saint Paul": Merge Many CSVs filesScenario: "Saint Paul": Merge Many CSVs files Level: Easy Type: Do Access: Email Description: Join (merge) all the 338 files in /home/admin/polldayregistrations_enregistjourduscrutin?????.csv into one single /home/admin/all.csv file with the contents of all the CSV files in any order. There should be only one line with the names of the columns as a header. Test: The "Check My Solution" button runs the script /home/admin/agent/check.sh, which you can see and execute. Time to Solve: 15 minutes. |
| 13 | "Bata": Find in /proc | 10 m | Do |
"Bata": Find in /procScenario: "Bata": Find in /proc Level: Easy Type: Do Access: Email Description: A spy has left a password in a file in /proc/sys . The contents of the file start with "secret:" (without the quotes). Test: Running md5sum /home/admin/secret.txt returns a7fcfd21da428dd7d4c5bb4c2e2207c4 Time to Solve: 10 minutes. |
| 14 | "Geneva": Renew an SSL Certificate | 10 m | Fix |
"Geneva": Renew an SSL CertificateScenario: "Geneva": Renew an SSL Certificate Level: Easy Type: Fix Access: Email Description: There's an Nginx web server running on this machine, configured to serve a simple "Hello, World!" page over HTTPS. However, the SSL certificate is expired. Test: Certificate should not be expired: echo | openssl s_client -connect localhost:443 2>/dev/null | openssl x509 -noout -dates and the subject of the certificate should be the same as the original one: echo | openssl s_client -connect localhost:443 2>/dev/null | openssl x509 -noout -subject Time to Solve: 10 minutes. |
| 15 | Linux Server Review - Guided Learning | 30 m | Do |
Linux Server Review - Guided LearningScenario: Linux Server Review - Guided Learning Level: Easy Type: Do Access: Email Description: This is a guided learning scenario. Follow this Linux Server Review Scenario Guide
Test: (there's no test) Time to Solve: 30 minutes. |
| 16 | "Tokamachi": Troubleshooting a Named Pipe | 15 m | Fix |
"Tokamachi": Troubleshooting a Named PipeScenario: "Tokamachi": Troubleshooting a Named Pipe Level: Easy Type: Fix Access: Email Description: There's a process reading from the named pipe /home/admin/namedpipe. Test: There should be a process running where a message is being sent to the pipe and that while that is running, another message can be sent to the pipe and read back. Time to Solve: 15 minutes. |
| 17 | "Yokohama": Linux Users Working Together | 15 m | Fix Pro |
"Yokohama": Linux Users Working TogetherScenario: "Yokohama": Linux Users Working Together Level: Easy Type: Fix Access: Paid Description: There are four Linux users working together in a project in this server: abe, betty, carlos, debora. Test: All users (abe, betty, carlos, debora) can write to their own files. None of them can write to another user's file. Time to Solve: 15 minutes. |
| 18 | "Fukuoka": Forbidden Association | 15 m | Fix Pro |
"Fukuoka": Forbidden AssociationScenario: "Fukuoka": Forbidden Association Level: Easy Type: Fix Access: Paid Description: There's a web server running on this host but curl localhost returns the default 404 Not Found page. Test: Running curl localhost should return HTTP 200 with the message Welcome to the Real Site!. Time to Solve: 15 minutes. |
| 19 | "Kampot": A New Port | 10 m | Do |
"Kampot": A New PortScenario: "Kampot": A New Port Level: Easy Type: Do Access: Email Description: A Python app serving simulated bank data runs as root and listens on port 20280. The app is managed by supervisor and cannot be stopped or reconfigured to use a different port. Test: curl localhost:80/accounts returns [{"id":1,"name":"Alice","type":"Checking"},{"id":2,"name":"Bob","type":"Savings"},{"id":3,"name":"Charlie","type":"Business"}] Time to Solve: 10 minutes. |
| 20 | "Rio de Janeiro": Do we have another option? | 15 m | Fix Pro |
"Rio de Janeiro": Do we have another option?Scenario: "Rio de Janeiro": Do we have another option? Level: Easy Type: Fix Access: Paid Description: This scenario server is dedicated to Jenkins, a Java application managed by systemd. Jenkins is failing to start. Troubleshoot and find the problem, then apply the solution so Jenkins runs properly. Test: The service must return the string "Sign in - Jenkins" amongst some other html code. You can check with the command curl -s localhost:8888/login | grep Jenkins | head -n1 Time to Solve: 15 minutes. |
| 21 | "Nuuk": More SSH Troubles | 10 m | Fix Pro |
"Nuuk": More SSH TroublesScenario: "Nuuk": More SSH Troubles Level: Easy Type: Fix Access: Paid Description: (NOTE: if you are a Pro user, you cannot SSH directly into this VM; click the "Open the Server Terminal" button to use the web browser instead). Test: You can ssh locally, i.e. ssh admin@127.0.0.1 works. Time to Solve: 10 minutes. |
| 22 | "Cairo": Time for a Timer | 15 m | Fix |
"Cairo": Time for a TimerScenario: "Cairo": Time for a Timer Level: Easy Type: Fix Access: Email Description: A critical health check script at /opt/scripts/health.sh is supposed to run every 10 seconds. This check is triggered by a systemd timer. Test: The /opt/scripts/health.sh script writes STATUS: OK to /var/log/health.log every 10 seconds. Time to Solve: 15 minutes. |
| 23 | "Alexandria": The Vanishing Backups | 5 m | Fix |
"Alexandria": The Vanishing BackupsScenario: "Alexandria": The Vanishing Backups Level: Easy Type: Fix Access: Email Description: A critical backup cron job has silently stopped working 3 days ago. The backup script is located at /opt/backup/backup.sh and should create daily backups in /var/backups/daily/, but no new backups have been created recently. Test: The solution will be validated by checking if a backup file has been created in the last 10 minutes. Time to Solve: 5 minutes. |
| 24 | "Kortenberg": Can't touch this! | 15 m | Fix Pro |
"Kortenberg": Can't touch this!Scenario: "Kortenberg": Can't touch this! Level: Easy Type: Fix Access: Paid Description: Is "All I want for Christmas is you" already everywhere?. A bit unrelated, someone messed up the permissions in this server, the admin user can't list new directories and can't write into new files. Fix the issue. Test: The admin user in a separate Bash login session should be able to create a new directory in your /home/admin directory, as well as being able to create a file into this new directory and add text into the new file. Time to Solve: 15 minutes. |
| 25 | "Hamburg": Find the AWS EC2 volume | 30 m | Do Pro |
"Hamburg": Find the AWS EC2 volumeScenario: "Hamburg": Find the AWS EC2 volume Level: Easy Type: Do Access: Paid Description: We have a lot of AWS EBS volumes, the description of which we have save to a file with: aws ec2 describe-volumes > aws-volumes.json. Test: Running md5sum /home/admin/mysolution returns e7e34463823bf7e39358bf6bb24336d8 (we also accept the file without a new line at the end). Time to Solve: 30 minutes. |
| # | Name | Time | Type | |
|---|---|---|---|---|
| 1 | "Manhattan": can't write data into database. | 20 m | Fix No Registration |
"Manhattan": can't write data into database.Scenario: "Manhattan": can't write data into database. Level: Medium Type: Fix Access: Public Description: Your objective is to be able to insert a row in an existing Postgres database. The issue is not specific to Postgres and you don't need to know details about it (although it may help). Test: (from default admin user) sudo -u postgres psql -c "insert into persons(name) values ('jane smith');" -d dt Time to Solve: 20 minutes. |
| 2 | "Tokyo": can't serve web file | 15 m | Fix |
"Tokyo": can't serve web fileScenario: "Tokyo": can't serve web file Level: Medium Type: Fix Access: Email Description: There's a web server serving a file /var/www/html/index.html with content "hello sadserver" but when we try to check it locally with an HTTP client like curl 127.0.0.1:80, nothing is returned. This scenario is not about the particular web server configuration and you only need to have general knowledge about how web servers work. Test: curl 127.0.0.1:80 should return: hello sadserver Time to Solve: 15 minutes. |
| 3 | "Cape Town": Borked Nginx | 15 m | Fix |
"Cape Town": Borked NginxScenario: "Cape Town": Borked Nginx Level: Medium Type: Fix Access: Email Description: There's an Nginx web server installed and managed by systemd. Running curl -I 127.0.0.1:80 returns curl: (7) Failed to connect to localhost port 80: Connection refused , fix it so when you curl you get the default Nginx page. Test: curl -Is 127.0.0.1:80|head -1 returns HTTP/1.1 200 OK Time to Solve: 15 minutes. |
| 4 | "Salta": Docker container won't start. | 15 m | Fix |
"Salta": Docker container won't start.Scenario: "Salta": Docker container won't start. Level: Medium Type: Fix Access: Email Description: There's a "dockerized" Node.js web application in the /home/admin/app directory. Create a Docker container so you get a web app on port :8888 and can curl to it. For the solution to be valid, there should be only one running Docker container. Test: curl localhost:8888 returns Hello World! from a running container. Time to Solve: 15 minutes. |
| 5 | "Venice": Am I in a container? | 15 m | Do |
"Venice": Am I in a container?Scenario: "Venice": Am I in a container? Level: Medium Type: Do Access: Email Description: Try and figure out if you are inside a container (like a Docker one for example) or inside a Virtual Machine (like in the other scenarios). Test: This scenario doesn't have a test (hence also no "Check My Solution" either). Time to Solve: 15 minutes. |
| 6 | "Oaxaca": Close an Open File | 15 m | Fix |
"Oaxaca": Close an Open FileScenario: "Oaxaca": Close an Open File Level: Medium Type: Fix Access: Email Description: The file /home/admin/somefile is open for writing by some process. Close this file without killing the process. Test: lsof /home/admin/somefile returns nothing. Time to Solve: 15 minutes. |
| 7 | "Melbourne": WSGI with Gunicorn | 20 m | Fix Pro |
"Melbourne": WSGI with GunicornScenario: "Melbourne": WSGI with Gunicorn Level: Medium Type: Fix Access: Paid Description: There is a Python WSGI web application file at /home/admin/wsgi.py , the purpose of which is to serve the string "Hello, world!". This file is served by a Gunicorn server which is fronted by an nginx server (both servers managed by systemd). So the flow of an HTTP request is: Web Client (curl) -> Nginx -> Gunicorn -> wsgi.py . The objective is to be able to curl the localhost (on default port :80) and get back "Hello, world!", using the current setup. Test: curl -s http://localhost returns Hello, world! (serving the wsgi.py file via Gunicorn and Nginx) Time to Solve: 20 minutes. |
| 8 | "Lisbon": etcd SSL cert troubles | 20 m | Fix |
"Lisbon": etcd SSL cert troublesScenario: "Lisbon": etcd SSL cert troubles Level: Medium Type: Fix Access: Email Description: There's an etcd server running on https://localhost:2379 , get the value for the key "foo", ie etcdctl get foo or curl https://localhost:2379/v2/keys/foo Test: etcdctl get foo returns bar. Time to Solve: 20 minutes. |
| 9 | "Kihei": Surely Not Another Disk Space Scenario | 30 m | Fix |
"Kihei": Surely Not Another Disk Space ScenarioScenario: "Kihei": Surely Not Another Disk Space Scenario Level: Medium Type: Fix Access: Email Description: There is a /home/admin/kihei program. Make the changes necessary so it runs succesfully, without deleting the /home/admin/datafile file. Test: Running /home/admin/kihei returns Done.. Time to Solve: 30 minutes. |
| 10 | "Unimak Island": Fun with Mr Jason | 15 m | Do Pro |
"Unimak Island": Fun with Mr JasonScenario: "Unimak Island": Fun with Mr Jason Level: Medium Type: Do Access: Paid Description: Using the file station_information.json , find the station_id where "has_kiosk" is false and "capacity" is greater than 30. Test: md5sum /home/admin/mysolution returns 8d8414808b15d55dad857fd5aeb2aebc Time to Solve: 15 minutes. |
| 11 | "Ivujivik": Parlez-vous Français? | 20 m | Do Pro |
"Ivujivik": Parlez-vous Français?Scenario: "Ivujivik": Parlez-vous Français? Level: Medium Type: Do Access: Paid Description: Given the CSV file /home/admin/table_tableau11.csv, find the Electoral District Name/Nom de circonscription that has the largest number of Rejected Ballots/Bulletins rejetés and also has a population of less than 100,000. Test: md5sum /home/admin/mysolution returns e399d171f21839a65f8f8ab55ed1e1a1 Time to Solve: 20 minutes. |
| 12 | "Paris": Where is my webserver? | 15 m | Hack |
"Paris": Where is my webserver?Scenario: "Paris": Where is my webserver? Level: Medium Type: Hack Access: Email Description: A developer put an important password on his webserver localhost:5000 . However, he can't find a way to recover it. This scenario is easy to to once you realize the one "trick". Test: md5sum ~/mysolution returns d8bee9d7f830d5fb59b89e1e120cce8e Time to Solve: 15 minutes. |
| 13 | "Buenos Aires": Kubernetes Pod Crashing | 20 m | Fix |
"Buenos Aires": Kubernetes Pod CrashingScenario: "Buenos Aires": Kubernetes Pod Crashing Level: Medium Type: Fix Access: Email Description: There are two pods: "logger" and "logshipper" living in the default namespace. Unfortunately, logshipper has an issue (crashlooping) and is forbidden to see what logger is trying to say. Could you help fix Logshipper? Test: kubectl get pods -l app=logshipper --no-headers -o json | jq -r '.items[] | "\(.status.containerStatuses[0].ready)"' returns true Time to Solve: 20 minutes. |
| 14 | "Tarifa": Between Two Seas | 20 m | Fix Pro |
"Tarifa": Between Two SeasScenario: "Tarifa": Between Two Seas Level: Medium Type: Fix Access: Paid Description: There are three Docker containers defined in the docker-compose.yml file: an HAProxy accepting connetions on port :5000 of the host, and two nginx containers, not exposed to the host. Test: Running curl localhost:5000 several times returns both hello there from nginx_0 and hello there from nginx_1 Time to Solve: 20 minutes. |
| 15 | "Marrakech": Word Histogram | 20 m | Do |
"Marrakech": Word HistogramScenario: "Marrakech": Word Histogram Level: Medium Type: Do Access: Email Description: Find in the file frankestein.txt the second most frequent word and save in UPPER (capital) case in the /home/admin/mysolution file. Test: echo "SOLUTION" | md5sum returns 19bf32b8725ec794d434280902d78e18 Time to Solve: 20 minutes. |
| 16 | "Rosario": Restore a MySQL database | 15 m | Fix |
"Rosario": Restore a MySQL databaseScenario: "Rosario": Restore a MySQL database Level: Medium Type: Fix Access: Email Description: A developer created a database named 'main' but now some data is missing in the database. You need to restore the database using the the dump "/home/admin/backup.sql". Test: The database, once restored, has a table named "solution". Time to Solve: 15 minutes. |
| 17 | "Abaokoro": Restore MySQL Databases Spooked by a Ghost | 20 m | Fix Pro |
"Abaokoro": Restore MySQL Databases Spooked by a GhostScenario: "Abaokoro": Restore MySQL Databases Spooked by a Ghost Level: Medium Type: Fix Access: Paid Description: There are three databases that need to be restored. You need to create three databases called "first", "second" and "third" and restore the databases using the file "/home/admin/dbs_to_restore.zip". Test: All databases, once restored, have a table named "foo". Time to Solve: 20 minutes. |
| 18 | "Poznań": Helm Chart Issue in Kubernetes | 15 m | Fix Pro |
"Poznań": Helm Chart Issue in KubernetesScenario: "Poznań": Helm Chart Issue in Kubernetes Level: Medium Type: Fix Access: Paid Description: NOTE: Prompt may take a few extra seconds to be responsive while the k3s environment gets ready. Root access is not needed for this challenge ("admin" user cannot sudo). Test: Doing curl on the default port (:80) of any nginx pod returns a Welcome SadServers page. The "Check My Solution" button runs the script /home/admin/agent/check.sh, which you can see and execute. Time to Solve: 15 minutes. |
| 19 | "Manado": How much do you press? | 30 m | Do Pro |
"Manado": How much do you press?Scenario: "Manado": How much do you press? Level: Medium Type: Do Access: Paid Description: You have been tasked with compressing the file /home/admin/names, which is 35147 bytes, to a size smaller than 9400 bytes. You can use any compressing tool at your disposal (there are many available in the server), also you can modify the file without deleting anything in it. Put the solution (compressed file) in the /home/user/admin/solution directory with the default extension used by the compression tool (example: ~/solution/names.gzip). Test: The size of the compressed file is smaller than 9400 bytes. Time to Solve: 30 minutes. |
| 20 | "Warsaw": Prometheus can't scrape the webserver | 30 m | Fix Pro |
"Warsaw": Prometheus can't scrape the webserverScenario: "Warsaw": Prometheus can't scrape the webserver Level: Medium Type: Fix Access: Paid Description: A developer created a golang application that is exposing the /metrics endpoint. They have a problem with scraping the metrics from the application. They asked you to help find the problem. Test: The endpoint http://localhost:9000/metrics should return HTTP code 200. Time to Solve: 30 minutes. |
| 21 | "Moyogalpa": Security Snag. The Trials of Mary and John | 30 m | Fix |
"Moyogalpa": Security Snag. The Trials of Mary and JohnScenario: "Moyogalpa": Security Snag. The Trials of Mary and John Level: Medium Type: Fix Access: Email Description: Mary and John are working on a Golang web application, and the security team has asked them to implement security measures. Unfortunately, they have broken the application, and it no longer functions. They need your help to fix it. Test: curl https://webapp:7000/users.html should return the content of file. Time to Solve: 30 minutes. |
| 22 | "Helsingør": The first walls of postgres physical replication | 20 m | Fix |
"Helsingør": The first walls of postgres physical replicationScenario: "Helsingør": The first walls of postgres physical replication Level: Medium Type: Fix Access: Email Description: You're setting up a PostgreSQL database with replication, you decided to use Docker along with Docker Compose to make it easier to manage and test, after a few hours of work you finished the job and the master database is up and running, but you're having trouble with the replica. Test: Postgres replica container works. Time to Solve: 20 minutes. |
| 23 | "Bekasi": Supervisor is still around | 20 m | Fix Pro |
"Bekasi": Supervisor is still aroundScenario: "Bekasi": Supervisor is still around Level: Medium Type: Fix Access: Paid Description: There is an nginx service running on port 443, it is the main web server for the company and looks like a new employee has deployed some changes to the configuration of supervisor and now it is not working as expected. Test: curl -k https://bekasi returns Hello SadServers! Time to Solve: 20 minutes. |
| 24 | "Depok": Nginx with Brotli | 15 m | Fix Pro |
"Depok": Nginx with BrotliScenario: "Depok": Nginx with Brotli Level: Medium Type: Fix Access: Paid Description: You are tasked to add compression to the company website. The website is running on an Nginx server, and you decide to add Brotli compression to it. Test: curl -H "Accept-Encoding: br" -sI http://localhost returns the header Content-Encoding: br. Time to Solve: 15 minutes. |
| 25 | "Tukaani": XZ LZMA Library Compromised | 15 m | Fix Pro |
"Tukaani": XZ LZMA Library CompromisedScenario: "Tukaani": XZ LZMA Library Compromised Level: Medium Type: Fix Access: Paid Description: (You can learn about Linux Libraries before starting this scenario). Test: lsof | grep liblzma.so.5 returns only the liblzma in the path: /usr/lib/x86_64-linux-gnu/liblzma.so.5.2.5 Time to Solve: 15 minutes. |
| 26 | "Atrani": Modify a SQlite3 Database | 15 m | Fix Pro |
"Atrani": Modify a SQlite3 DatabaseScenario: "Atrani": Modify a SQlite3 Database Level: Medium Type: Fix Access: Paid Description: A developer created a script /home/admin/readdb.py that tests access to a database. Without modifying the readdb.py file, change the database so that running the script returns the string "John Karmack". Test: Running /home/admin/readdb.py returns "John Karmack". Time to Solve: 15 minutes. |
| 27 | "Nerdearla Buenos Aires": Troubleshoot "A" no se conecta con "B" | 30 m | Fix |
"Nerdearla Buenos Aires": Troubleshoot "A" no se conecta con "B"Scenario: "Nerdearla Buenos Aires": Troubleshoot "A" no se conecta con "B" Level: Medium Type: Fix Access: Email Description: Hay un servidor web (Caddy) en el puerto HTTP :80 pero curl http://127.0.0.1 no funciona. Descubre lo que pasa y haz los arreglos necesarios y el servidor web te dará una URL. Test: El comando curl http://127.0.0.1 devuelve una dirección URL. Time to Solve: 30 minutes. |
| 28 | "Minneapolis with a Vengeance": Break a CSV file | 20 m | Do |
"Minneapolis with a Vengeance": Break a CSV fileScenario: "Minneapolis with a Vengeance": Break a CSV file Level: Medium Type: Do Access: Email Description: Break the Comma Separated Valued (CSV) file data.csv in the /home/admin/ directory into exactly 10 smaller files of about the same size named data-00.csv, data-01.csv, ... , data-09.csv files in the same directory. All the files should have the same header (first line with column names) as data.csv. None of the smaller files should be bigger than 32KB. Test: The "Check My Solution" button runs the script /home/admin/agent/check.sh, which you can see and execute. Time to Solve: 20 minutes. |
| 29 | "Hanoi": Find the Multitasking Users | 15 m | Do Pro |
"Hanoi": Find the Multitasking UsersScenario: "Hanoi": Find the Multitasking Users Level: Medium Type: Do Access: Paid Description: The Hanoi office has a Linux server with a large number of user accounts and groups. The system administrators need to identify which users belong to multiple groups for better access management. Test: Running md5sum /home/admin/multi-group-users.txt returns dc0ae86caae7125d21df03a0ab29d8ae Time to Solve: 15 minutes. |
| 30 | "Batumi": Troubleshoot "A" cannot connect to "B" | 20 m | Fix Pro |
"Batumi": Troubleshoot "A" cannot connect to "B"Scenario: "Batumi": Troubleshoot "A" cannot connect to "B" Level: Medium Type: Fix Access: Paid Description: (To learn the skills to solve this challenge, see Can't Connect to a Service: Linux Troubleshooting Guide) Test: The command curl http://127.0.0.1 returns a URL address. Time to Solve: 20 minutes. |
| 31 | "Bengaluru": Kubernetes StatefulSet least known characteristic | 15 m | Fix |
"Bengaluru": Kubernetes StatefulSet least known characteristicScenario: "Bengaluru": Kubernetes StatefulSet least known characteristic Level: Medium Type: Fix Access: Email Description: There's a Kubernetes cluster (created with "k3d") with two worker nodes and two pods on the node k3d-cluster-agent-0: a Deployment demo-deployment-... and a StatefulSet demo-statefulset-0. Their manifests are identical except for the different kind of K8s resource. Test: Node k3d-cluster-agent-0 is NotReady. Both the Deployment and the StatefulSet are running on the node k3d-cluster-agent-1 Time to Solve: 15 minutes. |
| 32 | "Constanta": Jumping Frog | 20 m | Hack |
"Constanta": Jumping FrogScenario: "Constanta": Jumping Frog Level: Medium Type: Hack Access: Email Description: This is a "hacking" or Capture The Flag challenge. You need to copy the message at /home/user3/secret.txt into the /home/admin/solution.txt file. Test: Running md5sum /home/admin/solution.txt returns the hash 7fe16554d0b326309d980314cebc2994 Time to Solve: 20 minutes. |
| 33 | "Bharuch": Lost in Translation | 20 m | Fix Pro |
"Bharuch": Lost in TranslationScenario: "Bharuch": Lost in Translation Level: Medium Type: Fix Access: Paid Description: There's a Docker container that runs a web server on port 3000, but it's not working. Test: curl http://localhost:3000 should return "Hello from sadservers!" Time to Solve: 20 minutes. |
| 34 | "Quito": Control One Container from Another | 20 m | Do |
"Quito": Control One Container from AnotherScenario: "Quito": Control One Container from Another Level: Medium Type: Do Access: Email Description: You have a running container named docker-access. Another container nginx is present but in a stopped state. Your goal is to start the nginx container from inside the docker-access container. Test: Executing docker ps inside the docker-access container: docker exec docker-access docker ps succeeds. Time to Solve: 20 minutes. |
| 35 | "Bangalore": Envoy Panics | 15 m | Fix |
"Bangalore": Envoy PanicsScenario: "Bangalore": Envoy Panics Level: Medium Type: Fix Access: Email Description: You have an Envoy proxy routing traffic to two unhealthy backend services. Test: Running curl localhost:10000 should return no healthy upstream. Time to Solve: 15 minutes. |
| 36 | "Budapest": User Creation | 30 m | Do |
"Budapest": User CreationScenario: "Budapest": User Creation Level: Medium Type: Do Access: Email Description: Given the file user_list.txt you must create all the users specified in the file with their corresponding passwords. Test: All users are created with the right password. Time to Solve: 30 minutes. |
| 37 | "Tokelau": Delete from history | 15 m | Do |
"Tokelau": Delete from historyScenario: "Tokelau": Delete from history Level: Medium Type: Do Access: Email Description: Inspired by this nixCraft article. Test: Running history |grep "foo" returns nothing. Time to Solve: 15 minutes. |
| 38 | "Bizerte": The Slow Application | 15 m | Fix |
"Bizerte": The Slow ApplicationScenario: "Bizerte": The Slow Application Level: Medium Type: Fix Access: Email Description: A Python web application running on port 5000 from the /opt directory is experiencing severe performance issues; every request takes more than 5 seconds to complete. Test: curl localhost:5000 returns Data from FAST cache! Time to Solve: 15 minutes. |
| 39 | "Ruaka": Kubernetes pod in distress | 15 m | Fix Pro |
"Ruaka": Kubernetes pod in distressScenario: "Ruaka": Kubernetes pod in distress Level: Medium Type: Fix Access: Paid Description: A developer wants to deploy an open-source tool on Kubernetes. The tool unfortunately has limited documentation. Test: kubectl get pod shows the ruaka application pod up and running, while no Helm fields have been taken out from the applicaiton chart. Time to Solve: 15 minutes. |
| 40 | "Campina Grande": Give me my cert, Vault | 15 m | Fix Pro |
"Campina Grande": Give me my cert, VaultScenario: "Campina Grande": Give me my cert, Vault Level: Medium Type: Fix Access: Paid Description: A web application running at https://nginx.example.com has an expired certificate. Issue a new certificate using the Hashicorp Vault running on the server. Test: Running curl https://nginx.example.com returns Hello!. Time to Solve: 15 minutes. |
| 41 | "Kampala": Strange Script Error | 15 m | Fix |
"Kampala": Strange Script ErrorScenario: "Kampala": Strange Script Error Level: Medium Type: Fix Access: Email Description: A developer has been working on Linux deployment scripts on their machine and then transferred the files to a Linux server. However, when they try to execute the scripts, they encounter the mysterious error: Test: All script files in /home/admin/deploy/ should execute without the cannot execute: required file not found error. Time to Solve: 15 minutes. |
| 42 | "Bondo": Split my pile! | 20 m | Fix |
"Bondo": Split my pile!Scenario: "Bondo": Split my pile! Level: Medium Type: Fix Access: Email Description: A developer wants to run a program that splits their pile of their data into compressed parts for efficient transport across their network. Unfortunately when the tool runs it never completes. Test: Executing /home/admin/bondo as admin returns part files generation completed!. Time to Solve: 20 minutes. |
| 43 | "Atlantis": Not found | 15 m | Fix Pro |
"Atlantis": Not foundScenario: "Atlantis": Not found Level: Medium Type: Fix Access: Paid Description: There is a small "C" application in the /home/admin/app directory. Create the Docker container "app" with a small footprint and minimalistic so you get a hello binary that returns a greeting in Atlantean (Docker multi-stage build). The binary application is automatically called when running docker run app Test: docker run app returns SOO-puhk Time to Solve: 15 minutes. |
| 44 | "Kilifi": Speculative Misallocation! | 20 m | Fix |
"Kilifi": Speculative Misallocation!Scenario: "Kilifi": Speculative Misallocation! Level: Medium Type: Fix Access: Email Description: A developer is having trouble deploying an application on a preconfigured cluster. Test: The kilifi application runs properly; it's Service on :3333/healthz returns "kilifi ready to serve". Time to Solve: 20 minutes. |
| 45 | "Solanea": ClickHouse mad house | 20 m | Do Pro |
"Solanea": ClickHouse mad houseScenario: "Solanea": ClickHouse mad house Level: Medium Type: Do Access: Paid Description: You have a ClickHouse installation CHI running on a Kubernetes cluster and a set of requests (located at ~/data/requests.csv) that you must populate into the http_requests table in the monitoring database (table may not exist in all pod instances). Test: You are able to query the database and see the data: Time to Solve: 20 minutes. |
| 46 | "Tunis": Redis Replication Problem | 20 m | Fix Pro |
"Tunis": Redis Replication ProblemScenario: "Tunis": Redis Replication Problem Level: Medium Type: Fix Access: Paid Description: A Redis master-replica setup is running on this server, with the master on port 6379 and the replica on port 6380. Both instances show as "connected" when you check their status, but data synchronization has silently broken. Test: The solution will be validated by writing a test key to the master and verifying it appears on the replica within 2 seconds. Time to Solve: 20 minutes. |
| 47 | "Toulon": Denied Lamp | 15 m | Fix Business |
"Toulon": Denied LampScenario: "Toulon": Denied Lamp Level: Medium Type: Fix Access: Business Description: The security team has asked again Mary and John to implemente more security measures. Unfortunately, this time they have broken the LAMP stack (Apache with PHP) so the frontend is unable get an answer upstream, thus, they need your help again to fix it. Test: curl localhost | head -n1 returns SadServers - LAMP Stack Time to Solve: 15 minutes. |
| 48 | "Bermuda": Command not found | 10 m | Fix Business |
"Bermuda": Command not foundScenario: "Bermuda": Command not found Level: Medium Type: Fix Access: Business Description: While working with a distro with a very small footprint, we just found out that there are some basic commands not present, this was supposed to be a security feature, after all this is just a small server, however, the web content was not deployed. Your task is to decompress the file /home/admin/web.zip and move the file home.html in it to /var/www/html/index.html Test: The service must return the string "Homepage". You can check with the command curl -s localhost Time to Solve: 10 minutes. |
| 49 | "Auderghem": Containers miscommunication | 15 m | Fix Pro |
"Auderghem": Containers miscommunicationScenario: "Auderghem": Containers miscommunication Level: Medium Type: Fix Access: Paid Description: There is an nginx Docker container that listens on port 80, the purpose of which is to redirect the traffic to two other containers statichtml1 and statichtml2 but this redirection is not working. Test: The nginx container must redirect the traffic to the statichtml1 and statichtml2 containers: Time to Solve: 15 minutes. |
| 50 | "Marseille": Rocky security | 15 m | Fix Pro |
"Marseille": Rocky securityScenario: "Marseille": Rocky security Level: Medium Type: Fix Access: Paid Description: As the Christmas shopping season approaches, the security team has asked Mary and John to implemente more security measures. Unfortunately, this time they have broken the LAMP stack; the frontend is unable get an answer from upstream, thus they need your help again to fix it. Test: curl localhost | head -n1 returns SadServers - LAMP Stack Time to Solve: 15 minutes. |
| 51 | "Woluwe": Too many images | 15 m | Fix Pro |
"Woluwe": Too many imagesScenario: "Woluwe": Too many images Level: Medium Type: Fix Access: Paid Description: A pipeline created a lot of Docker images locally for a web app. All these images except for one contain a typo introduced by a developer: there's an incorrect image instruction to pipe "HelloWorld" to "index.htmlz" instead of using the correct "index.html" Test: curl http://localhost:3000 should respond with HelloWorld;529 Time to Solve: 15 minutes. |
| 52 | "La Rinconada": Elevating privileges | 15 m | Hack |
"La Rinconada": Elevating privilegesScenario: "La Rinconada": Elevating privileges Level: Medium Type: Hack Access: Email Description: You are logged in as the user "admin" without general "sudo" privileges. Test: As the user "admin", md5sum /home/admin/solution.txt returns 52a55258e4d530489ffe0cc4cf02030c (we also accept the hash of the same secret string without an ending newline). Time to Solve: 15 minutes. |
| 53 | "Annapurna": High privileges | 20 m | Hack |
"Annapurna": High privilegesScenario: "Annapurna": High privileges Level: Medium Type: Hack Access: Email Description: You are logged in as the user admin. Test: Running md5sum /home/admin/mysolution.txt returns 47ee165a2262476f6866902a93f2a41d. (We also accept the md5sum of the same file without a newline at the end). Time to Solve: 20 minutes. |
| 54 | "Podgorica": Docker to Podman migration | 20 m | Do Pro |
"Podgorica": Docker to Podman migrationScenario: "Podgorica": Docker to Podman migration Level: Medium Type: Do Access: Paid Description: You have been tasked with migrating this future web server from using Docker (which uses a daemon) to rootless Podman. Test: The checker script will test if the container-nginx.service is active and enabled, and if it can stop and start the service. It will also verify that curl localhost:8888 returns the default "Welcome to nginx" web page. Time to Solve: 20 minutes. |
| 55 | "Torino": Optimize grande Docker image | 15 m | Do Pro |
"Torino": Optimize grande Docker imageScenario: "Torino": Optimize grande Docker image Level: Medium Type: Do Access: Paid Description: A Torino Node.js application is located in the ~/torino-app directory. Test: The torino Docker image is less than 122 MB and curl http://localhost:3000 returns Hello from Torino! Time to Solve: 15 minutes. |
| 56 | "Socorro, NM": Optimize Podman image | 15 m | Do Pro |
"Socorro, NM": Optimize Podman imageScenario: "Socorro, NM": Optimize Podman image Level: Medium Type: Do Access: Paid Description: The podman image localhost/prod:latest contains a static website. Test: The podman image localhost/prod:latest size is less than 200 MB and running curl localhost:8888 from a container named "check" created from the image retuns 100 lines. Time to Solve: 15 minutes. |
| 57 | "Sumé": Tied in a Knot | 20 m | Fix |
"Sumé": Tied in a KnotScenario: "Sumé": Tied in a Knot Level: Medium Type: Fix Access: Email Description: A DNS server running Knot DNS is serving the zone sadservers.internal (see ls /var/lib/knot/zones/), but users are reporting that they cannot access blog.sadservers.internal neither api.sadservers.internal. Your task is to diagnose and fix the DNS issues so the services become accessible. Test: You are able to access the blog and the API services: curl blog.sadservers.internal returns Welcome to blog.sadservers.internal Time to Solve: 20 minutes. |
| 58 | "San Juan": mucho Traefik | 20 m | Fix New |
"San Juan": mucho TraefikScenario: "San Juan": mucho Traefik Level: Medium Type: Fix Access: Email Description: There is a Traefik load balancer that must be up and running. The server and the backend services are managed by Docker Compose. Running curl -s app.sadserver | head -n1 must return the host ID of one of the backend servers, running the command again must return a new host ID. The server seems to be working some times, some others fails or just times out. Test: curl -s app.sadserver | head -n1 returns something like Hostname: Time to Solve: 20 minutes. |
| 59 | "Suzhou": MongoDB replicas! | 20 m | Fix New |
"Suzhou": MongoDB replicas!Scenario: "Suzhou": MongoDB replicas! Level: Medium Type: Fix Access: Email Description: A new MongoDB replica set has been setup in the development environment trough /home/admin/app/rs0.js, however, a variety or errors are showing up when trying to bring it up. You should bring up all the replica servers, get them communicating to each other and make sure the replica set is working as it should. Test: mongosh --eval "rs.status()" | grep health returns the status of all the replicas health: 1, health: 1, health: 1, The "Check My Solution" button runs the script /home/admin/agent/check.sh, which you can see and execute. Time to Solve: 20 minutes. |
| # | Name | Time | Type | |
|---|---|---|---|---|
| 1 | "Jakarta": it's always DNS. | 20 m | Fix No Registration |
"Jakarta": it's always DNS.Scenario: "Jakarta": it's always DNS. Level: Hard Type: Fix Access: Public Description: Can't ping google.com. It returns ping: google.com: Name or service not known. Expected is being able to resolve the hostname. (Note: currently the VMs can't ping outside so there's no automated check for the solution). Test: ping google.com should return something like PING google.com (172.217.2.46) 56(84) bytes of data. Time to Solve: 20 minutes. |
| 2 | "Bern": Docker web container can't connect to db container. | 20 m | Fix |
"Bern": Docker web container can't connect to db container.Scenario: "Bern": Docker web container can't connect to db container. Level: Hard Type: Fix Access: Email Description: There are two Docker containers running, a web application (Wordpress or WP) and a database (MariaDB) as back-end, but if we look at the web page, we see that it cannot connect to the database. curl -s localhost:80 |tail -4 returns: Test: sudo docker exec wordpress mysqladmin -h mysql -u root -ppassword ping . The wordpress container is able to connect to the database in the mariadb container and returns mysqld is alive. Time to Solve: 20 minutes. |
| 3 | "Singara": Docker and Kubernetes web app not working. | 20 m | Fix |
"Singara": Docker and Kubernetes web app not working.Scenario: "Singara": Docker and Kubernetes web app not working. Level: Hard Type: Fix Access: Email Description: There's a k3s Kubernetes install you can access with kubectl. The Kubernetes YAML manifests under /home/admin have been applied. The objective is to access from the host the "webapp" web server deployed and find what message it serves (it's a name of a town or city btw). In order to pass the check, the webapp Docker container should not be run separately outside Kubernetes as a shortcut. Test: curl localhost:8888 returns a value from the webapp deployed Kubernetes pod. Time to Solve: 20 minutes. |
| 4 | "Hong-Kong": can't write data into database. | 20 m | Fix Pro |
"Hong-Kong": can't write data into database.Scenario: "Hong-Kong": can't write data into database. Level: Hard Type: Fix Access: Paid Description: (Similar to "Manhattan" scenario but harder). Your objective is to be able to insert a row in an existing Postgres database. The issue is not specific to Postgres and you don't need to know details about it (although it may help). Test: sudo -u postgres psql -c "insert into persons(name) values ('jane smith');" -d dt Time to Solve: 20 minutes. |
| 5 | "Pokhara": SSH and other sshenanigans | 30 m | Fix Pro |
"Pokhara": SSH and other sshenanigansScenario: "Pokhara": SSH and other sshenanigans Level: Hard Type: Fix Access: Paid Description: A user client was added to the server, as well as their SSH public key. Test: As user admin: sudo -u client ssh client@localhost 'pwd' returns /home/client Time to Solve: 30 minutes. |
| 6 | "Roseau": Hack a Web Server | 30 m | Hack |
"Roseau": Hack a Web ServerScenario: "Roseau": Hack a Web Server Level: Hard Type: Hack Access: Email Description: There is a secret stored in a file that the local Apache web server can provide. Find this secret and have it as a /home/admin/secret.txt file. Test: sha1sum /home/admin/secret.txt |awk '{print $1}' returns cc2c322fbcac56923048d083b465901aac0fe8f8 Time to Solve: 30 minutes. |
| 7 | "Belo-Horizonte": A Java Enigma | 20 m | Fix Pro |
"Belo-Horizonte": A Java EnigmaScenario: "Belo-Horizonte": A Java Enigma Level: Hard Type: Fix Access: Paid Description: (Credit for the idea: fuero) Test: md5sum /home/admin/solution |awk '{print $1}' returns 9d2bd7aabb26681eacd9444da6b6643c Time to Solve: 20 minutes. |
| 8 | "Chennai": Pull a Rabbit from a Hat | 30 m | Fix Pro |
"Chennai": Pull a Rabbit from a HatScenario: "Chennai": Pull a Rabbit from a Hat Level: Hard Type: Fix Access: Paid Description: There is a RabbitMQ (RMQ) cluster defined in a docker-compose.yml file. Test: python3 ~/consumer.py returns hello-lwc Time to Solve: 30 minutes. |
| 9 | "Monaco": Disappearing Trick | 30 m | Hack |
"Monaco": Disappearing TrickScenario: "Monaco": Disappearing Trick Level: Hard Type: Hack Access: Email Description: There is a web server on :5000 with a form. POSTing the correct form password into this web service will return a secret. Test: md5sum /home/admin/mysolution returns a250aa19f16dda6f9fcef286f035ec4b Time to Solve: 30 minutes. |
| 10 | "Florence": Database Migration Hell | 30 m | Fix Pro |
"Florence": Database Migration HellScenario: "Florence": Database Migration Hell Level: Hard Type: Fix Access: Paid Description: You are working as a DevOps Engineer in a company and another team member left the company and left the docker-compose.yml of a database-backed web application unfinished. Test: curl --cacert /etc/nginx/certs/sadserver.crt https://sadserver.local returns a message containing "ready to serve requests" Time to Solve: 30 minutes. |
| 11 | "Zaragoza": Test changing critical files | 20 m | Do Pro |
"Zaragoza": Test changing critical filesScenario: "Zaragoza": Test changing critical files Level: Hard Type: Do Access: Paid Description: The goal is to make the script /home/admin/agent/check.sh return OK, without editing the original /etc/hosts file. Test: The string my.local.test is in /etc/hosts Time to Solve: 20 minutes. |
| 12 | "Amygdala": Do you have enough insight to see the secrets? | 20 m | Fix Pro |
"Amygdala": Do you have enough insight to see the secrets?Scenario: "Amygdala": Do you have enough insight to see the secrets? Level: Hard Type: Fix Access: Paid Description: Troubleshoot and fix a Kubernetes web application running in the app namespace. Make the deployment run successfully so that it returns Hello handsome! when you curl it. Test: Running: POD_IP=$(kubectl get po -n app -l app=app -o jsonpath='{.items[0].status.podIP}') curl http://$POD_IP returns Hello handsome!. Time to Solve: 20 minutes. |
| 13 | "Tigoni": Patch and Pray! | 20 m | Fix |
"Tigoni": Patch and Pray!Scenario: "Tigoni": Patch and Pray! Level: Hard Type: Fix Access: Email Description: A developer wants to upgrade their stateful application. This application handles their archives/backups. Test: The tigoni pod with version v2 runs correctly (its endpoint :3000/healthz displays serverVersion:v2) Time to Solve: 20 minutes. |
| 14 | "Cabedelo": Harbor full of issues | 20 m | Fix Pro |
"Cabedelo": Harbor full of issuesScenario: "Cabedelo": Harbor full of issues Level: Hard Type: Fix Access: Paid Description: You need to build and push a docker image without changing the Dockerfile to your company's Harbor registry, which is running at harbor.sadservers.local, with its home directory at /opt/harbor. You have full admin access with admin:Harbor12345 credential. The source code and the Dockerfile are in the ~/app directory. The image name must be harbor.sadservers.local/images/app:1.0.0. It is also expected that the application will be up and running at localhost:5000 in a container named app. Test: You are able to pull the application image from Harbor: Time to Solve: 20 minutes. |
| 15 | "Karakorum": WTFIT – What The Fun Is This? | 20 m | Fix Pro |
"Karakorum": WTFIT – What The Fun Is This?Scenario: "Karakorum": WTFIT – What The Fun Is This? Level: Hard Type: Fix Access: Paid Description: (NOTE: this is not a new scenario but an existing Pro one temporarily available to all users as the last Advent of SysAdmin 2025 scenario). Test: Running /home/admin/wtfit returns OK. Time to Solve: 20 minutes. |