TypeError: требуется байтоподобный объект, а не ‘str’ при чтении и переборе файла в Python3.x

#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 не может выполнять поиск по байтовому объекту, пытаясь найти строку.