【发布时间】:2021-10-17 00:58:20
【问题描述】:
我是 VBA/宏的新手,不知道技术术语或执行许多功能的最佳方法。但是,我能够创建一个宏,它可以部分完成我需要的部分,但我似乎无法弄清楚其余部分。
情况:我正在尝试以某种方式解析漏洞扫描结果,以便我可以正确获取相关信息,以便以简洁明了的方式将其提供给我的团队。目前,我将 vuln 结果放入一个 excel 文件中,该文件包含每个 vuln、每个主机的所有信息(因此 1 个 vuln 显示在 6 个主机上,产生 6 行)。我当前的宏能够提取信息,以便我可以将其视为每个 vuln 1 行(由唯一的 PluginID 指示),所有主机连接到由换行符分隔的 1 个单元格中。当前的宏很好地完成了这一点,但是 vuln 结果中有另一列非常重要 - “漏洞证明”。在某些 vuln 上,“漏洞证明”对于所有具有该 vuln 的主机都是相同的,而在某些情况下则不同。 我需要能够列出与证明相关的所有主机的所有唯一“漏洞证明”,以便获得“这些主机有这个证明,这些主机有这个证明等”的简明列表。
这里有一些示例源数据:
| PluginID | Description | Host | Vuln Proof |
|---|---|---|---|
| Plugin123 | CVE-Plugin123 | Host1 | Version 1.2.3 detected |
| Plugin123 | CVE-Plugin123 | Host2 | Version 1.2.3 detected |
| Plugin123 | CVE-Plugin123 | Host3 | Version 4.5.6 detected |
| Plugin456 | Plugin456-2021 Vuln | Host1 | Version 7.8.9 detected |
| Plugin456 | Plugin456-2021 Vuln | Host2 | Version 10.11.12 detected |
| Plugin456 | Plugin456-2021 Vuln | Host3 | Version 10.11.12 detected |
目前,当我运行我的宏(如下)时,我得到以下输出:
| PluginID | Description | Host | Vuln Proof |
|---|---|---|---|
| Plugin123 | CVE-Plugin123 | Host1, Host2, Host3 | Version 1.2.3 detected, Version 1.2.3 detected, Version 4.5.6 detected |
| Plugin456 | Plugin456-2021 Vuln | Host1, Host2, Host3 | Version 7.8.9 detected, Version 10.11.12 detected, Version 10.11.12 detected |
虽然实现了每个漏洞审查 1 行的目标,但如果/当证明很长,和/或有很多很多主机报告漏洞时,这并不能提供一个很好的方法来审查漏洞证明.
我希望如何接收输出:
| PluginID | Description | Host | Vuln Proof |
|---|---|---|---|
| Plugin123 | CVE-Plugin123 | Host1, Host2, Host3 | Host1, Host 2: Version 1.2.3 detected Host 3: Version 4.5.6 detected |
| Plugin456 | Plugin456-2021 Vuln | Host1, Host2, Host3 | Host 1: Version 7.8.9 detected Host 2, Host3: Version 10.11.12 detected |
我当前的宏是这样的:
Sub CombineDupRows()
Dim cCR As cCombinedRows
Dim colCR As Collection
Dim wsSrc As Worksheet, wsRes As Worksheet, rRes As Range
Dim vSrc As Variant, vRes() As Variant
Dim S As String
Dim I As Long, J As Long
Sheets("Results").Activate
Set wsSrc = Worksheets("Source")
Set wsRes = Worksheets("Results")
Set rRes = wsRes.Cells(1, 1)
With wsSrc
vSrc = .Range("a1", .Cells(.Rows.Count, "A").End(xlUp)).Resize(columnsize:=4)
End With
Application.ScreenUpdating = False
'collect source data
Set colCR = New Collection
On Error Resume Next
For I = 1 To UBound(vSrc)
Set cCR = New cCombinedRows
With cCR
For J = 1 To 2
.Key(J) = CStr(vSrc(I, J))
Next J
.Phrase(0) = vSrc(I, 3)
.ProofPhrase(0) = vSrc(I, 4)
'The key will be the concatenation of columns 1-2
S = Join(.Keys, Chr(1))
'if key is duplicate, add phrase to existing collection item
On Error Resume Next
colCR.Add cCR, S
Select Case Err.Number
Case 457 'duplicate key
Err.Clear
colCR(S).Phrase(UBound(colCR(S).Phrases) + 1) = .Phrase(0)
colCR(S).ProofPhrase(UBound(colCR(S).ProofPhrases) + 1) = .ProofPhrase(0)
Case Is <> 0 'some other error. Stop for debugging
Debug.Print Err.Number, Err.Description, Err.Source
Stop
End Select
On Error GoTo 0
End With
Next I
'Create results array
ReDim vRes(1 To colCR.Count, 1 To 4)
For I = 1 To colCR.Count
With colCR(I)
For J = 1 To 2
vRes(I, J) = colCR(I).Key(J)
Next J
vRes(I, J) = Join(.Phrases, " " & Chr(13) & Chr(10))
vRes(I, 4) = Join(.ProofPhrases, " " & Chr(13) & Chr(10))
End With
Next I
Set rRes = rRes.Resize(UBound(vRes, 1), UBound(vRes, 2))
With rRes
.Value = vRes
End With
作为其中的一部分,我还必须创建一个类模块,如下所示:
Option Explicit
Private pKeys() As String
Private pKey As String
Private pPhrases() As String
Private pPhrase As String
Private ProofpPhrases() As String
Private ProofpPhrase As String
Private Sub Class_Initialize()
ReDim pKeys(0)
ReDim pPhrases(0)
ReDim ProofpPhrases(0)
End Sub
Public Property Get Keys() As String()
Keys = pKeys
End Property
Public Property Get Key(index As Long) As String
Key = pKeys(index)
End Property
Public Property Let Key(index As Long, strValue As String)
If index > UBound(pKeys) Then ReDim Preserve pKeys(index)
pKeys(index) = strValue
End Property
Public Property Get Phrases() As String()
Phrases = pPhrases
End Property
Public Property Get Phrase(index As Long) As String
Phrase = pPhrases(index)
End Property
Public Property Let Phrase(index As Long, strValue As String)
If index > UBound(pPhrases) Then ReDim Preserve pPhrases(index)
pPhrases(index) = strValue
End Property
Public Property Get ProofPhrases() As String()
ProofPhrases = ProofpPhrases
End Property
Public Property Get ProofPhrase(index As Long) As String
ProofPhrase = ProofpPhrases(index)
End Property
Public Property Let ProofPhrase(index As Long, strValue As String)
If index > UBound(ProofpPhrases) Then ReDim Preserve ProofpPhrases(index)
ProofpPhrases(index) = strValue
End Property
我尝试再次为主机添加一些字符串类型,它们可用于在结果的证明列中提供某种连接,但到目前为止我还没有成功(即使它甚至不完全是我正在寻找的)。 我花了很多时间修修补补并试图让它发挥作用,最后我寻求帮助。我可以在宏中添加什么以使其正常工作以按照我正在寻找的方式获得结果?
【问题讨论】: