Skip to content

Commit 62c729d

Browse files
authored
Sync o365 package with beats (#716)
* Sync o365 package with beats * Add changelog
1 parent 77bc783 commit 62c729d

File tree

6 files changed

+589
-137
lines changed

6 files changed

+589
-137
lines changed

packages/o365/changelog.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
# newer versions go on top
2+
- version: "0.3.0"
3+
changes:
4+
- description: Add changes to use ECS 1.8 fields.
5+
type: enhancement # can be one of: enhancement, bugfix, breaking-change
6+
link: https://github.com/elastic/integrations/pull/716
27
- version: "0.1.0"
38
changes:
49
- description: initial release

packages/o365/data_stream/audit/agent/stream/log.yml.hbs

Lines changed: 241 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ tags:
1212
publisher_pipeline.disable_host: true
1313
{{/contains}}
1414
processors:
15+
- rename:
16+
fields:
17+
- from: json.error
18+
to: error
19+
ignore_missing: true
1520
- rename:
1621
fields:
1722
- from: json
@@ -191,7 +196,7 @@ processors:
191196
if (src[i] == null
192197
|| (name=src[i].Name) == null
193198
|| (newValue=src[i].NewValue) == null
194-
|| (oldValue=src[i].OldValue)) continue;
199+
|| (oldValue=src[i].OldValue) == null) continue;
195200
name = validFieldName(name);
196201
if (name in dict) {
197202
if (dict[name].NewValue instanceof Array) {
@@ -225,8 +230,113 @@ processors:
225230
return builder.Build();
226231
}
227232

228-
function azureADLogonSchema(debug) {
233+
function typeMapEnrich(conversions) {
234+
return function (evt) {
235+
var action = evt.Get("event.action");
236+
if (action != null && conversions.hasOwnProperty(action)) {
237+
var conv = conversions[action];
238+
if (conv.action !== undefined) evt.Put("event.action", conv.action);
239+
if (conv.category !== undefined) evt.Put("event.category", conv.category);
240+
if (conv.type !== undefined) evt.Put("event.type", conv.type);
241+
var n = conv.copy !== undefined? conv.copy.length : 0;
242+
for (var i=0; i<n; i++) {
243+
var value = evt.Get(conv.copy[i].from);
244+
if (value != null)
245+
evt.Put(conv.copy[i].to, value);
246+
}
247+
}
248+
}
249+
}
250+
251+
function azureADSchema(debug) {
252+
var azureADConversion = {
253+
'Add user.': {
254+
action: "added-user-account",
255+
category: 'iam',
256+
type: ['user', 'creation'],
257+
copy: [
258+
{
259+
from: 'o365audit.ObjectId',
260+
to: 'user.target.id',
261+
}
262+
],
263+
},
264+
'Update user.': {
265+
action: "modified-user-account",
266+
category: 'iam',
267+
type: ['user', 'change'],
268+
copy: [
269+
{
270+
from: 'o365audit.ObjectId',
271+
to: 'user.target.id',
272+
}
273+
],
274+
},
275+
'Delete user.': {
276+
action: "deleted-user-account",
277+
category: 'iam',
278+
type: ['user', 'deletion'],
279+
copy: [
280+
{
281+
from: 'o365audit.ObjectId',
282+
to: 'user.target.id',
283+
}
284+
],
285+
},
286+
};
287+
229288
var builder = new PipelineBuilder("o365.audit.AzureActiveDirectory", debug);
289+
builder.Add("setIAMFields", typeMapEnrich(azureADConversion));
290+
return builder.Build();
291+
}
292+
293+
function teamsSchema(debug) {
294+
var teamsConversion = {
295+
'TeamCreated': {
296+
action: "added-group-account-to",
297+
category: 'iam',
298+
type: ['group', 'creation'],
299+
copy: [
300+
{
301+
from: 'o365audit.TeamName',
302+
to: 'group.name',
303+
}
304+
],
305+
},
306+
'MemberAdded': {
307+
action: "added-users-to-group",
308+
category: 'iam',
309+
type: ['group', 'change'],
310+
},
311+
312+
'Delete user.': {
313+
action: "deleted-user-account",
314+
category: 'iam',
315+
type: ['user', 'deletion'],
316+
copy: [
317+
{
318+
from: 'o365audit.ObjectId',
319+
to: 'user.target.id',
320+
}
321+
],
322+
},
323+
};
324+
325+
var builder = new PipelineBuilder("o365.audit.MicrosoftTeams", debug);
326+
builder.Add("setIAMFields", typeMapEnrich(teamsConversion));
327+
builder.Add("groupMembersToRelatedUser", function (evt) {
328+
var m = evt.Get("o365audit.Members");
329+
if (m == null || m.forEach == null) return;
330+
m.forEach(function (obj) {
331+
if (obj != null && obj.hasOwnProperty('UPN'))
332+
evt.AppendTo('related.user', obj.UPN);
333+
})
334+
})
335+
return builder.Build();
336+
}
337+
338+
function azureADLogonSchema(debug) {
339+
var builder = new PipelineBuilder("o365.audit.AzureActiveDirectoryLogon", debug);
230340
builder.Add("setEventAuthFields", function(evt){
231341
evt.Put("event.category", "authentication");
232342
var outcome = evt.Get("event.outcome");
@@ -254,33 +364,34 @@ processors:
254364
ignore_missing: true,
255365
fail_on_error: false
256366
}));
257-
builder.Add("setEventCategory", new processor.AddFields({
258-
target: 'event',
259-
fields: {
260-
category: 'file',
261-
},
262-
}));
263-
builder.Add("mapEventType", makeMapper({
264-
from: 'o365audit.Operation',
265-
to: 'event.type',
266-
mappings: {
267-
'FileAccessed': 'access',
268-
'FileDeleted': 'deletion',
269-
'FileDownloaded': 'access',
270-
'FileModified': 'change',
271-
'FileMoved': 'change',
272-
'FileRenamed': 'change',
273-
'FileRestored': 'change',
274-
'FileUploaded': 'creation',
275-
'FolderCopied': 'creation',
276-
'FolderCreated': 'creation',
277-
'FolderDeleted': 'deletion',
278-
'FolderModified': 'change',
279-
'FolderMoved': 'change',
280-
'FolderRenamed': 'change',
281-
'FolderRestored': 'change',
282-
},
283-
}));
367+
368+
var actionToCategoryType = {
369+
ComplianceSettingChanged: ['configuration', 'change'],
370+
FileAccessed: ['file', 'access'],
371+
FileDeleted: ['file', 'deletion'],
372+
FileDownloaded: ['file', 'access'],
373+
FileModified: ['file', 'change'],
374+
FileMoved: ['file', 'change'],
375+
FileRenamed: ['file', 'change'],
376+
FileRestored: ['file', 'change'],
377+
FileUploaded: ['file', 'creation'],
378+
FolderCopied: ['file', 'creation'],
379+
FolderCreated: ['file', 'creation'],
380+
FolderDeleted: ['file', 'deletion'],
381+
FolderModified: ['file', 'change'],
382+
FolderMoved: ['file', 'change'],
383+
FolderRenamed: ['file', 'change'],
384+
FolderRestored: ['file', 'change'],
385+
};
386+
387+
builder.Add("setEventFields", function(evt) {
388+
var action = evt.Get("o365audit.Operation");
389+
if (action == null) return;
390+
var fields = actionToCategoryType[action];
391+
if (fields == null) return;
392+
evt.Put("event.category", fields[0]);
393+
evt.Put("event.type", fields[1]);
394+
});
284395
return builder.Build();
285396
}
286397

@@ -476,44 +587,94 @@ processors:
476587
fail_on_error: false
477588
}));
478589

