Bugku CTF 每日一题 闪电十六鞭

闪电十六鞭

点开发现出现源码

 <?php
    error_reporting(0);
    require __DIR__.'/flag.php';

    $exam = 'return\''.sha1(time()).'\';';

    if (!isset($_GET['flag'])) {
        echo '<a href="./?flag='.$exam.'">Click here</a>';
    }
    else if (strlen($_GET['flag']) != strlen($exam)) {
        echo '长度不允许';
    }
    else if (preg_match('/`|"|\.|\\\\|\(|\)|\[|\]|_|flag|echo|print|require|include|die|exit/is', $_GET['flag'])) {
        echo '关键字不允许';
    }
    else if (eval($_GET['flag']) === sha1($flag)) {
        echo $flag;
    }
    else {
        echo '马老师发生甚么事了';
    }

    echo '<hr>';

    highlight_file(__FILE__);

这直接就开始审计了

error_reporting(0); 可略过
require __DIR__.'/flag.php';
_DIR_是php5.3以后的一个魔术常量,用于指向当前执行的PHP脚本所在的目录
require就是文件包含函数 那意思就是包含flag.php
——————————————————————————————————————————————————————————
    $exam = 'return\''.sha1(time()).'\';';
    定义exam的值 其中sha1(time())表示获取当前时间的sha1散列值
    (所以点击超链接后f12看一下,然后刷新你会发现每一秒的flag值都不一样)
——————————————————————————————————————————————————————————
    if (!isset($_GET['flag'])) {
        echo '<a href="./?flag='.$exam.'">Click here</a>';
    }
    isset判断flag变量是否不为空
    !isset判断是否为空 为空则输出下面的代码
    (所以会看到一个click here,点击就会提交一个flag的参数(按f12去看),这个flag参数取exam的值,所以会通过下一个if
    但是最后一个else过不了所以会显示马老师发生什么事了)
——————————————————————————————————————————————————————————
    else if (strlen($_GET['flag']) != strlen($exam)) {
        echo '长度不允许';
    }
    判断提交的flag参数长度是否跟exam参数长度相等 相等则通过 否则提示长度不允许
——————————————————————————————————————————————————————————
    else if (preg_match('/`|"|\.|\\\\|\(|\)|\[|\]|_|flag|echo|print|require|include|die|exit/is', $_GET['flag'])) {
        echo '关键字不允许';
    }
    一堆正则,匹配flag的值 如果前两个if通过的话如果里面有相应的则输出关键字不允许
——————————————————————————————————————————————————————————
    else if (eval($_GET['flag']) === sha1($flag)) {
        echo $flag;
    }
将flag的sha1散列值和flag的值进行强比较,如果相同则返回flag
eval函数用于计算或执行参数,所以里面的===才会执行

所以初始思路是找sha1的碰撞 但是flag的值要和exam的值长度相等,而且exam的值是随时变化的。

不过发现有个eval函数 这个函数会导致任意代码执行,也就是常见的一句话木马<?php eval($_POST[cmd])?>
因为echo被禁了,所以该怎么构造flag的值呢?

看了一下其他人的wp,发现可以用<?=$flag?>代替 <?php echo $flag; ?>

因为传的exam的长度是49,所以构造payload的长度也要是49 (这个看上面的按f12那步,数一下长度就行)
然后不要出现被正则的内容就行。

于是可以构造

$hack=mlag;$hack{0}=f;111111111111;?><?=$$hack;?>
解释:
1.因为flag被禁了,所以可以用hack{0}=f来替换hack变量的第1个字母,所以被替换成flag
2.然后$$hack 代表$($hack)相当于$flag(因为hack变量的值后面变为flag)
3.<?=$$hack;?>代表<?=$flag;?> 就相当于<?php echo $flag; ?>
这样就输出了flag的值,最终得到了flag
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值