Appendix B: Open Locks Tampermonkey

For details on each lock, see Objective 11.

The full source for the Open Locks TamperMonkey script follows:

// ==UserScript==
// @name         Open Locks
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       0xdf
// @match        https://crate.elfu.org/
// @grant        GM.xmlHttpRequest
// @run-at       document-start
// ==/UserScript==


console.log = (function() {
    var orig = console.log;

    return function(text) {
        if (! window.logs) {
            window.logs = [];
        }

        window.logs.push(text);

        orig.call(console, text);
    }
})();


window.addEventListener('load', function() {
    unlock();
}, false);

function unlock(){
    document.querySelector('div.c2 > input').value = document.querySelector('div.libra>strong').textContent;
    document.querySelector('div.c2 > button').disabled = false;
    document.querySelector('div.c2 > button').click();
    document.querySelector('div.c4 > input').value = window.localStorage.getItem('🛢️🛢️🛢️');
    document.querySelector('div.c4 > button').disabled = false;
    document.querySelector('div.c4 > button').click();
    document.querySelector('div.c5 > input').value = window.document.title.slice(-8);
    document.querySelector('div.c5 > button').disabled = false;
    document.querySelector('div.c5 > button').click();
    document.querySelector('div.c6 > input').value = document.querySelector('.ZADFCDIV').textContent + document.querySelector('.GMSXHBQH').textContent + document.querySelector('.RPSMZXMY').textContent + document.querySelector('.IDOIJIKV').textContent + document.querySelector('.KXTBRPTJ').textContent + document.querySelector('.AJGXPXJV').textContent + document.querySelector('.ZWYRBISO').textContent + document.querySelector('.KPVVBGSG').textContent;
    document.querySelector('div.c6 > button').disabled = false;
    document.querySelector('div.c6 > button').click();
    document.querySelector('div.c7 > input').value = window.getComputedStyle(document.querySelector('.instructions'), null).getPropertyValue('font-family').split('"')[1]
    document.querySelector('div.c7 > button').disabled = false;
    document.querySelector('div.c7 > button').click();
    document.querySelector('div.c8 > input').value = "VERONICA"
    document.querySelector('div.c8 > button').disabled = false;
    document.querySelector('div.c8 > button').click();
    var lock10 = document.querySelector('div.c10');
    var led10 = document.querySelector('div.c10 > .led-indicator');
    var mac = document.querySelector('.macaroni');
    var swab = document.querySelector('.swab');
    var gnome = document.querySelector('.gnome');
    lock10.insertBefore(mac, led10)
    lock10.insertBefore(swab, led10)
    lock10.insertBefore(gnome, led10)
    document.querySelector('div.c10 > input').value = "KD29XJ37"
    document.querySelector('div.c10 > button').disabled = false;
    document.querySelector('div.c10 > button').click();

    var i,j, sel = /:active/;
    var res = ''
    for(i = 0; i < document.styleSheets.length; ++i){
        try {
            if(!document.styleSheets[i].cssRules) {
                continue;
            }
            for(j = 0; j < document.styleSheets[i].cssRules.length; ++j){
                if(sel.test(document.styleSheets[i].cssRules[j].selectorText)){
                    res = res + document.styleSheets[i].cssRules[j].style.cssText.split('"')[1]
                    console.log(document.styleSheets[i].cssRules[j].style.cssText)
                    console.log("new res = " + res)
                }
            }
        } catch(e) {
            if(e.name !== 'SecurityError') {
                throw e;
            }
        }
    }
    console.log("final res: " + res)
    document.querySelector('div.c9 > input').value = res;

    document.querySelector('div.c9 > button').disabled = false;
    document.querySelector('div.c9 > button').click();

    var guid = document.getElementsByTagName('link')[0].href.split('/')[5]
        GM.xmlHttpRequest({
        method: "GET",
        url: "/client.js/" + guid,
        onload: function(response) {
            var esc_code = response.responseText;
            var position = esc_code.indexOf("]('\\x25\\x63\\u258b\\x0a\\x25\\x63") + 29;
            var code = "";
            if(position > 100){
                for(var n = position; n < position + 32; n+=4) {
                    code += String.fromCharCode(parseInt(esc_code.substr(n+2, n+4), 16));
                }
            document.querySelector('div.c1> input').value = code
            document.querySelector('div.c1> button').disabled = false;
            document.querySelector('div.c1> button').click();
            } else {
                location.reload();
            }
        }
    });

    GM.xmlHttpRequest({
        method: "POST",
        url: "https://microsoft-azure-microsoft-computer-vision-v1.p.rapidapi.com/ocr",
        data: JSON.stringify({"url": "https://crate.elfu.org/images/" + guid + ".png"}),
        headers: {
            "x-rapidapi-host": "microsoft-azure-microsoft-computer-vision-v1.p.rapidapi.com",
            "x-rapidapi-key": "[redacted]",
            "content-type": "application/json",
	        "accept": "application/json"
        },
        onload: function(response) {
            var code = JSON.parse(response.responseText).regions[0].lines[0].words[0].text;
            document.querySelector('div.c3 > input').value = code
            document.querySelector('div.c3 > button').disabled = false;
            document.querySelector('div.c3 > button').click();
        }
    });
}

It will try to get the Javascript with the less obfuscated code for lock 1. If it fails to get that version, it will refresh the page.

Sometimes the OCR will fail. This will leave lock 3 unopened. Refreshing the page will try again. When it works, it’s very fast, ~0.5-1.5 seconds.