简体   繁体   中英

TypeError: a bytes-like object is required, not 'str' when reading and iterating over a file in Python3.x

I'm trying to read and iterate over a text file in Python but I keep running into this error. I'm pretty new to Python and I'm not sure where the error in my code is:

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()

I would like my program to iterate over a list of strings in a text file to compare against a banner, however, every time I run the code I get this error:

  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'

I've read few of the answers about this error and they talk about NOT opening the file as binary, but I don't think I'm doing that in my code. I'm simply trying to read each line in a text file and iterate over it. Can anyone point out the error in my code? Any help would be appreciated.

In getBanner , banner = s.recv(1024) is a bytes object, so banner in vulnCheck is also bytes . Since you did not open the file in binary mode, line.strip('\\n') will be a string . It is an error to search for str ings in bytes because a string must be encoded in order to do this (or the bytes must be decoded appropriately).

Thus, you should indeed open the file in binary mode.

横幅对象不是字符串,因此python无法搜索字节对象,试图找到字符串。

Your socket returns bytes while the file contains strings. You need to map one to the other - probably decode bytes banners to strings.

As an aside, repeatedly reading the same static text file is a significant bottleneck here. Unless the file is so huge that you should be using a database instead anyway, read it once, at the start.

The following also has assorted bug fixes and stylistic updates; most importantly, don't return in the middle of the vulnerability check if the first vulerability wasn't matched. Notice also how functions generally just return a result, and leave it to the caller to decide eg whether to print something based on that.

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()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM