Day1
这个讲到的是in_array()
这个函数的一个错误使用导致的过滤不严格问题。
in_array()
函数的第三个函数是配置是否进行强匹配的,很多情况下使用者都会忽略第三个参数,从而只进行弱匹配。
一般用来限定输入只能是数组中的几个数值,但是当我们输入的是字符串的时候,由于是判断是否在一个数字数组中,所以会强制类型转换为数字。只要我们保证强制类型转换后的结果在数组中就可以了,这样就可以绕过只能输入数字的限制。
这个知识点很简单。
接下来做留的题目。
//index.php
<?php
include 'config.php';
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("连接失败: ");
}
$sql = "SELECT COUNT(*) FROM users";
$whitelist = array();
$result = $conn->query($sql);
if($result->num_rows > 0){
$row = $result->fetch_assoc();
$whitelist = range(1, $row['COUNT(*)']);
}
$id = stop_hack($_GET['id']);
$sql = "SELECT * FROM users WHERE id=$id";
if (!in_array($id, $whitelist)) {
die("id $id is not in whitelist.");
}
$result = $conn->query($sql);
if($result->num_rows > 0){
$row = $result->fetch_assoc();
echo "<center><table border='1'>";
foreach ($row as $key => $value) {
echo "<tr><td><center>$key</center></td><br>";
echo "<td><center>$value</center></td></tr><br>";
}
echo "</table></center>";
}
else{
die($conn->error);
}
?>
//config.php
<?php
$servername = "localhost";
$username = "fire";
$password = "fire";
$dbname = "day1";
function stop_hack($value){
$pattern = "insert|delete|or|concat|concat_ws|group_concat|join|floor|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile|dumpfile|sub|hex|file_put_contents|fwrite|curl|system|eval";
$back_list = explode("|",$pattern);
foreach($back_list as $hack){
if(preg_match("/$hack/i", $value))
die("$hack detected!");
}
return $value;
}
?>
# 搭建CTF环境使用的sql语句
create database day1;
use day1;
create table users (
id int(6) unsigned auto_increment primary key,
name varchar(20) not null,
email varchar(30) not null,
salary int(8) unsigned not null );
INSERT INTO users VALUES(1,'Lucia','Lucia@hongri.com',3000);
INSERT IN