这个真的是爆破
源码分析
<?php
error_reporting(0);
session_start();
require('./flag.php');
// 初始化$_SESSION['nums']、$_SESSION['time']、$_SESSION['whoami'],isset函数是检测变量是否设置
if(!isset($_SESSION['nums'])){
$_SESSION['nums'] = 0;
$_SESSION['time'] = time();
$_SESSION['whoami'] = 'ea';
}
// 时间限制,从第一请求计时两分钟后销毁会话中的全部数据
if($_SESSION['time']+120<time()){
session_destroy();
}
// 请求参数
$value = $_REQUEST['value'];
// 产出 a - z 数组
$str_rand = range('a', 'z');
// 随机两次从$str_rand数组获取两个字母
$str_rands = $str_rand[mt_rand(0,25)].$str_rand[mt_rand(0,25)];
// 条件1 请求参数$value的前两位等于$_SESSION['whoami'],条件2 请求参数$value的MD5值从第六位开始取四位数等于0
if($_SESSION['whoami']==($value[0].$value[1]) && substr(md5($value),5,4)==0){
// $_SESSION['nums'] 累加
$_SESSION['nums']++;
// 将上方产生两个字母赋值$_SESSION['whoami']
$_SESSION['whoami'] = $str_rands;
// 返回下次请求参数的两位
echo $str_rands;
}
// $_SESSION['nums']大于等于10才能得到flag
if($_SESSION['nums']>=10){
echo $flag;
}
show_source(__FILE__);
?>
在两分钟之内通过GET或POST发送正确参数,能够通过第二判断至少十一次$_SESSION[‘nums’]
解题重点 PHP-MD5()函数漏洞
var_dump( 0 == "a" );
var_dump( "0" == "a" );
数字与字符串之间的比较第一个返回的是 true ,第二个返回的是 false。因为php把字母开头的转化为整型时,转化为0, 前面数字后面字母的话就只取到第一个字母出现的位置之前(如intval(’'123abd45gf)结果为123。详情请点击下方链接
https://blog.csdn.net/qq_19980431/article/details/83018232
解题思路
发送的参数能够通过第二判断,第二判断条件1 S E S S I O N [ ′ w h o a m i ′ ] = = ( _SESSION['whoami']==( SESSION[′whoami′]==(value[0]. v a l u e [ 1 ] ) 参 数 的 前 两 位 已 经 在 页 面 和 代 码 中 显 示 , 第 二 判 断 条 件 2 s u b s t r ( m d 5 ( value[1]) 参数的前两位已经在页面和代码中显示,第二判断条件2 substr(md5( value[1])参数的前两位已经在页面和代码中显示,第二判断条件2substr(md5(value),5,4)==0 通过利用PHP-MD5()函数漏洞,在请求参数的前两位之后增加数值,保证参数的MD5值第六位不是数字。
解题步骤
1、 编写代码在参数的前两位之后增加数值,返回参数的MD5值第六位不是数字的参数。
public static void main(String[] args) {
while (true){
System.out.println("请输入参数:");
String msg = "";
Scanner scanner = new Scanner(System.in);
msg = scanner.nextLine();
Boolean b = true;
String msgMd5 = "";
int i = 0;
while (b) {
msgMd5 = stringToMD5(msg);
if (!isInteger(msgMd5.substring(5,6))) {
b = false;
} else {
msg = msg + i;
}
i++;
}
System.out.println(msg);
}
}
public static String stringToMD5(String plainText) {
byte[] secretBytes = null;
try {
secretBytes = MessageDigest.getInstance("md5").digest(
plainText.getBytes());
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("没有这个md5算法!");
}
String md5code = new BigInteger(1, secretBytes).toString(16);
for (int i = 0; i < 32 - md5code.length(); i++) {
md5code = "0" + md5code;
}
return md5code;
}
public static boolean isInteger(String str) {
Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
return pattern.matcher(str).matches();
}
2、循环发送参数