那些年我们学过的PHP黑魔法

作者:Matrix_ling

这里必须得说一下==和===这俩货的重要性。
==是比较运算,它不会去检查条件式的表达式的类型
===是恒等,它会检查查表达式的值与类型是否相等
NULL,0,”0″,array()使用==和false比较时,都是会返回true的,而使用===却不会
这个基础知识点大家应该都知道,所以提一下,下面就不会再拿出来说了。

数组

0x01
很多时候,PHP数组都发挥了至关重要的作用,先来看下BOSTEN KEYPARTY中的一道题:

 
 
 
 
 

Default

 
1
2
3
4
5
6
7
8
if (isset($_GET['name']) and isset($_GET['password'])) {
    if ($_GET['name'] == $_GET['password'])
        print 'Your password can not be your name.';
    else if (sha1($_GET['name']) === sha1($_GET['password']))
        die('Flag: '.$flag);
    else
        print 'Invalid password';
}

这道题,我们首先要确保name和password的值不能相同,其次,sha1加密之后的name和password的值又必须完全相同 我们知道,这时的a[0] = 1;所以name[] = 1和password[]= 2相比较,可以跳过第一个判断,而如果使用sha1对一个数组进行加密,返回的将是NULL,NULL===NULL,这是成立的,所以构造两个数组,成功拿到flag

0x02
再看bosten keyparty上的另外一道题:

 
 
 
 
 

Default

 
1
2
3
4
5
6
if (isset($_GET['password'])) {  
    if (strcmp($_GET['password'], $flag) == 0)  
        die('Flag: '.$flag);  
    else  
        print 'Invalid password';  
}

这里,使用strcmp去比较password和flag,如果==0的话,就给出flag,但是strcmp比较,如果相等才会返回0,如果不相等的话,要么大于0,要么小于0,但是strcmp只会处理字符串参数,如果给个数组的话呢,就会返回NULL,而判断使用的是==,NULL==0是bool(true)的,所以,这道题还是一如既往构造一个数组进去

0x03
bosten keyparty上的又又一道题:

 
 
 
 
 
 

