krypted.com

Tiny Deathstars of Foulness

There’s a macOS tool called AssetCacheLocatorUtil located at /usr/bin/AssetCacheLocatorUtil. The output is in… stderr. Because stderr is so fun to work with (note that sed -i only works with stdin). So, to update the caching server(s) you are using and only print the IP address of those, you’d do the following:

/usr/bin/AssetCacheLocatorUtil 2>&1 | grep guid | awk '{print$4}' | sed 's/^\(.*\):.*$/\1/' | uniq

If you use Jamf Pro and would like to use this as an extension attribute, that’s posted here: https://github.com/krypted/cachecheck. I didn’t do any of the if/then there, as I’d usually just do that on the JSS.

April 17th, 2017

Posted In: Mac OS X, Mac Security, Mass Deployment, Network Infrastructure, precache

Tags: , , , , , , , , , ,

Leave a Comment

I recently had an issue where QuickLook was crashing every time I clicked on certain file types. I thought they were unsupported by QuickLook. But it turns out that they were animated and trying to start while the QuickLook animation was starting. So disable the QuickLook animation and the files appeared as intended. To do so, write a key called QLPanelAnimationDuration into the global defaults database, with a -float value of 0, as follows:

defaults write -g QLPanelAnimationDuration -float 0

April 16th, 2017

Posted In: Mac OS X

Tags: , ,

Leave a Comment

The xxd is a bash command in Linux and macOS that is used to take a hexdump (convert a string to hex), or convert hex back to a string. To use xxd, just call it with a couple of options. Below, we’ll use the -p option to export into plain hexdump, and we’ll quote it and the <<< is to take input rather than a file name to convert (the default behavior), as follows:

xxd -p <<< "hey it's a string"

The output would be a hex string, as follows:

6865792069742773206120737472696e670a

Then use the -r option to revert your hex back to text. Since xxd doesn’t allow for a positional parameter to revert, we’ll simply echo the hex string and pipe it back into xxd, as follows:

echo 6865792069742773206120737472696e670a | xxd -r -p

And the output would be (is):

hey it's a string

Other useful options:

  • -b: Perform a binary dump instead of a hex dump
  • -e: what it looks like when a little endian takes a hex dump
  • -h: get help with the command
  • -len: stop after the defined number of characters
  • -u: use uppercase in the hex, instead of the default lower-case (doesn’t seem to actually work on macOS)
  • -v: grab the version of xxd

April 2nd, 2017

Posted In: Mac OS X, Mac OS X Server, Mac Security, Ubuntu, Unix

Tags: , , , , , ,

This is the first page of a 5 page piece I just finished writing for MacTech. After the last episode of the MacAdmins podcast though, I wanted to go ahead and get some of the information out there. For a much more detailed analysis, check out MacTech!

Apple has a number of different logging APIs. For the past few releases, Apple has tried to capture everything possible in logs, creating what many administrators and developers might consider to be a lot of chatter. As such, an entirely new interface needed to be developed to categorize and filter messages sent into system logs.

Writing Logs

The logger command is still used to create entries in system logs. However, if you are then using tail to view /var/log/system.log then you will notice that you no longer see your entry being written. This is because as the logs being created in macOS have gotten more complex, the tools to read and write those logs has gotten more complicated as well.

Let’s take a simple log entry. Below, we’ll write the string “Hello Logs” into the system log. To do so, use the –i option to put the process id of the logger process and –s to write to the system log, as well as to stderr. To make the entry easier we’ll tag it with –t followed by the string of the tag. And finally, we’ll quote the entry we want written into the log. This is basically the simplest form of an entry:

logger -is -t krypted "Hello Logs"

Once written, use the log command to read your spiffy new entries. This isn’t terribly different than how things worked previously. If you’re a developer, you will need to note that all of the legacy APIs you might be using, which include asl_log_message, NSLog, and syslog, have been redirected to the new Unified Logging system, provided you build software for 10.12 (you can still build as before for 10.11, iOS 9, tvOS 10, and watchOS 3 and below). These are replaced with the os_log, os_log_info, os_log_debug, os_log_error, os_log_fault, and os_log_create APIs (which correspond to various levels of logs that are written).

