Skip to content

Commit

Permalink
Version 1.4
Browse files Browse the repository at this point in the history
Updated BAIs pattern to limit to elements with SI comms.
Added NetworkDevice edge connectivity pattern (PoC)
Added Win2k8 fix to TSAK and fixed some ECA errors.
  • Loading branch information
codefitz committed Jun 10, 2019
1 parent 436c49d commit a79ab38
Show file tree
Hide file tree
Showing 4 changed files with 205 additions and 127 deletions.
74 changes: 41 additions & 33 deletions traversys_BAIs.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ configuration ignore 1.0

end configuration;

pattern WebsiteBAIs 1.0
pattern WebsiteBAIs 1.1

"""
Author: Wes Moskal-Fitzpatrick
Expand All @@ -28,6 +28,7 @@ pattern WebsiteBAIs 1.0

Change History:
2019-05-25 1.0 WMF : Created.
2019-06-04 1.1 WMF : Added conditional to limit BAI creation only if communicating SIs is discovered.

"""

Expand Down Expand Up @@ -57,40 +58,47 @@ pattern WebsiteBAIs 1.0
name := "%sc.instance% %type%";
key := text.hash(instance);

bai := model.BusinessApplicationInstance(
key := key,
type := type,
name := name,
instance := sc.instance,
_traversys:= true
);
// ContainedSoftware:SoftwareContainment:SoftwareContainer:BusinessApplicationInstance
model.addContainment(bai, sc);

containing_sis := search(in sc traverse ContainedSoftware:SoftwareContainment:SoftwareContainer:SoftwareInstance);
model.addContainment(bai, containing_sis);

outgoing_sis := search(in containing_sis traverse Connecting:ObservedCommunication:Listening:SoftwareInstance);
model.addContainment(bai, outgoing_sis);
// Some of these will be DB servers, but the SIDs can vary so we can add the DB server and try to work it out manually.
databases := search(in outgoing_sis traverse ElementWithDetail:Detail:Detail:Database where lower(instance) = %instance%);
// Dependant:Dependency:DependedUpon:Database
model.rel.Dependency(Dependant := bai, DependedUpon := databases);

si_dependencies:= search(in containing_sis traverse Dependant:Dependency:DependedUpon:SoftwareInstance);
model.addContainment(bai, si_dependencies);

si_containers := search(in containing_sis traverse ContainedSoftware:SoftwareContainment:SoftwareContainer:SoftwareInstance);
model.addContainment(bai, si_containers);

lb_members := search(in containing_sis traverse ServiceProvider:SoftwareService:Service:LoadBalancerMember);
lb_pools := search(in lb_members traverse ContainedMember:Containment:Container:LoadBalancerPool where lower(name) = "%instance%");
lb_services := search(in lb_pools traverse ContainedPool:Containment:Container:LoadBalancerService);
model.addContainment(bai, lb_services);

//lb_instances := search(in lb_pools traverse ContainedPool:Containment:Container:LoadBalancerInstance);
//lb_failover := search(in lb_instances traverse ContainedInstance:Containment:Container:LoadBalancerGroup
// traverse Container:Containment:ContainedInstance:LoadBalancerInstance where failover_state = "Standby");

// Create only a BAI if there is a communicating SI - in this way we
// try to model something that looks like like a genuine BAI
if size(outgoing_sis) > 0 then

bai := model.BusinessApplicationInstance(
key := key,
type := type,
name := name,
instance := sc.instance,
_traversys:= true
);
// ContainedSoftware:SoftwareContainment:SoftwareContainer:BusinessApplicationInstance
model.addContainment(bai, sc);
model.addContainment(bai, containing_sis);
model.addContainment(bai, outgoing_sis);

// Some of these will be DB servers, but the SIDs can vary so we can add the DB server and try to work it out manually.
databases := search(in outgoing_sis traverse ElementWithDetail:Detail:Detail:Database where lower(instance) = %instance%);

// Dependant:Dependency:DependedUpon:Database
model.rel.Dependency(Dependant := bai, DependedUpon := databases);

si_dependencies:= search(in containing_sis traverse Dependant:Dependency:DependedUpon:SoftwareInstance);
model.addContainment(bai, si_dependencies);

si_containers := search(in containing_sis traverse ContainedSoftware:SoftwareContainment:SoftwareContainer:SoftwareInstance);
model.addContainment(bai, si_containers);

lb_members := search(in containing_sis traverse ServiceProvider:SoftwareService:Service:LoadBalancerMember);
lb_pools := search(in lb_members traverse ContainedMember:Containment:Container:LoadBalancerPool where lower(name) = "%instance%");
lb_services := search(in lb_pools traverse ContainedPool:Containment:Container:LoadBalancerService);
model.addContainment(bai, lb_services);

//lb_instances := search(in lb_pools traverse ContainedPool:Containment:Container:LoadBalancerInstance);
//lb_failover := search(in lb_instances traverse ContainedInstance:Containment:Container:LoadBalancerGroup
// traverse Container:Containment:ContainedInstance:LoadBalancerInstance where failover_state = "Standby");

