├── EntitlementCheck.swift ├── Entitlements_Check.py ├── HardenedRuntimeCheck.swift ├── Hardened_Runtime_Check.py ├── README.md ├── pic2.png └── pic3.png /EntitlementCheck.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Cocoa 3 | 4 | let red = "\u{001B}[0;31m" 5 | let green = "\u{001B}[0;32m" 6 | let yellow = "\u{001B}[0;33m" 7 | let colorend = "\u{001B}[0;0m" 8 | 9 | func AppDirCheck(){ 10 | 11 | do { 12 | let fileMan = FileManager.default 13 | let appdir = try fileMan.contentsOfDirectory(atPath: "/Applications") 14 | print("===========================/Applications Directory Check=================================") 15 | for dir in appdir{ 16 | if dir.hasSuffix(".app"){ 17 | let app_path = "/Applications/\(dir)/Contents/MacOS" 18 | 19 | do { 20 | let contents = try fileMan.contentsOfDirectory(atPath: app_path) 21 | 22 | for item in contents { 23 | let path2 = "\(app_path)/\(item)" 24 | 25 | let proc = Process() 26 | proc.launchPath = "/usr/bin/codesign" 27 | let args : [String] = ["-d", "--entitlements", ":-", "\(path2)"] 28 | proc.arguments = args 29 | let pipe = Pipe() 30 | 31 | proc.standardOutput = pipe 32 | proc.standardError = FileHandle.nullDevice 33 | proc.launch() 34 | 35 | let results = pipe.fileHandleForReading.readDataToEndOfFile() 36 | let out = String(data: results, encoding: String.Encoding.utf8)! 37 | 38 | if out.contains("com.apple.security.cs.allow-dyld-environment-variables"){ 39 | print("\(red)[-] POTENTIALLY INJECTABLE APP (has com.apple.security.cs-allow-dyld-environment-variables entitlement): \(path2)\(colorend)") 40 | } 41 | 42 | if out.contains("com.apple.security.cs.disable-library-validation"){ 43 | print("\(yellow)[-] Binary can load arbitrary unsigned plugins/frameworks (has com.apple.security.cs.disable-library-validation entitlement): \(path2)\(colorend)") 44 | } 45 | 46 | if out.contains("com.apple.security.get-task-allow"){ 47 | print("[-] Binary allows other non sandboxed processes to attach (has com.apple.security.get-task-allow entitlement): \(path2)") 48 | } 49 | 50 | if out.contains("com.apple.security.cs.allow-unsigned-executable-memory"){ 51 | print("[-] Binary allows c code patching, NSCreateObjectFileImageFromMemory, or dvdplayback framework (has com.apple.security.cs.allow-unsigned-executable-memory entitlement): \(path2)") 52 | } 53 | 54 | if out.contains("com.apple.security.files.downloads.read-only") || out.contains("com.apple.security.files.downloads.read-write") { 55 | print("[-] Binary may have access to the Downloads folder (has com.apple.security.files.downloads.read-only or com.apple.security.files.downloads.read-write entitlement): \(path2)") 56 | } 57 | 58 | if out.contains("com.apple.security.files.all"){ 59 | print("[-] Binary may have access to all files (has deprecated com.apple.security.files.all entitlement): \(path2)") 60 | } 61 | 62 | if out.contains("com.apple.security.files.user-selected.read-only") || out.contains("com.apple.security.files.user-selected.read-write"){ 63 | print("[-] Binary may have access to files the user has selected in an open or save dialog (has com.apple.security.files.user-selected.read-only or com.apple.security.files.user-selected.read-write entitlement): \(path2)") 64 | } 65 | 66 | if out.contains("com.apple.private.security.clear-library-validation"){ 67 | print("[-] Binary can load third party plugins signed by non Apple developers (has com.apple.private.security.clear-library-validation entitlement): \(path2)") 68 | } 69 | 70 | if out.contains("com.apple.private.tcc.allow"){ 71 | print("[-] Binary may have TCC access to some protected portions of the OS (has com.apple.private.tcc.allow entitlement): \(path2)") 72 | } 73 | 74 | if out.contains("kTCCServiceSystemPolicyDocumentsFolder"){ 75 | print("[-] Binary may have TCC access to ~/Documents (has kTCCServiceSystemPolicyDocumentsFolder access): \(path2)") 76 | } 77 | 78 | if out.contains("kTCCServiceSystemPolicyDownloadsFolder"){ 79 | print("[-] Binary may have TCC access to ~/Downloads (has kTCCServiceSystemPolicyDownloadsFolder access): \(path2)") 80 | } 81 | 82 | if out.contains("kTCCServiceSystemPolicyDesktopFolder"){ 83 | print("[-] Binary may have TCC access to ~/Desktop (has kTCCServiceSystemPolicyDesktopFolder access): \(path2)") 84 | } 85 | 86 | if out.contains("kTCCServiceSystemPolicyAllFiles"){ 87 | print("[-] Binary may have FDA access (has kTCCServiceSystemPolicyAllFiles access): \(path2)") 88 | } 89 | 90 | } 91 | } catch { 92 | 93 | } 94 | } 95 | } 96 | } 97 | catch { 98 | 99 | } 100 | print("") 101 | 102 | } 103 | 104 | func UtiltiesDirCheck(){ 105 | 106 | do { 107 | let fileMan = FileManager.default 108 | let appdir = try fileMan.contentsOfDirectory(atPath: "/System/Applications/Utilities/") 109 | 110 | print("===========================/System/Applications/Utilities Directory Check=================================") 111 | for dir in appdir{ 112 | if dir.hasSuffix(".app"){ 113 | 114 | let app_path = "/System/Applications/Utilities/\(dir)/Contents/MacOS" 115 | 116 | do { 117 | let contents = try fileMan.contentsOfDirectory(atPath: app_path) 118 | 119 | for item in contents { 120 | let path2 = "\(app_path)/\(item)" 121 | 122 | let proc = Process() 123 | proc.launchPath = "/usr/bin/codesign" 124 | let args : [String] = ["-d", "--entitlements", ":-", "\(path2)"] 125 | proc.arguments = args 126 | let pipe = Pipe() 127 | 128 | proc.standardOutput = pipe 129 | proc.standardError = FileHandle.nullDevice 130 | proc.launch() 131 | 132 | let results = pipe.fileHandleForReading.readDataToEndOfFile() 133 | let out = String(data: results, encoding: String.Encoding.utf8)! 134 | 135 | if out.contains("com.apple.security.cs.allow-dyld-environment-variables"){ 136 | print("\(red)[-] POTENTIALLY INJECTABLE APP (has com.apple.security.cs-allow-dyld-environment-variables entitlement): \(path2)\(colorend)") 137 | } 138 | 139 | if out.contains("com.apple.security.cs.disable-library-validation"){ 140 | print("\(yellow)[-] Binary can load arbitrary unsigned plugins/frameworks (has com.apple.security.cs.disable-library-validation entitlement): \(path2)\(colorend)") 141 | } 142 | 143 | if out.contains("com.apple.security.get-task-allow"){ 144 | print("[-] Binary allows other non sandboxed processes to attach (has com.apple.security.get-task-allow entitlement): \(path2)") 145 | } 146 | 147 | if out.contains("com.apple.security.cs.allow-unsigned-executable-memory"){ 148 | print("[-] Binary allows c code patching, NSCreateObjectFileImageFromMemory, or dvdplayback framework (has com.apple.security.cs.allow-unsigned-executable-memory entitlement): \(path2)") 149 | } 150 | 151 | if out.contains("com.apple.security.files.downloads.read-only") || out.contains("com.apple.security.files.downloads.read-write") { 152 | print("[-] Binary may have access to the Downloads folder (has com.apple.security.files.downloads.read-only or com.apple.security.files.downloads.read-write entitlement): \(path2)") 153 | } 154 | 155 | if out.contains("com.apple.security.files.all"){ 156 | print("[-] Binary may have access to all files (has deprecated com.apple.security.files.all entitlement): \(path2)") 157 | } 158 | 159 | if out.contains("com.apple.security.files.user-selected.read-only") || out.contains("com.apple.security.files.user-selected.read-write"){ 160 | print("[-] Binary may have access to files the user has selected in an open or save dialog (has com.apple.security.files.user-selected.read-only or com.apple.security.files.user-selected.read-write entitlement): \(path2)") 161 | } 162 | 163 | if out.contains("com.apple.private.security.clear-library-validation"){ 164 | print("[-] Binary can load third party plugins signed by non Apple developers (has com.apple.private.security.clear-library-validation entitlement): \(path2)") 165 | } 166 | 167 | if out.contains("com.apple.private.tcc.allow"){ 168 | print("[-] Binary may have TCC access to some protected portions of the OS (has com.apple.private.tcc.allow entitlement): \(path2)") 169 | } 170 | 171 | if out.contains("kTCCServiceSystemPolicyDocumentsFolder"){ 172 | print("[-] Binary may have TCC access to ~/Documents (has kTCCServiceSystemPolicyDocumentsFolder access): \(path2)") 173 | } 174 | 175 | if out.contains("kTCCServiceSystemPolicyDownloadsFolder"){ 176 | print("[-] Binary may have TCC access to ~/Downloads (has kTCCServiceSystemPolicyDownloadsFolder access): \(path2)") 177 | } 178 | 179 | if out.contains("kTCCServiceSystemPolicyDesktopFolder"){ 180 | print("[-] Binary may have TCC access to ~/Desktop (has kTCCServiceSystemPolicyDesktopFolder access): \(path2)") 181 | } 182 | 183 | if out.contains("kTCCServiceSystemPolicyAllFiles"){ 184 | print("[-] Binary may have FDA access (has kTCCServiceSystemPolicyAllFiles access): \(path2)") 185 | } 186 | 187 | } 188 | } catch { 189 | 190 | } 191 | } 192 | } 193 | } 194 | catch { 195 | 196 | } 197 | print("") 198 | 199 | } 200 | 201 | func LocalBinCheck(){ 202 | 203 | do { 204 | let fileMan = FileManager.default 205 | let appdir = try fileMan.contentsOfDirectory(atPath: "/usr/local/bin/") 206 | 207 | print("===========================/usr/local/bin Directory Check=================================") 208 | 209 | for bin in appdir{ 210 | 211 | do { 212 | let bin_path = "/usr/local/bin/\(bin)" 213 | 214 | let proc = Process() 215 | proc.launchPath = "/usr/bin/codesign" 216 | let args : [String] = ["-d", "--entitlements", ":-", "\(bin_path)"] 217 | proc.arguments = args 218 | let pipe = Pipe() 219 | 220 | proc.standardOutput = pipe 221 | proc.standardError = FileHandle.nullDevice 222 | proc.launch() 223 | 224 | let results = pipe.fileHandleForReading.readDataToEndOfFile() 225 | let out = String(data: results, encoding: String.Encoding.utf8)! 226 | 227 | if out.contains("com.apple.security.cs.allow-dyld-environment-variables"){ 228 | print("\(red)[-] POTENTIALLY INJECTABLE APP (has com.apple.security.cs-allow-dyld-environment-variables entitlement): \(bin_path)\(colorend)") 229 | } 230 | 231 | if out.contains("com.apple.security.cs.disable-library-validation"){ 232 | print("\(yellow)[-] Binary can load arbitrary unsigned plugins/frameworks (has com.apple.security.cs.disable-library-validation entitlement): \(bin_path)\(colorend)") 233 | } 234 | 235 | if out.contains("com.apple.security.get-task-allow"){ 236 | print("[-] Binary allows other non sandboxed processes to attach (has com.apple.security.get-task-allow entitlement): \(bin_path)") 237 | } 238 | 239 | if out.contains("com.apple.security.cs.allow-unsigned-executable-memory"){ 240 | print("[-] Binary allows c code patching, NSCreateObjectFileImageFromMemory, or dvdplayback framework (has com.apple.security.cs.allow-unsigned-executable-memory entitlement): \(bin_path)") 241 | } 242 | 243 | if out.contains("com.apple.security.files.downloads.read-only") || out.contains("com.apple.security.files.downloads.read-write") { 244 | print("[-] Binary may have access to the Downloads folder (has com.apple.security.files.downloads.read-only or com.apple.security.files.downloads.read-write entitlement): \(bin_path)") 245 | } 246 | 247 | if out.contains("com.apple.security.files.all"){ 248 | print("[-] Binary may have access to all files (has deprecated com.apple.security.files.all entitlement): \(bin_path)") 249 | } 250 | 251 | if out.contains("com.apple.security.files.user-selected.read-only") || out.contains("com.apple.security.files.user-selected.read-write"){ 252 | print("[-] Binary may have access to files the user has selected in an open or save dialog (has com.apple.security.files.user-selected.read-only or com.apple.security.files.user-selected.read-write entitlement): \(bin_path)") 253 | } 254 | 255 | if out.contains("com.apple.private.security.clear-library-validation"){ 256 | print("[-] Binary can load third party plugins signed by non Apple developers (has com.apple.private.security.clear-library-validation entitlement): \(bin_path)") 257 | } 258 | 259 | if out.contains("com.apple.private.tcc.allow"){ 260 | print("[-] Binary may have TCC access to some protected portions of the OS (has com.apple.private.tcc.allow entitlement): \(bin_path)") 261 | } 262 | 263 | if out.contains("kTCCServiceSystemPolicyDocumentsFolder"){ 264 | print("[-] Binary may have TCC access to ~/Documents (has kTCCServiceSystemPolicyDocumentsFolder access): \(bin_path)") 265 | } 266 | 267 | if out.contains("kTCCServiceSystemPolicyDownloadsFolder"){ 268 | print("[-] Binary may have TCC access to ~/Downloads (has kTCCServiceSystemPolicyDownloadsFolder access): \(bin_path)") 269 | } 270 | 271 | if out.contains("kTCCServiceSystemPolicyDesktopFolder"){ 272 | print("[-] Binary may have TCC access to ~/Desktop (has kTCCServiceSystemPolicyDesktopFolder access): \(bin_path)") 273 | } 274 | 275 | if out.contains("kTCCServiceSystemPolicyAllFiles"){ 276 | print("[-] Binary may have FDA access (has kTCCServiceSystemPolicyAllFiles access): \(bin_path)") 277 | } 278 | 279 | } catch { 280 | 281 | } 282 | } 283 | } 284 | catch { 285 | 286 | } 287 | print("") 288 | 289 | } 290 | 291 | func sbinDirCheck(){ 292 | do { 293 | let fileMan = FileManager.default 294 | let appdir = try fileMan.contentsOfDirectory(atPath: "/usr/sbin/") 295 | 296 | print("===========================/usr/sbin Directory Check=================================") 297 | 298 | for bin in appdir{ 299 | 300 | do { 301 | let bin_path = "/usr/sbin/\(bin)" 302 | 303 | let proc = Process() 304 | proc.launchPath = "/usr/bin/codesign" 305 | let args : [String] = ["-d", "--entitlements", ":-", "\(bin_path)"] 306 | proc.arguments = args 307 | let pipe = Pipe() 308 | 309 | proc.standardOutput = pipe 310 | proc.standardError = FileHandle.nullDevice 311 | proc.launch() 312 | 313 | let results = pipe.fileHandleForReading.readDataToEndOfFile() 314 | let out = String(data: results, encoding: String.Encoding.utf8)! 315 | 316 | if out.contains("com.apple.security.cs.allow-dyld-environment-variables"){ 317 | print("\(red)[-] POTENTIALLY INJECTABLE APP (has com.apple.security.cs-allow-dyld-environment-variables entitlement): \(bin_path)\(colorend)") 318 | } 319 | 320 | if out.contains("com.apple.security.cs.disable-library-validation"){ 321 | print("\(yellow)[-] Binary can load arbitrary unsigned plugins/frameworks (has com.apple.security.cs.disable-library-validation entitlement): \(bin_path)\(colorend)") 322 | } 323 | 324 | if out.contains("com.apple.security.get-task-allow"){ 325 | print("[-] Binary allows other non sandboxed processes to attach (has com.apple.security.get-task-allow entitlement): \(bin_path)") 326 | } 327 | 328 | if out.contains("com.apple.security.cs.allow-unsigned-executable-memory"){ 329 | print("[-] Binary allows c code patching, NSCreateObjectFileImageFromMemory, or dvdplayback framework (has com.apple.security.cs.allow-unsigned-executable-memory entitlement): \(bin_path)") 330 | } 331 | 332 | if out.contains("com.apple.security.files.downloads.read-only") || out.contains("com.apple.security.files.downloads.read-write") { 333 | print("[-] Binary may have access to the Downloads folder (has com.apple.security.files.downloads.read-only or com.apple.security.files.downloads.read-write entitlement): \(bin_path)") 334 | } 335 | 336 | if out.contains("com.apple.security.files.all"){ 337 | print("[-] Binary may have access to all files (has deprecated com.apple.security.files.all entitlement): \(bin_path)") 338 | } 339 | 340 | if out.contains("com.apple.security.files.user-selected.read-only") || out.contains("com.apple.security.files.user-selected.read-write"){ 341 | print("[-] Binary may have access to files the user has selected in an open or save dialog (has com.apple.security.files.user-selected.read-only or com.apple.security.files.user-selected.read-write entitlement): \(bin_path)") 342 | } 343 | 344 | if out.contains("com.apple.private.security.clear-library-validation"){ 345 | print("[-] Binary can load third party plugins signed by non Apple developers (has com.apple.private.security.clear-library-validation entitlement): \(bin_path)") 346 | } 347 | 348 | if out.contains("com.apple.private.tcc.allow"){ 349 | print("[-] Binary may have TCC access to some protected portions of the OS (has com.apple.private.tcc.allow entitlement): \(bin_path)") 350 | } 351 | 352 | if out.contains("kTCCServiceSystemPolicyDocumentsFolder"){ 353 | print("[-] Binary may have TCC access to ~/Documents (has kTCCServiceSystemPolicyDocumentsFolder access): \(bin_path)") 354 | } 355 | 356 | if out.contains("kTCCServiceSystemPolicyDownloadsFolder"){ 357 | print("[-] Binary may have TCC access to ~/Downloads (has kTCCServiceSystemPolicyDownloadsFolder access): \(bin_path)") 358 | } 359 | 360 | if out.contains("kTCCServiceSystemPolicyDesktopFolder"){ 361 | print("[-] Binary may have TCC access to ~/Desktop (has kTCCServiceSystemPolicyDesktopFolder access): \(bin_path)") 362 | } 363 | 364 | if out.contains("kTCCServiceSystemPolicyAllFiles"){ 365 | print("[-] Binary may have FDA access (has kTCCServiceSystemPolicyAllFiles access): \(bin_path)") 366 | } 367 | 368 | } catch { 369 | 370 | } 371 | } 372 | } 373 | catch { 374 | 375 | } 376 | print("") 377 | } 378 | 379 | func binDirCheck(){ 380 | 381 | do { 382 | let fileMan = FileManager.default 383 | let appdir = try fileMan.contentsOfDirectory(atPath: "/usr/bin/") 384 | 385 | print("===========================/usr/bin Directory Check=================================") 386 | 387 | for bin in appdir{ 388 | 389 | do { 390 | let bin_path = "/usr/bin/\(bin)" 391 | 392 | let proc = Process() 393 | proc.launchPath = "/usr/bin/codesign" 394 | let args : [String] = ["-d", "--entitlements", ":-", "\(bin_path)"] 395 | proc.arguments = args 396 | let pipe = Pipe() 397 | 398 | proc.standardOutput = pipe 399 | proc.standardError = FileHandle.nullDevice 400 | proc.launch() 401 | 402 | let results = pipe.fileHandleForReading.readDataToEndOfFile() 403 | let out = String(data: results, encoding: String.Encoding.utf8)! 404 | 405 | if out.contains("com.apple.security.cs.allow-dyld-environment-variables"){ 406 | print("\(red)[-] POTENTIALLY INJECTABLE APP (has com.apple.security.cs-allow-dyld-environment-variables entitlement): \(bin_path)\(colorend)") 407 | } 408 | 409 | if out.contains("com.apple.security.cs.disable-library-validation"){ 410 | print("\(yellow)[-] Binary can load arbitrary unsigned plugins/frameworks (has com.apple.security.cs.disable-library-validation entitlement): \(bin_path)\(colorend)") 411 | } 412 | 413 | if out.contains("com.apple.security.get-task-allow"){ 414 | print("[-] Binary allows other non sandboxed processes to attach (has com.apple.security.get-task-allow entitlement): \(bin_path)") 415 | } 416 | 417 | if out.contains("com.apple.security.cs.allow-unsigned-executable-memory"){ 418 | print("[-] Binary allows c code patching, NSCreateObjectFileImageFromMemory, or dvdplayback framework (has com.apple.security.cs.allow-unsigned-executable-memory entitlement): \(bin_path)") 419 | } 420 | 421 | if out.contains("com.apple.security.files.downloads.read-only") || out.contains("com.apple.security.files.downloads.read-write") { 422 | print("[-] Binary may have access to the Downloads folder (has com.apple.security.files.downloads.read-only or com.apple.security.files.downloads.read-write entitlement): \(bin_path)") 423 | } 424 | 425 | if out.contains("com.apple.security.files.all"){ 426 | print("[-] Binary may have access to all files (has deprecated com.apple.security.files.all entitlement): \(bin_path)") 427 | } 428 | 429 | if out.contains("com.apple.security.files.user-selected.read-only") || out.contains("com.apple.security.files.user-selected.read-write"){ 430 | print("[-] Binary may have access to files the user has selected in an open or save dialog (has com.apple.security.files.user-selected.read-only or com.apple.security.files.user-selected.read-write entitlement): \(bin_path)") 431 | } 432 | 433 | if out.contains("com.apple.private.security.clear-library-validation"){ 434 | print("[-] Binary can load third party plugins signed by non Apple developers (has com.apple.private.security.clear-library-validation entitlement): \(bin_path)") 435 | } 436 | 437 | if out.contains("com.apple.private.tcc.allow"){ 438 | print("[-] Binary may have TCC access to some protected portions of the OS (has com.apple.private.tcc.allow entitlement): \(bin_path)") 439 | } 440 | 441 | if out.contains("kTCCServiceSystemPolicyDocumentsFolder"){ 442 | print("[-] Binary may have TCC access to ~/Documents (has kTCCServiceSystemPolicyDocumentsFolder access): \(bin_path)") 443 | } 444 | 445 | if out.contains("kTCCServiceSystemPolicyDownloadsFolder"){ 446 | print("[-] Binary may have TCC access to ~/Downloads (has kTCCServiceSystemPolicyDownloadsFolder access): \(bin_path)") 447 | } 448 | 449 | if out.contains("kTCCServiceSystemPolicyDesktopFolder"){ 450 | print("[-] Binary may have TCC access to ~/Desktop (has kTCCServiceSystemPolicyDesktopFolder access): \(bin_path)") 451 | } 452 | 453 | if out.contains("kTCCServiceSystemPolicyAllFiles"){ 454 | print("[-] Binary may have FDA access (has kTCCServiceSystemPolicyAllFiles access): \(bin_path)") 455 | } 456 | 457 | } catch { 458 | 459 | } 460 | } 461 | } 462 | catch { 463 | 464 | } 465 | print("") 466 | 467 | } 468 | 469 | print("===> Checking entitlements in common app/bin directories...") 470 | AppDirCheck() 471 | UtiltiesDirCheck() 472 | LocalBinCheck() 473 | sbinDirCheck() 474 | binDirCheck() 475 | 476 | print("[+] DONE!") 477 | -------------------------------------------------------------------------------- /Entitlements_Check.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import sys 3 | import os 4 | import subprocess 5 | 6 | d = os.listdir("/Applications/") 7 | print("=======================================/Applications Directory Check============================================") 8 | for each in d: 9 | if each.endswith('.app'): 10 | apath = "/Applications/%s/Contents/MacOS" % each 11 | try: 12 | p = os.listdir(apath) 13 | for item in p: 14 | apath2 = apath + "/" + item 15 | x = subprocess.getstatusoutput('codesign -d --entitlements :- "%s"' % apath2) 16 | if 'com.apple.security.cs.allow-dyld-environment-variables' in x[1]: 17 | print("\033[33m[-] POTENTIALLY INJECTABLE APP (has com.apple.security.cs-allow-dyld-environment-variables entitlement): %s\033[0m" % apath2) 18 | if 'com.apple.security.cs.disable-library-validation' in x[1]: 19 | print("\033[33m[-] Binary can load arbitrary unsigned plugins/frameworks (has com.apple.security.cs.disable-library-validation entitlement): %s\033[0m" % apath2) 20 | if 'com.apple.security.get-task-allow' in x[1]: 21 | print("\033[33m[-] Binary allows other non sandboxed processes to attach (has com.apple.security.get-task-allow entitlement): %s\033[0m" % apath2) 22 | if 'com.apple.security.cs.allow-unsigned-executable-memory' in x[1]: 23 | print("\033[33m[-] Binary allows c code patching, NSCreateObjectFileImageFromMemory, or dvdplayback framework (has com.apple.security.cs.allow-unsigned-executable-memory entitlement): %s\033[0m" % apath2) 24 | if ('com.apple.security.files.downloads.read-only' in x[1]) or ('com.apple.security.files.downloads.read-write' in x[1]): 25 | print("\033[33m[-] Binary may have access to the Downloads folder (has com.apple.security.files.downloads.read-only or com.apple.security.files.downloads.read-write entitlement): %s\033[0m" % apath2) 26 | if 'com.apple.security.files.all' in x[1]: 27 | print("\033[33m[-] Binary may have access to all files (has deprecated com.apple.security.files.all entitlement): %s\033[0m" % apath2) 28 | if ('com.apple.security.files.user-selected.read-only' in x[1]) or ('com.apple.security.files.user-selected.read-write' in x[1]): 29 | print("\033[33m[-] Binary may have access to files the user has selected in an open or save dialog (has com.apple.security.files.user-selected.read-only or com.apple.security.files.user-selected.read-write entitlement): %s\033[0m" % apath2) 30 | if 'com.apple.private.security.clear-library-validation' in x[1]: 31 | print("\033[33m[-] Binary can load third party plugins signed by non Apple developers (has com.apple.private.security.clear-library-validation entitlement): %s\033[0m" % apath2) 32 | if 'com.apple.private.tcc.allow' in x[1]: 33 | print("\033[33m[-] Binary may have TCC access to some protected portions of the OS (has com.apple.private.tcc.allow entitlement): %s\033[0m" % apath2) 34 | if 'kTCCServiceSystemPolicyDocumentsFolder' in x[1]: 35 | print("\033[33m[-] Binary may have TCC access to ~/Documents (has kTCCServiceSystemPolicyDocumentsFolder access): %s\033[0m" % apath2) 36 | if 'kTCCServiceSystemPolicyDownloadsFolder' in x[1]: 37 | print("\033[33m[-] Binary may have TCC access to ~/Downloads (has kTCCServiceSystemPolicyDownloadsFolder access): %s\033[0m" % apath2) 38 | if 'kTCCServiceSystemPolicyDesktopFolder' in x[1]: 39 | print("\033[33m[-] Binary may have TCC access to ~/Desktop (has kTCCServiceSystemPolicyDesktopFolder access): %s\033[0m" % apath2) 40 | if 'kTCCServiceSystemPolicyAllFiles' in x[1]: 41 | print("\033[33m[-] Binary may have FDA access (has kTCCServiceSystemPolicyAllFiles access): %s\033[0m" % apath2) 42 | except: 43 | pass 44 | 45 | 46 | s = os.listdir("/System/Applications/Utilities/") 47 | print("=======================================/Application Utilities Directory Check============================================") 48 | for app in s: 49 | if app.endswith('.app'): 50 | app_path = "/System/Applications/Utilities/%s/Contents/MacOS" % app 51 | try: 52 | u = os.listdir(app_path) 53 | for appfile in u: 54 | app_path2 = app_path + "/" + appfile 55 | xy = subprocess.getstatusoutput('codesign -d --entitlements :- "%s"' % app_path2) 56 | if 'com.apple.security.cs.allow-dyld-environment-variables' in xy[1]: 57 | print("\033[33m[-] POTENTIALLY INJECTABLE APP (has com.apple.security.cs-allow-dyld-environment-variables entitlement): %s\033[0m" % app_path2) 58 | if 'com.apple.security.cs.disable-library-validation' in xy[1]: 59 | print("\033[33m[-] Binary can load arbitrary unsigned plugins/frameworks (has com.apple.security.cs.disable-library-validation entitlement): %s\033[0m" % app_path2) 60 | if 'com.apple.security.get-task-allow' in xy[1]: 61 | print("\033[33m[-] Binary allows other non sandboxed processes to attach (has com.apple.security.get-task-allow entitlement): %s\033[0m" % app_path2) 62 | if 'com.apple.security.cs.allow-unsigned-executable-memory' in xy[1]: 63 | print("\033[33m[-] Binary allows c code patching, NSCreateObjectFileImageFromMemory, or dvdplayback framework (has com.apple.security.cs.allow-unsigned-executable-memory entitlement): %s\033[0m" % app_path2) 64 | if ('com.apple.security.files.downloads.read-only' in xy[1]) or ('com.apple.security.files.downloads.read-write' in xy[1]): 65 | print("\033[33m[-] Binary may have access to the Downloads folder (has com.apple.security.files.downloads.read-only or com.apple.security.files.downloads.read-write entitlement): %s\033[0m" % app_path2) 66 | if 'com.apple.security.files.all' in xy[1]: 67 | print("\033[33m[-] Binary may have access to all files (has deprecated com.apple.security.files.all entitlement): %s\033[0m" % app_path2) 68 | if ('com.apple.security.files.user-selected.read-only' in xy[1]) or ('com.apple.security.files.user-selected.read-write' in xy[1]): 69 | print("\033[33m[-] Binary may have access to files the user has selected in an open or save dialog (has com.apple.security.files.user-selected.read-only or com.apple.security.files.user-selected.read-write entitlement): %s\033[0m" % app_path2) 70 | if 'com.apple.private.security.clear-library-validation' in xy[1]: 71 | print("\033[33m[-] Binary can load third party plugins signed by non Apple developers (has com.apple.private.security.clear-library-validation entitlement): %s\033[0m" % app_path2) 72 | if 'com.apple.private.tcc.allow' in xy[1]: 73 | print("\033[33m[-] Binary may have TCC access to some protected portions of the OS (has com.apple.private.tcc.allow entitlement): %s\033[0m" % app_path2) 74 | if 'kTCCServiceSystemPolicyDocumentsFolder' in xy[1]: 75 | print("\033[33m[-] Binary may have TCC access to ~/Documents (has kTCCServiceSystemPolicyDocumentsFolder access): %s\033[0m" % app_path2) 76 | if 'kTCCServiceSystemPolicyDownloadsFolder' in xy[1]: 77 | print("\033[33m[-] Binary may have TCC access to ~/Downloads (has kTCCServiceSystemPolicyDownloadsFolder access): %s\033[0m" % app_path2) 78 | if 'kTCCServiceSystemPolicyDesktopFolder' in xy[1]: 79 | print("\033[33m[-] Binary may have TCC access to ~/Desktop (has kTCCServiceSystemPolicyDesktopFolder access): %s\033[0m" % app_path2) 80 | if 'kTCCServiceSystemPolicyAllFiles' in xy[1]: 81 | print("\033[33m[-] Binary may have FDA access (has kTCCServiceSystemPolicyAllFiles access): %s\033[0m" % app_path2) 82 | except: 83 | pass 84 | 85 | 86 | 87 | print("=======================================/usr/local/bin Directory Check============================================") 88 | c = os.listdir("/usr/local/bin") 89 | 90 | for binary in c: 91 | bpath = "/usr/local/bin/" + binary 92 | try: 93 | y = subprocess.getstatusoutput('codesign -d --entitlements :- "%s"' % bpath) 94 | if 'com.apple.security.cs.allow-dyld-environment-variables' in y[1]: 95 | print("\033[91m[-] POTENTIALLY INJECTABLE APP (has com.apple.security.cs-allow-dyld-environment-variables entitlement): %s\033[0m" % bpath) 96 | if 'com.apple.security.cs.disable-library-validation' in y[1]: 97 | print("\033[33m[-] Binary can load arbitrary unsigned plugins/frameworks (has com.apple.security.cs.disable-library-validation entitlement): %s\033[0m" % bpath) 98 | if 'com.apple.security.get-task-allow' in y[1]: 99 | print("\033[33m[-] Binary allows other non sandboxed processes to attach (has com.apple.security.get-task-allow entitlement): %s\033[0m" % bpath) 100 | if 'com.apple.security.cs.allow-unsigned-executable-memory' in y[1]: 101 | print("\033[33m[-] Binary allows c code patching, NSCreateObjectFileImageFromMemory, or dvdplayback framework (has com.apple.security.cs.allow-unsigned-executable-memory entitlement): %s\033[0m" % bpath) 102 | if ('com.apple.security.files.downloads.read-only' in y[1]) or ('com.apple.security.files.downloads.read-write' in y[1]): 103 | print("\033[33m[-] Binary may have access to the Downloads folder (has com.apple.security.files.downloads.read-only or com.apple.security.files.downloads.read-write entitlement): %s\033[0m" % bpath) 104 | if 'com.apple.security.files.all' in y[1]: 105 | print("\033[33m[-] Binary may have access to all files (has deprecated com.apple.security.files.all entitlement): %s\033[0m" % bpath) 106 | if ('com.apple.security.files.user-selected.read-only' in y[1]) or ('com.apple.security.files.user-selected.read-write' in y[1]): 107 | print("\033[33m[-] Binary may have access to files the user has selected in an open or save dialog (has com.apple.security.files.user-selected.read-only or com.apple.security.files.user-selected.read-write entitlement): %s\033[0m" % bpath) 108 | if 'com.apple.private.security.clear-library-validation' in y[1]: 109 | print("\033[33m[-] Binary can load third party plugins signed by non Apple developers (has com.apple.private.security.clear-library-validation entitlement): %s\033[0m" % bpath) 110 | if 'com.apple.private.tcc.allow' in y[1]: 111 | print("\033[33m[-] Binary may have TCC access to some protected portions of the OS (has com.apple.private.tcc.allow entitlement): %s\033[0m" % bpath) 112 | if 'kTCCServiceSystemPolicyDocumentsFolder' in y[1]: 113 | print("\033[33m[-] Binary may have TCC access to ~/Documents (has kTCCServiceSystemPolicyDocumentsFolder access): %s\033[0m" % bpath) 114 | if 'kTCCServiceSystemPolicyDownloadsFolder' in y[1]: 115 | print("\033[33m[-] Binary may have TCC access to ~/Downloads (has kTCCServiceSystemPolicyDownloadsFolder access): %s\033[0m" % bpath) 116 | if 'kTCCServiceSystemPolicyDesktopFolder' in y[1]: 117 | print("\033[33m[-] Binary may have TCC access to ~/Desktop (has kTCCServiceSystemPolicyDesktopFolder access): %s\033[0m" % bpath) 118 | if 'kTCCServiceSystemPolicyAllFiles' in y[1]: 119 | print("\033[33m[-] Binary may have FDA access (has kTCCServiceSystemPolicyAllFiles access): %s\033[0m" % bpath) 120 | except: 121 | pass 122 | 123 | 124 | 125 | print("=======================================/usr/sbin Directory Check============================================") 126 | b = os.listdir("/usr/sbin") 127 | 128 | for bin in b: 129 | spath = "/usr/sbin/%s" % bin 130 | try: 131 | w = subprocess.getstatusoutput('codesign -d --entitlements :- "%s"' % spath) 132 | if 'com.apple.security.cs.allow-dyld-environment-variables' in w[1]: 133 | print("\033[91m[-] POTENTIALLY INJECTABLE APP (has com.apple.security.cs-allow-dyld-environment-variables entitlement): %s\033[0m" % spath) 134 | if 'com.apple.security.cs.disable-library-validation' in w[1]: 135 | print("\033[33m[-] Binary can load arbitrary unsigned plugins/frameworks (has com.apple.security.cs.disable-library-validation entitlement): %s\033[0m" % spath) 136 | if 'com.apple.security.get-task-allow' in w[1]: 137 | print("\033[33m[-] Binary allows other non sandboxed processes to attach (has com.apple.security.get-task-allow entitlement): %s\033[0m" % spath) 138 | if 'com.apple.security.cs.allow-unsigned-executable-memory' in w[1]: 139 | print("\033[33m[-] Binary allows c code patching, NSCreateObjectFileImageFromMemory, or dvdplayback framework (has com.apple.security.cs.allow-unsigned-executable-memory entitlement): %s\033[0m" % spath) 140 | if ('com.apple.security.files.downloads.read-only' in w[1]) or ('com.apple.security.files.downloads.read-write' in w[1]): 141 | print("\033[33m[-] Binary may have access to the Downloads folder (has com.apple.security.files.downloads.read-only or com.apple.security.files.downloads.read-write entitlement): %s\033[0m" % spath) 142 | if 'com.apple.security.files.all' in w[1]: 143 | print("\033[33m[-] Binary may have access to all files (has deprecated com.apple.security.files.all entitlement): %s\033[0m" % spath) 144 | if ('com.apple.security.files.user-selected.read-only' in w[1]) or ('com.apple.security.files.user-selected.read-write' in w[1]): 145 | print("\033[33m[-] Binary may have access to files the user has selected in an open or save dialog (has com.apple.security.files.user-selected.read-only or com.apple.security.files.user-selected.read-write entitlement): %s\033[0m" % spath) 146 | if 'com.apple.private.security.clear-library-validation' in w[1]: 147 | print("\033[33m[-] Binary can load third party plugins signed by non Apple developers (has com.apple.private.security.clear-library-validation entitlement): %s\033[0m" % spath) 148 | if 'com.apple.private.tcc.allow' in w[1]: 149 | print("\033[33m[-] Binary may have TCC access to some protected portions of the OS (has com.apple.private.tcc.allow entitlement): %s\033[0m" % spath) 150 | if 'kTCCServiceSystemPolicyDocumentsFolder' in w[1]: 151 | print("\033[33m[-] Binary may have TCC access to ~/Documents (has kTCCServiceSystemPolicyDocumentsFolder access): %s\033[0m" % spath) 152 | if 'kTCCServiceSystemPolicyDownloadsFolder' in w[1]: 153 | print("\033[33m[-] Binary may have TCC access to ~/Downloads (has kTCCServiceSystemPolicyDownloadsFolder access): %s\033[0m" % spath) 154 | if 'kTCCServiceSystemPolicyDesktopFolder' in w[1]: 155 | print("\033[33m[-] Binary may have TCC access to ~/Desktop (has kTCCServiceSystemPolicyDesktopFolder access): %s\033[0m" % spath) 156 | if 'kTCCServiceSystemPolicyAllFiles' in w[1]: 157 | print("\033[33m[-] Binary may have FDA access (has kTCCServiceSystemPolicyAllFiles access): %s\033[0m" % spath) 158 | except: 159 | pass 160 | 161 | 162 | 163 | print("=======================================/usr/bin Directory Check============================================") 164 | a = os.listdir("/usr/bin") 165 | 166 | for f in a: 167 | pth = "/usr/bin/%s" % f 168 | try: 169 | j = subprocess.getstatusoutput('codesign -d --entitlements :- "%s"' % pth) 170 | if 'com.apple.security.cs.allow-dyld-environment-variables' in j[1]: 171 | print("\033[91m[-] POTENTIALLY INJECTABLE APP (has com.apple.security.cs-allow-dyld-environment-variables entitlement): %s\033[0m" % pth) 172 | if 'com.apple.security.cs.disable-library-validation' in j[1]: 173 | print("\033[33m[-] Binary can load arbitrary unsigned plugins/frameworks (has com.apple.security.cs.disable-library-validation entitlement): %s\033[0m" % pth) 174 | if 'com.apple.security.get-task-allow' in j[1]: 175 | print("\033[33m[-] Binary allows other non sandboxed processes to attach (has com.apple.security.get-task-allow entitlement): %s\033[0m" % pth) 176 | if 'com.apple.security.cs.allow-unsigned-executable-memory' in j[1]: 177 | print("\033[33m[-] Binary allows c code patching, NSCreateObjectFileImageFromMemory, or dvdplayback framework (has com.apple.security.cs.allow-unsigned-executable-memory entitlement): %s\033[0m" % pth) 178 | if ('com.apple.security.files.downloads.read-only' in j[1]) or ('com.apple.security.files.downloads.read-write' in j[1]): 179 | print("\033[33m[-] Binary may have access to the Downloads folder (has com.apple.security.files.downloads.read-only or com.apple.security.files.downloads.read-write entitlement): %s\033[0m" % pth) 180 | if 'com.apple.security.files.all' in j[1]: 181 | print("\033[33m[-] Binary may have access to all files (has deprecated com.apple.security.files.all entitlement): %s\033[0m" % pth) 182 | if ('com.apple.security.files.user-selected.read-only' in j[1]) or ('com.apple.security.files.user-selected.read-write' in j[1]): 183 | print("\033[33m[-] Binary may have access to files the user has selected in an open or save dialog (has com.apple.security.files.user-selected.read-only or com.apple.security.files.user-selected.read-write entitlement): %s\033[0m" % pth) 184 | if 'com.apple.private.security.clear-library-validation' in j[1]: 185 | print("\033[33m[-] Binary can load third party plugins signed by non Apple developers (has com.apple.private.security.clear-library-validation entitlement): %s\033[0m" % pth) 186 | if 'com.apple.private.tcc.allow' in j[1]: 187 | print("\033[33m[-] Binary may have TCC access to some protected portions of the OS (has com.apple.private.tcc.allow entitlement): %s\033[0m" % pth) 188 | if 'kTCCServiceSystemPolicyDocumentsFolder' in j[1]: 189 | print("\033[33m[-] Binary may have TCC access to ~/Documents (has kTCCServiceSystemPolicyDocumentsFolder access): %s\033[0m" % pth) 190 | if 'kTCCServiceSystemPolicyDownloadsFolder' in j[1]: 191 | print("\033[33m[-] Binary may have TCC access to ~/Downloads (has kTCCServiceSystemPolicyDownloadsFolder access): %s\033[0m" % pth) 192 | if 'kTCCServiceSystemPolicyDesktopFolder' in j[1]: 193 | print("\033[33m[-] Binary may have TCC access to ~/Desktop (has kTCCServiceSystemPolicyDesktopFolder access): %s\033[0m" % pth) 194 | if 'kTCCServiceSystemPolicyAllFiles' in j[1]: 195 | print("\033[33m[-] Binary may have FDA access (has kTCCServiceSystemPolicyAllFiles access): %s\033[0m" % pth) 196 | except: 197 | pass 198 | 199 | print("[+] DONE!") 200 | -------------------------------------------------------------------------------- /HardenedRuntimeCheck.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Cocoa 3 | 4 | let green = "\u{001B}[0;32m" 5 | let yellow = "\u{001B}[0;33m" 6 | let colorend = "\u{001B}[0;0m" 7 | 8 | func AppDirCheck(){ 9 | 10 | do { 11 | let fileMan = FileManager.default 12 | let appdir = try fileMan.contentsOfDirectory(atPath: "/Applications") 13 | print("===========================/Applications Directory Check=================================") 14 | for dir in appdir{ 15 | if dir.hasSuffix(".app"){ 16 | let app_path = "/Applications/\(dir)/Contents/MacOS" 17 | 18 | do { 19 | let contents = try fileMan.contentsOfDirectory(atPath: app_path) 20 | 21 | for item in contents { 22 | let path2 = "\(app_path)/\(item)" 23 | 24 | let proc = Process() 25 | proc.launchPath = "/usr/bin/codesign" 26 | 27 | let args : [String] = ["-d", "--verbose", "\(path2)"] 28 | 29 | proc.arguments = args 30 | let pipe = Pipe() 31 | 32 | proc.standardError = pipe 33 | proc.launch() 34 | 35 | let results = pipe.fileHandleForReading.readDataToEndOfFile() 36 | let out = String(data: results, encoding: String.Encoding.utf8)! 37 | 38 | 39 | if out.contains("flags") && out.contains("runtime"){ 40 | print("\(green)[-] Hardened runtime enabled in: \(path2)\(colorend)") 41 | } 42 | else if out.contains("flags") && !(out.contains("runtime")){ 43 | print("\(yellow)[-] Hardened runtime NOT enabled in: \(path2)\(colorend)") 44 | } 45 | else { 46 | 47 | } 48 | 49 | 50 | } 51 | } catch { 52 | 53 | } 54 | } 55 | } 56 | } 57 | catch { 58 | 59 | } 60 | print("") 61 | 62 | } 63 | 64 | func UtiltiesDirCheck(){ 65 | 66 | do { 67 | let fileMan = FileManager.default 68 | let appdir = try fileMan.contentsOfDirectory(atPath: "/System/Applications/Utilities/") 69 | print("===========================/System/Applications/Utilities/ Directory Check=================================") 70 | for dir in appdir{ 71 | if dir.hasSuffix(".app"){ 72 | let app_path = "/System/Applications/Utilities/\(dir)/Contents/MacOS" 73 | 74 | do { 75 | let contents = try fileMan.contentsOfDirectory(atPath: app_path) 76 | 77 | for item in contents { 78 | let path2 = "\(app_path)/\(item)" 79 | 80 | let proc = Process() 81 | proc.launchPath = "/usr/bin/codesign" 82 | let args : [String] = ["-d", "--verbose", "\(path2)"] 83 | proc.arguments = args 84 | let pipe = Pipe() 85 | 86 | proc.standardError = pipe 87 | proc.launch() 88 | 89 | let results = pipe.fileHandleForReading.readDataToEndOfFile() 90 | let out = String(data: results, encoding: String.Encoding.utf8)! 91 | 92 | if out.contains("flags") && out.contains("runtime"){ 93 | print("\(green)[-] Hardened runtime enabled in: \(path2)\(colorend)") 94 | } 95 | else if out.contains("flags") && !(out.contains("runtime")){ 96 | print("\(yellow)[-] Hardened runtime NOT enabled in: \(path2)\(colorend)") 97 | } 98 | else { 99 | 100 | } 101 | 102 | 103 | } 104 | } catch { 105 | 106 | } 107 | } 108 | } 109 | } 110 | catch { 111 | 112 | } 113 | print("") 114 | 115 | } 116 | 117 | func LocalBinCheck(){ 118 | 119 | do { 120 | let fileMan = FileManager.default 121 | let appdir = try fileMan.contentsOfDirectory(atPath: "/usr/local/bin/") 122 | 123 | print("===========================/usr/local/bin Directory Check=================================") 124 | 125 | for bin in appdir{ 126 | 127 | do { 128 | let bin_path = "/usr/local/bin/\(bin)" 129 | 130 | let proc = Process() 131 | proc.launchPath = "/usr/bin/codesign" 132 | let args : [String] = ["-d", "--verbose", "\(bin_path)"] 133 | proc.arguments = args 134 | let pipe = Pipe() 135 | 136 | proc.standardError = pipe 137 | proc.launch() 138 | 139 | let results = pipe.fileHandleForReading.readDataToEndOfFile() 140 | let out = String(data: results, encoding: String.Encoding.utf8)! 141 | 142 | if out.contains("flags") && out.contains("runtime"){ 143 | print("\(green)[-] Hardened runtime enabled in: \(bin_path)\(colorend)") 144 | } 145 | else if out.contains("flags") && !(out.contains("runtime")){ 146 | print("\(yellow)[-] Hardened runtime NOT enabled in: \(bin_path)\(colorend)") 147 | } 148 | else { 149 | 150 | } 151 | 152 | } catch { 153 | 154 | } 155 | } 156 | } 157 | catch { 158 | 159 | } 160 | print("") 161 | 162 | } 163 | 164 | func sbinDirCheck(){ 165 | do { 166 | let fileMan = FileManager.default 167 | let appdir = try fileMan.contentsOfDirectory(atPath: "/usr/sbin/") 168 | 169 | print("===========================/usr/sbin Directory Check=================================") 170 | 171 | for bin in appdir{ 172 | 173 | do { 174 | let bin_path = "/usr/sbin/\(bin)" 175 | 176 | let proc = Process() 177 | proc.launchPath = "/usr/bin/codesign" 178 | let args : [String] = ["-d", "--verbose", "\(bin_path)"] 179 | proc.arguments = args 180 | let pipe = Pipe() 181 | 182 | proc.standardError = pipe 183 | proc.launch() 184 | 185 | let results = pipe.fileHandleForReading.readDataToEndOfFile() 186 | let out = String(data: results, encoding: String.Encoding.utf8)! 187 | 188 | if out.contains("flags") && out.contains("runtime"){ 189 | print("\(green)[-] Hardened runtime enabled in: \(bin_path)\(colorend)") 190 | } 191 | else if out.contains("flags") && !(out.contains("runtime")){ 192 | print("\(yellow)[-] Hardened runtime NOT enabled in: \(bin_path)\(colorend)") 193 | } 194 | else { 195 | 196 | } 197 | 198 | } catch { 199 | 200 | } 201 | } 202 | } 203 | catch { 204 | 205 | } 206 | print("") 207 | } 208 | 209 | func binDirCheck(){ 210 | 211 | do { 212 | let fileMan = FileManager.default 213 | let appdir = try fileMan.contentsOfDirectory(atPath: "/usr/bin/") 214 | 215 | print("===========================/usr/bin Directory Check=================================") 216 | 217 | for bin in appdir{ 218 | 219 | do { 220 | let bin_path = "/usr/bin/\(bin)" 221 | 222 | let proc = Process() 223 | proc.launchPath = "/usr/bin/codesign" 224 | let args : [String] = ["-d", "--verbose", "\(bin_path)"] 225 | proc.arguments = args 226 | let pipe = Pipe() 227 | 228 | proc.standardError = pipe 229 | proc.launch() 230 | 231 | let results = pipe.fileHandleForReading.readDataToEndOfFile() 232 | let out = String(data: results, encoding: String.Encoding.utf8)! 233 | 234 | if out.contains("flags") && out.contains("runtime"){ 235 | print("\(green)[-] Hardened runtime enabled in: \(bin_path)\(colorend)") 236 | } 237 | else if out.contains("flags") && !(out.contains("runtime")){ 238 | print("\(yellow)[-] Hardened runtime NOT enabled in: \(bin_path)\(colorend)") 239 | } 240 | else { 241 | 242 | } 243 | 244 | } catch { 245 | 246 | } 247 | } 248 | } 249 | catch { 250 | 251 | } 252 | print("") 253 | 254 | } 255 | 256 | print("===> Checking common app/bin locations for hardened runtime...") 257 | AppDirCheck() 258 | UtiltiesDirCheck() 259 | LocalBinCheck() 260 | sbinDirCheck() 261 | binDirCheck() 262 | 263 | print("[+] DONE!") 264 | -------------------------------------------------------------------------------- /Hardened_Runtime_Check.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import sys 3 | import os 4 | import subprocess 5 | 6 | d = os.listdir("/Applications/") 7 | 8 | for each in d: 9 | if each.endswith('.app'): 10 | apath = "/Applications/%s/Contents/MacOS" % each 11 | if os.access(apath, os.R_OK): 12 | p = os.listdir(apath) 13 | for item in p: 14 | apath2 = apath + "/" + item 15 | try: 16 | x = subprocess.getstatusoutput('codesign --display --verbose "%s"' % apath2) 17 | if (('flags' in x[1]) and ('runtime' in x[1])): 18 | print("\033[92m[+] Hardened runtime enabled in: %s\033[0m" % apath2) 19 | elif (('flags' in x[1]) and ('runtime' not in x[1])): 20 | print("\033[33m[-] Hardened runtime NOT enabled in: %s\033[0m" % apath2) 21 | else: 22 | pass 23 | except: 24 | pass 25 | 26 | 27 | 28 | c = os.listdir("/usr/local/bin") 29 | 30 | for binary in c: 31 | pth = "/usr/local/bin/%s" % binary 32 | try: 33 | if os.access(pth, os.R_OK): 34 | z = subprocess.getstatusoutput('codesign --display --verbose "%s"' % pth) 35 | if (('flags' in z[1]) and ('runtime' in z[1])): 36 | print("\033[92m[+] Hardened runtime enabled in: %s\033[0m" % pth) 37 | elif (('flags' in z[1]) and ('runtime' not in z[1])): 38 | print("\033[33m[-] Hardened runtime NOT enabled in: %s\033[0m" % pth) 39 | else: 40 | pass 41 | except: 42 | pass 43 | 44 | 45 | 46 | 47 | b = os.listdir("/usr/sbin") 48 | 49 | for bin in b: 50 | pth2 = "/usr/sbin/%s" % bin 51 | try: 52 | if os.access(pth2, os.R_OK): 53 | y = subprocess.getstatusoutput('codesign --display --verbose "%s"' % pth2) 54 | if (('flags' in y[1]) and ('runtime' in y[1])): 55 | print("\033[92m[+] Hardened runtime enabled in: %s\033[0m" % pth2) 56 | elif (('flags' in y[1]) and ('runtime' not in y[1])): 57 | print("\033[33m[-] Hardened runtime NOT enabled in: %s\033[0m" % pth2) 58 | else: 59 | pass 60 | except: 61 | pass 62 | 63 | 64 | 65 | 66 | a = os.listdir("/usr/bin") 67 | 68 | for file in a: 69 | pth3 = "/usr/bin/%s" % file 70 | try: 71 | q = subprocess.getstatusoutput('codesign --display --verbose "%s"' % pth3) 72 | if (('flags' in q[1]) and ('runtime' in q[1])): 73 | print("\033[92m[+] Hardened runtime enabled in: %s\033[0m" % pth3) 74 | elif (('flags' in q[1]) and ('runtime' not in q[1])): 75 | print("\033[33m[-] Hardened runtime NOT enabled in: %s\033[0m" % pth3) 76 | else: 77 | pass 78 | except: 79 | pass 80 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Entitlement AND Hardened Runtime Check 2 | Wrapper around the codesign binary to recursively check installed apps for problematic entitlements and for whether or not Hardened Runtime is enabled. 3 | 4 | The following entitlements are checked currently: 5 | 6 | - com.apple.security.cs.disable-library-validation 7 | - com.apple.security.cs-allow-dyld-environment-variables 8 | - com.apple.security.get-task-allow 9 | - com.apple.security.cs.allow-unsigned-executable-memory 10 | - com.apple.security.files.downlaods.read-only 11 | - com.apple.security.files.downloads.read-write 12 | - com.apple.security.files.all (deprecated...but you never know...) 13 | - com.apple.security.files.user-selected.read-only 14 | - com.apple.security.files.user-selected.read-write 15 | - com.apple.private.security.clear-library-validation 16 | - com.apple.private.tcc.allow 17 | 18 | **NOTE: It is possible that an app can have one or more of the entitlements above while also having hardened runtime enabled (which may mitigate the attack path for abusing the entitlement in question). To check specifically for hardened runtime, run the command below and search for flags in the output:** 19 | 20 | 21 | 22 | For Hardened Runtime checks, my script runs the command below and filters based on output: 23 | 24 | `codesign --display --verbose /Applications/[name]/Contents/MacOS/[name]` 25 | 26 | 27 | The following directories are checked by both the Entitlements and Hardened Runtime Check Scripts: 28 | - /Applications 29 | - /System/Applications/Utilities 30 | - /usr/local/bin 31 | - /usr/bin 32 | - /usr/sbin 33 | 34 | ## Steps - To Run The Swift Versions: 35 | 36 | **Instructions:** 37 | 1. `EntitlementCheck.swift`: Wrapper around the codesign binary to search for apps/bins with potentially problematic entitlements. Swift version of my original python script at https://github.com/cedowens/EntitlementCheck. Steps: 38 | 39 | > swiftc -o EntitlementCheck EntitlementCheck.swift 40 | > 41 | > ./EntitlementCheck 42 | 43 | 2. `HardenedRuntimeCheck.swift`: Wrapper around the codesign binary to search for apps/bins without hardened runtime enabled. Swift version of my original python script at https://github.com/cedowens/EntitlementCheck. Steps: 44 | 45 | > swiftc -o HardenedRuntimeCheck HardenedRuntimeCheck.swift 46 | > 47 | > ./HardenedRuntimeCheck 48 | 49 | ## Steps - To Run The Python Versions: 50 | 51 | **Instructions:** 52 | 1. Entitlements Check: `chmod +x Entitlements_Check.py && ./Entitlements_Check.py ` OR `python3 Entitlements_Check.py ` 53 | 2. Hardened Runtime Check: `chmod +x Hardened_Runtime_Check.py && ./Hardened_Runtime_Check.py ` OR `python3 Hardened_Runtime_Check.py ` 54 | 3. results will be displayed to stdout. Can simply redirect to an output file as well (ex: `python3 Hardened_Runtime_Check.py > outfile.txt`) 55 | 56 | **you can use my Dylib Injection binary at https://github.com/cedowens/Inject_Dylib to validate/test potentially injectable apps found by these scripts** 57 | 58 | ## Sample Output 59 | Sample output from Entitlements_Check.py: 60 | ![Image](pic2.png) 61 | 62 | Sample output from Hardened_Runtime_Check.py: 63 | ![Image](pic3.png) 64 | -------------------------------------------------------------------------------- /pic2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedowens/EntitlementCheck/d702fb0b59e46b274de9471544f79c0cce50202c/pic2.png -------------------------------------------------------------------------------- /pic3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedowens/EntitlementCheck/d702fb0b59e46b274de9471544f79c0cce50202c/pic3.png --------------------------------------------------------------------------------