谷歌身份验证器动态code破解

想要破解谷歌身份验证器的动态码,需要知道它生成的secret,一般这个值都是存放在数据库中的。至于怎么拿到secret这个值,这里不多缀述。

破解方法:保存下列PHP代码到为xxxx.php,之后修改其中的$secret变量为你获取到的值。即修改xxxxxxxxxxxxxxxx为16位secret值。之后运行 php xxxx.php

运行结果如下:

PHP代码:

<?php
class PHPGangsta_GoogleAuthenticator{protected $_codeLength = 6;public function createSecret($secretLength = 16){$validChars = $this->_getBase32LookupTable();if ($secretLength < 16 || $secretLength > 128) {throw new Exception('Bad secret length');}$secret = '';$rnd = false;if (function_exists('random_bytes')) {$rnd = random_bytes($secretLength);} elseif (function_exists('mcrypt_create_iv')) {$rnd = mcrypt_create_iv($secretLength, MCRYPT_DEV_URANDOM);} elseif (function_exists('openssl_random_pseudo_bytes')) {$rnd = openssl_random_pseudo_bytes($secretLength, $cryptoStrong);if (!$cryptoStrong) {$rnd = false;}}if ($rnd !== false) {for ($i = 0; $i < $secretLength; ++$i) {$secret .= $validChars[ord($rnd[$i]) & 31];}} else {throw new Exception('No source of secure random');}return $secret;}public function getCode($secret, $timeSlice = null){if ($timeSlice === null) {$timeSlice = floor(time() / 30);}$secretkey = $this->_base32Decode($secret);$time = chr(0).chr(0).chr(0).chr(0).pack('N*', $timeSlice);$hm = hash_hmac('SHA1', $time, $secretkey, true);$offset = ord(substr($hm, -1)) & 0x0F;$hashpart = substr($hm, $offset, 4);$value = unpack('N', $hashpart);$value = $value[1];$value = $value & 0x7FFFFFFF;$modulo = pow(10, $this->_codeLength);return str_pad($value % $modulo, $this->_codeLength, '0', STR_PAD_LEFT);}public function getQRCodeGoogleUrl($name, $secret, $title = null, $params = array()){$width = !empty($params['width']) && (int) $params['width'] > 0 ? (int) $params['width'] : 200;$height = !empty($params['height']) && (int) $params['height'] > 0 ? (int) $params['height'] : 200;$level = !empty($params['level']) && array_search($params['level'], array('L', 'M', 'Q', 'H')) !== false ? $params['level'] : 'M';$urlencoded = urlencode('otpauth://totp/'.$name.'?secret='.$secret.'');if (isset($title)) {$urlencoded .= urlencode('&issuer='.urlencode($title));}return "https://api.qrserver.com/v1/create-qr-code/?data=$urlencoded&size=${width}x${height}&ecc=$level";}public function verifyCode($secret, $code, $discrepancy = 1, $currentTimeSlice = null){if ($currentTimeSlice === null) {$currentTimeSlice = floor(time() / 30);}if (strlen($code) != 6) {return false;}for ($i = -$discrepancy; $i <= $discrepancy; ++$i) {$calculatedCode = $this->getCode($secret, $currentTimeSlice + $i);if ($this->timingSafeEquals($calculatedCode, $code)) {return true;}}return false;}public function setCodeLength($length){$this->_codeLength = $length;return $this;}protected function _base32Decode($secret){if (empty($secret)) {return '';}$base32chars = $this->_getBase32LookupTable();$base32charsFlipped = array_flip($base32chars);$paddingCharCount = substr_count($secret, $base32chars[32]);$allowedValues = array(6, 4, 3, 1, 0);if (!in_array($paddingCharCount, $allowedValues)) {return false;}for ($i = 0; $i < 4; ++$i) {if ($paddingCharCount == $allowedValues[$i] && substr($secret, -($allowedValues[$i])) != str_repeat($base32chars[32], $allowedValues[$i])) {return false;}}$secret = str_replace('=', '', $secret);$secret = str_split($secret);$binaryString = '';for ($i = 0; $i < count($secret); $i = $i + 8) {$x = '';if (!in_array($secret[$i], $base32chars)) {return false;}for ($j = 0; $j < 8; ++$j) {$x .= str_pad(base_convert(@$base32charsFlipped[@$secret[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT);}$eightBits = str_split($x, 8);for ($z = 0; $z < count($eightBits); ++$z) {$binaryString .= (($y = chr(base_convert($eightBits[$z], 2, 10))) || ord($y) == 48) ? $y : '';}}return $binaryString;}protected function _getBase32LookupTable(){return array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','2','3','4','5','6','7','=',);}private function timingSafeEquals($safeString, $userString){if (function_exists('hash_equals')) {return hash_equals($safeString, $userString);}$safeLen = strlen($safeString);$userLen = strlen($userString);if ($userLen != $safeLen) {return false;}$result = 0;for ($i = 0; $i < $userLen; ++$i) {$result |= (ord($safeString[$i]) ^ ord($userString[$i]));}return $result === 0;}}$ga = new PHPGangsta_GoogleAuthenticator();

//$secret = $ga->createSecret();//用于生成secret 字符串存到数据库,如果是破解code,这里是用不到这个的,需要自己直接定义secret
$secret = 'xxxxxxxxxxxxxxxx';  //破解code,从数据库中取出secret,定义赋值给secret
$oneCode = $ga->getCode($secret);echo "密钥 '$secret' 对应的动态码: '$oneCode'\n";