Difficulty
easy

Categories
misc linux

Description
It's time to load the presents into Santa's Slegih at the North Pole, a task assigned to Jinglebell this year. Jinglebell keeps the password for the warehouse safely in a file in his home directory. Unfortunately, the other elves have played a prank—they've hidden the warehouse password in a tangled maze throughout the workshop. Things are falling behind schedule, and Jinglebell needs your help. Can you navigate the labyrinth and find the password?

Solution

Upon SSHing into the Linux box, we’re presented with an Ubuntu 24.04.3 LTS system. Looking around, we find an interesting file in our home directory:

elf@host:~$ ls -lah ~
total 12K
drwxr-x---. 1 elf  elf    46 Dec  4 12:38 .
drwxr-xr-x. 1 root root   17 Nov 24 20:52 ..
-rw-r--r--. 1 elf  elf   220 Mar 31  2024 .bash_logout
-rw-r--r--. 1 elf  elf  3.7K Mar 31  2024 .bashrc
drwx------. 2 elf  elf    34 Dec  4 12:38 .cache
-rw-r--r--. 1 elf  elf   807 Mar 31  2024 .profile
lrwxrwxrwx. 1 elf  elf    16 Dec  4 12:36 warehouse_password -> /workshop/cbamf2

We see that warehouse_password is a symlink to /workshop/cbamf2. Unfortunately, we don’t have permission to access the /workshop folder or any files within it.

Remembering the challenge title loop-de-link and the description hinting at a maze, we take an educated guess that we’re dealing with a symlink chain, where one symlink points to another in sequence. Normally, we’d use readlink -f <path> to traverse the chain, but that requires permissions we don’t have. So, we look for other ways to walk this chain.

We run sudo -l to check the sudo permissions for our user:

elf@host:~$ sudo -l
Matching Defaults entries for elf on host:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty

User elf may run the following commands on host:
    (root) NOPASSWD: /bin/cat /workshop/*
    (root) NOPASSWD: /usr/bin/stat /workshop/*

Nice! We’re allowed to use /bin/cat and /usr/bin/stat on the /workshop folder.

Running the stat command on the first few links reveals:

elf@host:~$ sudo /usr/bin/stat /workshop/cbamf2
  File: /workshop/cbamf2 -> /workshop/irtegm
  Size: 16              Blocks: 0          IO Block: 4096   symbolic link
Device: 0,171   Inode: 270187127   Links: 1
Access: (0777/lrwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2025-12-04 12:36:19.897048505 +0000
Modify: 2025-12-04 12:36:19.897048505 +0000
Change: 2025-12-04 12:36:19.897048505 +0000
 Birth: 2025-12-04 12:36:19.897048505 +0000
elf@host:~$ sudo /usr/bin/stat /workshop/irtegm
  File: /workshop/irtegm -> /workshop/i1edct
  Size: 16              Blocks: 0          IO Block: 4096   symbolic link
Device: 0,171   Inode: 270187126   Links: 1
Access: (0777/lrwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2025-12-04 12:36:19.897048505 +0000
Modify: 2025-12-04 12:36:19.897048505 +0000
Change: 2025-12-04 12:36:19.897048505 +0000
 Birth: 2025-12-04 12:36:19.897048505 +0000

Obviously, there can be many links in the chain, so we use an LLM to generate a walk.sh script to automate the process:

#!/usr/bin/env bash
set -euo pipefail

cur="${1:-/workshop/cbamf2}"
declare -A seen

while true; do
  out="$(sudo /usr/bin/stat "$cur")"
  echo "$out"
  file_line="$(printf '%s\n' "$out" | head -n1)"
  if [[ "$file_line" =~ \-\>\  ]]; then
    tgt="${file_line#*-> }"
    [[ -n "${seen[$cur]:-}" ]] && { echo "Loop detected at: $cur -> $tgt" >&2; exit 2; }
    seen["$cur"]=1
    cur="$tgt"
  else
    echo "Reached non-symlink: $cur"
    sudo /bin/cat "$cur"
    exit 0
  fi
done

Running this script for about a minute rewards us with our daily flag!

elf@host:/tmp$ chmod +x walk.sh
elf@host:/tmp$ ./walk.sh
...
Reached non-symlink: /workshop/dz4xzp
FV25{ELOOP_ELOOP_ELOOP_ELOOP}

Flag:

FV25{ELOOP_ELOOP_ELOOP_ELOOP}

External discussions


Leave a comment

(required)(will not be published)(required)

Comments

There are no comments yet. Be the first to add one!