<?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>
由于表编码(不正确),如果要在名称中插入unicode字符,例如输出将被截断,从而导致可能的对象注入
示例:
数据集1:无注入
数据集2:对象注入
评论=随便
表数据值= a:2:{s:4:“name”; s: 69 :“John”; O:8:“stdClass”:1:{s :4: “测试”; I:1;}; S:4:等等; S:1: “注释”}
在最后一种情况下,我们可以看到注入实际上有些成功,但是,与名称(John)相关的值的字符串长度不正确,它应该是4而不是 69 使注入成功,以便在调用unserialize时执行。
我尝试了几种方法,例如插入空字符,退格字符,删除字符等等,但是我无法使其工作。
开发人员说“它并不脆弱”所以我希望有人可以帮助我找到它实际上很脆弱的证据。
感谢您的时间。