end if;

end body;

Expand Down
61 changes: 61 additions & 0 deletions traversys_ND_Edge_Connectivity_POC.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// (C) 2019 Traversys Limited
// Licensed under GPL-3.0-or-later

tpl 1.15 module ndEdgeConnectivity;

metadata
__name :='NetworkDevice Edge Connectivity PoC';
origin :='Traversys';
description:='Proof of Concept for Network Device Edge Connectivity';
tree_path :='Traversys', 'Extensions', 'ND Edge Connectivity';
end metadata;

from TSAKLicense import gpl_license 1.0;

pattern ndEdgeConnectivity 1.0

"""
Author: Wes Moskal-Fitzpatrick

Proof of Concept for 2 random network devices selected in BMC's Demo Appliance.

Change History:
2019-06-09 1.0 WMF : Created.

"""

overview
tags traversys, NetworkDevice, edge;
end overview;

triggers
on nd:= NetworkDevice created, confirmed where name = "swd77";
end triggers;

body
if gpl_license.accept_gpl = false then
stop;
end if;

interfaces:= search(in nd traverse DeviceWithInterface:DeviceInterface:InterfaceOfDevice:NetworkInterface where interface_name = "fc0");

if size(interfaces) > 0 then
interface:= interfaces[0];
log.debug("Interface of %nd.name% = %interface.name%");
edgeDevices:= search(NetworkDevice where name = "ais-saas-f5.calbro.com");
if size(edgeDevices) > 0 then
edgeDevice:= edgeDevices[0];
log.debug("Edge Device = %edgeDevice.name%");
edgeIfaces:= search(in edgeDevice traverse DeviceWithInterface:DeviceInterface:InterfaceOfDevice:NetworkInterface where interface_name = "external");
if size(edgeIfaces) > 0 then
edgeIface:= edgeIfaces[0];
log.debug("Linking Interface %interface.name% to Edge Interface %edgeIface.name%...");
// EdgeDevice:NetworkLink:EdgeClient:NetworkInterface
model.rel.NetworkLink(EdgeDevice := interface, EdgeClient := edgeIface);
end if;
end if;
end if;

end body;

end pattern;
127 changes: 103 additions & 24 deletions traversys_TSAK.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ end metadata;

from TSAKLicense import gpl_license 1.0;

