Skip to content

Intercepting Requests to Unlock Hidden Functionality

When you fill out a form on a website and hit submit, your browser constructs a POST request and sends it to the website so that it can decide what to do with that information. It would contain not only the data you entered into the form but information about your login session and a cross-site request forgery token (hopefully).

If you're interested in understanding a website's functionality, capturing requests as they exit your browser lets you examine how to effectively interact with the site, as these requests are crafted by developers to elicit successful responses. You can use this insight to create custom requests, which can sometimes yield intriguing results.

Let's look at how to do that with a simple example.

Example: Status Cafe

We'll be using this cute site, status.cafe, a simple status sharing website to demonstrate how this can be quite neat.

Intercept the Request

  1. Open the browser (we're assuming you're using chrome/chromium based browser)
  2. Navigate to status.cafe (assuming you have already made your account)
  3. CTRL+SHIFT+I to open developer tools
  4. Click the network tab
  5. Fill out the status updating form
  6. Hit submit.
  7. Look in the network tab for add
  8. Right click it, select Copy > Copy as cURL
  9. Paste into a text editor.

Refer to the image above for visual aid.

Analyzing the Curl Command

WARNING: It's probably a good time to say that you have to guard the information in this command. It contains sensitive data that someone can act on behalf of your account without having your password if they see it.

It will look something like this. Of course I've removed the sensitive parts.

curl 'https://status.cafe/add' \
  -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7' \
  -H 'Accept-Language: en-US,en;q=0.9' \
  -H 'Cache-Control: max-age=0' \
  -H 'Connection: keep-alive' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -b '_gorilla_csrf=YOUR_CSRF_TOKEN_WILL_BE_HERE' \
  -H 'Origin: https://status.cafe' \
  -H 'Referer: https://status.cafe/' \
  -H 'Sec-Fetch-Dest: document' \
  -H 'Sec-Fetch-Mode: navigate' \
  -H 'Sec-Fetch-Site: same-origin' \
  -H 'Sec-Fetch-User: ?1' \
  -H 'Upgrade-Insecure-Requests: 1' \
  -H 'User-Agent: REDACTED' \
  -H 'sec-ch-ua: "REDACTED"' \
  -H 'sec-ch-ua-mobile: REDACTED' \
  -H 'sec-ch-ua-platform: "REDACTED"' \
  --data-raw 'gorilla.csrf.Token=YOUR_CSRF_TOKEN_WILL_BE_HERE&face=%F0%9F%99%83&content=I%27m+going+to+write+a+quick+blog+post+before+going+to+bed.'

The part that we want to look at is this line right here

--data-raw 'gorilla.csrf.Token=YOUR_CSRF_TOKEN_WILL_BE_HERE&face=%F0%9F%99%83&content=I%27m+going+to+write+a+quick+blog+post+before+going+to+bed.'

The CSRF token is here: gorilla.csrf.Token=YOUR_CSRF_TOKEN_WILL_BE_HERE The emoji from the form is here: face=%F0%9F%99%83 The text of your status is here: content=I%27m+going+to+write+a+quick+blog+post+before+going+to+bed.'

Constructing Our Own Command

Let's write a bash script.

We'll save this into a file update_status_cafe.sh and we'll pass it two arguments.

#!/bin/bash

text="$1"   # First arg: text (e.g., "hello world")
emoji="$2"  # Second arg: emoji (e.g., "🙂")

encoded_text=$(printf "%s" "$text" | jq -sRr '@uri' | sed 's/%20/+/g')
encoded_emoji=$(printf "%s" "$emoji" | jq -sRr '@uri')

curl 'https://status.cafe/add' \
  -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7' \
  -H 'Accept-Language: en-US,en;q=0.9' \
  -H 'Cache-Control: max-age=0' \
  -H 'Connection: keep-alive' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -b '_gorilla_csrf=YOUR_CSRF_TOKEN_WILL_BE_HERE' \
  -H 'Origin: https://status.cafe' \
  -H 'Referer: https://status.cafe/' \
  -H 'Sec-Fetch-Dest: document' \
  -H 'Sec-Fetch-Mode: navigate' \
  -H 'Sec-Fetch-Site: same-origin' \
  -H 'Sec-Fetch-User: ?1' \
  -H 'Upgrade-Insecure-Requests: 1' \
  -H 'User-Agent: REDACTED' \
  -H 'sec-ch-ua: "REDACTED"' \
  -H 'sec-ch-ua-mobile: REDACTED' \
  -H 'sec-ch-ua-platform: "REDACTED"' \
  --data-raw "gorilla.csrf.Token=YOUR_CSRF_TOKEN_WILL_BE_HERE&face=$encoded_emoji&content=$encoded_text"

And we'll call the command like so

bash update_status_cafe.sh "Hello From Curl!" "🤓"

What's Cool About This

You probably noticed that the status.cafe form doesn't have a nerd face emoji.

It does have 90-100 emojis for you to pick from using the default form on the site but if you construct a curl command, you can pass in something like 3,782 possible options.

One Last Bit of Advice

We used an example site where leaving a bash script like this around means the worst that can happen is an attacker who finds this file could post something stupid on your status.cafe, but if you're analyzing the authenticated requests of more security-critical sites and leaving the data around on your machine in plain text, that is a bad thing.

Don't do anything I wouldn't do.