CTFshow

php特性

web89:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php

include("flag.php");
highlight_file(__FILE__);

if(isset($_GET['num'])){
$num = $_GET['num'];
if(preg_match("/[0-9]/", $num)){
die("no no no!");
}
if(intval($num)){
echo $flag;
}
}

preg_match只能处理字符串,如果不按规定传一个字符串,通常是传一个数组进去,这样就会报错

intval() 函数用于获取变量的整数值。

intval() 函数通过使用指定的进制 base 转换(默认是十进制),返回变量 var 的 integer 数值。 intval() 不能用于 object,否则会产生 E_NOTICE 错误并返回 1。

先让第一个if不相等执行下一个语句,判断有无num,第二个if正则匹配[0-9],第三个if如果等于1的话,执行if里边的语句

1
?num[]=1

web90:

1
2
3
4
5
6
7
8
9
10
11
12
13
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==="4476"){
die("no no no!");
}
if(intval($num,0)===4476){
echo $flag;
}else{
echo intval($num,0);
}
}
1
== ===缺陷绕过 == 弱类型对比 ===还会比较类型

intval() 函数用于获取变量的整数值。

intval() 函数通过使用指定的进制 base 转换(默认是十进制),返回变量 var 的 integer 数值。 intval() 不能用于 object,否则会产生 E_NOTICE 错误并返回 1。

强类型比较 把4476转换成十六进制

1
?num=0x117c

image-20220410180533122img.png

web91:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
show_source(__FILE__);
include('flag.php');
$a=$_GET['cmd'];
if(preg_match('/^php$/im', $a)){
if(preg_match('/^php$/i', $a)){
echo 'hacker';
}
else{
echo $flag;
}
}
else{
echo 'nonononono';
}

preg_match先看这个函数:preg_match 函数用于执行一个正则表达式匹配。

看第一个if匹配php,第二个if匹配到php输出hacker,要输出第三个else则需要绕过第二个if,用正则表达式来绕过

/i表示匹配大小写
字符 ^ 和 $ 同时使用时,表示精确匹配,需要匹配以php开头和以php结尾
/m 多行匹配 若存在换行\n并且有开始^或结束$符的情况下,将以换行为分隔符,逐行进行匹配
但是当出现换行符 %0a的时候,$cmd的值会被当做两行处理,而此时第二个if正则匹配不符合以php开头和以php结尾

1
/?cmd=%0aphp

web92:

1
2
3
4
5
6
7
8
9
10
11
12
13
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==4476){
die("no no no!");
}
if(intval($num,0)==4476){
echo $flag;
}else{
echo intval($num,0);
}
}

弱类型比较,十六进制可绕过

1
2
?num=4476.1
?num=0x117c

web93:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==4476){
die("no no no!");
}
if(preg_match("/[a-z]/i", $num)){
die("no no no!");
}
if(intval($num,0)==4476){
echo $flag;
}else{
echo intval($num,0);
}
}

可以看到过滤了[a-z],和上题一样,用浮点数绕过

1
?nmu=4476.1

web94:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==="4476"){
die("no no no!");
}
if(preg_match("/[a-z]/i", $num)){
die("no no no!");
}
if(!strpos($num, "0")){
die("no no no!");
}
if(intval($num,0)===4476){
echo $flag;
}
}

strpos() f函数查找字符串在另一字符串中第一次出现的位置(区分大小写)。

=== 强类型比较,绕过去之后preg_match[a-z]/i,第三个if出现了一个函数strpos

image-20220410181801815

因为八进制需要开头指定为0,而strpos()会匹配到返回0,!0也就是1得执行die,我们可以在前面加个空格,这样strpos()会返回1,所以我们把4476转换为8进制10574后,前面再加一个空格即可,payload为

1
2
?num=%20010574
还一种思路:?num=4476.0

web95:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==4476){
die("no no no!");
}
if(preg_match("/[a-z]|\./i", $num)){
die("no no no!!");
}
if(!strpos($num, "0")){
die("no no no!!!");
}
if(intval($num,0)===4476){
echo $flag;
}
}

弱类型比较,思路一样

1
?num=%20010574

web96:

1
2
3
4
5
6
7
8
9
10
11
highlight_file(__FILE__);

if(isset($_GET['u'])){
if($_GET['u']=='flag.php'){
die("no no no");
}else{
highlight_file($_GET['u']);
}


}

弱类型,读取flag.php文件

1
?u=./flag.php

web97:

1
2
3
4
5
6
7
8
9
10
include("flag.php");
highlight_file(__FILE__);
if (isset($_POST['a']) and isset($_POST['b'])) {
if ($_POST['a'] != $_POST['b'])
if (md5($_POST['a']) === md5($_POST['b']))
echo $flag;
else
print 'Wrong.';
}
?>

POST发包输出个a再输出个b且强类型比较md5加密了,两个NULL值相等即可

payload:

1
2
POST:
a[]=1&bp[]=2