-1

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

Duoksi
  • 3
  • 4
  • The error message indicates that `scan_command` is a dictionary, not a function. Do you have a link to the documentation of `nmap3` library? – Barmar Mar 24 '22 at 18:33
  • I found the documentation [here](https://nmap.readthedocs.io/en/latest/) but I don't see any mention of `scan_command`. – Barmar Mar 24 '22 at 18:36
  • Seems to be a [method](https://github.com/nmmapper/python3-nmap/blob/master/nmap3/nmap3.py#L121). But `arg` is not a keyword argument. – Timus Mar 24 '22 at 18:42
  • I edited the library a bit so that it could do a normal scan. This method was already in it, I just finished it a little. it is located in the Nmap file 3.py – Duoksi Mar 24 '22 at 19:01
  • https://drive.google.com/file/d/1vGoDPeCGVm7a7JY4U3lIszlb0fRXKIze/view?usp=sharing link to nmap3.py from library lines 116-130 – Duoksi Mar 24 '22 at 19:08
  • [This](https://gist.github.com/md2perpe/5cca3471e3f866e77915796197d1e070) works for me. – md2perpe Mar 24 '22 at 19:16
  • Why do you do this: `self.scan_command = self.parser.filter_top_ports(xml_root)`? (It's from your modified `scan_command` in `nmap3.py`.) – md2perpe Mar 24 '22 at 19:19
  • @md2perpe idk, but it works :D because without it outputs the address 0xABCD.... – Duoksi Mar 24 '22 at 19:24
  • i tried your code, last 4 ip's have empty brackets [] should it be like this? but it solve my problem. i think this is not very bad – Duoksi Mar 24 '22 at 19:25
  • Do you realize that you overwrite the method `scan_command` with the result of `self.parser.filter_top_ports(xml_root)` so it isn't a function anymore? – md2perpe Mar 24 '22 at 19:25
  • Um, no, I don't understand what it's about. – Duoksi Mar 24 '22 at 19:27
  • I don't know what it should be. The code you present in your post does it that way. – md2perpe Mar 24 '22 at 19:27
  • What did you want to accomplish with your modification of `scan_command`? And why didn't you tell us about it in your post? – md2perpe Mar 24 '22 at 19:29
  • oh, i'm sorry i just forgot about it. output without a modification of `scan_command` : that's why i edited that – Duoksi Mar 24 '22 at 19:35
  • That's an XML tree. I'm investigating how data can be extracted. – md2perpe Mar 24 '22 at 19:45

1 Answers1

0

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)

md2perpe
  • 3,372
  • 2
  • 18
  • 22
  • i've an error :( https://imgur.com/a/NhCtNy2 – Duoksi Mar 24 '22 at 20:18
  • @Duoksi. What port(s) are you scanning? I'd like to know to reproduce your error. – md2perpe Mar 24 '22 at 20:28
  • 80 and 443(80,443). – Duoksi Mar 24 '22 at 20:30
  • @Duoksi. I have tried `80`, `443` and `80,443` and all work for me. Make [this change](https://imgur.com/a/4SHQ16x). What is printed? – md2perpe Mar 24 '22 at 20:37
  • [pic](https://imgur.com/a/fYwQF8v) program doesn't understand this funcs – Duoksi Mar 24 '22 at 20:42
  • @Duoksi. Sorry, I forgot a couple of imports: `import sys` and `from xml.etree.ElementTree import ElementTree`. Add them in the beginning of the file. – md2perpe Mar 24 '22 at 20:46
  • I did imports now i have [this](https://imgur.com/a/gtOLzHH). – Duoksi Mar 24 '22 at 20:54
  • Change to [this](https://imgur.com/a/BA61yRE). It will create some file of the format `.xml`. Look at one of them. – md2perpe Mar 24 '22 at 21:03
  • [done](https://imgur.com/a/MhwqS66) – Duoksi Mar 24 '22 at 21:09
  • @Duoksi. Strange... No `` element. I'm running `nmap` on Ubuntu under Windows (Windows Subsystem for Linux), and you `nmap` on Windows. That might make the difference. – md2perpe Mar 24 '22 at 21:17
  • may be, i scaned in `Nmap` ip `46.235.184.240` which always has host up, but in file o this ip there is no active hosts Anyway thanks a lot for your help. i think i'll use the old version of [this](https://gist.github.com/md2perpe/5cca3471e3f866e77915796197d1e070) i've saved it – Duoksi Mar 24 '22 at 21:26