Home > Blockchain >  Python error 'dict' object is not callable
Python error 'dict' object is not callable

Time:03-25

I'm new in python And I have a problem that I haven't been able to solve for a couple of days and I don't understand what the error is at all. I am writing a program based on the Nmap program and the library of the same name, the functionality of which is to scan open ports of some list of ip addresses. I'm trying to implement this through a dictionary, when I did everything on a static variable of ports, everything was fine, but when the program scans ports for each address, such an error is issued on the second iteration of the scan cycle.

'dict' object is not callable
File "C:\Users\Duoksi\Desktop\codes\python\NmapScanPy\test.py", line 47, in ScanPorts
    result = nmap.scan_command(ip, arg = attribute)

Below is the function code. You can also install the library with this command: pip install python3-nmap

import nmap3
def Portscan():
    nmap = nmap3.Nmap()
    attribute = "-p "
    port = input("Enter ports(ex. 80,443)\n")
    attribute  = str(port)
    ipport = dict()
    IPrange = ['93.187.72.82', '93.187.72.94', '93.187.72.115', '93.187.72.241', '93.187.72.19', '93.187.72.59', '93.187.72.208', 
    '93.187.72.179', '93.187.72.24', '93.187.72.137', '93.187.72.136', '93.187.72.130']
    for ip in IPrange: 
        result = nmap.scan_command(ip, arg = attribute) 
        resultclean = re.findall('\'protocol\': \'\w \', \'portid\': \'\w \', \'state\': \'\w \'', str(result))
        for res in resultclean:
            ipport.setdefault(ip, []).append(res)
    return ipport

Output that i expect: pic of output

CodePudding user response:

The unmodified scan_command method returns an xml.etree.ElementTree.Element object representing an XML tree that looks like this:

<nmaprun scanner="nmap" args="/usr/bin/nmap -oX - -p 80 93.187.72.82" start="1648151628" startstr="Thu Mar 24 20:53:48 2022" version="7.80" xmloutputversion="1.04">
    <scaninfo type="connect" protocol="tcp" numservices="1" services="80" />
    <verbose level="0" />
    <debugging level="0" />
    <host starttime="1648151628" endtime="1648151629">
        <status state="up" reason="syn-ack" reason_ttl="0" />
        <address addr="93.187.72.82" addrtype="ipv4" />
        <hostnames>
        </hostnames>
        <ports>
            <port protocol="tcp" portid="80">
                <state state="open" reason="syn-ack" reason_ttl="0" />
                <service name="http" method="table" conf="3" />
            </port>
        </ports>
        <times srtt="64487" rttvar="50416" to="266151" />
    </host>
    <runstats>
        <finished time="1648151629" timestr="Thu Mar 24 20:53:49 2022" elapsed="1.28" summary="Nmap done at Thu Mar 24 20:53:49 2022; 1 IP address (1 host up) scanned in 1.28 seconds" exit="success" />
        <hosts up="1" down="0" total="1" />
    </runstats>
</nmaprun>

Here's code to get the protocol, portid and state from it:

import nmap3

IP_RANGE = [
    '93.187.72.82',  '93.187.72.94',  '93.187.72.115', '93.187.72.241', '93.187.72.19',  '93.187.72.59',
    '93.187.72.208', '93.187.72.179', '93.187.72.24',  '93.187.72.137', '93.187.72.136', '93.187.72.130',
]

def scan_one_ip(ip: str, port: str) -> list[str]:
    result = nmap3.Nmap().scan_command(ip, arg=f"-p {port}")
    port_element = result.find("./host/ports/port")
    return [
        port_element.get("protocol"),
        port_element.get("portid"),
        port_element.find("state").get("state"),
    ]

def scan_port(port: str) -> dict[str, list[str]]:
    return {ip: scan_one_ip(ip, port) for ip in IP_RANGE}


def main():
    port = input("Enter ports (ex. 80,443)\n")
    print(scan_port(port))


if __name__ == '__main__':
    main()

(Also available at https://gist.githubusercontent.com/md2perpe/5cca3471e3f866e77915796197d1e070/raw/cfdab2d99926030a61201748b3ec2cbbc429b7cf/main.py)

  • Related