php弱类型
== 在进行比较的时候,会先判断两种字符串的类型是否相等,再比较
=== 在进行比较的时候,会先将字符串类型转化成相同,再比较
哈希(Md5)绕过
登录验证V1
$a != $b
Md5 ($a) == md5 ($b)
这是一道登录验证的题目,观察可以发现他要求我们输入字符串a与字符串b,并且要求,字符串a与b的Md5值弱相等,可以联想到0e开头的字符串进行==比较时会被解析为科学计数法,也就是说0e1234566 == 0e121
登录验证V2
$a != $b
Md5 ($a) === md5 ($b)
V2版本将弱相等改为了强相等,可以联想到arry与awww这样数组(在php中用?a[]=1&b[]=2,[]表示后面的是数组)在进行md5运算时输出均为NULL
登录验证V3
(string)$a != (string)$b
Md5 ($a) === md5 ($b)
这题强制要求输入的字符串不相等,但是最后的md5相等,进行MD5 碰撞,找到两个不同的数据块经过 MD5 算法计算后,产生的 128 位哈希值相同即可
变量覆盖
用传参的值替换原有变量的值
<?php
header('Content-type:text/html;charset=utf-8');
error_reporting(0);
highlight_file(__file__);
//level 1
if (isset($_GET['num'])){
$num = $_GET['num'];
if(intval($num) < 2020 && intval($num + 1) > 2021){
echo "我不经意间看了看我的劳力士,不是想看时间,只是想不经意间,让你知道我过得比你好。</br>";
}else{
die("金钱解决不了穷人的本质问题");
}
}else{
die("去非洲吧");
}
//level 2
if (isset($_GET['md5'])){
$md5=$_GET['md5'];
if ($md5==md5($md5))
echo "想到这个CTFer拿到flag后,感激涕零,跑去东湖岸,找一家餐厅,把厨师叫出去,自己炒两个拿手小菜,倒一杯敌装白酒,致富有道,别学小黑";
else
die("我赶紧喝完我的酒肉朋友,他打了个电话,把他一家安排到了非洲");
}else{
die("去非洲吧");
}
//get flag
if (isset($_GET['get_flag'])){
$get_flag = $_GET['get_flag'];
if(!strstr($get_flag," ")){
看题目要求,num在取整前要求< 2020,num先+1再取整要求> 2021,这显然矛盾
在php5里,intval对于2e4这样的数字处理后结果是2,2e4+1再取intval则是20001满足条件,level2中md5有两层含义,一层是md5变量,一层是取md5变换
因此我只要找到一个a在进行一次md5变换后与原先弱相等即可
首先就想到0e形式的数字0e215962017 -> md5值: 0e291242476940776845150308577824
最后一关直接输入get_flag即可拿到flag
构造请求:?num=2e4&md5=0e215962017&get_flag=1
随机数问题
无需暴破还原mt_rand()种子
def main(_R000, _R227, offset):
# Both were >> 1, so the leftmost byte is unknown
_R000 <<= 1
_R227 <<= 1
for R000_0 in range(2):
for R227_0 in range(2):
R000 = _R000 | R000_0
R227 = _R227 | R227_0
S000 = undo_php_mt_rand(R000)
S227 = undo_php_mt_rand(R227)
seed = undo_php_mt_reload(S000, S227, offset)
if seed:
print(seed)
只要给定间隔226个值的两个mt_rand()
输出结果,我们就有可能计算出原始种子,无需暴力破解,因此也能计算出之前或者之后的mt_rand()
输出值,成功解密PRNG
Comments NOTHING