编程语言
首页 > 编程语言> > CTFSHOW-PHP特性

CTFSHOW-PHP特性

作者:互联网

WEB89

题目:

<?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;
    }
}

知识点:

数组绕过正则表达式

1、preg_match()

preg_match()返回 pattern 的匹配次数。 它的值将是0次(不匹配)或1次,因为preg_match()在第一次匹配后 将会停止搜索。preg_match_all()不同于此,它会一直搜索subject 直到到达结尾。 如果发生错误preg_match()返回 false

preg_match只能处理字符串,如果不按规定传一个字符串,通常是传一个数组进去,这样就会报错,从而返回false,达到我们的目的。

2、intval()

 获取变量的整数值

只有value 是一个字符串时,base才会起作用。

通过使用指定的进制 base 转换(默认是十进制),成功时返回 value 的 integer 值,失败时返回 0。 空的 array 返回 0,非空的 array 返回 1。 intval() 不能用于 object,否则会产生 E_NOTICE 错误并返回 1。

intval()函数,如果$base为0,则$var中存在字母的话遇到字母就停止

方法:

payload:?num[]=1

WEB90

题目:

<?php

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、

==只比较值是否相等,比如'1'==1是相等的(弱比较),在进行数值的比较时会进行进制的转换,如16==0x10是正确的,而16==‘0x10’是不对的,后面的‘0x10’转换为数字是等于0,16==‘16.0’是正确的,16==‘16.1’是错误的。

=是赋值,比如:$a=2;$a=$q;这时你无论echo $a还是echo $q都会输出2, 

全等===,既比较类型又比较字符串大小的,例如:1===1是相等的,"1"===1是不相等的;进行数值的比较时不会进行进制的转换,如'16'==='0x10'是错误的。即等式左右一模一样

2、字符串转换为数值

因为我们提交的参数值默认就是字符串类型 ,所以base会起作用,传参一个数既要使其不强等于4476,又要使得intval函数处理后的结果强等于4476

所以,payload:

?num=4476a

intval(‘4476a’)只读取4476从而转化为4476
其他payload:
intval('4476.0')===4476    小数点  
intval('+4476.0')===4476   正负号
intval('4476e0')===4476    科学计数法
intval('0x117c')===4476    16进制
intval('010574')===4476    8进制
intval(' 010574')===4476   8进制+空格

其他问题:

<?php
$a=$_GET['1'];
$b=$_GET[2];
$c=$_POST['3'];
$d=$_POST[4];
var_dump($a);
var_dump($b);
var_dump($c);
var_dump($d);
?>
//里面的一般默认加引号,数字可以不用区别,但是字符串需要不然会报错但是不影响运行
例如
Warning: Use of undefined constant b - assumed 'b' (this will throw an Error in a future version of PHP) in /Applications/phpstudy/WWW/test.php on line 5
string(3) "xxx" string(3) "aaa" string(3) "yyy" string(3) "bbb"

从下图可以看到,POST和GET传参都是为字符串类型

 WEB91

题目:

<?php
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';
}

 知识点:

1、正则匹配

修饰符:

iignore - 不区分大小写

将匹配设置为不区分大小写,搜索时不区分大小写: A 和 a 没有区别。

mmulti line - 多行匹配使边界字符 ^ 和 $ 匹配每一行的开头和结尾,记住是多行,而不是整个字符串的开头和结尾。所有行只要有一行匹配到了就返回1

元字符:

^

匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 '\n' 或 '\r' 之后的位置。

$

匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 '\n' 或 '\r' 之前的位置。

在默认状态下,一个字符串无论是否换行只有一个开始^和结尾$,如果采用多行匹配(加了m),那么每一行都有一个^和结尾$。

^php          意思为以php开头
php$          意思是以php结尾
^php$        意思是以php开头并以php结尾

方法:

payload:?num=%0aphp
%0aphp即换行+php:
'
php'

经过第一个匹配时,以换行符为分割也就是%0a,前面因为是空的,所以只匹配换行符后面的,所以可以通过。
经过第二个正则表达式时,因为我们是%0aphp 不符合正则表达式的以php开头以php结尾。所以无法通过,最后输出flag