pattern TSAK_Host 1.2
pattern TSAK_Host 1.3
"""
Author: Wes Moskal-Fitzpatrick

Expand All @@ -29,6 +29,9 @@ pattern TSAK_Host 1.2
2019-05-08 1.2 WMF : Local Groups and Members powershell command.
Fixed uptime typo.
Added DeviceGuard policy capture.
2019-06-04 1.3 WMF : Fixed ECA error in Linux uptime query.
Fixed ECA error with Windows users wmi query.
Updated local groups command with alternative methods.

Troubleshooting Windows commands (remquery):
1) Run cmd as Administrator
Expand Down Expand Up @@ -118,34 +121,52 @@ pattern TSAK_Host 1.2
end if;

// Logged Users
users := discovery.wmiQuery(h, 'select LastLogon, Name, UserType from Win32_NetworkLoginProfile', 'root\CIMV2');
loggedUsers := [];
for row in users do
user := "%row.Name%, %row.LastLogon%";
list.append(loggedUsers, user);
end for;
h.tsak_logged_users := loggedUsers;
users := discovery.wmiQuery(h, 'select LastLogon, Name, UserType from Win32_NetworkLoginProfile', 'root\CIMV2');
loggedUsers := [];
if users then
for row in users do
user:= "%row.Name%, %row.LastLogon%";
list.append(loggedUsers, user);
end for;
h.tsak_logged_users:= loggedUsers;
end if;

// Registered Owner
regOwner := discovery.registryKey(h, raw "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\RegisteredOwner");
regOwner := discovery.registryKey(h, raw "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\RegisteredOwner");
if regOwner and regOwner.value then
h.tsak_registered_owner := regOwner.value;
end if;

// Get Groups and Members
psGroups := discovery.runCommand(h,
//'powershell "foreach ($LocalGroup in Get-LocalGroup){ Get-LocalGroupMember $LocalGroup -ErrorAction SilentlyContinue | select $LocalGroup.name, Name | convertTo-Json}"'
//'powershell "Get-LocalGroup"'
//'powershell "Get-LocalGroup | foreach { $_.Name }"'
'powershell "Get-LocalGroup | foreach { Get-LocalGroupMember $_.Name -ErrorAction SilentlyContinue | select $_.Name, Name | Write-Host }"'
);
if psGroups and psGroups.result then
groups:= regex.extractAll(psGroups.result, regex "@\{(.*?)=;\sName=(.*?)}");
log.debug("Groups = %groups%");
h.tsak_group_membership:= groups;
end if;

deviceGuard := discovery.runCommand(h, 'powershell "get-cipolicyinfo"');
ngCmd:= raw '''FOR /F "skip=4 tokens=*" %i IN ('net localgroup') DO @echo %i''';
groupMembers:= [];
netGroups := discovery.runCommand(h, ngCmd);
if netGroups and netGroups.result then
groups:= regex.extractAll(netGroups.result, regex "\*(.*)");
for group in groups do
// FOR /F "skip=6 tokens=*" %i IN ('net localgroup administrators ^| findstr /vb "The command completed successfully."') DO @echo %i
ngGroupCmd:= raw '''FOR /F "skip=6 tokens=*" %i IN ('net localgroup "''' + text.rightStrip(group) + raw '''" ^| findstr /vb "The command completed successfully."') DO @echo %i''';
users:= discovery.runCommand(h, ngGroupCmd);
end for;
else
psGroups := discovery.runCommand(h,
raw '%windir%\System32\WindowsPowerShell\v1.0\powershell.exe "Get-LocalGroup | foreach { Get-LocalGroupMember $_.Name -ErrorAction SilentlyContinue | select $_.Name, Name | Write-Host }"'
//'powershell "foreach ($LocalGroup in Get-LocalGroup){ Get-LocalGroupMember $LocalGroup -ErrorAction SilentlyContinue | select $LocalGroup.name, Name | convertTo-Json}"'
//'powershell "Get-LocalGroup"'
//'powershell "Get-LocalGroup | foreach { $_.Name }"'
);
if psGroups and psGroups.result then
groups:= regex.extractAll(psGroups.result, regex "@\{(.*?)=;\sName=(.*?)}");
log.debug("Groups = %groups%");
for group in groups do
log.debug("User / Group = %group%");
list.append(groupMembers, group);
end for;
h.tsak_group_membership:= groupMembers;
end if;
end if;

deviceGuard := discovery.runCommand(h, 'powershell "get-cipolicyinfo"');
if deviceGuard and deviceGuard.result then
h.tsak_device_guard:= deviceGuard.result;
end if;
Expand All @@ -164,9 +185,9 @@ pattern TSAK_Host 1.2
// Get Host Uptime
up := discovery.runCommand(h, "uptime -p");
if up and up.result matches "usage:" then
up := discovery.runCommand(h, "uptime");
up := discovery.runCommand(h, "uptime");
h.tsak_uptime := up.result;
end if;
h.tsak_uptime := up.result;

// Last Reboot
lastBoot := discovery.runCommand(h, "who -b");
Expand Down Expand Up @@ -243,3 +264,61 @@ pattern TSAK_UID 1.1
end body;

end pattern;


pattern Win7_2008Fix 1.0
"""
This pattern fixes Windows Version 6.1.7601 which stands for both Windows 7 and Windows 2008 R2.
If WMI and RemQuery fails - then the OS name string is not returned.

Change History:
2018-05-01 1.0 WMF : Created.

Validation Query:
search Host where os = 'Microsoft Windows [Version 6.1.7601]'
show name, type, os_version, os, age_count, #:::DiscoveryAccess.#:::DeviceInfo.os

"""

overview
tags Windows, Traversys;
end overview;

triggers
on h:= Host created, confirmed where os = "Microsoft Windows [Version 6.1.7601]";
end triggers;

body

if gpl_license.accept_gpl = false then
stop;
end if;

sysInfo := discovery.runCommand(h, 'systeminfo | findstr /B /C:"OS Name" /C:"OS Version" /C:"OS Manufacturer"');
regProductName := discovery.registryKey(h, raw "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProductName");

reqList := discovery.listRegistry(h, raw "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion");
regReleaseId := discovery.registryKey(h, raw "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ReleaseId");

hOS:= h.os;

if sysInfo and sysInfo.result then
hOS:= regex.extract(sysInfo.result, regex "OS Name:\s+(.*)", raw "\1");
h.os_version:= regex.extract(hOS, regex "Microsoft Windows (.*) (Enterprise|Standard)", raw "\1", no_match:= hOS);
h.os_edition:= regex.extract(hOS, regex "Microsoft Windows (.*) (Enterprise|Standard)", raw "\2", no_match:= hOS);
elif regProductName and regProductName.value then
hOS:= regProductName.value;
h.os:= hOS;
h.os_version:= regex.extract(hOS, regex "Windows (.*) (Enterprise|Standard)", raw "\1", no_match:= hOS);
h.os_edition:= regex.extract(hOS, regex "Windows (.*) (Enterprise|Standard)", raw "\2", no_match:= hOS);
end if;

if hOS matches "Windows 7" then
h.host_type:= "Windows Desktop";
h.type:= "Windows Desktop";
h._os_modified:= true;
end if;

end body;

end pattern;
70 changes: 0 additions & 70 deletions traversys_Win2k8Fix.tpl

This file was deleted.

0 comments on commit a79ab38

Please sign in to comment.