Reading Logs

Logs are now stored in the tracev3 formatted files in /var/db/diagnostics, which is a compressed binary format. As with all binary files, you’ll need new tools to read the files. Console has been updated with a new hierarchical capability and the ability to watch activities, subsystems, etc.

The log command provides another means of reading those spiffy new logs. To get started, first check out the man page:

man log

That “Hello Logs” string we used earlier is part of a message that you can easily view using the ‘log show’ command. In the below example, we’ll just run a scan of the last 3 minutes, using the –last option, and then providing a –predicate. We’ll explain those a bit later, but think of it as query parameters – here, we’ll specify to look for “Hello Logs” in eventMessage:

log show --predicate 'eventMessage contains "Hello Logs"' --last 3m

Filtering the log data using “eventMessage CONTAINS “Hello Logs”” shows us that our entry appears as follows:

Timestamp                       Thread     Type        Activity             PID

2017-03-23 23:51:05.236542-0500 0x4b83bb   Default     0x0                  88294  logger: Hello Logs

——————————————————————————————————————–

Log      – Default:          1, Info:                0, Debug:             0, Error:          0, Fault:          0

Activity – Create:           0, Transition:          0, Actions:           0

March 26th, 2017

Posted In: Mac OS X, Mac OS X Server

Tags: , , , , , ,

The next release of iOS (10.3), macOS (10.12.4), and tvOS (10.2) bring us a host of new management features. These include DEP configuration, remote wipe, single app mode, conference room mode, and remote reboot for Apple TVs. The next evolution of iOS brings us sounds in lost mode, the ability to prevent users from connecting to unmanaged wireless networks (just make sure to push that policy after sending down the actual managed wireless networks – or eek), the option to remotely shut down and reboot devices,

The Mac options includes some of the above but also restricting the feature to unlock macOS devices with Touch ID, restrict documents and desktop syncing with Apple’s iCloud service. Shared iPad environments also get new passcode policies.

Jamf Pro 9.98 has also comes with Symantec PKI integration and lots, and lots, and lots of resolutions to product issues. For more, see https://www.jamf.com/blog/are-you-ready-for-apples-next-release/. For a full run-down of profile options and MDM commands: http://docs.jamf.com/9.98/casper-suite/release-notes/What’s_New_in_This_Release.html.

Keeping with Apple’s evolving standards, Managed Preferences and Provisioning Profiles are being deprecated: http://docs.jamf.com/9.98/casper-suite/release-notes/Deprecations_and_Removals.html (which isn’t to say you can’t still deploy these kinds of things using your own scripts, etc).

Finally, if you have a problem in your environment and want to see if it’s been fixed, for a list of defects and product improvements – see http://docs.jamf.com/9.98/casper-suite/release-notes/Bug_Fixes_and_Enhancements.html

March 23rd, 2017

Posted In: JAMF, Mac OS X, Mac OS X Server

Tags: , , , ,

You search for items in macOS using compound conditions in a number of ways. One way is with awk. Here, we’re going to grab the output of a simple ls command. That gets piped into an awk statement. Then we’re going to look at the expression to evaluate. Basically, we’re going to say anything that contains com. as well as apple and .plist. Because it’s ls, we’re looking for names of files that match those patterns. Each pattern is listed in brackets. And then there’s the {print} to lay out the action of printing to the files that match the pattern to the screen:

ls |awk '/[com.][apple][.plist]/ {print}'

Note: I know you’re not supposed to use ls in scripts. Don’t care. If it were dates and such, I’d of used stat…

March 14th, 2017

Posted In: Mac OS X, Mac OS X Server

Tags: , , , ,

If you happen to be tweaking the macOS subsystems for logging, I’ve put them into a little python class. If you need it, find it at this gist:

https://gist.github.com/krypted/495e48a995b2c08d25dc4f67358d1983

