-
Notifications
You must be signed in to change notification settings - Fork 30
/
BannerProcessor.cpp
77 lines (57 loc) · 1.59 KB
/
BannerProcessor.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include "BannerProcessor.h"
#include "ServiceRegexMatcher.h"
#include "CpeDictionaryMatcher.h"
#include "ProtocolTokenizer.h"
using namespace std;
void BannerProcessor::Scan(Service* service)
{
auto matches = Scan(service->banner);
if (matches.size() > 0)
{
service->cpe.insert(service->cpe.end(), matches.begin(), matches.end());
}
}
vector<string> BannerProcessor::AutoProcess(const string& banner, bool processVendor)
{
vector<string> cpes;
// the regular expression pattern matcher implementation generally matches
// against full service banners and as a result it is much more accurate
static ServiceRegexMatcher srm;
auto rmlst = srm.Scan(banner, processVendor);
if (rmlst.size() > 0)
{
cpes.insert(cpes.end(), rmlst.begin(), rmlst.end());
}
// the CPE dictionary entry matcher requires tokenization in order to be
// more precise
static CpeDictionaryMatcher cdm;
auto tokens = ProtocolTokenizer::AutoTokenize(banner);
for (auto token : tokens)
{
auto cdlst = cdm.Scan(token, processVendor);
if (cdlst.size() > 0)
{
cpes.insert(cpes.end(), cdlst.begin(), cdlst.end());
}
}
// if neither methods matched, re-try matching the full service banner
// with the CPE dictionary matcher as a last resort
if (cpes.size() == 0)
{
auto cdlst = cdm.Scan(banner, processVendor);
if (cdlst.size() > 0)
{
cpes.insert(cpes.end(), cdlst.begin(), cdlst.end());
}
}
// remove duplicates
if (cpes.size() > 1)
{
sort(cpes.begin(), cpes.end());
cpes.erase(unique(cpes.begin(), cpes.end()), cpes.end());
}
return cpes;
}
BannerProcessor::~BannerProcessor()
{
}