Default

 
1
2
3
4
5
6
7
8
if (isset ($_GET['password'])) {  
    if (ereg ("^[a-zA-Z0-9]+[        DISCUZ_CODE_2        ]quot;, $_GET['password']) === FALSE)  
        echo 'You password must be alphanumeric';  
    else if (strpos ($_GET['password'], '--') !== FALSE)  
        die('Flag: ' . $flag);  
    else  
        echo 'Invalid password';  
}

这道题有两种做法,我们还是先说数组 ereg是处理字符串的,所以,按照原理,我们将password构造一个arr[],传入之后,ereg是返回NULL的,===判断NULL和FALSE,是不相等的,所以可以进入第二个判断,而strpos处理数组,也是返回NULL,注意这里的是!==,NULL!==FALSE,条件成立,拿到flag, 第二种做法,ereg读到%00的时候,就截止了,所以可以构造s%00–,也能拿到flag(这也算是一个黑魔法吗?哈哈)

数字的比较

0x01
wechall上的一道题:

 
 
 
 
 

Default

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function noother_says_correct($number)
{
        $one = ord('1');
        $nine = ord('9');
        // Check all the input characters!
        for ($i = 0; $i < strlen($number); $i++)
        {
                // Disallow all the digits!
                $digit = ord($number{$i});
                if ( ($digit >= $one) && ($digit <= $nine) )
                {
                        // Aha, digit not allowed!
                        return false;
                }
        }
       return $number == "3735929054";
}

这里,它不让输入1到9的数字,但是后面却让比较一串数字,平常的方法肯定就不能行事了,大家都知道计算机中的进制转换,当然也是可以拿来比较的,0x开头则表示16进制,将这串数字转换成16进制之后发现,是deadc0de,在开头加上0x,代表这个是16进制的数字,然后再和十进制的3735929054比较,答案当然是相同的,返回true拿到flag

0x02
看安全宝约宝妹的一道题:

 
 
 
 
 

Default

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$flag = "THIS IS FLAG";
if  ("POST" == $_SERVER['REQUEST_METHOD'])
{
    $password = $_POST['password'];
    if (0 >= preg_match('/^[[:graph:]]{12,}$/', $password))
    {
        echo 'Wrong Format';
        exit;
    }
    while (TRUE)
    {
        $reg = '/([[:punct:]]+|[[:digit:]]+|[[:upper:]]+|[[:lower:]]+)/';
        if (6 > preg_match_all($reg, $password, $arr))
            break;
        $c = 0;
        $ps = array('punct', 'digit', 'upper', 'lower');
        foreach ($ps as $pt)
        {
            if (preg_match("/[[:$pt:]]+/", $password))
                $c += 1;
        }
        if ($c < 3) break;
        if ("42" == $password) echo $flag;
        else echo 'Wrong password';
        exit;
    }
}

在乌云zone上,X总已经对其进行分析了

传送门,这块是数学的东西了。。 42.00e+0000000000,10的00000次方。。等于42.000000…. 结果其实就是42,不过有时候这些东西也会出奇迹的是不是。。

switch没有break

在wechall上有一道题:

 
 
 
 
 

Default

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if (isset($_GET['which']))
{
        $which = $_GET['which'];
        switch ($which)
        {
        case 0:
        case 1:
        case 2:
                require_once $which.'.php';
                break;
        default:
                echo GWF_HTML::error('PHP-0817', 'Hacker NoNoNo!', false);
                break;
        }
}

让我们包含当前目录中的solution文件,这里会发现在case 0和case 1的时候,没有break,按照常规思维,应该是0比较不成功,进入比较1,然后比较2,再然后进入default,但是事实却不是这样,事实上,在case 0的时候,进入了case 0的方法体,但是却没有break,这个时候,默认判断已经比较成功了,而如果匹配成功之后,会继续执行后面的语句,这个时候,是不会再继续进行任何判断的。也就是说,我们which传入solution的时候,case 0比较进入了方法体,但是没有break,默认已经匹配成功,往下执行不再判断,进入2的时候,执行了require_once solution.php,查阅资料之后发现, 这个黑魔法是继承于C语言,paper传送阵:传送阵

小结

至此,就我自己遇到过的很有意思的php黑魔法就这么点了,若大家有其他猥琐的trick或者屌炸天的黑魔法,大家一起交流交流咯,无形装逼,最为致命,摸摸大。

【via@Sco4x0

PHP黑魔法(该篇文章转自:http://www.91ri.org/12634.html 目的是作为自己的笔记方便查找)的更多相关文章

  1. 在知乎上看到 Web Socket这篇文章讲得确实挺好,从头看到尾都非常形象生动,一口气看完,没有半点模糊,非常不错

    在知乎上看到这篇文章讲得确实挺好,从头看到尾都非常形象生动,一口气看完,没有半点模糊,非常不错,所以推荐给大家,非常值得一读. 作者:Ovear链接:https://www.zhihu.com/que ...

  2. vs2010如何安装mvc3,怎样安装,详细的步骤,从哪下载?请看这篇文章。

    vs2010如何安装mvc3,怎样安装,详细的步骤,从哪下载?请看这篇文章. 安装步骤:vs2010 -> vs2010sp1 -> AspNetMVC3Setup -> AspNe ...

  3. Java设计模式(十三) 别人再问你设计模式,叫他看这篇文章

    原创文章,转载请务注明出处 OOP三大基本特性 封装 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的属性和方法只让可信的类操作,对不可信的进行信息隐藏. 继承 继承是指这样一种能力,它可以使 ...

  4. APP的缓存文件到底应该存在哪?看完这篇文章你应该就自己清楚了

    APP的缓存文件到底应该存在哪?看完这篇文章你应该就自己清楚了 彻底理解android中的内部存储与外部存储 存储在内部还是外部 所有的Android设备均有两个文件存储区域:"intern ...

  5. jq最新前三篇文章高亮显示

    /*---------最新前三篇文章高亮显示-------------*/ function latest(){ var color_arr=new Array( "blue", ...

  6. 一篇文章,读懂 Netty 的高性能架构之道

    原文 Netty是一个高性能.异步事件驱动的NIO框架,它提供了对TCP.UDP和文件传输的支持,作为一个异步NIO框架,Netty的所有IO操作都是异步非阻塞的,通过Future-Listener机 ...

  7. Node.js 创建HTTP服务器(经过测试,这篇文章是靠谱的T_T)

    Node.js 创建HTTP服务器 如果我们使用PHP来编写后端的代码时,需要Apache 或者 Nginx 的HTTP 服务器,并配上 mod_php5 模块和php-cgi. 从这个角度看,整个& ...

  8. 细心看完这篇文章,刷新对Javascript Prototype的理解

    var person={name:'ninja'}; person.prototype.sayName=function(){ return this.name; } 分析上面这段代码,看看有没有问题 ...

  9. 【转】APP的缓存文件到底应该存在哪?看完这篇文章你应该就自己清楚了

    只要是需要进行联网获取数据的APP,那么不管是版本更新,还是图片缓存,都会在本地产生缓存文件.那么,这些缓存文件到底放在什地方合适呢?系统有没有给我们提供建议的缓存位置呢?不同的缓存位置有什么不同呢? ...

随机推荐

  1. 遍历所有子物体中renderer(渲染器)中的material(材质)

    //得到所有可渲染的子物体Renderer[] rds = transform.GetComponentsInChildren<Renderer>();//逐一遍历他的子物体中的Rende ...

  2. TensorFlow学习笔记——节点(constant、placeholder、Variable)

    一. constant(常量) constant是TensorFlow的常量节点,通过constant方法创建,其是计算图(Computational Graph)中的起始节点,是传入数据. 创建方式 ...

  3. 十三. Python基础(13)--生成器进阶

    十三. Python基础(13)--生成器进阶 1 ● send()方法 generator.send(value) Resumes the execution, and "sends&qu ...

  4. 打开和写入excel文件

    一.使用win32读取excel内容 # -*- coding: utf-8 -*- from win32com import client as wc def open_excel(): excel ...

  5. jackson中的@JsonBackReference

    #    StackOverflowError / 无限递归 / json递归 / JsonBackReference 环境:springmvc+hibernate+json 在controller返 ...

  6. 用MyEclipse开发REST Web Service

    MyEclipse 在线订购年终抄底促销!火爆开抢>> MyEclipse最新版下载 使用MyEclipse开发RESTWeb服务来放大您的Web应用程序.在本教程示例中,您将创建一个简单 ...

  7. 干货分享!DevExpress v17.1最新版帮助文档下载大全

    DevExpress v17.1.5帮助文档下载列表大全来啦!包含.NET.VCL.HTML/JS系列所有帮助文档,提供CHM和PDF两个版本.除已停止更新的Silverlight.Windows 8 ...

  8. 谷歌开源的TensorFlow Object Detection API视频物体识别系统实现(二)[超详细教程] ubuntu16.04版本

    本节对应谷歌开源Tensorflow Object Detection API物体识别系统 Quick Start步骤(一): Quick Start: Jupyter notebook for of ...

  9. mvc项目中实现备份数据库(sqlserver2005)

    功能要求:mvc项目,实现数据库备份(bak文件) 实现步骤:<a id="backupDB" href="javascript:" >数据库备份& ...

  10. Effective Java Methods Common to All Objects

    Obey the general contract when overriding equals 先了解equals 和 == 的区别,如果不重写equals, equals比较的仅仅只是是否引用同一 ...