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

时间:2012-01-05 21:58:07

标签: python tcp stream

我在python中编写一个工具(platform is 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流 支持重组。

  • pypcappylibpcap作为libpcap的包装器。同样,libpcap用于数据包 捕获,我需要流重组,这是不可能的 到this question

在深入了解这些图书馆之前,我想知道是否有人 有一个工作代码片段(这似乎是一个相当常见的问题)。如果,我也很感激 有人可以就正确的方法提出建议。

由于

2 个答案:

答案 0 :(得分:1)

Jon Oberheide一直致力于维持pynids,这在以下方面是最新的: http://jon.oberheide.org/pynids/

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

答案 1 :(得分:1)

就像后续行动一样:我放弃了监控tcp层流的想法。相反,我在python中编写了一个代理,让我想监视的连接(一个http会话)通过这个代理连接。结果更稳定,不需要root权限即可运行。此解决方案取决于pymiproxy

这是一个独立的程序,例如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连接。