记一次CTF题目 CTF_论剑场(web26)

机缘巧合在这个网站打CTF,看到题目web26,分值很低想着不会太难就点进去查看,上题目:

<?php
$num=$_GET['num'];
$str=$_GET['str'];
show_source(__FILE__);
if (isset($num)&&isset($str)) {
    if (preg_match('/\d+/sD',$str)) {
        echo "vagetable hhhh";
        exit();
    }
    $result=is_numeric($num) and is_numeric($str);
    if ($result) {
        include "flag.php";
        echo "$flag";
    }
    else{
        echo "vagetablessssss";
    }
} 

题目理解为必须对‘num’变量和‘str’量进行get传参,判断两个变量不为空后,对‘str’变量进行判断,如果为数字字符串则直接退出。
分析到这有意思的来了:

$result=is_numeric($num) and is_numeric($str);
    if ($result) {
        include "flag.php";
        echo "$flag";
    }
    else{
        echo "vagetablessssss";
    }

这串代码我的理解是,先对‘num’变量和‘str’变量进行是否为数字的判断进行and运算后赋值给result变量,如果result为1输出flag,如果不为1输出vegetable。
当时就懵了(php学的并不好)这str到底传字符串还是数字…
去网上找writeup找到这么一段话:
在这里插入图片描述“中间用and连接,则两边只要一边为True即可执行下面的if语句“
我对自己的基础知识产生了怀疑,查询学习后得到以下知识:

| 和 ||,& 和 && 的区别

我们将 || 和 && 定义为逻辑运算符,而 | 和 & 定义为位运算符。

&& 如果两个操作数都非零,则条件为真;

|| 如果两个操作数中有任意一个非零,则条件为真。

& 按位与操作,按二进制位进行"与"运算。运算规则:(有 0 则为 0)

0&0=0; 0&1=0; 1&0=0; 1&1=1;

| 按位或运算符,按二进制位进行"或"运算。运算规则:(有 1 则为 1)

0|0=0; 0|1=1; 1|0=1; 1|1=1;

在对自己的基础知识得到了肯定后,我开始继续研究,我将网上所给的payload:?num=1&str=aaa传参上去发现确实得到了flag。我更疑惑了,这str的判断到底是怎么执行的?
在进行一系列的研究判断后,我发现只要前者验证为真时(is_numeric($num))就会得到flag,于是继续查阅资料试验后发现了一个遗漏的知识点:符号优先级

php中运算符的优先级

递增/递减 > ! > 数学运算 > 大小比较 > 等号或不等号比较 > 引用 > 位运算符(^) > 位运算符号(|) > 逻辑与 >
逻辑或 > 三元运算 > 赋值 > and > xor > or

|| 和 && 与 or 和 and 的优先级不同并且有短路作用$a = true || b = = 1 ; / / 只 执 行 b == 1; //只执行 b==1;//a = true,
||运算一边为真结果为真,左边 a = t r u e 为 真 , 所 以 右 边 的 a = true为真,所以右边的 a=trueb == 1不执行

$a = false && b = = 1 ; / / 只 执 行 b == 1; //只执行 b==1;//a = false, &&运算两边为真结果为真,左边 a = f a l s e 为 假 , 所 以 右 边 的 a = false为假,所以右边的 a=falseb == 1不执行

a = f a l s e ∣ ∣ t r u e ; / / a = false || true; // a=falsetrue;//a = true, = 和 ||中 || 的优先级较高,所以先执行 false ||
true结果为true

a = f a l s e o r t r u e ; / / a = false or true; // a=falseortrue;//a = false, = 和 or 中 = 的优先级较高,所以先执行 $a =
false

$a = 0;

$b = 0;

if($a = 1 > 0 || $b = 3 > 0)
{

$a++;

$b++;

echo $a;

echo $b;

}

根据优先级, > 大于 || 大于 =,所以上面if中的执行顺序应该是

$a = ((1 > 0) || $b = 1 >0)

此时 || 左边的 1 > 0 结果为true 所以 右边的 $b = 1 > 0 短路不执行

if执行完后 a = t r u e , a = true, a=trueb = 0;

再执行$a++; b++;

所以结果$a = 1, b= 1

这里有一点,递增递减不影响布尔值,即true / false 执行 ++或 – 结果还是本身,所以上面的$a = true,++ 过后还是true

直接破案,因为符号优先集的问题

$result=is_numeric($num) and is_numeric($str);

result变量直接赋值了is_numeric($num),后面的and根本没起作用,但是为了符合之前的判断

{
    if (preg_match('/\d+/sD',$str)) {
        echo "vagetable hhhh";
        exit();
    }

所以不能是数字。

ps:没想到工作了也需要打CTF,工作的内容需要将之前的很多知识一点一点拾起来,慢慢来吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值