прежде всего я хотел бы заявить, что я бы НИКОГДА сделай что-нибудь подобное Я провожу небольшой аудит проекта и обнаружил, что они сериализуют весь массив $ _POST и сохраняют их как комментарии к статьям. Я повторил сценарий в следующем коде:
<?php
/*
CREATE TABLE `comments` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`data` mediumtext NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
*/
ini_set('display_errors','On');
error_reporting(E_ALL);
$comments = Array();
try{
$options = [
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET CHARACTER SET utf8'
];
$dsn = 'mysql:host=localhost;dbname=test';
$pdo = new \PDO($dsn,'user','password',$options);
$pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
if($_POST){
$comment = serialize($_POST);
$sql = "INSERT INTO comments SET data = :data";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':data',serialize($_POST));
$stmt->execute();
}
$stmt = $pdo->prepare('SELECT data FROM comments');
$stmt->execute();
$comments = $stmt->fetchAll(PDO::FETCH_ASSOC);
}catch(\Exception $e){
echo $e->getMessage();
}
?>
<html>
<head>
<title>My nice little comment form</title>
</head>
<body>
<form method="POST" action="" enctype="text/plain">
<label for="name">Name</label>
<input type="text" name="name" />
<br />
<label for="comment">Comment</label>
<textarea name="comment"></textarea>
<br />
<input type="submit" value="Send" />
</form>
<?php foreach($comments as $comment):?>
<?php $data = unserialize($comment['data']);?>
<p>Name: <?php echo $data['name']; ?></p>
<p><?php echo $data['comment'];?></p>
<?php endforeach;?>
</body>
</html>
Из-за кодировки таблицы (что неверно), если вы добавите в имя юникод-символ, например, , результат будет урезан, что приведет к возможному внедрению объекта
Примеры:
Набор данных 1: без инъекций
Набор данных 2: Внедрение объекта
комментарий = что угодно
Значение данных таблицы = a: 2: {s: 4: «имя»; s:69: «Джон»; O: 8: «StdClass»: 1: {s: 4: «тест»; я: 1;}; s: 4: бла; s: 1: «комментарий»}
В последнем случае мы видим, что внедрение на самом деле несколько успешное, однако длина строки значения, относящегося к имени (Джон), неверна, она должна быть 4 вместо 69 чтобы внедрение было успешным для выполнения при вызове unserialize.
Я пробовал несколько подходов, таких как вставка нулевых символов, символов возврата на задний план, удаление символов и что нет, но я не могу заставить его работать.
Разработчики говорят «это не уязвимо», поэтому я надеялся, что кто-нибудь может помочь мне найти доказательства того, что он действительно уязвим.
Спасибо за ваше время.
Задача ещё не решена.
Других решений пока нет …