1

我正在使用端口扫描器来扫描我的子网。不幸的是,端口扫描器一次只能扫描一台主机的一个端口。此外,扫描仪对无法访问的主机有 1 秒的超时。扫描仪(作为外部程序)必须从 subprocess.Popen() 运行并加快速度 - 这样我就可以发送多个探测器,而之前的一些探测器正在等待回复 - 我使用线程。问题出现在具有大量线程的完整 /24 子网扫描中。一些实际打开的端口显示为关闭。我怀疑输出会以某种方式出现乱码。请注意,如果我一次扫描较少的主机或一台主机,则不会发生这种情况

以下代码是我尝试创建一个线程池,该线程池采用 IP 地址并为定义的端口运行“顺序”端口扫描。一旦扫描了所有指定的端口,它就会从列表中选择下一个 IP。

        while True:
            if not thread_queue.empty():
                try:
                    hst = ip_iter.next()
                except StopIteration:
                    break
                m=thread_queue.get()
                l=ThreadWork(self,hst,m)
                l.start()
        while open_threads != 0:
            pass      

该片段设置线程队列的位置

        thread_list = [x for x in range(num_threads)]
        for t in thread_list:
            thread_queue.put(str(t))
        ip_iter=iter(self.final_target)

在 ThreadWork 函数中,我保留了一个打开线程的选项卡(因为 thread_queue.empty 被证明是不可靠的,我不得不使用这种粗略的方式)

class ThreadWork(threading.Thread):
    def __init__(self,i,hst,thread_no):
        global open_threads
        threading.Thread.__init__(self)
        self.host = hst
        self.ptr = i
        self.t = thread_no
        lock.acquire()
        open_threads = open_threads + 1
        lock.release() 

    def run(self):
        global thread_queue
        global open_threads
        global lock
        user_log.info("Executing sinfp for IP Address : %s"%self.host)
        self.ptr.result.append(SinFpRes(self.host,self.ptr.init_ports,self.ptr.all_ports,self.ptr.options,self.ptr.cf))
        lock.acquire()
        open_threads = open_threads - 1
        lock.release()
        thread_queue.put(self.t)

对 SinFpRes 的调用会为一个 IP 创建一个结果对象,并仅为该 IP 启动端口的顺序扫描。每个端口的实际扫描如图所示

        com_string = '/usr/local/sinfp/bin/sinfp.pl '+self.options+' -ai '+str(self.ip)+' -p '+str(p)
        args = shlex.split(com_string) 
        self.result=subprocess.Popen(args,stdout=subprocess.PIPE).communicate()[0]
        self.parse(p)

然后,解析函数利用存储在 self.result 中的结果来存储该端口的输出。所有端口的聚合构成 IP 的扫描结果。

使用 10 个线程调用此代码可提供准确的 o/p(与 nmap 输出相比)。在提供 15 个线程时,偶尔会错过打开的端口。在提供 20 个线程时,会丢失更多开放端口。在提供 50 个线程时,许多端口被遗漏。

PS - 作为第一个计时器,这段代码非常复杂。向清教徒道歉。

PPS - 对于几乎没有扫描 20 个端口的整个 C 类子网,即使是线程化端口扫描也需要 15 分钟。我想知道是否应该将此代码移至另一种语言并使用 Python 仅解析结果。有人可以建议我一种语言吗?注意 - 我正在探索 S.Lott 所示的 Shell 选项,但在将其转储到文件之前需要手动处理。

4

3 回答 3

1

使用外壳

 for h in host1 host2 host3
 do
     scan $h >$h.scan &
 done
 cat *.scan >all.scan

这将同时扫描整个主机列表,每个主机都在一个单独的进程中。没有线程。

每次扫描都会生成一个.scan文件。然后,您可以将所有.scan文件集中到一个大all.scan文件中以进行进一步处理或您正在做的任何事情。

于 2010-12-17T12:02:46.530 回答
1

你为什么不试试呢?

(答案:不,他们会有自己的管道)

于 2010-12-16T11:16:32.010 回答
0

使用 Perl 而不是 Python。该程序 (SinFP) 是用 Perl 编写的,您可以修改代码以满足您的需要。

于 2010-12-21T07:43:31.040 回答