WEB92 

题目:

<?php

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);
    }
}

方法:

用4476a是无法绕过第六行的,弱比较下两者直接相等

可以利用16进制、8进制、小数点过滤,做法类似web90

payload:?num=4476.1(小数点位只要不是0就行)
因为是弱比较,4476==‘4476.0’是正确的,4476==‘4476.1’是错误的

方法2:

e这个字母比较特殊,在PHP中会被当作科学计数法。这是PHP在处理字符串时的一个缺陷

所以为了绕过第5行:==4476,我们就可以构造4476e123,被认为是科学计数法,值是:4476×10^123

第8行intval()函数处理时遇到字母就停止,所以只读取4476而不是4476e123,从而绕过

WEB93

题目:

<?php
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);
    }
}

方法:

过滤了字母,用8进制、小数点

WEB94

题目:

<?php
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、strpos()

 strpos() 函数对大小写敏感。

strpos() 函数查找字符串在另一字符串中第一次出现的位置(区分大小写且从0开始)。同时如果没有找到字符串会 FALSE。

同时注意字符串位置是从0开始,而不是从1开始的。

分析:

比上一关增加条件,strpos函数限制了传参第一位不能为0,如果为0,就die.

但是如果找不到的0话也会die。因为是强等于符合,所以payload可以为:

我们可以在八进制前加一个空格

?num= 010574

或者用小数点

?num=4476.0

或者再加个 +

?num=+4476.0

WEB95

题目:

<?php
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;
    }
}

分析:过滤了点

过滤了点,使用八进制

根据定义,这题的$num参数中必须满足这几点:
1. 值不能是4476
2. 不能含有字母
3. 值中必须有0,但第一个数字不能是0
4. intval($num,0)===4476
5. 不能有小数点

通过换行符%0a 、空格符%20结合八进制绕过

方法:

payload:     
?num= 010574  //注意开头的空格
?num=%0a010574
?num=%20010574
?num=+010574
?num=%09010574
?num=%2b010574 (%2b是+的url编码)

intval 会对以+或空格开头数字当作正数处理

WEB96

题目:

<?php
highlight_file(__FILE__);

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

知识点:

在linux下面表示当前目录是 ./ 

payload:
./flag.php                          相对路径

php://filter/resource=flag.php      php伪协议 

php://filter/read=convert.base64-encode/resource=flag.php

随便输入一个文件

发现了路径,所以还可以用绝对路径来显示这个文件。

payload:?u = /var/www/html/flag.php

WEB97 

题目:

<?php
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.';
}
?>

 知识点:

php中hash比较缺陷

md5强碰撞收集

【PHP】MD5比较漏洞 弱比较、强比较、强碰撞

MD5碰撞的一些例子

这里用的是强比较,所以利用MD5加密后为0e开头的字符串做法是不行的

方法1:数组

md5()函数无法处理数组,如果传入的为数组,会返回NULL,所以两个数组经过加密后得到的都是NULL,也就是强相等的。

payload:a[]=1&b[]=2

方法2:

不利用数组,而是使用md5加密后数据一致但原始数据不同的两个字符串。原理是将hex字符串转化为ascii字符串,并写入到bin文件

考虑到要将一些不可见字符传到服务器,这里使用url编码

a=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%00%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1U%5D%83%60%FB_%07%FE%A2&b=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%02%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1%D5%5D%83%60%FB_%07%FE%A2

(这里用HackBar不能出结果,需用burpsuit)

拓展

md5弱比较,使用了强制类型转换后不再接收数组

$a=$_POST['a'];

$b=$_POST['b'];

if(  ($a!==$b) && (md5($a)==md5($b)) ){

echo $flag;

}

md5弱比较,为0e开头的会被识别为科学记数法,结果均为0,所以只需找两个md5后都为0e开头且0e后面均为数字的值即可。

payload: a=QNKCDZO&b=240610708

WEB98

题目:

持续更新:

标签:php,intval,特性,num,CTFSHOW,字符串,PHP,payload,4476
来源: https://blog.csdn.net/qq_46918279/article/details/120667769