如何嗅探和注入原始套接字?

时间:2016-12-01 13:14:12

标签: python linux sockets tcp

我在这里问这个问题只是因为我经常搜索,直到现在我还无法找到关于如何完成这项任务的线索。手头的任务是构建一个能够:

的python脚本
  • 嗅探tcp数据包;
  • 解码de payload,在我的情况下用JWT加密 - JWT in turn是base64中的json;
  • 使用解密数据重新包装;
  • 如果可能,将数据包重新注入同一接口,但可以是a 虚拟界面;
  • 它必须在飞行中发生。

到达服务器的所有流量都进入一个没有任何IP关联的接口,因此嗅探必须在第2层发生并重新注入第2层,但是可能在第2层捕获并且重新注入第3层,但在这种情况下,我不知道该怎么做。通过第2层,我的意思是绑定到接口,而不是主机名和端口。

我已根据此http://www.offensivepython.com/2014/08/tcp-packet-injection-with-python.html进行了我的脚本注射,并在实验室(Kali,Centos 6.8)中正常工作,将元组主机,端口传递给socket.bind()并进行嗅探我写的以下内容:

#!/usr/bin/python


import socket
import ctypes
import fcntl
from struct import *
from time import sleep
class ifreq(ctypes.Structure):
    _fields_ = [("ifr_ifrn", ctypes.c_char * 16),("ifr_flags", ctypes.c_short)]


IFACE="eth0"
ETH_P_IP=0x0800
IFF_PROMISC = 0x100
SIOCGIFFLAGS = 0x8913
SIOCSIFFLAGS = 0x8914

skt = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(ETH_P_IP))

ifr = ifreq()
ifr.ifr_ifrn = IFACE
fcntl.ioctl(skt.fileno(), SIOCGIFFLAGS, ifr)
ifr.ifr_flags |= IFF_PROMISC
fcntl.ioctl(skt.fileno(), SIOCSIFFLAGS, ifr)


print "[+] Sniffing packets"
while True:
    pct = skt.recvfrom(65535)
    pct = pct[0]
    ipheader = pct[:20]
    iph = unpack('!BBHHHBBH4s4s', ipheader)
    version_ih1 = iph[0]
    version = version_ih1 >> 4
    ih1 = version_ih1 & 0xF
    iph_length = ih1 * 4
    ttl = iph[5]
    protocol = iph[6]
    src_addr = socket.inet_ntoa(iph[8])
    dst_addr = socket.inet_ntoa(iph[9])

    print 'Version: %s \nIP Header Length: %s\nTTL: %s\nProtocol: %s\nSource Addr: %s\nDest Addr: %s'%(version, iph_length, ttl, protocol, src_addr, dst_addr)

    tcp_header = pct[iph_length:iph_length+20]
    tcph = unpack('!HHLLBBHHH', tcp_header)
    src_port = tcph[0]
    dst_port = tcph[1]
    sequence = tcph[2]
    ack = tcph[3]
    doff_reserved = tcph[4]
    tcph_length = doff_reserved >> 4
    if src_port == 0 | dst_port == 0:
        continue

    print 'SRC Port: %s \nDST_Port: %s\nSEQ: %s\nACK: %s\nDoff Reserved: %s\nTCP Header Length: %s'%(src_port, dst_port, sequence, ack, doff_reserved, tcph_length)

    h_size = iph_length + tcph_length * 4
    data_size = len(pct) - h_size
    data = pct[h_size:]
    print 'Data: %s\n' %data
    sleep(2)

我已经测试了这个solution并且在我的实验室(Kali,CentOS 6.8)中可以正常进行注射,我可以运行tcpdump并看到数据包进入指定的接口但是在生产中(RHEL 6.8) )现在在tcpdump中显示任何内容。

我一直在socket linux docs中搜索过这个问题,在一些书籍中搜索python socket文档,比如Core Python,网络编程基础,Linux编程接口,并且有关于如何正确使用AF_PACKET的信息。 我的问题是:

  • 是否可以解码第2层的流量;
  • 如果是,则遵循上述脚本的推理 我做错了什么?
  • 套接字实现之间是否存在一些差异 不同的Linux发行版(RHEL,Centos,Debian);
  • 如何使用参数正确使用套接字接口 (socket.AF_PACKET,socket.SOCK_RAW,[OPTIONAL]);
  • 上面项目中的OPTIONAL参数是协议,在某些例子中,我看过socket.htons(ETH_P_IP),ETH_P_IP,socket.ntohs(ETH_P_IP),常量有时是ETH_P_ALL,有什么区别?
  • 有人可以在这里留下一个例子吗?

这个问题是因为我正在使用威胁检测工具处理所有数据并生成警报,事件和报告,但使用JWT编码的数据无法查看请求中实际发生的情况,因此无法查看实际数据并正确使用该工具。

提前致谢。

0 个答案:

没有答案