Repository navigation
Expand file tree
/
Copy path8.html
More file actions
293 lines (261 loc) · 14.4 KB
/
Copy path8.html
File metadata and controls
293 lines (261 loc) · 14.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="author" content="AnnaWiktoria">
<meta name="copyright" content="AnnaWiktoria">
<meta name="description" content="Interaktywny kurs bezpieczeństwa aplikacji webowych. Licencja CC BY-NC-SA.">
<meta http-equiv="Content-Security-Policy" content="default-src 'self';
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
font-src 'self' https://fonts.gstatic.com;
script-src 'self' 'unsafe-inline';
img-src 'self' data:;">
<title>Kurs bezpieczeństwa aplikacji webowych - Lekcja 08: SQL Injection</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css">
<style>
/* Akcent: Toxic Green (Code Injection / Matrix) */
:root {
--accent: #39ff14;
--accent-glow: rgba(57, 255, 20, 0.3);
}
.sql-keyword {
color: #ff0055;
font-weight: bold;
}
/* Słowa kluczowe SQL */
.sql-string {
color: #ffd600;
}
/* Tekst w SQL */
.sql-input {
color: #39ff14;
font-weight: bold;
text-decoration: underline;
}
/* Wstrzyknięty kod */
</style>
</head>
<body>
<div class="container">
<header>
<h1>SQL INJECTION</h1>
<p>MODUŁ 08: ' OR 1=1 -- // Przejmowanie bazy danych</p>
</header>
<!-- 1. MECHANIZM -->
<section>
<h2>> JAK TO DZIAŁA?</h2>
<p>SQL Injection (SQLi) występuje, gdy aplikacja bierze dane od użytkownika i <strong>skleja je</strong> z
zapytaniem do bazy danych, zamiast je odseparować.</p>
<div class="card">
<h3>ANATOMIA ATAKU</h3>
<p>Wyobraź sobie kod logowania w PHP (zły kod):</p>
<pre><code>$sql = "SELECT * FROM users WHERE name = '" . <span class="highlight">$user</span> . "'";</code></pre>
<p>Jeśli wpiszesz <code>admin</code>, zapytanie wygląda tak:</p>
<pre><code>SELECT * FROM users WHERE name = '<span class="sql-string">admin</span>'</code></pre>
<p>Ale jeśli wpiszesz <code>admin' OR '1'='1</code>, zapytanie zmienia się w:</p>
<pre><code>SELECT * FROM users WHERE name = '<span class="sql-string">admin</span><span class="sql-input">' OR '1'='1</span>'</code></pre>
<p><strong>Efekt:</strong> Baza danych sprawdza: "Czy nazwa to admin? NIE. Czy 1 równa się 1? TAK."
<br>Warunek jest spełniony dla każdego rekordu. Jesteś zalogowany.</p>
</div>
</section>
<!-- 2. TYPY SQLi -->
<section>
<h2>> TYPY SQL INJECTION</h2>
<p>Nie zawsze jest tak łatwo. Czasem nie widzisz błędów.</p>
<div class="card">
<h3>1. IN-BAND (CLASSIC)</h3>
<p>Widzisz wyniki ataku bezpośrednio na stronie.</p>
<ul>
<li><strong>Error-Based:</strong> Strona wyświetla błąd bazy danych (np. "SQL Syntax Error"), który
zdradza strukturę bazy.</li>
<li><strong>UNION-Based:</strong> Używasz operatora <code>UNION SELECT</code>, aby dokleić wyniki z
innej tabeli do wyników widocznych na stronie (np. wyświetlasz hasła w miejscu tytułów
artykułów).</li>
</ul>
</div>
<div class="card">
<h3>2. BLIND (ŚLEPE)</h3>
<p>Strona nie pokazuje błędów ani danych, ale reaguje inaczej na prawdę i fałsz.</p>
<ul>
<li><strong>Boolean-Based:</strong> Pytasz bazy: <em>"Czy hasło zaczyna się na 'A'?"</em>
(<code>AND substring(pass,1,1)='A'</code>). Jeśli strona ładuje się normalnie -> TAK. Jeśli
brakuje elementu -> NIE.</li>
<li><strong>Time-Based:</strong> Pytasz: <em>"Jeśli jestem adminem, poczekaj 10 sekund"</em>
(<code>WAITFOR DELAY '0:0:10'</code>). Jeśli strona mieli 10 sekund -> Jesteś adminem.</li>
</ul>
</div>
</section>
<!-- 3. NARZĘDZIA I OBRONA -->
<section>
<h2>> NARZĘDZIA I OBRONA</h2>
<div class="card">
<h3>SQLMAP - AUTOMATYZACJA</h3>
<p>To potężne narzędzie w terminalu. Wykrywa i eksploatuje większość błędów SQLi.</p>
<pre><code>sqlmap -u "http://target.com/page?id=5" --dbs</code></pre>
<p><span class="comment">// Komenda powyżej spróbuje wyciągnąć listę baz danych.</span></p>
</div>
<div class="card" style="border-color: var(--success);">
<h3>JEDYNA SKUTECZNA OBRONA</h3>
<p>Nie "filtrowanie znaków". Nie "Firewalle".</p>
<p>Jedynym lekiem są <strong>Prepared Statements (Parametryzowane Zapytania)</strong>.</p>
<pre><code><span class="comment">// Bezpieczny kod:</span>
$stmt = $pdo->prepare('SELECT * FROM users WHERE name = :name');
$stmt->execute(['name' => $userInput]);</code></pre>
<p>W tym przypadku baza danych traktuje wejście <strong>zawsze jako tekst</strong>, a nie kod
wykonywalny. Nawet <code>' OR 1=1</code> zostanie potraktowane jako dziwne imię użytkownika.</p>
</div>
</section>
<!-- CHECKLIST -->
<section>
<h2>CHECKLISTA / RED FLAGS</h2>
<div class="card checklist-card">
<div class="checklist-item">
<span class="check-icon">⚠</span>
<div><strong>Błąd 500 po wpisaniu apostrofu ( ' ):</strong> Najsilniejszy sygnał, że zapytanie SQL
się "rozjechało".</div>
</div>
<div class="checklist-item">
<span class="check-icon">⚠</span>
<div><strong>Parametry ID w URL:</strong> `product.php?id=10`. Zmień na `10-1`. Jeśli wyświetli
produkt 9 -> Baza wykonuje matematykę -> SQLi możliwe.</div>
</div>
<div class="checklist-item">
<span class="check-icon">⚠</span>
<div><strong>Formularze wyszukiwania i logowania:</strong> To najczęstsze punkty wejścia.</div>
</div>
</div>
</section>
<!-- QUIZ -->
<section id="quiz-section">
<h2>🎓 WERYFIKACJA WIEDZY</h2>
<div id="quiz-container"></div>
</section>
<footer>
<p style="text-align: center; margin-top: 50px; color: #555;">© 2026 Hack & Learn: Web Edition | Moduł 08</p>
</footer>
</div>
<!-- DANE DO QUIZU -->
<script>
const quizData = [
{
question: "Co to jest SQL Injection?",
options: [
"Błąd polegający na wstrzyknięciu złośliwego kodu JavaScript do przeglądarki.",
"Błąd polegający na manipulacji zapytaniem do bazy danych poprzez nieodpowiednio przefiltrowane dane wejściowe.",
"Atak polegający na zgadywaniu haseł.",
"Przeciążenie bazy danych dużą liczbą zapytań."
],
correct: 1,
explanation: "SQLi dzieje się, gdy aplikacja nie odróżnia kodu SQL od danych użytkownika, pozwalając atakującemu zmienić logikę zapytania."
},
{
question: "Który znak jest najczęściej używany do testowania (wywoływania błędu) w SQL Injection?",
options: [
"Znak zapytania (?)",
"Pojedynczy apostrof (')",
"Wykrzyknik (!)",
"Kropka (.)"
],
correct: 1,
explanation: "Pojedynczy apostrof (') służy w SQL do zamykania ciągów tekstowych. Wpisanie go często 'psuje' składnię zapytania, co powoduje błąd serwera."
},
{
type: "scenario",
question: "Widzisz panel logowania. Wpisujesz w pole login: admin' OR '1'='1 -- . Co próbujesz osiągnąć?",
options: [
"Chcesz usunąć bazę danych.",
"Chcesz obejść uwierzytelnianie (Authentication Bypass) poprzez sprawienie, że warunek WHERE będzie zawsze prawdziwy.",
"Chcesz wywołać błąd XSS.",
"Chcesz zaszyfrować hasło."
],
correct: 1,
explanation: "Ponieważ 1=1 jest zawsze prawdą, a operator OR sprawia, że wystarczy jeden prawdziwy warunek, baza zwraca pierwszy rekord (zazwyczaj admina) i loguje Cię."
},
{
question: "Na czym polega 'Blind SQL Injection'?",
options: [
"Atakujący ma zawiązane oczy.",
"Aplikacja nie zwraca żadnych danych ani błędów z bazy, ale zachowuje się inaczej w zależności od tego, czy zapytanie jest prawdziwe, czy fałszywe.",
"Atak działa tylko w nocy.",
"Baza danych jest ukryta za firewallem."
],
correct: 1,
explanation: "W 'ślepym' ataku bawisz się w 'ciepło-zimno'. Zadajesz pytania Tak/Nie (np. czy hasło zaczyna się na 'A'?) i obserwujesz reakcję aplikacji (czas ładowania, długość treści)."
},
{
question: "Jaki jest najskuteczniejszy sposób obrony przed SQL Injection?",
options: [
"Filtrowanie słów 'SELECT' i 'UNION'.",
"Używanie Prepared Statements (zapytań parametryzowanych).",
"Szyfrowanie bazy danych.",
"Ukrywanie błędów serwera."
],
correct: 1,
explanation: "Prepared Statements oddzielają strukturę zapytania od danych. Baza wie, że to, co wpisał użytkownik, to TYLKO tekst, a nie komenda SQL."
},
{
type: "scenario",
question: "Testujesz URL: sklep.php?id=10. Zmieniasz go na sklep.php?id=10-1. Strona wyświetla produkt o ID 9. Co to oznacza?",
options: [
"Aplikacja wykonuje operacje matematyczne wewnątrz zapytania SQL. To silny wskaźnik podatności na SQL Injection.",
"To normalne zachowanie PHP.",
"Aplikacja ma błąd XSS.",
"Serwer jest przeciążony."
],
correct: 0,
explanation: "Jeśli `10-1` działa jak `9`, to znaczy, że Twój input trafił bezpośrednio do silnika bazy danych (który wykonał odejmowanie). Masz punkt zaczepienia!"
},
{
question: "Co robi operator UNION w ataku SQL Injection?",
options: [
"Łączy atakującego z serwerem.",
"Pozwala połączyć wyniki oryginalnego zapytania z wynikami zapytania wstrzykniętego przez atakującego (np. wypisać loginy i hasła na ekranie).",
"Tworzy nową tabelę.",
"Usuwa duplikaty."
],
correct: 1,
explanation: "UNION to potężne narzędzie. Jeśli strona wyświetla listę produktów, możesz użyć UNION, aby na tej samej liście wyświetlić zawartość tabeli 'users'."
},
{
question: "Co oznacza podwójny myślnik (--) w SQL?",
options: [
"Operator odejmowania.",
"Znak komentarza. Wszystko po nim jest ignorowane przez bazę danych.",
"Koniec linii.",
"Błąd składni."
],
correct: 1,
explanation: "Hakerzy używają `--` (lub `#` w MySQL), aby 'uciąć' resztę oryginalnego zapytania (np. sprawdzanie hasła), które mogłoby spowodować błąd składni."
},
{
type: "scenario",
question: "Używasz narzędzia sqlmap i widzisz komunikat: 'GET parameter 'id' seems to be 'AND boolean-based blind'. Co to znaczy?",
options: [
"Parametr jest bezpieczny.",
"Narzędzie wykryło, że może zadawać pytania Prawda/Fałsz i na tej podstawie wyciągać dane, mimo braku widocznych błędów.",
"Musisz użyć przeglądarki.",
"Baza danych jest wyłączona."
],
correct: 1,
explanation: "Sqlmap automatyzuje żmudny proces Blind SQLi, zadając tysiące pytań logicznych do serwera, aby literka po literce odczytać nazwę bazy i tabele."
},
{
question: "Dlaczego samo 'ukrywanie błędów' (wyłączenie verbose errors) nie chroni przed SQL Injection?",
options: [
"Bo hakerzy mają specjalne okulary.",
"Bo nadal możliwe są ataki typu Blind SQL Injection (Time-based lub Boolean-based), które nie wymagają widocznych komunikatów błędów.",
"Bo błędy i tak są w logach.",
"Chroni, to wystarczające zabezpieczenie."
],
correct: 1,
explanation: "Ukrycie błędów utrudnia sprawę (zmienia Classic SQLi w Blind SQLi), ale nie usuwa podatności. Dziura nadal tam jest, tylko trudniej ją zauważyć."
}
];
</script>
<script src="quiz.js"></script>
</body>
</html>