Catchf1r3 / MNScan

masscan+nmap,结合了massacn的快速扫描和nmap精准识别端口的特点。
5 stars 0 forks source link

师傅,有个问题请教下 #1

Open gusechuisheng opened 8 months ago

gusechuisheng commented 8 months ago

能正常扫描但是输出有问题,还有扫描完成之后报错 Masscan completed successfully.
Traceback (most recent call last): File "MNScan.py", line 114, in run_masscan(args.output_file_path, args.target, args.ports, args.rate) File "MNScan.py", line 86, in run_masscan ip_ports_mapping = parse_masscan_output(masscan_output) File "MNScan.py", line 14, in parse_masscan_output results = json.loads(masscan_output) File "/usr/lib/python3.8/json/init.py", line 357, in loads return _default_decoder.decode(s) File "/usr/lib/python3.8/json/decoder.py", line 337, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) File "/usr/lib/python3.8/json/decoder.py", line 355, in raw_decode raise JSONDecodeError("Expecting value", s, err.value) from None json.decoder.JSONDecodeError: Expecting value: line 3 column 1 (char 155) 上面是扫描完成之后的报错,下面是输出结果不合适

image
gusechuisheng commented 8 months ago

我运行的命令是python3 MNScan.py -i 4.x.x.x -p 5003 -o /home/out.txt 我的python文件内容是 `import subprocess import argparse import re import json from collections import defaultdict import concurrent.futures

def is_valid_ip(ip):

Regular expression to match IP address format

ip_pattern = re.compile(r'\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b')
return bool(ip_pattern.match(ip))

def parse_masscan_output(masscan_output): results = json.loads(masscan_output)

# 使用 defaultdict 创建一个以 IP 为键的字典,值是该 IP 对应的端口列表
ip_ports_mapping = defaultdict(list)

for result in results:
    ip = result.get("ip", "")
    ports = result.get("ports", [])

    # 添加到字典中
    ip_ports_mapping[ip].extend([str(port_info["port"]) for port_info in ports])

return ip_ports_mapping

def nmap_scan(ip, ports, output_file_path): nmap_path = "/usr/bin/nmap" ports_str = ",".join(ports) nmap_cmd = ["nmap_path", ip, "-p", ports_str, "-sV", "-Pn", "-oN", output_file_path,"--append-output"] subprocess.run(nmap_cmd, check=True)

# 读取 nmap 输出文件
with open(output_file_path, 'r') as f:
    nmap_output = f.read()

#匹配当前 ip 的nmap输出
pattern = rf'Nmap scan report for {re.escape(ip)}([\s\S]*?)Nmap done at'
matches = re.findall(pattern, nmap_output)

# 匹配 https和http 端口信息
for match in matches:
    https_ports = re.findall(r'(\d+)/tcp\s+open\s+.*ssl.*\n', match)
    http_ports = re.findall(r'(\d+)/tcp\s+open\s+http', match)

# 格式化 https 端口信息,并追加到输出文件
if https_ports:
    with open(output_file_path, 'a') as f:
        print(f"\nHTTPS Services:")
        f.write("\n\nHTTPS Services:\n")
        for port in https_ports:
            print(f"\033[92mhttps://{ip}:{port}\033[0m")
            f.write(f"https://{ip}:{port}\n")

# 格式化 http 端口信息,并追加到输出文件
if http_ports:
    with open(output_file_path, 'a') as f:
        print(f"\nHTTP Services:")
        f.write("\n\nHTTP Services:\n")
        for port in http_ports:
            print(f"\033[92mhttp://{ip}:{port}\033[0m")
            f.write(f"http://{ip}:{port}\n")

def run_masscan(output_file_path, target, ports, rate): masscan_path = "/usr/bin/masscan" # 替换为实际的 masscan 路径,再替换下面 is_valid_ip(target) 判断中 "masscan"

# 根据输入参数类型构建 masscan 命令
if is_valid_ip(target):
    masscan_cmd = ["masscan", target, "--ports", ports, "-oJ", output_file_path, "--rate", rate]
else:
    masscan_cmd = ["masscan", "-iL", target, "--ports", ports, "-oJ", output_file_path, "--rate", rate]

try:
    # 调用 masscan 命令
    subprocess.run(masscan_cmd, check=True)
    print("Masscan completed successfully.")

    # 读取 masscan 输出文件
    with open(output_file_path, 'r') as f:
        masscan_output = f.read()

    # 解析 masscan 输出
    ip_ports_mapping = parse_masscan_output(masscan_output)

    # 使用多线程扫描每个 IP 的端口
    with concurrent.futures.ThreadPoolExecutor() as executor:
        # 提交每个 IP 的扫描任务
        futures = [executor.submit(nmap_scan, ip, ports, output_file_path) for ip, ports in ip_ports_mapping.items()]

        # 等待所有任务完成
        concurrent.futures.wait(futures)

except subprocess.CalledProcessError as e:
    print(f"Error running Masscan: {e}")

if name == "main": parser = argparse.ArgumentParser(description="Run Masscan with custom parameters") parser.add_argument("-i", "--ip", dest="target", help="Single target IP address") parser.add_argument("-f", "--file", dest="target", help="File containing target IPs (one per line)") parser.add_argument("-o", "--output", dest="output_file_path", default="./output.txt", help="Output file path,default output.txt") parser.add_argument("-r", "--rate", dest="rate", default="1000", help="Scan rate,dafault 1000") parser.add_argument("-p", "--ports", dest="ports", default="1-65535", help="Port range (default: 1-65535)")

args = parser.parse_args()

if not args.target:
    print("Please specify either -i/--ip or -f/--file for target IPs.")
    exit(1)

# 调用 run_masscan 函数
run_masscan(args.output_file_path, args.target, args.ports, args.rate)

`

Catchf1r3 commented 8 months ago
图片 图片

这个是你的masscan扫描结果最后多了一个逗号引起的,导致json解析错误,我的masscan输出的json最后没有这个逗号,可能我们masscan的版本不一样,我更新了代码,在代码里加了判断过滤掉这个逗号,我试了可以正常使用了,另外之前程序里没有判断masscan扫描结果是否为空,会导致异常退出程序,我更新后加入了判断,可以更加明了显示结果。

gusechuisheng commented 7 months ago

多谢师傅