line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package XML::IODEF::Simple; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
50546
|
use 5.008008; |
|
1
|
|
|
|
|
2
|
|
4
|
1
|
|
|
1
|
|
4
|
use strict; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
14
|
|
5
|
1
|
|
|
1
|
|
3
|
use warnings; |
|
1
|
|
|
|
|
8
|
|
|
1
|
|
|
|
|
47
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
our $VERSION = '0.00_03'; |
8
|
|
|
|
|
|
|
$VERSION = eval $VERSION; # see L<perlmodstyle> |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
require XML::IODEF; |
11
|
1
|
|
|
1
|
|
465
|
use Module::Pluggable require => 1; |
|
1
|
|
|
|
|
8269
|
|
|
1
|
|
|
|
|
4
|
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
# Preloaded methods go here. |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
sub new { |
16
|
0
|
|
|
0
|
|
|
my ($class,$info) = @_; |
17
|
|
|
|
|
|
|
|
18
|
0
|
|
0
|
|
|
|
my $description = lc($info->{'description'}) || 'unknown'; |
19
|
0
|
|
|
|
|
|
my $confidence = $info->{'confidence'}; |
20
|
0
|
|
|
|
|
|
my $severity = $info->{'severity'}; |
21
|
0
|
|
0
|
|
|
|
my $restriction = $info->{'restriction'} || 'private'; |
22
|
0
|
|
0
|
|
|
|
my $source = $info->{'source'} || 'localhost'; |
23
|
0
|
|
|
|
|
|
my $relatedid = $info->{'relatedid'}; |
24
|
0
|
|
|
|
|
|
my $alternativeid = $info->{'alternativeid'}; |
25
|
0
|
|
0
|
|
|
|
my $alternativeid_restriction = $info->{'alternativeid_restriction'} || 'private'; |
26
|
0
|
|
0
|
|
|
|
my $purpose = $info->{'purpose'} || 'mitigation'; |
27
|
|
|
|
|
|
|
|
28
|
0
|
|
|
|
|
|
my $dt = $info->{'detecttime'}; |
29
|
|
|
|
|
|
|
# default it to the hour |
30
|
0
|
0
|
|
|
|
|
unless($dt){ |
31
|
0
|
|
|
|
|
|
require DateTime; |
32
|
0
|
|
|
|
|
|
$dt = DateTime->from_epoch(epoch => time()); |
33
|
0
|
|
|
|
|
|
$dt = $dt->ymd().'T'.$dt->hour().':00:00Z'; |
34
|
|
|
|
|
|
|
} |
35
|
0
|
|
|
|
|
|
$info->{'detecttime'} = $dt; |
36
|
|
|
|
|
|
|
|
37
|
0
|
|
|
|
|
|
my $iodef = XML::IODEF->new(); |
38
|
0
|
|
|
|
|
|
$iodef->add('Incidentpurpose',$purpose); |
39
|
0
|
0
|
|
|
|
|
$iodef->add('IncidentIncidentIDname',$source) if($source); |
40
|
0
|
0
|
|
|
|
|
$iodef->add('IncidentDetectTime',$dt) if($dt); |
41
|
0
|
0
|
|
|
|
|
$iodef->add('IncidentRelatedActivityIncidentID',$relatedid) if($relatedid); |
42
|
0
|
0
|
|
|
|
|
if($alternativeid){ |
43
|
0
|
|
|
|
|
|
$iodef->add('IncidentAlternativeIDIncidentID',$alternativeid); |
44
|
0
|
|
|
|
|
|
$iodef->add('IncidentAlternativeIDIncidentIDrestriction',$alternativeid_restriction); |
45
|
|
|
|
|
|
|
} |
46
|
0
|
|
|
|
|
|
$iodef->add('Incidentrestriction',$restriction); |
47
|
0
|
0
|
|
|
|
|
$iodef->add('IncidentDescription',$description) if($description); |
48
|
0
|
0
|
|
|
|
|
if($confidence){ |
49
|
0
|
|
|
|
|
|
$iodef->add('IncidentAssessmentConfidencerating','numeric'); |
50
|
0
|
|
|
|
|
|
$iodef->add('IncidentAssessmentConfidence',$confidence); |
51
|
|
|
|
|
|
|
} |
52
|
0
|
0
|
0
|
|
|
|
if($severity && $severity =~ /(low|medium|high)/){ |
53
|
0
|
|
|
|
|
|
$iodef->add('IncidentAssessmentImpactseverity',$severity); |
54
|
|
|
|
|
|
|
} |
55
|
|
|
|
|
|
|
|
56
|
0
|
|
|
|
|
|
foreach($class->plugins()){ |
57
|
0
|
0
|
|
|
|
|
if($_->prepare($info)){ |
58
|
0
|
|
|
|
|
|
$iodef = $_->convert($info,$iodef); |
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
} |
61
|
0
|
|
|
|
|
|
my $impact = $info->{'impact'}; |
62
|
0
|
0
|
|
|
|
|
$iodef->add('IncidentAssessmentImpact',$impact) if($impact); |
63
|
0
|
|
|
|
|
|
return $iodef; |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
1; |
68
|
|
|
|
|
|
|
__END__ |
69
|
|
|
|
|
|
|
=head1 NAME |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
XML::IODEF::Simple - Perl extension for easier IODEF message generation |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
=head1 SYNOPSIS |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
use XML::IODEF::Simple; |
76
|
|
|
|
|
|
|
my $report = XML::IODEF::Simple->new({ |
77
|
|
|
|
|
|
|
guid => 'mygroup.example.com', |
78
|
|
|
|
|
|
|
source => 'example.com', |
79
|
|
|
|
|
|
|
restriction => 'need-to-know', |
80
|
|
|
|
|
|
|
description => 'spyeye', |
81
|
|
|
|
|
|
|
impact => 'botnet', |
82
|
|
|
|
|
|
|
address => '1.2.3.4', |
83
|
|
|
|
|
|
|
protocol => 'tcp', |
84
|
|
|
|
|
|
|
portlist => '8080', |
85
|
|
|
|
|
|
|
contact => { |
86
|
|
|
|
|
|
|
name => 'root', |
87
|
|
|
|
|
|
|
email => 'root@localhost', |
88
|
|
|
|
|
|
|
}, |
89
|
|
|
|
|
|
|
purpose => 'mitigation', |
90
|
|
|
|
|
|
|
confidence => '85', |
91
|
|
|
|
|
|
|
alternativeid => 'https://example.com/rt/Ticket/Display.html?id=1234', |
92
|
|
|
|
|
|
|
alternativeid_restriction => 'private', |
93
|
|
|
|
|
|
|
sharewith => 'partners.example.com,leo.example.com', |
94
|
|
|
|
|
|
|
}); |
95
|
|
|
|
|
|
|
my $xml = $report->out(); |
96
|
|
|
|
|
|
|
my $hash = $report->to_tree(); |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
# generates |
99
|
|
|
|
|
|
|
<?xml version="1.0" encoding="UTF-8"?> |
100
|
|
|
|
|
|
|
<IODEF-Document version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:ietf:params:xmls:schema:iodef-1.0"><Incident purpose="mitigation" restriction="need-to-know"><IncidentID name="example.com"/><AlternativeID><IncidentID restriction="private">https://example.com/rt/Ticket/Display.html?id=1234</IncidentID></AlternativeID><DetectTime>2011-10-24T13:00:00Z</DetectTime><Description>spyeye</Description><Assessment><Impact severity="high">botnet</Impact><Confidence rating="numeric">85</Confidence></Assessment><Contact type="person" role="creator"><ContactName>root</ContactName><Email>root@localhost</Email></Contact><EventData><Flow><System><Node><Address category="ipv4-addr">1.2.3.4</Address></Node><Service ip_protocol="6"><Portlist>8080</Portlist></Service></System></Flow></EventData><AdditionalData dtype="string" meaning="guid">mygroup.example.com</AdditionalData><AdditionalData dtype="string" meaning="sharewith">leo.example.com</AdditionalData><AdditionalData dtype="string" meaning="sharewith">partners.example.com</AdditionalData></Incident></IODEF-Document> |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
=head1 DESCRIPTION |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
This module makes it a bit simpler to crank out XML+IODEF messages. It uses what it finds under XML/IODEF/Simple/Plugin/ to adapt "defaults" to the keypairs it takes in. To allow for other default settings / manipulations, create XML::IODEF::Simple::Plugin::MyPlugin and Module::Pluggable will pick it up on the fly. See XML::IODEF::Simple::Plugin::Ipv4 as an example. |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
This module takes into account some of the work done with the Collective Intelligence Framework. It makes assumptions about severity based on the impact given. Up to date documentation surrounding this taxonomy can be found at http://code.google.com/p/collective-intelligence-framework/wiki/Taxonomy |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=head1 Addons |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
To enhance the exchange of XML::IODEF based messages, the 'sharewith' and 'guid' tags have been added to IncidentAdditionalData |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
=head2 sharewith |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
A comma-seperated or array value that denotes what other federations a derivative of this message may be shared with. These are usually denoted by a FQDN: |
115
|
|
|
|
|
|
|
grp1.example.com |
116
|
|
|
|
|
|
|
grp2.example.com |
117
|
|
|
|
|
|
|
leo.example.com |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
=head2 guid |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
A simple FQDN used (in CIF) as a unix-style permission that denotes what groups within a federation can have access to this data. Groups are simple strings, in this example we use FQDN's to ensure unique-ness throughout a federation. Typically groups are hashed into v5 uuid's behind the scenes. |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
=head1 EXAMPLES |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
=head2 Botnet |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
Typically a high-severity observation |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
=head2 Malware / Exploit |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
Typically a medium-severity observation |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
=head2 Phishing |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
Typically a medium-severity observation |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
=head2 Highjacked |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
Typcially a medium-severity observation |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
=head1 PLUGINS |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
This module can be extended at run-time by adding plugins under XML::IODEF::Simple::Plugin (eg: XML::IODEF::Simple::Plugin::MyPlug). See the lib/XML/IODEF/Simple/Plugin directory or XML::IODEF::Simple::Plugin::TLP for more examples. |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
=head1 SEE ALSO |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
XML::IODEF, http://code.google.com/p/collective-intelligence-framework/ |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
=head1 AUTHOR |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
Wes Young, E<lt>wes@barely3am.comE<gt> |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
Copyright 2011 The Trustees of Indiana University, indiana.edu |
156
|
|
|
|
|
|
|
Copyright 2011 REN-ISAC, ren-isac.net |
157
|
|
|
|
|
|
|
Copyright 2011 Wes Young, claimid.com/wesyoung |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or modify |
160
|
|
|
|
|
|
|
it under the same terms as Perl itself, either Perl version 5.10.0 or, |
161
|
|
|
|
|
|
|
at your option, any later version of Perl 5 you may have available. |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
=cut |