2016-12-27 155 views
3

我從http://allanrbo.blogspot.in/2011/12/raw-sockets-with-bpf-in-python.html得到了代碼。它工作正常,但我想嗅探多個TCP端口像端口90008022交通......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的流量。我沒有完全理解代碼。任何幫助?

回答

3

據我所知,問題似乎來自您的前兩個條件跳轉的邏輯。具體做法是:

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), 

… 
+0

感謝您的回答。如果我想過濾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

+0

@Veerendra:我編輯了三個端口的答案(儘管如此還沒有測試過)。 – Qeole

+0

謝謝!你保存了我的一天:)現在我得到的數據包是哪個目的端口=='9000'或'8084'或'22'(無論我們在過濾器中添加了什麼),但我需要兩種方式,比如我需要有興趣的數據包端口(有興趣的端口可以在'source'或'destination':需要兩個包!)任何幫助? – Veerendra