#python #python-3.x
#python #python-3.x
Вопрос:
Я пытаюсь прочитать и выполнить итерацию по текстовому файлу на Python, но я продолжаю сталкиваться с этой ошибкой. Я довольно новичок в Python, и я не уверен, где ошибка в моем коде:
import socket
def getBanner(ip, port):
try:
socket.setdefaulttimeout(2)
s = socket.socket()
s.connect((ip, port))
banner = s.recv(1024)
return banner
except:
return
def vulnCheck(banner):
f = open("vuln_banners.txt", 'r')
for line in f.readlines():
if line.strip('n') in banner:
print("[ ] Server is vulnerable: " banner.strip('n'))
else:
print("[-] FTP Server is not vulnerable.")
return
def main():
portList = [21, 22, 25, 80, 110, 443]
for x in range(1, 255):
ip = '192.168.1.' str(x)
for port in portList:
banner = getBanner(ip, port)
if banner:
print("[ ] " str(ip) ": " str(banner))
vulnCheck(banner)
if __name__ == '__main__':
main()
Я бы хотел, чтобы моя программа перебирала список строк в текстовом файле для сравнения с баннером, однако каждый раз, когда я запускаю код, я получаю эту ошибку:
File "/home/testing/Documents/HelloWorld.py", line 17, in vulnCheck
if line.strip('n') in banner:
TypeError: a bytes-like object is required, not 'str'
Я прочитал несколько ответов об этой ошибке, и в них говорится о ТОМ, что файл НЕ открывается как двоичный, но я не думаю, что я делаю это в своем коде. Я просто пытаюсь прочитать каждую строку в текстовом файле и выполнить итерацию по ней. Может кто-нибудь указать на ошибку в моем коде? Любая помощь будет оценена.
Комментарии:
1. Python 3 — это небольшая проблема, поскольку многие сообщения и файловые буферы теперь являются байтовыми объектами, а не строками. Самая простая вещь, которая обычно работает, — это
decode()
строковый метод. напримерmystring = mybuffer.decode()
. Вы также можете использоватьencode()
при переходе другим путем.
Ответ №1:
Ваш сокет возвращает bytes
, пока файл содержит строки. Вам нужно сопоставить одно с другим — возможно, декодировать bytes
баннеры в строки.
Кроме того, многократное чтение одного и того же статического текстового файла является здесь существенным узким местом. Если файл не настолько огромен, что вместо него все равно следует использовать базу данных, прочитайте его один раз, в начале.
В следующем также есть различные исправления ошибок и стилистические обновления; самое главное, не return
проверяйте уязвимость в середине, если первая ошибка не была сопоставлена. Обратите внимание также на то, как обычно работает только return
результат, и оставьте его вызывающему, чтобы решить, например, печатать ли что-то на основе этого.
import socket
def get_banner(ip, port):
try:
socket.setdefaulttimeout(2)
s = socket.socket()
s.connect((ip, port))
banner = s.recv(1024)
return banner.decode('utf-8')
except:
return
def vuln_check(banner, vulnlist):
for line in vulnlist:
if line in banner:
return True
return False
def read_vulns(filename):
with open(filename, 'r') as f:
return f.read().splitlines()
def main():
vulns = read_vulns("vuln_banners.txt")
port_list = [21, 22, 25, 80, 110, 443]
for x in range(1, 255):
ip = '192.168.1.' str(x)
for port in port_list:
banner = get_banner(ip, port)
if banner:
print("[ ]", ip ":", banner)
if vuln_check(banner, vulns):
print("[ ] Server is vulnerable:", banner.strip('n'))
else:
print("[-] FTP Server is not vulnerable.")
if __name__ == '__main__':
main()
Ответ №2:
In getBanner
— banner = s.recv(1024)
это bytes
объект, поэтому banner
in vulnCheck
также bytes
. Поскольку вы не открывали файл в двоичном режиме, line.strip('n')
это будет строка. Поиск str
ings в является ошибкой, bytes
поскольку для этого строка должна быть закодирована (или байты должны быть декодированы соответствующим образом).
Таким образом, вы действительно должны открыть файл в двоичном режиме.
Ответ №3:
Объект banner не является строкой, поэтому python не может выполнять поиск по байтовому объекту, пытаясь найти строку.