Как продемонстрировать SQL-инъекцию второго порядка?

Поэтому я пытаюсь реплицировать SQL Injection второго порядка. Вот пример шаблона из двух php-сайтов, которые я подготовил. Давайте просто назовем это регистрационной формой избирателя. Пользователь может зарегистрироваться, а затем вы можете проверить, являетесь ли вы зарегистрированным избирателем или нет.

insert.php

<?php $db_selected = mysql_select_db('canada',$conn); if (!db_selected) die("can't use mysql: ". mysql_error()); $sql_statement = "INSERT into canada (UserID,FirstName,LastName,Age,State,Town) values ('".mysql_real_escape_string($_REQUEST["UserID"])."', '".mysql_real_escape_string($_REQUEST["FirstName"])."', '".mysql_real_escape_string($_REQUEST["LastName"])."', ".intval($_REQUEST["Age"]).", '".mysql_real_escape_string($_REQUEST["State"])."', '".mysql_real_escape_string($_REQUEST["Town"])."')"; echo "You ran the sql query=".$sql_statement."<br/>"; $qry = mysql_query($sql_statement,$conn) || die (mysql_error()); mysql_close($conn); Echo "Data inserted successfully"; } ?> 

select.php

 <?php $db_selected = mysql_select_db('canada', $conn); if(!db_selected) die('Can\'t use mysql:' . mysql_error()); $sql = "SELECT * FROM canada WHERE UserID='".addslashes($_POST["UserID"])."'"; echo "You ran the sql query=".$sql."<br/>"; $result = mysql_query($sql,$conn); $row=mysql_fetch_row($result); $sql1 = "SELECT * FROM canada WHERE FirstName = '".$row[1]."'"; echo "The web application ran the sql query internally=" .$sql1. "<br/>"; $result1 = mysql_query($sql1, $conn); $row1 = mysql_fetch_row($result1); mysql_close($conn); echo "<br><b><center>Database Output</center></b><br><br>"; echo "<br>$row1[1] $row1[2] , you are a voter! <br>"; echo "<b>VoterID: $row[0]</b><br>First Name: $row[1]<br>Last Name: $row[2] <br>Age: $row[3]<br>Town: $row[4]<br>State: $row[5]<br><hr><br>"; } ?> 

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

Например: я введу на страницу insert.php как: userid = 17

firstname = (мне нужно что-то вводить)

lastname = ..

возраст = ..

Город = ..

state = ..

Затем, когда я проверяю свои данные и набираю 17, будет запущен SQL-скрипт. Могу ли я получить несколько примеров того, какие уязвимости я могу показать через это?

Использование имени:

 ' OR 1 OR ' 

Это создаст предложение where во втором SQL

WHERE FirstName = '' ИЛИ ​​1 ИЛИ ''

Поэтому результатом будет первая запись в таблице.

Добавив предложение LIMIT, вы можете извлечь все строки из таблицы:

'ИЛИ 1 ORDER BY UserID ASC LIMIT 0, 1 –

Очевидно, что он будет извлекать только одну строку за раз, поэтому вам нужно будет повторить это и увеличить 0 в LIMIT. В этом примере используется комментарий -- для завершения оставшегося SQL, который в противном случае вызывал бы запрос, потому что он добавил бы одну цитату после вашего LIMIT.

Вышеприведенный пример является простым примером, более сложной атакой было бы использовать UNION SELECT, который предоставит вам доступ ко всей БД с помощью information_schema.

Также вы используете addslashes() в одном из своих запросов. Это не так безопасно, как mysql_real_escape_string() и в свою очередь: экранирование кавычек с помощью либо не так безопасно, как использование подготовленных операторов или параметризованных запросов, например, в PDO или MySQLi.

Что нужно продемонстрировать?

SQL-инъекция второго порядка – это не что иное, как инъекция SQL, но небезопасный код не является первой строкой.

Итак, чтобы продемонстрировать:

1) Создайте строку ввода SQL, которая сделает что-то нежелательное при выполнении без экранирования.

2) Храните эту строку безопасно в своей БД (с экранированием).

3) Пусть какой-нибудь другой фрагмент вашего кода FETCH, который строит, и использовать его в другом месте, не избегая.

EDIT: добавлен пример кода:

Стол:

 CREATE TABLE tblUsers ( userId serial PRIMARY KEY, firstName TEXT ) 

Предположим, у вас есть какой-то SAFE-код, похожий на это, получив имя из формы:

 $firstname = someEscapeFunction($_POST["firstname"]); $SQL = "INSERT INTO tblUsers (firstname) VALUES ('{$firstname }');"; someConnection->execute($SQL); 

Пока что так хорошо, если предположить, что someEscapeFunction () выполняет прекрасную работу. Невозможно добавить SQL.

Если бы я отправил в качестве значения для первого имени следующую строку, вы бы не возражали:

л '); УДАЛИТЬ ИЗ tblUsers; //

Теперь предположим, что кто-то из одной системы хочет перенести firstName из tblUsers в tblWhatever и делает это вот так:

 $userid = 42; $SQL = "SELECT firstname FROM tblUsers WHERE (userId={$userid})"; $RS = con->fetchAll($SQL); $firstName = $RS[0]["firstName"]; 

А затем вставляет его в tblВ любом случае без экранирования:

 $SQL = "INSERT INTO tblWhatever (firstName) VALUES ('{$firstName}');"; 

Теперь, если firstname содержит некоторый файл deleteecommand, он все равно будет выполнен.