Could use an array of all the levels, TTLs, and options. But I’ll get to that when I get some time. If this is all you need, though:

class Logging(object):

__name__ = 'logger.info(1)'
plist = '/System/Library/Preferences/Logging/Subsystems/'

def __init__(__name__, plist, *args, **kwargs):
super(getLogger/, self).__init__()

logger.info('Input parameters:\n'
'accessibility: "{com.apple.Accessibility.plist}"\n'
'StandaloneHIDFudPlugins: "{com.apple.StandaloneHIDFudPlugins.plist}"\n'
'duetactivityscheduler: "{com.apple.duetactivityscheduler.plist}"\n'
'passkit: "{com.apple.passkit.plist}"\n'
'AppKit: "{com.apple.AppKit.plist}"\n'
'SystemConfiguration: "{com.apple.SystemConfiguration.plist}"\n'
'eapol: "{com.apple.eapol.plist}"\n'
'persona: "{com.apple.persona.plist}"\n'
'AppleIR: "{com.apple.AppleIR.plist}"\n'
'TCC: "{com.apple.TCC.plist}"\n'
'icloudpreferences: "{com.apple.icloudpreferences.plist}"\n'
'apple.pf: "{com.apple.pf.plist}"\n'
'AssetCache: "{com.apple.AssetCache.plist}"\n'
'TimeMachine: "{com.apple.TimeMachine.plist}"\n'
'internetAccounts: "{com.apple.internetAccounts.plist}"\n'
'photoanalysisd.graph: "{com.apple.photoanalysisd.graph.plist}"\n'
'AssetCacheServices: "{com.apple.AssetCacheServices.plist}"\n'
'Transport: "{com.apple.Transport.plist}"\n'
'libsqlite3: "{com.apple.libsqlite3.plist}"\n'
'photoanalysisd.job: "{com.apple.photoanalysisd.job.plist}"\n'
'BezelServices: "{com.apple.BezelServices.plist}"\n'
'accounts: "{com.apple.accounts.plist}"\n'
'locationd.Core: "{com.apple.locationd.Core.plist}"\n'
'photoanalysisd: "{com.apple.photoanalysisd.plist}"\n'
'DesktopServices: "{com.apple.DesktopServices.plist}"\n'
'amp.MediaServices: "{com.apple.amp.MediaServices.plist}"\n'
'locationd.Legacy: "{com.apple.locationd.Legacy.plist}"\n'
'pluginkit: "{com.apple.pluginkit.plist}"\n'
'ExchangeWebServices: "{com.apple.ExchangeWebServices.plist}"\n'
'authkit: "{com.apple.authkit.plist}"\n'
'locationd.Motion: "{com.apple.locationd.Motion.plist}"\n'
'sandbox.reporting: "{com.apple.sandbox.reporting.plist}"\n'
'FaceTime: "{com.apple.FaceTime.plist}"\n'
'avfaudio: "{com.apple.avfaudio.plist}"\n'
'locationd.Position: "{com.apple.locationd.Position.plist}"\n'
'sbd: "{com.apple.sbd.plist}"\n'
'Finder: "{com.apple.Finder.plist}"\n'
'awd.awdd: "{com.apple.awd.awdd.plist}"\n'
'locationd.Utility: "{com.apple.locationd.Utility.plist}"\n'
'securityd: "{com.apple.securityd.plist}"\n'
'HTTPServer: "{com.apple.HTTPServer.plist}"\n'
'awd.framework: "{com.apple.awd.framework.plist}"\n'
'mDNSResponder: "{com.apple.mDNSResponder.plist}"\n'
'sharing: "{com.apple.sharing.plist}"\n'
'IDS: "{com.apple.IDS.plist}"\n'
'bluetooth: "{com.apple.bluetooth.plist}"\n'
'mac.install: "{com.apple.mac.install.plist}"\n'
'siri: "{com.apple.siri.plist}"\n'
'IPConfiguration: "{com.apple.IPConfiguration.plist}"\n'
'calendar: "{com.apple.calendar.plist}"\n'
'mail: "{com.apple.mail.plist}"\n'
'social: "{com.apple.social.plist}"\n'
'ManagedClient: "{com.apple.ManagedClient.plist}"\n'
'captive: "{com.apple.captive.plist}"\n'
'mediaremote: "{com.apple.mediaremote.plist}"\n'
'socialpushagent: "{com.apple.socialpushagent.plist}"\n'
'Messages: "{com.apple.Messages.plist}"\n'
'catalyst: "{com.apple.catalyst.plist}"\n'
'multipeerconnectivity: "{com.apple.multipeerconnectivity.plist}"\n'
'symptomsd: "{com.apple.symptomsd.plist}"\n'
'MessagesEvents: "{com.apple.MessagesEvents.plist}"\n'
'cdp: "{com.apple.cdp.plist}"\n'
'network: "{com.apple.network.plist}"\n'
'syncdefaults: "{com.apple.syncdefaults.plist}"\n'
'NetworkSharing: "{com.apple.NetworkSharing.plist}"\n'
'clouddocs: "{com.apple.clouddocs.plist}"\n'
'networkextension: "{com.apple.networkextension.plist}"\n'
'useractivity: "{com.apple.useractivity.plist}"\n'
'ProtectedCloudStorage: "{com.apple.ProtectedCloudStorage.plist}"\n'
'coreanimation: "{com.apple.coreanimation.plist}"\n'
'networkserviceproxy: "{com.apple.networkserviceproxy.plist}"\n'
'Registration: "{com.apple.Registration.plist}"\n'
'coreaudio: "{com.apple.coreaudio.plist}"\n'
'nlcd: "{com.apple.nlcd.plist}"\n'
'SkyLight: "{com.apple.SkyLight.plist}"\n'
'coredata: "{com.apple.coredata.plist}"\n'
'notes: "{com.apple.notes.plist}"\n'

try:
plist()
except Exception as e:
logger.error(e)

March 13th, 2017

Posted In: Mac OS X

Tags: , , , , , , , ,

You can quickly and easily back up your Filewave databases using the fwcontrol command to stop a Filewave server (thus preserving the integrity of the data you are backing up) and then backing up the database using the /fwxserver directory.

To get started, we’ll first down the server. This is done using the fwcontrol command along with the server option and the stop verb, as follows:

sudo fwcontrol server stop

Now that there won’t be data trying to commit into the database, let’s make a backup of the database directory using the cp command:

cp -rp /fwxserver/DB ~/Desktop/Databasebak

To start the database, use the decontrol command with the server option and the start verb, as follows:

fwcontrol server start

Note, if you will be moving to a new Filewave server, you would want to lock clients during this transition, so before restarting your server, use the sqlite3 command to set the status to 1 in the user table:

sqlite3 /fwxserver/DB/server.sqlite 'update user set status = 1;'

February 15th, 2017

Posted In: Mac OS X, Mac OS X Server, Mac Security, Network Infrastructure

Tags: ,

So I comment a lot of lines out in my /etc/hosts file. This usually means that I end up with a lot of cruft at the top of my file. And while I write comments into files and scripts here and there, I don’t always want to see them. So I can grep them out by piping the output of the file to grep as follows:

cat /etc/hosts | grep -v "^#"

You could also do the same, eliminating all lines that start with a “v” instead:

cat !$ | grep -v "^v"

February 13th, 2017

Posted In: Mac OS X, Unix

Tags: , , , , , ,

The “What’s New in macOS” page for Sierra (10.12) lays out a little known change that a colleague at Jamf was working on the other day (hat tip to Brock):

Starting in macOS 10.12, you can no longer provide external code or data alongside your code-signed app in a zip archive or unsigned disk image. An app distributed outside the Mac App Store runs from a randomized path when it is launched and so cannot access such external resources. To provide secure execution, code sign your disk image itself using the codesign tool, or distribute your app through the Mac App Store. For more information, see the updated revision to macOS Code Signing In Depth.

This is further explained in the equally misnamed “OS X Code Signing In Depth“:

If using a disk image to ship an app, users should drag the app from the image to its desired installation location (usually /Applications) before launching it. This also applies to apps installed via ZIP or other archive formats or apps downloaded to the Downloads directory: ask the user to drag the app to /Applications and launch it from there.

This practice avoids an attack where a validly signed app launched from a disk image, ZIP archive, or ISO (CD/DVD) image can load malicious code or content from untrusted locations on the same image or archive. Starting with macOS Sierra, running a newly-downloaded app from a disk image, archive, or the Downloads directory will cause Gatekeeper to isolate that app at a unspecified read-only location in the filesystem. This will prevent the app from accessing code or content using relative paths.

The gist is, if an app isn’t signed via the Mac App Store, Gatekeeper is going to limit the ability of the app to launch via “Gatekeeper Path Randomization.” Basically, treat an app from a mounted drive as if it were coming from a Safari download. There are a few ways to distribute app bundles or binaries that do not violate this. One is to sign a disk image that contains such an app:

spctl -a -t open --context context:primary-signature -v /Volumes/MyApp/MyApp.dmg

If spctl runs properly, you should see the following:

/Volumes/MyApp/MyAppImage.dmg: accepted source=mydeveloperid

In the above spctl command, we use the following options:

  • -a assesses the file you indicate (basically required for this operation)
  • -t allows me to specify a type of execution to allow, in this case it’s ‘open’
  • –context
  • -v run verbosely so I can build error correction into any scripts
  • –status while I don’t use status, I could do a second operation to validate that the first worked and use the status option to check it
  • –remove I also don’t use remove, but I could undo what I just did by doing so (or just deleting the dmg

For more on managing Gatekeeper from the command line, see http://krypted.com/mac-security/manage-gatekeeper-from-the-command-line-in-mountain-lion/.

Another method is to remove the lsquarantine attribute, which is automagically applied, using xattr as follows:

xattr -r -d com.apple.quarantine /Volumes/MyApp/MyAppImage.app

The options in the above use of the xattr command:

  • -r run recursively so we catch binaries inside the app bundle
  • -d delete the com.apple.quarantine bit

Xattr has a lot of different uses; you can programmatically manage Finder tags with it, http://krypted.com/mac-os-x/command-line-finder-tags/. To see the full xattr dump on a given file, use the -l option as follows:

xattr -l com.apple.quarantine MyAppImage.dmg

The output is as follows:

xattr: No such file: com.apple.quarantine
MyAppImage.dmg: com.apple.metadata:kMDItemDownloadedDate:
00000000 62 70 6C 69 73 74 30 30 A1 01 33 41 BE 31 0B A5 |bplist00..3A.1..|
00000010 70 D4 56 08 0A 00 00 00 00 00 00 01 01 00 00 00 |p.V………….|
00000020 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 |…………….|
00000030 00 00 00 00 13 |…..|
00000035
MyAppImage.dmg: com.apple.metadata:kMDItemWhereFroms:
00000000 62 70 6C 69 73 74 30 30 A1 01 5F 10 22 63 69 64 |bplist00.._.”cid|
00000010 3A 69 6D 61 67 65 30 30 31 2E 70 6E 67 40 30 31 |:myappimage.dmg@01|
00000020 44 32 36 46 46 44 2E 35 37 31 30 37 30 46 30 08 |D26FFD.571070F0.|
00000030 0A 00 00 00 00 00 00 01 01 00 00 00 00 00 00 00 |…………….|
00000040 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |…………….|
00000050 2F |/|
00000051

This could be helpful when troubleshooting and/or scripting (or just way too much informations!).

Finally, if you’re an application developer, check out new API for App Translocation in the 10.12 SDK for <Security/SecTranslocate.h>  I guess one way to think of this is… Apple doesn’t want you running software this way any more. And traditionally they lock things down further, not less, so probably best to find alternatives to running apps out of images, from a strategy standpoint.

January 25th, 2017

Posted In: Mac OS X, Mac Security

Tags: , , , , ,

Next Page »