-
Notifications
You must be signed in to change notification settings - Fork 0
/
2networkisolation-enforce.sh
292 lines (229 loc) · 13.1 KB
/
2networkisolation-enforce.sh
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
#!/bin/bash
####################################################################################################
#
# Copyright (c) 2021, Jamf, LLC. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the JAMF Software, LLC nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY JAMF SOFTWARE, LLC "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL JAMF SOFTWARE, LLC BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
####################################################################################################
# Endpoint Network Isolation - Enforce
#
# written by Matthieu Castel, Jamf May 2021
# edited by Matt Taylor, Jamf October 2021
# v2.0
#
# This script is designed as a response workflow to isolate an endpoint based upon it's network connectivity, executed by Jamf Pro. This might be automatically triggered by the Jamf Protect and Jamf Pro remediation integration or instead manually.
#
# Script functions
# - Obtain the Jamf Pro URL
# - Configure and enforce a set of rules with the Packet Filter (pf) binary to only permit inbound and outbound traffic (on any port) to the list of Apple addresses and the Jamf Pro URL
# - Create a LaunchDaemon to load the service at startup
# - Optionally notify the user with IBM Notifier
# - Optionally call upon additional Jamf Pro Policies by a custom trigger
# Known issues
# - Using the Jamf Pro fully qualified domain name as a rule causes the pfctl rules to fail to load at system startup, seemingly because the IP addresses can't be obtained at that time. As such, the PF rules fail to enforce after a reboot unless another '/sbin/pfctl -e -f /etc/pf.anchors/"$filename".pf.conf' command is run to enforce them again
# Script Dependencies
# - A folder named 'IRSupport' at /Library/Application Support/ is used for assets when using the IBM Notifier.app for end-user communication
#
# The dependencies must be pre-staged to your devices in order for this workflow to complete fully. Please the see github.com/jamf/jamfprotect Wiki for more information.
#===================================
# For JNUC 2023 conference
# https://reg.rainfocus.com/flow/jamf/jnuc2023/home23/page/sessioncatalog/session/1682577708226001MoLa
# Edited by Natnicha Sangsasitorn, Magic Hat Inc.
# 28/08/2023
# To able to send the information to Splunk, we need to whitelist Splunk communication as well.
# please set Splunk IP address and Splunk HTTP Endpoint Collection URL (Line 77-78).
# Also, before the network isolation enforces, commands for killing interactive shell process are added and executed. (Line 265-267)
# ※ In order to revert network setting back, please refer to script in https://github.com/jamf/jamfprotect/blob/main/soar_playbooks/endpoint_network_isolation/endpoint_network_isolation_revert.sh .
# 27/02/2024 Change file naming convention, Natnicha S.
#===================================
####################################################################################################
#####################################################
############# Script Configuration Area #############
#####################################################
# LOGGED IN USER
# Getting the current logged in user
loggedInUser=$(stat -f %Su /dev/console)
# PACKET FILTER FIREWALL SETTINGS
# This is the required IP range for persisting APNs connectivity on macOS devices. Please refer to Apple's documentation for more information: https://support.apple.com/en-gb/HT210060. Values in the variable must be separated by a comma and space.
apnsIPRange="17.0.0.0/8"
splunkIP=""
splunkHEC=""
# FILE NAMING CONVENTION
# The naming convention to use for any preference files created throughout this workflow. This will be used for preference files so must be in domain naming format, such as 'com.acmesoft.isolate' and will often be followed by .plist, as an exmaple.
fileName="com.magichat.isolate"
# INCIDENT RESPONSE RESOURCES FOLDER
# Incident Response directory containing resources for this workflow. By default the files expected in this directory are:
# - IBM Notifier.app and icon file for end-user notifications (if enabled)
# IMPORTANT: This path and resources must be pre-staged prior to this workflow. If missing, elements of the workflow that require it will not function. Please refer to the Github Wiki for more information.
IRSupportDIR="/Library/Application Support/IRSupport"
# USER NOTIFICATION SETTINGS
# This script will use the 'mac-ibm-notifications' tool to display an information window to the end-user about the event. A signed and notarised version of this application can be downloaded from https://github.com/IBM/mac-ibm-notifications/releases and should be present on the device in order for it to be used.
# Set whether or not to notify the user of this event
# "yes" = the user will be notified
# "no" = the user will not be notified and all actions will be silent
notifyUser="no"
notificationApp="${IRSupportDIR}/IBM Notifier.app/Contents/MacOS/IBM Notifier"
# IBM Notifier app settings. This can be configured as desired per the workflow and end-user communication required.
window="popup"
barTitle="Acmesoft Information Security Notification"
title="This is an important message from the Acmesoft Information Security Team"
subTitle="Substantial information about the event here."
mainButtonLabel="Acknowledge"
tertiaryButtonLabel="Learn More"
tertiaryButtonType="link"
tertiaryButtonPayload="additionalresourceURL"
helpButtonType="infopopup"
helpButtonPayload="This information is provided by the Acmesoft Information Security Team"
iconPath="${IRSupportDIR}/logo.png"
# ADDITIONAL JAMF PRO POLICY SETTINGS
# Additional artefact collection from a Jamf Pro Policy settings
# Set this to yes and provide a custom trigger to call a second Jamf Pro Policy for additional artefact collection following this event
# "yes" = the Jamf Pro binary will be used to check for additional Policies
# "no" = no action will be taken
moreJamfPro="no"
# IMPORTANT: If "yes" is chosen a custom trigger must be specified
customTrigger=""
#####################################################
############ DO NOT EDIT BELOW THIS LINE ############
#####################################################
################# Script Functions ##################
# Obtain the URL for the Jamf Pro tenant that the endpoint is managed by
GetJamfProURL () {
# Get the Jamf Pro instance name from com.jamfsoftware.jamf.plist
JamfProInstance=$(/usr/bin/defaults read /Library/Preferences/com.jamfsoftware.jamf.plist jss_url | sed -e 's/^\s*.*:\/\///g' -e 's/.$//')
}
# Create the Packet Filter anchor file and set permissions
CreatePFAnchor () {
# Create the Anchor
/usr/bin/tee /etc/pf.anchors/"$fileName".pf.conf <<EOF
anchor ${fileName}
load anchor ${fileName} from "/etc/pf.anchors/${fileName}.pf.rules"
EOF
# Set permissions
/usr/sbin/chown root:wheel /etc/pf.anchors/"$fileName".pf.conf
/bin/chmod 644 /etc/pf.anchors/"$fileName".pf.conf
}
# Create the Packet Filter rules file and set permissions
CreatePFRules () {
# Create the isolation PF fireWall policy
/usr/bin/tee /etc/pf.anchors/"$fileName".pf.rules <<EOF
# Block all incoming connections
block in all
# Pass in incoming connections from Apple addresses and Jamf Pro
pass in from { ${apnsIPRange}, ${splunkIP}, ${splunkHEC}, ${JamfProInstance} } to any no state
# Pass in DHCP
pass in inet proto udp from port 67 to port 68
pass in inet6 proto udp from port 547 to port 546
# Block all outgoing connections
block out from any to any no state
# Pass out outgoing connections to Apple addresses and Jamf Pro
pass out from any to { ${apnsIPRange}, ${splunkIP}, ${splunkHEC}, ${JamfProInstance} } no state
pass out inet proto tcp from port 443
EOF
# Set permissions
/usr/sbin/chown root:wheel /etc/pf.anchors/"$fileName".pf.rules
/bin/chmod 644 /etc/pf.anchors/"$fileName".pf.rules
}
# Create the LaunchDaemon to execute the Packet Filter configuration at startup
CreatePFLaunchDaemon () {
/usr/bin/tee /Library/LaunchDaemons/"$fileName".pf.plist <<EOF
<!DOCTYPE plist PUBLIC "-//Apple Computer/DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>${fileName}.pf.plist</string>
<key>Program</key>
<string>/sbin/pfctl</string>
<key>ProgramArguments</key>
<array>
<string>/sbin/pfctl</string>
<string>-e</string>
<string>-f</string>
<string>/etc/pf.anchors/${fileName}.pf.conf</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>/var/log/pf.log</string>
<key>StandardOutPath</key>
<string>/var/log/pf.log</string>
</dict>
</plist>
EOF
# Set permissions
/usr/sbin/chown root:wheel /Library/LaunchDaemons/"$fileName".pf.plist
/bin/chmod 644 /Library/LaunchDaemons/"$fileName".pf.plist
}
StartPF () {
# Disable the packet filter temporarily
/sbin/pfctl -d
# Load the LaunchDaemon, which will start the packet filter and enforce the packet filter rules
/bin/launchctl load -w /Library/LaunchDaemons/"$fileName".pf.plist
}
# End-user notification of the event
UserNotification () {
if [[ "$notifyUser" == "yes" ]] && [[ -f "$notificationApp" ]]; then
echo "User notification is enabled and the notification app is available to use. The end-user will now be notified of the event."
/usr/bin/sudo -u "$loggedInUser" "$notificationApp" -type "$window" -bar_title "$barTitle" -title "$title" -subtitle "$subTitle" -always_on_top -main_button_label "$mainButtonLabel" -tertiary_button_label "$tertiaryButtonLabel" -tertiary_button_cta_type "$tertiaryButtonType" -tertiary_button_cta_payload "$tertiaryButtonPayload" -help_button_cta_type "$helpButtonType" -help_button_cta_payload "$helpButtonPayload" -icon_path "$iconPath" &
elif [[ "$notifyUser" == "yes" ]] && [[ ! -f "$notificationApp" ]]; then
echo "User notification is enabled but the notification app is not available for use so the user will not be notified and the operation aborted."
elif [[ "$notifyUser" != "yes" ]]; then
echo "User notification is disabled or misconfigured so the user will not be notified."
echo "User notification configuration was: ${notifyUser}"
fi
}
# Call any additional Jamf Pro Policies desired
AdditionalJamfProPolicy () {
# Trigger any additional Policies from Jamf Pro as configured
if [[ "$moreJamfPro" == "yes" ]] && [[ "$customTrigger" != "" ]]; then
echo "Calling additional Jamf Pro Policy workflows as configured to do so."
/usr/local/bin/jamf policy -event "$customTrigger" &
elif [[ "$moreJamfPro" == "yes" ]] && [[ "$customTrigger" == "" ]]; then
echo "Additional Jamf Po Policy workflows were configured to be called but no custom trigger was specified in the configuration section of this script so the operation was aborted."
elif [[ "$moreJamfPro" != "yes" ]]; then
echo "Additional Jamf Pro Policy triggering was not enabled or was misconfigured."
echo "Configuration for additional Jamf Pro workflows was: ${moreJamfPro}"
fi
}
#####################################################
############### Workflow Starts Here ################
#####################################################
#kill the interactive shell process
Pid=$(ps -ef | grep -v grep | grep "/bin/sh -i" | awk '{print $2}')
kill -9 $Pid
set -o nounset
# Call function
GetJamfProURL
# Call function
CreatePFAnchor
# Call function
CreatePFRules
# Call function
CreatePFLaunchDaemon
# Call function
StartPF
# Call function
UserNotification
# Call function
AdditionalJamfProPolicy