本文正在参与「金石方案 . 分割6万现金大奖」

前语

关于PHP咱们一定不生疏,但你知道PHP在CTF中是怎么考察的吗,本文给咱们带来的是经过PHP特性来进行CTF竞赛中解题出题的常识,会介绍一下CTF中常见的php特性以及围绕该常识点的相关案例,由于内容过多这儿分红上中下三篇来讲,下面咱们展开来讲。

MD5强弱碰撞

CTF中的PHP特性函数(上)

关于MD5加密咱们一定很熟悉,在PHP里同样存在函数MD5,该函数能够将指定的字符串经过哈希函数转为复杂的加密字符串。在CTF中有着关于MD5的最基本的常识,即强/弱类型比较。

弱类型比较

调查以下代码:

if(md5($_GET['a'])==md5($_GET['b']))
echo $xino;

能够看到比较时有两个等号,咱们要怎样让他们持平呢?根据php弱类型比较特性,当两个等于号时,会将变量转化为同类型,那么咱们能够考虑,假如把传入的数据改成md5加密后都为最初0e的字符串是不是就能够绕过了,由于这样会被认为是科学计数法,不论加什么都永远是0,咱们也就绕过了,这儿举几个字符串md5加密后都为0e的:

NWWKITQ:0e763082070976038347657360817689
NOOPCJF:0e818888003657176127862245791911
s878926199a:0e545993274517709034328855841020
s1091221200a:0e940624217856561557816327384675

强类型比较

调查下面代码:

if (md5($_POST['a']) === md5($_POST['b']))
echo xino;

假如咱们等号变成三个还能够用上面办法绕过吗?答案是否定的,由于三个等号在PHP里意味着强类型比较,上面的办法由于0e后面数据不同便不可行了,所以这儿能够用数组来绕过,由于PHP特性允许接受数组,而数组在MD5加密后为NULL,所以凭借这个特性能够进行绕过。

咱们能够传入下面的PAYLOAD绕过:

a[]=a&b[]=b

强碰撞

难度进一步晋级,假如咱们要面对的是以下代码呢:

$a = (string)$_GET['a'];
$b = (string)$_GET['b'];
if (md5($a) === md5($b)) {
die('OK');
}

由于强制类型转换的原因,咱们不能像上面相同传入数组了,所以需要进行MD5强碰撞,及内容不同而MD5值要相同,这就很难办了,可是咱们能够用东西生成,这儿给咱们举一个可行的例子:

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

preg_match()

CTF中的PHP特性函数(上)

这是一个正则表达式函数,简略来说会对咱们设置的数据进行匹配,比如:

<?php
if (preg_match("/xino/i", "XINO IS A BOY .")){ 
echo "查找到匹配的字符串 php。"; } 
else { echo "未发现匹配的字符串 php。"; } ?>

由于咱们用/i设置了大小写不灵敏,所以能够找到匹配字符串,所以会返回查询到的字符串,下面咱们看看怎么绕过。

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

其中intval的作用是取整,能够看到正则过滤了数字,但由于PHP特性,该函数只能处理字符串,所以咱们能够传入数组进行绕过:

?num[]=1

提交后成功echo出了flag,绕过成功。

结语

作为PHP特性总结的第一篇,介绍了一下最简略的特性函数以及绕过办法,后面还会给咱们带来更多的PHP特性常识,希望咱们能喜欢。