[MRCTF2020]Ezaudit (buu)

1、题目提示审计,可能有源码,但是网站里面啥都没有,可以用工具扫描一下

 

 

2、下载源码进行代码审计:

<?php 
header('Content-type:text/html; charset=utf-8');
error_reporting(0);
if(isset($_POST['login'])){
    $username = $_POST['username'];
    $password = $_POST['password'];
    $Private_key = $_POST['Private_key'];
    if (($username == '') || ($password == '') ||($Private_key == '')) {
        // 若为空,视为未填写,提示错误,并3秒后返回登录界面
        header('refresh:2; url=login.html');
        echo "用户名、密码、密钥不能为空啦,crispr会让你在2秒后跳转到登录界面的!";
        exit;
}
    else if($Private_key != '*************' )
    {
        header('refresh:2; url=login.html');
        echo "假密钥,咋会让你登录?crispr会让你在2秒后跳转到登录界面的!";
        exit;
    }

    else{
        if($Private_key === '************'){
        $getuser = "SELECT flag FROM user WHERE username= 'crispr' AND password = '$password'".';'; 
        $link=mysql_connect("localhost","root","root");
        mysql_select_db("test",$link);
        $result = mysql_query($getuser);
        while($row=mysql_fetch_assoc($result)){
            echo "<tr><td>".$row["username"]."</td><td>".$row["flag"]."</td><td>";
        }
    }
    }

} 
// genarate public_key 
function public_key($length = 16) {
    $strings1 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    $public_key = '';
    for ( $i = 0; $i < $length; $i++ )
    $public_key .= substr($strings1, mt_rand(0, strlen($strings1) - 1), 1);
    return $public_key;
  }

  //genarate private_key
  function private_key($length = 12) {
    $strings2 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    $private_key = '';
    for ( $i = 0; $i < $length; $i++ )
    $private_key .= substr($strings2, mt_rand(0, strlen($strings2) - 1), 1);
    return $private_key;
  }
  $Public_key = public_key();
  //$Public_key = KVQP0LdJKRaV3n9D  how to get crispr's private_key???

 

1)得到login.html路径,并且需要提交username、password、private_key这三个变量。如果私钥匹配的话就从user表中将用户crispr的flag字段输出,这里将$password传入了,那么还需要绕过一下crispr用户的密码。

2)有公钥和私钥两个函数,并且给出了公钥的值,在这里公钥和私钥是使用mt_rand来随机匹配$string1、2中的字符

 

3、获取私钥

这里需要知道伪随机数函数mt_rand的利用方式,mt_rand函数是通过撒播随机数种子来生成随机数的,并且mt_rand生成随机数只撒播一次种子,之后的随机数都使用同一个种子生成。如果知道了随机数种子,就可以将私钥得出。

 

工具:php_mt_seed

1)通过公钥将种子得出

首先需要将公钥转化为php_mt_seed的输入:

文档中是这么求得的:

    <?php
    $allowable_characters = 'abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789';
    $len = strlen($allowable_characters) - 1;
    $pass = $argv[1];
    for ($i = 0; $i < strlen($pass); $i++) {
      $number = strpos($allowable_characters, $pass[$i]);
      echo "$number $number 0 $len  ";
    }
    echo "\n";
    ?>

需要写个脚本去得到php_mt_seed的输入:

string2 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
public_key = 'KVQP0LdJKRaV3n9D'
seed = ''

for i in range(len(public_key)-1):
    for j in range(len(string2)-1):
        if public_key[i] == string2[j]:
            seed += str(j) + ' ' + str(j) + ' ' + '0' + ' ' + str(len(string2)-1) + ' '

print(seed)

得到了php_mt_seed输入:36 36 0 61 47 47 0 61 42 42 0 61 41 41 0 61 52 52 0 61 37 37 0 61 3 3 0 61 35 35 0 61 36 36 0 61 43 43 0 61 0 0 0 61 47 47 0 61 55 55 0 61 13 13 0 61

然后使用工具爆破种子:

 

 

2)通过种子将私钥得出

<?php 
mt_srand('1775196155');
function public_key($length = 16) {
    $strings1 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    $public_key = '';
    for ( $i = 0; $i < $length; $i++ )
    $public_key .= substr($strings1, mt_rand(0, strlen($strings1) - 1), 1);
    return $public_key;
  }

  //genarate private_key
  function private_key($length = 12) {
    $strings2 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    $private_key = '';
    for ( $i = 0; $i < $length; $i++ )
    $private_key .= substr($strings2, mt_rand(0, strlen($strings2) - 1), 1);
    return $private_key;
  }
  //$Public_key = KVQP0LdJKRaV3n9D  how to get crispr's private_key???
 
  echo public_key().'</br>';
  echo private_key();
  ?>

私钥:XuNhoueCDCGc

 

4、绕过password

使用' or '1'='1万能密码,username随便输入得到flag

 

posted @ 2021-04-21 13:22  1jzz  阅读(166)  评论(0编辑  收藏  举报