Type: Forensic / Log analysis
Files in archive: tutorial.txt, access.log
Password to extract archive: ThisIsAFunTutorial1#
About: Throughout the Grimoires of the Gauntlet, you'll have to investigate attacks, analyze malicious files, and identify threat actors. For each exercise, you will have to provide answers in different formats. While you may be used to answering exercises in the Offsec Learning Platform with a specific flag or term, the exercises of the Gauntlet often need to be answered using descriptive text.
This writeup is a step‑by‑step practical guide to solving the Tutorial challenge. Follow the commands exactly on your analysis machine where the ZIP and logs are available. All commands assume a Linux-like environment (bash).
1. Setup & sanity checks
Create a working directory and copy the ZIP archive into it (or
cdinto the folder where you uploaded the files):
mkdir -p ~/grimoire_tutorial && cd ~/grimoire_tutorial
# move the zip here, or operate in place
Verify the files you have (confirm
tutorial.txtandaccess.logare present after extraction step below):
ls -la
file tutorial.txt access.log || true
file is useful to check if tutorial.txt is a plain text file or something encoded/packed.
2. Extract the tutorial ZIP (if zipped)
If the challenge provided a ZIP you must extract it with the given password. Replace archive.zip with the actual ZIP name.
unzip -l archive.zip # list contents (optional)
unzip -P 'ThisIsAFunTutorial1#' archive.zip
# or: unzip -P ThisIsAFunTutorial1# archive.zip
ls -la
You should now see tutorial.txt and access.log (or equivalents).
3. Inspect tutorial.txt to retrieve the flag / answer
Start by quickly viewing the file, but don’t trust visual output only — confirm file type and encoding.
# quick peek
head -n 50 tutorial.txt
# file type and encoding
file tutorial.txt
# if it's base64 or binary, try this:
hexdump -C tutorial.txt | head
If the file looks like base64 (long single-line with A-Za-z0-9+/= characters), decode it.
# decode base64 safely to a new file
base64 -d tutorial.txt > tutorial_decoded.txt 2>/dev/null || true
# inspect decoded result
less tutorial_decoded.txt
grep -i "flag\|answer\|Try" -n tutorial_decoded.txt || true
Expected result: The decoded text contains an explicit answer line. In this challenge the decoded output ends with a line similar to:
The answer to this exercise is "TryHarder"
So the required submission is:
TryHarder
(Or, if the grader expects a flag format, Flag{TryHarder} may also be accepted.)
4. Analyze access.log (final exercise)
We now move to the forensic/log analysis portion. The goal: determine attacker IP, how they extracted sensitive data, what data, and how it could yield interactive access.
4.1 Start with simple enumeration
Find unique client IPs that made requests around the suspicious timeframe.
# Typical log entries start with an IP. Extract unique IPs:
awk '{print $1}' access.log | sort | uniq -c | sort -nr | head -n 50
This reveals the most active IPs. Note any external (non-private) addresses or an outlier IP repeated with suspicious requests.
4.2 Search for file-read attempts and path traversal patterns
Look for requests containing .., /etc/, .ssh/, id_rsa, or obvious plugin paths that might expose files.
# common path-traversal indicators
grep -E "(\.\./|\.\.\\|%2e%2e|/\\.\\.|id_rsa|\\.ssh|/etc/passwd|/home/.*/\.ssh)" access.log -n | less
If you find lines like GET /public/plugins/welcome/../../../../home/dave/.ssh/id_rsa, that's direct evidence of a directory traversal / arbitrary file read request.
4.3 Extract the offending log line(s) with context
Once you have matching lines, pull multiple lines of context for timestamps and surrounding activity.
# show matching lines with surrounding 3 lines for context
grep -n "id_rsa\|\\.ssh\|welcome/\\." access.log | cut -d: -f1 | while read ln; do
start=$((ln-3)); [ $start -lt 1 ] && start=1
sed -n "${start},$((ln+3))p" access.log
echo "----"
done
4.4 Capture the private key payload from the log
Sometimes logs also contain the response bodies or truncated responses. Search for the key markers that delineate SSH private keys:
# Extract key blocks between BEGIN and END markers
sed -n '/-----BEGIN OPENSSH PRIVATE KEY-----/,/-----END OPENSSH PRIVATE KEY-----/p' access.log > extracted_id_rsa || true
wc -l extracted_id_rsa && ls -l extracted_id_rsa
If the file extracted_id_rsa contains a key block, make it usable:
# secure the file and inspect header
chmod 600 extracted_id_rsa
file extracted_id_rsa
sed -n '1,5p' extracted_id_rsa
If the key is present, it likely belongs to a user on the host (for example dave) and can be used to attempt SSH authentication to hosts that trust that key.
4.5 Confirm which user the key belongs to (from logs)
Search the log for references to the username path (/home/dave/.ssh/id_rsa) or other usernames mentioned in the request URI.
grep -E "/home/.+/.ssh/id_rsa|/home/.+/.ssh/authorized_keys" access.log -n
If the retrieval path explicitly references /home/dave/.ssh/id_rsa, you can reasonably infer the private key belongs to dave (logs often include the full filesystem path as part of the request when exploited).
5. Recreate the impact (offline / safe environment)
Do not attempt to use the key against remote systems you do not own. In a safe lab:
Create a throwaway VM or docker container that accepts that key for SSH to simulate the impact:
# create a test user on a local VM or container
useradd -m -s /bin/bash testdave
mkdir -p /home/testdave/.ssh
cp extracted_id_rsa /root/tmp_id_rsa
# derive public key (if OpenSSH private key format supports it)
ssh-keygen -y -f /root/tmp_id_rsa > /home/testdave/.ssh/authorized_keys
chown -R testdave:testdave /home/testdave/.ssh
chmod 700 /home/testdave/.ssh
chmod 600 /home/testdave/.ssh/authorized_keys
# now you can test locally:
ssh -i /root/tmp_id_rsa [email protected]
If the private key is not passphrase-protected, the ssh command will grant shell access as the user if the key matches the server's authorized_keys entry. If the key is passphrase-protected, local testing will prompt for the passphrase and you should not attempt brute-forcing in real scenarios.
6. Write the final answer (concise report)
Grading usually expects a compact answer. Structure it like a short incident report:
Attacker IP: <IP found from logs>
How they extracted data:
- A path traversal / file read was performed against the web plugin endpoint, requesting /home/dave/.ssh/id_rsa. The server returned a 200 response containing the private SSH key.
Sensitive data obtained:
- /home/dave/.ssh/id_rsa (private SSH key for user dave)
How it can be used for interactive access:
- The private SSH key can be used with `ssh -i extracted_id_rsa dave@<server_ip>` to obtain an interactive shell (if the key is not passphrase-protected or its passphrase is known).
Replace placeholders with the actual IP and paths extracted from your access.log analysis.
7. Quick command reference (copy-paste)
# 1. list candidate IPs
awk '{print $1}' access.log | sort | uniq -c | sort -nr | head
# 2. find path traversal / ssh leaks
grep -E "id_rsa|\\.ssh|/etc/passwd|\\.\\./|%2e%2e|welcome/\\." access.log -n
# 3. extract private key block
sed -n '/-----BEGIN OPENSSH PRIVATE KEY-----/,/-----END OPENSSH PRIVATE KEY-----/p' access.log > extracted_id_rsa
# 4. secure and test locally (lab only)
chmod 600 extracted_id_rsa
ssh-keygen -y -f extracted_id_rsa > pubkey && cat pubkey
# (simulate by placing pubkey in a test user's authorized_keys)

