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)