云演 【ctf实验】

无聊随便做了几个题目

目录

矛盾

单身一百年也没用 

单身20年的手速

ereg 

intval


矛盾

<?php
$num=$_GET['num'];
if(!is_numeric($num))
{
echo $num;
if($num==1)
echo 'flag{**********}';
}
?>

正常给了一串代码,正常思维下会觉得有矛盾,矛盾点在于函数is_numeric()需要使num不为整形数字。但num==1,这是一个矛盾应该如何绕过就是需要探讨的。

首先,这是一个num与1的弱比较,而弱比较与强比较的区别在于:

当php中数字与字符串作比较或者进行运算时,php会先将字符串转换为数字再比较。

其中php的转换规则为:如果字符串是以数字开头,则取开头的数字为转换结果。若无数字则取0.

PHP一个数字和一个字符串进行比较或者进行运算时,PHP会把字符串转换成数字再进行比较。PHP转换的规则的是:若字符串以数字开头,则取开头数字作为转换结果,若无则输出0。 在PHP中,== 会先进行类型转换,再进行对比,而===会先比较类型,如果类型不同直接返回false。

根据上述弱比较的转换方法构造payload为?num=1+其它的字符即可绕过。


单身一百年也没用 

 

可以看到点击链接会跳转到search_key.php下,但点击后发现

跳到了no_key.php下,说明在目标链接的内容中有跳转,所以用bp抓包阻止眺转

 

 最后发现key,即目标flag


单身20年的手速

和上一题没什么不同,且它的flag完全没藏


ereg 

前置知识

  • ereg()函数用指定的模式搜索一个字符串中指定的字符串,如果匹配成功返回true,否则,则返回false。搜索字母的字符是大小写敏感的。

  • ereg函数存在NULL截断漏洞,导致了正则过滤被绕过,所以可以使用%00截断正则匹配

开局一片白,做题全靠扫

 

 

发现源码放在robots.txt里 

if (isset ($_GET['password'])) {
     
	if (ereg ("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE)//如果password不为数字或者字母
	{
		echo '<p>You password must be alphanumeric</p>';
	
    }
	  else if (strlen($_GET['password']) < 8 && $_GET['password'] > 9999999)//password长度小于8,key值大于9999999
	{    
    
		if (strpos ($_GET['password'], '*-*') !== FALSE)// 判断password参数值是否出现*-*
		{
			die('Flag: ' . $flag);
		}
		else
		{
			echo('<p>*-* have not been found</p>');
		}
	}
	else
	{
		echo '<p>Invalid password</p>';
	}
}

通过分析最后构造payload为?password=1e9%00*-*

参考:四叶草云演-CTF03# ereg_weixin_43973521的博客-CSDN博客


intval

前置知识--int溢出

当前 PHP 版本支持的最大整型数字。在 32 位系统中通常为 int(2147483647),64 位系统中为 int(9223372036854775807)。自 PHP 5.0.5 起可用。

<?php
if(!isset($_GET['source'])){
    highlight_file('index.php');
    die();
}
include('flag.php');
$key1 = $_GET['f'];
$key2 = $_GET['l'];
$key3 = $_GET['a'];
$key4 = $_GET['g'];
if(isset($key1)&&isset($key2)&&isset($key3)&&isset($key4))
{
    if(intval($key1) > 1 || intval($key1) < 0)
        die("key1 is error.");
    elseif(intval(intval($key1)) < 1)
    {
        if($key1 == 1){
            if($key2 < 1){
                die("key2 is error.");
            }else{
                if(intval($key2 + $key1) > 1){
                    die("key is error.");
                }else{
                    $check = is_numeric($key3) and is_numeric($key4);
                    if(!$check){
                        die("key3 or key4 is error.");
                    }elseif(!(is_numeric($key3) and is_numeric($key4))){
                        $key3 = $flag;
                        $key4 = $redpacket;
                    }
                    die("flag:".$key3."<br>"."支付宝红包口令".$key4);
                }
            }
        }
        else
            die("key1 is error.");
    }
    else
        die("key1 is error.");
}
?>

经过分析:

*对于key1而言需要构造一个使intval(key1)<1且key1==1 -->这里主要针对intval下手 

方法:可以用16进制的0x绕过intval,0x1被intval翻译过来等于0,但实际就是1

*对于key2而言大于等于1的同时,加上key1要小于等于1  -->这里会用到int最大长度溢出

当溢出后会使得二级制原本管理正负号的位数变动,导致原本的正好成负号

方法:利用最大int(9223372036854775807)在加1以后为负

*而key3与key4需要在检测变量是否为数字或数字字符串的同时有一个或两个都为null -->这里是代码优先级出现了问题

方法:利用=与and的优先级对g置空即可

最后构造payload为:?f=0x1&l=9223372036854775807&a=1&g=&source=1

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

errorr0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值