Objective

1545393808358

Terminal - CURLing Master

Challenge

I’ll find Holly Evergreen in the hallway to the left of the main entrance:

1546340089902

Oh that Bushy!

Sorry to vent, but that brother of mine did something strange.

The trigger to restart the Candy Striper is apparently an arcane HTTP call or 2.

I sometimes wonder if all IT folk do strange things with their home networks…

                                                                               
                                                                               
                  .....................................                        
                 ...',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'....                      
                 ...,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'...                     
                  ......'''''''''''''''''''''''',,,,,,,'...                    
                     ............................',,,,,,,...                   
                                                ...,,,,,,'...                  
                                                 ..',,,,,,'..                  
                                                 ...,,,,,,,...                 
                                                 ...,,,,,,,...                 
            ........................................,,,,,,,'......             
         .....''''''''''''''''''''''''''''''''''''',,,,,,,,,,'''.....          
        ...............................................................        
        ...............................................................        
      .:llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllc.       
     .llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll;      
    'llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll:     
   .kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk:    
   o0000000000000000000000000000000000000000000000000000000000000000000000O    
   O00000000000000000000000000000000000000000000000000000000000000000000000'   
   O00000000000000000000000000000000000000000000000000000000000000000000000'   
   d0000000000000000000000000000000000000000000000000000000000000000000000O.   
   'OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOc    
    ,llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll:     
     ,llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll:      
      .clllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll'       
        'clllllllllllllllllllllllllllllllllllllllllllllllllllllllllll,         
          .,clllllllllllllllllllllllllllllllllllllllllllllllllllll;.           
              .';:cllllllllllllllllllllllllllllllllllllllllcc;,..              
                                                                               
I am Holly Evergreen, and now you won't believe:
Once again the striper stopped; I think I might just leave!
Bushy set it up to start upon a website call.
Darned if I can CURL it on - my Linux skills apall.
Could you be our CURLing master - fixing up this mess?
If you are, there's one concern you surely must address.
Something's off about the conf that Bushy put in place.
Can you overcome this snag and save us all some face?
  Complete this challenge by submitting the right HTTP 
  request to the server at http://localhost:8080/ to 
  get the candy striper started again. You may view 
  the contents of the nginx.conf file in 
  /etc/nginx/, if helpful.
elf@a8793020a6c7:~$

Solution

