使用 `ip = ipaddress.ip_address(args.ip)` 的 TCP 端口测试不准确

Posted

技术标签:

【中文标题】使用 `ip = ipaddress.ip_address(args.ip)` 的 TCP 端口测试不准确【英文标题】:TCP port testing not accurate with `ip = ipaddress.ip_address(args.ip)` 【发布时间】:2019-05-22 08:11:45 【问题描述】:

在这台测试机器中,tcp/80 正在监听,而 tcp/4444 没有。 (我已经用netstat -an 验证了这一点)

如果我只是将args.ip 的值传递给ip,并将其转发给scan() 函数,那么扫描结果总是准确的。

ip = args.ip

正常输出:

C:\>python script.py 127.0.0.1
Port number: 80
Connecting to 127.0.0.1:80
OK 127.0.0.1:80

C:\>python script.py 127.0.0.1
Port number: 4444
Connecting to 127.0.0.1:4444
FAIL 127.0.0.1:4444

C:\>

但是,当我尝试使用以下函数验证 IP 地址时

ip = ipaddress.ip_address(args.ip)

扫描结果总是错误的。

错误的输出...tcp/80 已启动并正在运行:

C:\>python script.py 127.0.0.1
Port number: 80
Connecting to 127.0.0.1:80
FAIL 127.0.0.1:80

这段代码有什么问题?

import socket, argparse, ipaddress

def main():
    global ip
    parser = argparse.ArgumentParser()
    parser.add_argument('-u')
    group = parser.add_mutually_exclusive_group()
    group.add_argument('-i')
    group.add_argument('ip', nargs='?')
    args = parser.parse_args()
    if args.i:                                      
        print("IP Address is .. " + args.i)
    elif args.ip:                                   
        ip = ipaddress.ip_address(args.ip)          # Prob
        #ip = args.ip                               # OK
        scan()
    elif args.u:
        print("URL is " + args.u)
    else:
        print('No argument provided')

def scan():
    port = input('Port number: ')
    print('Connecting to %s:%s' % (ip,port))    
    try:
        s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((ip, int(port)))
        print('OK %s:%s' % (ip, port))
    except:
        print('FAIL %s:%s' % (ip, port))

main()

是否可以验证 IP 地址,然后将其转发到另一个函数,并且仍然获得正确的端口扫描测试?

【问题讨论】:

【参考方案1】:

您尝试将IPv4Address 而非字符串传递给s.connect

如果你不使用包罗万象的except 会更明显。没有它,这就是你得到的:

thierry@amd:~$ python3 test.py 127.0.0.1
Port number: 80
Connecting to 127.0.0.1:80
Traceback (most recent call last):
  File "test.py", line 32, in <module>
    main()
  File "test.py", line 16, in main
    scan()
  File "test.py", line 27, in scan
    s.connect((ip, int(port)))
TypeError: str, bytes or bytearray expected, not IPv4Address

只需使用str(ip) 而不是ip

def scan():
    port = input('Port number: ')
    print('Connecting to %s:%s' % (ip,port))    
    try:
        s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((str(ip), int(port)))  # ip is an IPv4Address
        print('OK %s:%s' % (ip, port))   # no problem here, str will be used for print
    except ValueError:
        print('FAIL %s:%s' % (ip, port))

thierry@amd:~$ python3 test.py 127.0.0.1
Port number: 80
Connecting to 127.0.0.1:80
OK 127.0.0.1:80

您可能还想将您的 except: 更改为 except ConnectionRefusedError: 以避免模糊地捕获所有异常。

【讨论】:

哇!!!非常感谢。我花了几个小时查看这段代码,但无法弄清楚。您能否分享一些提示,您是如何快速调试此类问题的?顺便说一句,我还是 Python 新手……刚刚开始。

以上是关于使用 `ip = ipaddress.ip_address(args.ip)` 的 TCP 端口测试不准确的主要内容,如果未能解决你的问题,请参考以下文章

动态IP能否使用HSS

手机如何修改ip地址,使用全国动态ip呢

如何使用Python实现爬虫代理IP池

如何用ip访问网站

为LAN链接配置的IP地址需要使用自动IP地址?

兔子IP教你解决日常使用过程中ip被封锁IP被限制的几种方法