簡體   English   中英

嘗試根據多個其他列表檢查列表列表

[英]Trying to check a list of list against multiple other lists

我有一個從防火牆日志派生的 CSV 派生的列表的 100,000 個條目列表。 我的願景是以一個文件結束,該文件輸出任意兩個 IP 之間使用的端口,例如:1.1.1.1。 至 2.2.2.2 端口(25、53、80) 2.2.2.2 至 1.1.1.1 端口(443、123)

到目前為止,我已經能夠將文件讀入列表,然后創建源 ips 列表和目標 ips 列表。 然后我可以手動獲取與手動輸入的 IP 關聯的端口。 但是,有 4 個來源和 67 個目的地。 我不想手動運行 268 次。 我的問題是我想以某種方式遍歷列表列表,檢查源和目標,然后添加這些端口。 我的想法是對 lst object 做一個 for 循環,然后循環源列表和目標列表,然后收集端口。 我不確定這是否可以做到,以及我是否做得正確。

我知道有一些格式問題和更好的方法來做這些,相當新。

日志示例(稍后將刪除 srcport=,因為此時這樣做並不重要):

1.1.1.1,2.2.2.2,srcport=58084,dstport=161,proto=17,service=SNMP
5.5.5.5,2.2.2.2,srcport=58082,dstport=123,proto=17,service=NTP
1.1.1.1,3.3.3.3,srcport=59089,dstport=123,proto=17,service=NTP
6.6.6.6,3.3.3.3,srcport=41376,dstport=123,proto=17,service=NTP
1.1.1.1,4.4.4.4,srcport=53546,dstport=22,proto=6,app=SSH

    #! python3

import csv
#Read the file and covert the CSV to a usable list format
csv_filename = 'data-for-csv-reader_no_parentheses_v3.csv'
#need to add operation to strip " from lines
#open file and read into a list of lists:
with open(csv_filename) as f:
    reader =csv.reader(f)
    lst = list(reader)


#Extract all Source IPs:
srcips =[]
for item in lst:
    srcips.append(item[0])

#Deduplicate source IPS:
srciplist = [*set(srcips)]
print("The number of source IPs is " + str(len(srciplist)) + ".")

#Strip 'srcip= off of entry (no longer needed, pherhaps)
srciplist_stripped = [j.strip('srcip=') for j in srciplist]
srciplist_stripped.sort()
print(srciplist_stripped)

#Extract all destination IPs:
dstips =[]
for item in lst:
    dstips.append(item[1])

#Deduplicate destination IPs:
dstiplist = [*set(dstips)]
print("The number of destination IPs is " + str(len(dstiplist)) + ".")

#Strip 'dstip= off of entry (no longer needed, pherhaps)
dstiplist_stripped = [j.strip('dstip=') for j in dstiplist]
dstiplist_stripped.sort()
print(dstiplist_stripped)

#Manual operation to get one source and one destination's ports:
port_list = []
for item in lst:
    if item[0] == srciplist_stripped[2] and item[1] == dstiplist_stripped[4]:
        port_list.append(item[3])

#Presents port list for the prior two IPs
port_list = [*set(port_list)]
print("Source IP:" + str(srciplist_stripped[2]) + " Destination IP:" + str(dstiplist_stripped[4]) + " Port_list :" + str(port_list))
print("The number of ports is " + str(len(port_list)) + ".")

除非您針對 csv 文件運行該代碼,否則該代碼將不起作用。 正如所寫的那樣,它得到了以下信息(針對 IP 進行了編輯):

The number of source IPs is 4.
['1.1.1.1', '2.2.2.2', '3.3.3.3', '4.4.4.4']
The number of destination IPs is 67.
['7.7.7.7', '6.6.6.6', '5.5.5.5', <--omitted for brevity-->]
Source IP:1.1.1.1. Destination IP:2.2.2.2 Port_list :['dstport=644', 'dstport=1039',<--omitted for brevity-->]
The number of ports is 873.

(IP 是偽造的,因此它們與示例防火牆日志中顯示的索引不一致)

我想要它 output 這個:

Source IP:1.1.1.1. Destination IP:2.2.2.2 Port_list :['dstport=644', 'dstport=1039',<--omitted for brevity-->]
    The number of ports is 873.

但是對於每個 ip 地址組合,然后將其寫入文件。 最終的 output 將是上面發布的 4 個源和 67 個目標之間的內容,因此有 268 個條目(其中許多在 Port_list 中將是空白的,並且列表 0 表示端口數)。

我希望我已經正確理解了你的問題。

您可以將源 IP 加載到字典(其中鍵是源 IP,值是格式為 {destination IP: [list of ports]} 的字典)。

import csv
from itertools import product

src, dst = {}, set()

with open("data.csv", "r") as f_in:
    reader = csv.reader(f_in)
    for row in reader:
        src.setdefault(row[0], {}).setdefault(row[1], []).append(
            row[3].split("=")[-1]
        )
        dst.add(row[1])

for s, d in product(src, dst):
    print(f"Source IP: {s} Destination IP: {d} Port_list: {src[s].get(d, [])}")

印刷:

Source IP: 1.1.1.1 Destination IP: 3.3.3.3 Port_list: ['123']
Source IP: 1.1.1.1 Destination IP: 4.4.4.4 Port_list: ['22']
Source IP: 1.1.1.1 Destination IP: 2.2.2.2 Port_list: ['161', '123']
Source IP: 5.5.5.5 Destination IP: 3.3.3.3 Port_list: []
Source IP: 5.5.5.5 Destination IP: 4.4.4.4 Port_list: []
Source IP: 5.5.5.5 Destination IP: 2.2.2.2 Port_list: ['123']
Source IP: 6.6.6.6 Destination IP: 3.3.3.3 Port_list: ['123']
Source IP: 6.6.6.6 Destination IP: 4.4.4.4 Port_list: []
Source IP: 6.6.6.6 Destination IP: 2.2.2.2 Port_list: []

data.csv中使用的數據:

1.1.1.1,2.2.2.2,srcport=58084,dstport=161,proto=17,service=SNMP
1.1.1.1,2.2.2.2,srcport=58084,dstport=123,proto=17,service=SNMP
5.5.5.5,2.2.2.2,srcport=58082,dstport=123,proto=17,service=NTP
1.1.1.1,3.3.3.3,srcport=59089,dstport=123,proto=17,service=NTP
6.6.6.6,3.3.3.3,srcport=41376,dstport=123,proto=17,service=NTP
1.1.1.1,4.4.4.4,srcport=53546,dstport=22,proto=6,app=SSH

由於您已經在使用 CSV 模塊,您可以使用DictReader來使用列名,這比索引更靈活。 然后在列表推導上應用set()來計算唯一值。 例子:

import csv

fieldnames = ['src_ip', 'dst_ip', 'src_port', 'dst_port', 'proto', 'service']

with open('firewall.csv', newline='') as csvfile:
    reader = csv.DictReader(csvfile, delimiter=',', fieldnames=fieldnames)
    lines = list(reader)

unique_src_ips = set([line["src_ip"] for line in lines])
print(f"The number of source IPs is {len(unique_src_ips)}.")

unique_dst_ips = set([line["dst_ip"] for line in lines])
print(f"The number of destination IPs is {len(unique_dst_ips)}.")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM