#!/bin/sh
# 此脚本可实现 自动登录 jumpserver 会自动验证秘密及google的两部验证
# google验证 使用的php算法获取 # php .asdf.php
secret=ZUM6YNUG4WWYG66Q
user=teooo
ip=172.21.34.100
passwd=123456
port=2222
cat <<-aaa > .asdf.php
<?php
/**
* PHP Class for handling Google Authenticator 2-factor authentication
*
* @author Michael Kliewe
* @copyright 2012 Michael Kliewe
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @link http://www.phpgangsta.de/
*/
class PHPGangsta_GoogleAuthenticator
{
protected \$_codeLength = 6;
/**
* Create new secret.
* 16 characters, randomly chosen from the allowed base32 characters.
*
* @param int \$secretLength
* @return string
*/
public function createSecret(\$secretLength = 16)
{
\$validChars = \$this->_getBase32LookupTable();
unset(\$validChars[32]);
\$secret = '';
for (\$i = 0; \$i < \$secretLength; \$i++) {
\$secret .= \$validChars[array_rand(\$validChars)];
}
return \$secret;
}
/**
* Calculate the code, with given secret and point in time
*
* @param string \$secret
* @param int|null \$timeSlice
* @return string
*/
public function getCode(\$secret, \$timeSlice = null)
{
if (\$timeSlice === null) {
\$timeSlice = floor(time() / 30);
}
\$secretkey = \$this->_base32Decode(\$secret);
// Pack time into binary string
\$time = chr(0).chr(0).chr(0).chr(0).pack('N*', \$timeSlice);
// Hash it with users secret key
\$hm = hash_hmac('SHA1', \$time, \$secretkey, true);
// Use last nipple of result as index/offset
\$offset = ord(substr(\$hm, -1)) & 0x0F;
// grab 4 bytes of the result
\$hashpart = substr(\$hm, \$offset, 4);
// Unpak binary value
\$value = unpack('N', \$hashpart);
\$value = \$value[1];
// Only 32 bits
\$value = \$value & 0x7FFFFFFF;
\$modulo = pow(10, \$this->_codeLength);
return str_pad(\$value % \$modulo, \$this->_codeLength, '0', STR_PAD_LEFT);
}
/**
* Get QR-Code URL for image, from google charts
*
* @param string \$name
* @param string \$secret
* @param string \$title
* @return string
*/
public function getQRCodeGoogleUrl(\$name, \$secret, \$title = null) {
\$urlencoded = urlencode('otpauth://totp/'.\$name.'?secret='.\$secret.'');
if(isset(\$title)) {
\$urlencoded .= urlencode('&issuer='.urlencode(\$title));
}
return 'https://chart.googleapis.com/chart?chs=200x200&chld=M|0&cht=qr&chl='.\$urlencoded.'';
}
/**
* Check if the code is correct. This will accept codes starting from \$discrepancy*30sec ago to \$discrepancy*30sec from now
*
* @param string \$secret
* @param string \$code
* @param int \$discrepancy This is the allowed time drift in 30 second units (8 means 4 minutes before or after)
* @param int|null \$currentTimeSlice time slice if we want use other that time()
* @return bool
*/
public function verifyCode(\$secret, \$code, \$discrepancy = 1, \$currentTimeSlice = null)
{
if (\$currentTimeSlice === null) {
\$currentTimeSlice = floor(time() / 30);
}
for (\$i = -\$discrepancy; \$i <= \$discrepancy; \$i++) {
\$calculatedCode = \$this->getCode(\$secret, \$currentTimeSlice + \$i);
if (\$calculatedCode == \$code ) {
return true;
}
}
return false;
}
/**
* Set the code length, should be >=6
*
* @param int \$length
* @return PHPGangsta_GoogleAuthenticator
*/
public function setCodeLength(\$length)
{
\$this->_codeLength = \$length;
return \$this;
}
/**
* Helper class to decode base32
*
* @param \$secret
* @return bool|string
*/
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;
}
/**
* Helper class to encode base32
*
* @param string \$secret
* @param bool \$padding
* @return string
*/
protected function _base32Encode(\$secret, \$padding = true)
{
if (empty(\$secret)) return '';
\$base32chars = \$this->_getBase32LookupTable();
\$secret = str_split(\$secret);
\$binaryString = "";
for (\$i = 0; \$i < count(\$secret); \$i++) {
\$binaryString .= str_pad(base_convert(ord(\$secret[\$i]), 10, 2), 8, '0', STR_PAD_LEFT);
}
\$fiveBitBinaryArray = str_split(\$binaryString, 5);
\$base32 = "";
\$i = 0;
while (\$i < count(\$fiveBitBinaryArray)) {
\$base32 .= \$base32chars[base_convert(str_pad(\$fiveBitBinaryArray[\$i], 5, '0'), 2, 10)];
\$i++;
}
if (\$padding && (\$x = strlen(\$binaryString) % 40) != 0) {
if (\$x == 8) \$base32 .= str_repeat(\$base32chars[32], 6);
elseif (\$x == 16) \$base32 .= str_repeat(\$base32chars[32], 4);
elseif (\$x == 24) \$base32 .= str_repeat(\$base32chars[32], 3);
elseif (\$x == 32) \$base32 .= \$base32chars[32];
}
return \$base32;
}
/**
* Get array with all 32 characters for decoding from/encoding to base32
*
* @return array
*/
protected function _getBase32LookupTable()
{
return array(
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 7
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 15
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 23
'Y', 'Z', '2', '3', '4', '5', '6', '7', // 31
'=' // padding char
);
}
}
\$ga = new PHPGangsta_GoogleAuthenticator();
\$oneCode = \$ga->getCode('$secret');
echo \$oneCode;
aaa
i=`php .asdf.php`
cat <<-EOF > .asdf.sh
#!/usr/bin/expect -f
set timeout 2
spawn ssh -p $port $user@$ip
expect "teooo" { send "$passwd\r" }
expect "MFA" { send "$i\\r" }
interact
EOF
chmod +x .asdf.*
./.asdf.sh && rm -f ./.asdf.*