479-
var actionToCategoryType = {
480-
// Network or verified admin changes the information that appears on
481-
// member profiles for network users network.
482-
ProcessProfileFields: [ "iam", "user"],
590+
var yammerConversion = {
591+
// Network or verified admin changes the Yammer network's configuration.
592+
// This includes setting the interval for exporting data and enabling chat.
593+
NetworkConfigurationUpdated: {
594+
category: "configuration",
595+
type: "change",
596+
},
483597
// Verified admin updates the Yammer network's security configuration.
484598
// This includes setting password expiration policies and restrictions
485599
// on IP addresses.
486-
NetworkSecurityConfigurationUpdated: [ "iam", "admin"],
600+
NetworkSecurityConfigurationUpdated: {
601+
category: ["iam", "configuration"],
602+
type: ["admin", "change"],
603+
},
604+
// Verified admin updates the setting for the network data retention
605+
// policy to either Hard Delete or Soft Delete. Only verified admins
606+
// can perform this operation.
607+
SoftDeleteSettingsUpdated: {
608+
category: "configuration",
609+
type: "change",
610+
},
611+
// Network or verified admin changes the information that appears on
612+
// member profiles for network users network.
613+
ProcessProfileFields: {
614+
category: "configuration",
615+
type: "change"
616+
},
617+
// Verified admin turns Private Content Mode on or off. This mode
618+
// lets an admin view the posts in private groups and view private
619+
// messages between individual users (or groups of users). Only verified
620+
// admins only can perform this operation.
621+
SupervisorAdminToggled: {
622+
category: "configuration",
623+
type: "change"
624+
},
487625
// User uploads a file.
488-
FileCreated: [ "file", "creation"],
626+
FileCreated: {
627+
category: "file",
628+
type: "creation"
629+
},
489630
// User creates a group.
490-
GroupCreation: [ "iam", ["group", "creation"] ],
631+
GroupCreation: {
632+
category: "iam",
633+
type: ["group", "creation"],
634+
},
491635
// A group is deleted from Yammer.
492-
GroupDeletion: [ "iam", ["group", "deletion"] ],
636+
GroupDeletion: {
637+
category: "iam",
638+
type: ["group", "deletion"]
639+
},
493640
// User downloads a file.
494-
FileDownloaded: [ "file", "access"],
641+
FileDownloaded: {
642+
category: "file",
643+
type: "access"
644+
},
495645
// User shares a file with another user.
496-
FileShared: [ "file", "access"],
646+
FileShared: {
647+
category: "file",
648+
type: "access"
649+
},
497650
// Network or verified admin suspends (deactivates) a user from Yammer.
498-
NetworkUserSuspended: [ "iam", "user"],
651+
NetworkUserSuspended: {
652+
category: "iam",
653+
type: "user"
654+
},
499655
// User account is suspended (deactivated).
500-
UserSuspension: [ "iam", "user"],
656+
UserSuspension: {
657+
category: "iam",
658+
type: "user"
659+
},
501660
// User changes the description of a file.
502-
FileUpdateDescription: [ "file", "access"],
661+
FileUpdateDescription: {
662+
category: "file",
663+
type: "access"
664+
},
503665
// User changes the name of a file.
504-
FileUpdateName: [ "file", "creation"],
666+
FileUpdateName: {
667+
category: "file",
668+
type: "creation",
669+
},
505670
// User views a file.
506-
FileVisited: [ "file", "access"],
671+
FileVisited: {
672+
category: "file",
673+
type: "access",
674+
},
507675
};
508676

509-
builder.Add("setEventFields", function(evt) {
510-
var action = evt.Get("event.action");
511-
if (action == null) return;
512-
var fields = actionToCategoryType[action];
513-
if (fields == null) return;
514-
evt.Put("event.category", fields[0]);
515-
evt.Put("event.type", fields[1]);
516-
});
677+
builder.Add("setEventFields", typeMapEnrich(yammerConversion));
517678
return builder.Build();
518679
}
519680

