zoukankan      html  css  js  c++  java
  • php伪随机数安全

    随机数真的随机吗?

    PHP中的随机函数

    在PHP中,常用的随机数生成算法有rand(),mt_rand().

    这两个函数各有最大范围不超过2147483647,rand()的范围是很小的,非常不安全的,所以一般用mt_rand().

    <?php
    //on windows
    print getrandmax();//2147483647
    print mt_getrandmax();//2147483647
    ?>
    

    然鹅mt_rand()在实现上也有缺陷.

    伪随机数是由数学算法来实现的,真正随机的地方在于种子.种子一旦确定,再通过同一随机数算法计算出来的随机数,值是固定的.多次计算所得值得顺序也是固定的

    在PHP4.2.0之前的版本,必须要通过srand()或mt_srand()给rand()或mt_rand()播种,

    在PHP4.2.0之后的版本,事先可以不再通过srand()或mt_srand()播种. 如直接调用mt_rand(),系统会自动播种.

    但是,可能为了和之前版本兼容,PHP代码里面还会这样写:

    mt_srand(time());
    mt_srand((double) microtime() * 100000);
    mt_srand((double) microtime() * 1000000);
    mt_srand((double) microtime() * 10000000);
    

    但是,时间也不是随机的 . 攻击者通过某种方式获取系统时间,就可以短时间内枚举出种子

    上面提到的如果不播种,系统会自动播种,系统播种种子范围为0-2^32(32位系统),这样似乎也能枚举emm

    固定的种子

    下面谈谈种子固定会发生什么?

    **在同一进程中,同一个seed,每次通过mt_rand()生成的值都是固定的: **

    rand.php:

    <?php
    mt_srand(1);
    echo mt_rand().'<br/>';
    echo mt_rand().'<br/>';
    echo mt_rand().'<br/>';
    echo mt_rand().'<br/>';
    echo mt_rand().'<br/>';
    echo mt_rand().'<br/>';
    ?>
    

    无论访问这个页面多少次,都是上面的结果,上面的序列.正好验证了上面的结论;

    得到相同的种子

    这里有个trick是,可以通过Keep-Alive HTTP头,迫使服务端使用同一PHP进程相应请求,所以也就能使种子保持一直.

    别的就依赖PHP程序员出错了.

    获得种子

    既然知道了,同一个种子生成的序列是固定的,那么也能根据序列猜测seed

    工具:php_mt_seed:https://github.com/lepiaf/php_mt_seed
    Linux下安装使用方法

    git clone https://github.com/lepiaf/php_mt_seed 
    cd php_mt_seed/
    gcc php_mt_seed.c -o php_mt_seed
    make
    

    使用: ./php_mt_seed 随机数

    就会根据随机数,找seed,可能会找到多个,就需要自己验证哪个seed符和条件了

    CTF题目

    题目来自@https://ctf.show/

    0x01

    <?php
    
    /*
    # -*- coding: utf-8 -*-
    # @Author: h1xa
    # @Date:   2020-09-03 13:26:39
    # @Last Modified by:   h1xa
    # @Last Modified time: 2020-09-03 13:53:31
    # @email: h1xa@ctfer.com
    # @link: https://ctfer.com
    
    */
    
    error_reporting(0);
    include("flag.php");
    if(isset($_GET['r'])){
        $r = $_GET['r'];
        mt_srand(372619038);
        if(intval($r)===intval(mt_rand())){
            echo $flag;
        }
    }else{
        highlight_file(__FILE__);
        echo system('cat /proc/version');
    }
    
     mt_srand(372619038);
     var_dump(mt_rand());//int(1155388967)
    

    0x02

    <?php
    
    /*
    # -*- coding: utf-8 -*-
    # @Author: h1xa
    # @Date:   2020-09-03 13:56:57
    # @Last Modified by:   h1xa
    # @Last Modified time: 2020-09-03 15:47:33
    # @email: h1xa@ctfer.com
    # @link: https://ctfer.com
    
    */
    
    
    error_reporting(0);
    include("flag.php");
    if(isset($_GET['r'])){
        $r = $_GET['r'];
        mt_srand(hexdec(substr(md5($flag), 0,8)));
        $rand = intval($r)-intval(mt_rand());
        if((!$rand)){
            if($_COOKIE['token']==(mt_rand()+mt_rand())){
                echo $flag;
            }
        }else{
            echo $rand;
        }
    }else{
        highlight_file(__FILE__);
        echo system('cat /proc/version');
    }
    

    由?r=1

    可以算出序列中第一个数,再跑脚本

    找到两个种子,一个一个试

    可以利用插件改cookie

  • 相关阅读:
    gulp之webpack-stream模块
    AMD、CMD与commonJS
    gulp之gulp-replace模块
    gulp之gulp-uglify模块
    gulp之gulp-sequence模块
    规范-命名、词汇
    gulp之gulp-connect模块
    angularjs $injector:nomod
    because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled
    jxls2 java.lang.NegativeArraySizeException
  • 原文地址:https://www.cnblogs.com/l0nmar/p/13966460.html
Copyright © 2011-2022 走看看