In nginx.conf, this line shows that the server will be talking over http2 on port 8080:

        server {
        # love using the new stuff! -Bushy
                listen                  8080 http2;
                # server_name           localhost 127.0.0.1;
                root /var/www/html;

If I try to request the server root using just using normal curl, I get back what looks like binary garbage:

elf@3a9d6b4b52cd:~$ curl http://localhost:8080
^C.  . �^D^A���

That’s because http2 is a binary protocol, not the typical ascii protocol typically used with http1. Chris Elgee gives a good overview of HTTP/2 in his KringleCon talk on the subject.

If I look with the verbose flag on, I can see that my curl is trying to communicate, but it’s not offering http2:

elf@3a9d6b4b52cd:~$ curl -v http://localhost:8080/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.52.1
> Accept: */*
> 
* Curl_http_done: called premature == 0
* Connection #0 to host localhost left intact
^R^D  ^C �^D^A���

curl -h will print the various options for curl. There are 4 related to http:

elf@3a9d6b4b52cd:~$ curl -h | grep http 
 -0, --http1.0       Use HTTP 1.0 (H)
     --http1.1       Use HTTP 1.1 (H)
     --http2         Use HTTP 2 (H)
     --http2-prior-knowledge  Use HTTP 2 without HTTP/1.1 Upgrade (H)

--http2 seems like a good place to start. This time, I see curl offering the upgrade to http2, but it’s doing it over an http1 request. In the real world, this will typically work, as very few servers will just listen on http2 without http1. But in this case, the server still doesn’t understand the request, and sends back binary that curl isn’t expecting (comments added by me):

elf@3a9d6b4b52cd:~$ curl -v --http2 http://localhost:8080/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.52.1
> Accept: */*
> Connection: Upgrade, HTTP2-Settings
> Upgrade: h2c                                <-- offering upgrade to http2
> HTTP2-Settings: AAMAAABkAARAAAAA            <-- http2 specific settings
> 
* Curl_http_done: called premature == 0
* Connection #0 to host localhost left intact
^R^D  ^C �^D^A���

This is a perfect case for the --http-prior-knowledge flag. It tells curl to just start in http2 (comments added by me):

elf@3a9d6b4b52cd:~$ curl -v --http2-prior-knowledge http://localhost:8080/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
* Using HTTP2, server supports multi-use                <-- initial connection is http2
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x55d4003c8dc0)
> GET / HTTP/1.1                                  <-- GET request shows 1, but that
> Host: localhost:8080                                is likely just how curl is
> User-Agent: curl/7.52.1                             showing us
> Accept: */*
> 
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2 200                                      <-- actual response back understood
< server: nginx/1.10.3
< date: Sat, 22 Dec 2018 15:30:10 GMT
< content-type: text/html; charset=UTF-8
< 
<html>
 <head>
  <title>Candy Striper Turner-On'er</title>
 </head>
 <body>
 <p>To turn the machine on, simply POST to this URL with parameter "status=on"
 
 </body>
</html>
* Curl_http_done: called premature == 0
* Connection #0 to host localhost left intact

Ok, so the page suggests that we just need to POST with the parameter status=on. That’s easy enough to do. I’ll just add -X POST to tell curl to use a POST request, and -d to specify the data I want to send (and I’ve dropped the -v because I don’t need the headers any more):

elf@3a9d6b4b52cd:~$ curl --http2-prior-knowledge -X POST -d "status=on" http://localhost:8080/
<html>
 <head>
  <title>Candy Striper Turner-On'er</title>
 </head>
 <body>
 <p>To turn the machine on, simply POST to this URL with parameter "status=on"
                                                                                
                                                                okkd,          
                                                               OXXXXX,         
                                                              oXXXXXXo         
                                                             ;XXXXXXX;         
                                                            ;KXXXXXXx          
                                                           oXXXXXXXO           
                                                        .lKXXXXXXX0.           
  ''''''       .''''''       .''''''       .:::;   ':okKXXXXXXXX0Oxcooddool,   
 'MMMMMO',,,,,;WMMMMM0',,,,,;WMMMMMK',,,,,,occccoOXXXXXXXXXXXXXxxXXXXXXXXXXX.  
 'MMMMN;,,,,,'0MMMMMW;,,,,,'OMMMMMW:,,,,,'kxcccc0XXXXXXXXXXXXXXxx0KKKKK000d;   
 'MMMMl,,,,,,oMMMMMMo,,,,,,lMMMMMMd,,,,,,cMxcccc0XXXXXXXXXXXXXXOdkO000KKKKK0x. 
 'MMMO',,,,,;WMMMMMO',,,,,,NMMMMMK',,,,,,XMxcccc0XXXXXXXXXXXXXXxxXXXXXXXXXXXX: 
 'MMN,,,,,,'OMMMMMW;,,,,,'kMMMMMW;,,,,,'xMMxcccc0XXXXXXXXXXXXKkkxxO00000OOx;.  
 'MMl,,,,,,lMMMMMMo,,,,,,cMMMMMMd,,,,,,:MMMxcccc0XXXXXXXXXXKOOkd0XXXXXXXXXXO.  
 'M0',,,,,;WMMMMM0',,,,,,NMMMMMK,,,,,,,XMMMxcccckXXXXXXXXXX0KXKxOKKKXXXXXXXk.  
 .c.......'cccccc.......'cccccc.......'cccc:ccc: .c0XXXXXXXXXX0xO0000000Oc     
                                                    ;xKXXXXXXX0xKXXXXXXXXK.    
                                                       ..,:ccllc:cccccc:'      
                                                                               
Unencrypted 2.0? He's such a silly guy.
That's the kind of stunt that makes my OWASP friends all cry.
Truth be told: most major sites are speaking 2.0;
TLS connections are in place when they do so.
-Holly Evergreen
<p>Congratulations! You've won and have successfully completed this challenge.
<p>POSTing data in HTTP/2.0.
 </body>
</html>

Another achievement:

1546394935764

Hints

On solving, Holly tells me the following, and unlocks two hints about Bloodhound:

Unencrypted HTTP/2? What was he thinking? Oh well.

Have you ever used Bloodhound for testing Active Directory implementations?

It’s a merry little tool that can sniff AD and find paths to reaching privileged status on specific machines.

AD implementations can get so complicated that administrators may not even know what paths they’ve set up that attackers might exploit.

Have you seen anyone demo the tool before?

1546395459599 1546395470702

I’ll need to use Bloodhound to solve the this main objective.

AD Privilege Discovery

After downloading the image, I’ll import it into VirtualBox. It’s important to change the Machine type to 64-bit, as it seems to default to 32-bit. Then boot it up.

On the desktop, there’s a shortcut to Bloodhound, and on opening it, I’ll see it’s already populated with some data set. The default view is showing me the members of the Domain_Admins group:

1545503168380

Bloodhound has some queries you can run against the data, and one is “Shortest Paths to Domain Admins from Kerberoastable Users”:

1545503289888

Running that gives the possible paths:

1545503422091

If I cross out the links that involve “CanRDP” as instructed in the question, I one remaining path:

1545503459404

I can click on that user node to get information about the user, including the answer to this objective:

1545512947891

Answer: LDUBEJ00320@AD.KRINGLECASTLE.COM

Another achievement:

1546381216226