@@ -598,6 +759,22 @@ processors:
598759
return builder.Build();
599760
}
600761

762+
function splitEmailUserID(prefix) {
763+
var idField = prefix + ".id",
764+
nameField = prefix + ".name",
765+
domainField = prefix + ".domain",
766+
emailField = prefix + ".email";
767+
return function(evt) {
768+
var email = evt.Get(idField);
769+
if (email == null) return;
770+
var pos = email.indexOf('@');
771+
if (pos === -1) return;
772+
evt.Put(emailField, email);
773+
evt.Put(nameField, email.substr(0, pos));
774+
evt.Put(domainField, email.substr(pos+1));
775+
}
776+
}
777+
601778
function AuditProcessor(tenant_names, debug) {
602779
var builder = new PipelineBuilder("o365.audit", debug);
603780

@@ -751,12 +928,14 @@ processors:
751928
},
752929
'ExchangeAdmin': exchangeAdminSchema(debug).Run,
753930
'ExchangeItem': exchangeMailboxSchema(debug).Run,
931+
'AzureActiveDirectory': azureADSchema(debug).Run,
754932
'AzureActiveDirectoryStsLogon': azureADLogonSchema(debug).Run,
755933
'SharePointFileOperation': sharePointFileOperationSchema(debug).Run,
756934
'SecurityComplianceAlerts': securityComplianceAlertsSchema(debug).Run,
757935
'ComplianceDLPSharePoint': dlp.Run,
758936
'ComplianceDLPExchange': dlp.Run,
759937
'Yammer': yammerSchema(debug).Run,
938+
'MicrosoftTeams': teamsSchema(debug).Run,
760939
}));
761940

762941
builder.Add("extractClientIPPortBrackets", new processor.Dissect({
@@ -807,12 +986,14 @@ processors:
807986
fail_on_error: false
808987
}));
809988

810-
builder.Add("setUserFieldsFromId", new processor.Dissect({
811-
tokenizer: "%{name}@%{domain}",
812-
field: "user.id",
813-
target_prefix: "user",
814-
'when.contains.user.id': '@',
815-
}));
989+
[
990+
'user',
991+
'user.target',
992+
'source.user',
993+
'destination.user',
994+
].forEach(function (prefix) {
995+
builder.Add('setFromID' + prefix, splitEmailUserID(prefix));
996+
})
816997

817998
builder.Add("setNetworkType", function(event) {
818999
var ip = event.Get("client.ip");
@@ -831,6 +1012,7 @@ processors:
8311012
builder.Add("setRelatedUser", appendFields({
8321013
fields: [
8331014
"user.name",
1015+
"user.target.name",
8341016
"file.owner",
8351017
],
8361018
to: 'related.user'
@@ -896,4 +1078,4 @@ processors:
8961078
- add_fields:
8971079
target: ''
8981080
fields:
899-
ecs.version: 1.6.0
1081+
ecs.version: 1.8.0

0 commit comments

Comments
 (0)