如何在python中实现tcpflow功能(遵循tcp流)



我正在用python(平台是linux)编写一个工具,其中一项任务是捕获实时tcp流对每一行应用一个函数。目前我正在使用

import subprocess
proc = subprocess.Popen(['sudo','tcpflow', '-C', '-i', interface, '-p', 'src', 'host', ip],stdout=subprocess.PIPE)
for line in iter(proc.stdout.readline,''):
    do_something(line)

这工作得很好(在/etc/sudoers中有适当的条目),但我希望避免调用外部程序。

到目前为止,我已经研究了以下可能性:

  • flowgrep:一个python工具,看起来就像我需要的,但是:它使用pynids内部,它已经7年了,似乎几乎被抛弃了。没有pynids包对于我的gentoo系统,它附带了libnids的修补版本如果不进一步调整,我就无法编译。

  • scapy:这是一个python的包操作程序/库,我不确定tcp流支持重新装配。

  • pypcap或pylibpcap作为libpcap的包装器。同样,libpcap用于数据包捕获,我需要重新组装流,根据对于这个问题。

在我深入研究这些图书馆之前,我想知道是否有人有一个工作代码片段(这似乎是一个相当常见的问题)。如果有人可以就正确的道路提供建议。

感谢

Jon Oberheide领导了维护pynids的工作,这是最新的:http://jon.oberheide.org/pynids/

因此,这可能允许您进一步探索flowgrep。Pynids本身处理流重构相当优雅。请参阅http://monkey.org/~jose/ppresentation/pysniff04.d/获取一些好的示例。

作为后续:我放弃了在tcp层上监视流的想法。相反,我用python编写了一个代理,并让我想要监控的连接(http会话)通过这个代理进行连接。结果更加稳定,并且不需要root权限即可运行。这个解决方案依赖于吡喹酮。

这将进入一个独立的程序,例如helper_proxy.py

from multiprocessing.connection import Listener
import StringIO
from httplib import HTTPResponse
import threading
import time
from miproxy.proxy import RequestInterceptorPlugin, ResponseInterceptorPlugin, AsyncMitmProxy
class FakeSocket(StringIO.StringIO):
    def makefile(self, *args, **kw):
        return self
class Interceptor(RequestInterceptorPlugin, ResponseInterceptorPlugin):
    conn = None
    def do_request(self, data):
        # do whatever you need to sent data here, I'm only interested in responses
        return data
    def do_response(self, data):
        if Interceptor.conn:   # if the listener is connected, send the response to it
            response = HTTPResponse(FakeSocket(data))
            response.begin()
            Interceptor.conn.send(response.read())
        return data
def main():
    proxy = AsyncMitmProxy()
    proxy.register_interceptor(Interceptor)
    ProxyThread = threading.Thread(target=proxy.serve_forever)
    ProxyThread.daemon=True
    ProxyThread.start()
    print "Proxy started."
    address = ('localhost', 6000)     # family is deduced to be 'AF_INET'
    listener = Listener(address, authkey='some_secret_password')
    while True:
        Interceptor.conn = listener.accept()
        print "Accepted Connection from", listener.last_accepted
        try:
            Interceptor.conn.recv()
        except: time.sleep(1)
        finally:
            Interceptor.conn.close()
if __name__ == '__main__':
    main()

python helper_proxy.py开始。这将创建一个代理,侦听端口8080上的http连接,并侦听端口6000上的另一个python程序。一旦另一个python程序在该端口上连接,助手代理将向其发送所有http回复。这样,助手代理就可以继续运行,保持http连接,并且可以重新启动侦听器进行调试。

以下是侦听器的工作方式,例如listener.py:

from multiprocessing.connection import Client
def main():
    address = ('localhost', 6000)
    conn = Client(address, authkey='some_secret_password')
    while True:
        print conn.recv()
if __name__ == '__main__':
    main()

这只会打印所有回复。现在,将浏览器指向运行在8080端口上的代理,并建立要监视的http连接。

相关内容

  • 没有找到相关文章

最新更新