python中的BPF来嗅探多个TCP端口的数据包
问题描述:
我从http://allanrbo.blogspot.in/2011/12/raw-sockets-with-bpf-in-python.html得到了代码。它工作正常,但我想嗅探多个TCP端口像端口9000
,80
,22
交通......python中的BPF来嗅探多个TCP端口的数据包
所以我已经修改了filter_list
像打击
filters_list = [
# Must have dst port 67. Load (BPF_LD) a half word value (BPF_H) in
# ethernet frame at absolute byte offset 36 (BPF_ABS). If value is equal to
# 67 then do not jump, else jump 5 statements.
bpf_stmt(BPF_LD | BPF_H | BPF_ABS, 36),
bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 9000, 0, 5), <===== Here I added another port
bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 80, 0, 5),
# Must be UDP (check protocol field at byte offset 23)
bpf_stmt(BPF_LD | BPF_B | BPF_ABS, 23),
bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 0x06, 0, 3), #<==Changed for TCP "0x06"
# Must be IPv4 (check ethertype field at byte offset 12)
bpf_stmt(BPF_LD | BPF_H | BPF_ABS, 12),
bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 0x0800, 0, 1),
bpf_stmt(BPF_RET | BPF_K, 0x0fffffff), # pass
bpf_stmt(BPF_RET | BPF_K, 0), # reject ]
的事情是,有时有时候它不是工作,就像只有9000而不是80的流量,有时80的流量。我没有完全理解代码。任何帮助?
答
据我所知,问题似乎来自您的前两个条件跳转的逻辑。具体做法是:
bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 9000, 0, 5), # if false, skip 5 instructions
bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 80, 0, 5),
的指令bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, <val>, <jtrue>, <jfalse>)
意味着
if value currently in register K is equal to <val>
then add <jtrue> to instruction pointer
(i.e. skip the next <jtrue> instructions),
else add <jfalse> instead`
因此,两行表示:
if port is 9000
then if port is 80
then go on with checks…
else skip 5 instructions (i.e. reject)
else
skip 5 instructions (i.e. pass, as jump offset was not updated from 5 to 6)
虽然你可能想要的东西,看起来更像是:
if port is 9000
then go on with checks…
else
if port is 80
then go on with checks…
else reject
我h AVE没有测试过,但得到这个逻辑,我会说,你需要适应跳偏移如下:
bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 9000, 1, 0), # if true skip 1 insn
# (i.e. port 80 check) else 0
# and check for port 80
bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 80, 0, 5), # if true skip 0 else skip 5
# (and land on “reject”)
编辑1:然后用于过滤三个端口,这将成为:
bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 8084, 2, 0), # skip the next 2 checks if true
bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 9000, 1, 0), # skip the next check if true
bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 22, 0, 5), # if true go on else reject
编辑2:要同时过滤源端口(除目的端口),你可以尝试这样的事情(仍然没有在我的身边测试):
# Load TCP src port into register K, and check port value
# For packets with IP header len == 20 bytes, TCP src port should be at offset 34
# We adapt the jump offsets to go to next check if no match (or to “reject” after
# the last check), or to skip all remaining checks on ports if a match is found.
bpf_stmt(BPF_LD | BPF_H | BPF_ABS, 34), # 34 == offset of src port
bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 8084, 6, 0),
bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 9000, 5, 0),
bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 22, 4, 0),
# As before: if no match on src port, check on dst port
bpf_stmt(BPF_LD | BPF_H | BPF_ABS, 36),
bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 8084, 2, 0),
bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 9000, 1, 0),
bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 22, 0, 5),
…
感谢您的回答。如果我想过滤2个或更多的端口,过滤器是什么。我尝试了3个端口---> bpf_jump(BPF_JMP | BPF_JEQ | BPF_K,8084,1,0),bpf_jump(BPF_JMP | BPF_JEQ | BPF_K,9000,1,0),bpf_jump(BPF_JMP | BPF_JEQ | BPF_K,22,0 ,5),'。我只有'9000'和'22'的流量。 – Veerendra
@Veerendra:我编辑了三个端口的答案(尽管如此还没有测试过)。 – Qeole
谢谢!你保存了我的一天:)现在我得到的数据包是哪个目的端口=='9000'或'8084'或'22'(无论我们在过滤器中添加了什么),但我需要两种方式,比如我需要有兴趣的数据包端口(有兴趣的端口可以在'source'或'destination':需要两个包!)任何帮助? – Veerendra