Skip to content

Instantly share code, notes, and snippets.

@dayglojesus
Created May 8, 2012 14:41
Show Gist options
  • Save dayglojesus/2635697 to your computer and use it in GitHub Desktop.
Save dayglojesus/2635697 to your computer and use it in GitHub Desktop.
Patch Lion HomeDirMechanism Format Strings with Null Bytes and Purge Security Logs
#!/usr/bin/ruby
# This code comes with no guarantees and it is not a "fix", just a workaround.
# It would be trivial to replace the patched file and restore these debugging messages.
# Also, this script modifies a Mac OS X System file, so...
require 'etc'
require 'fileutils'
require 'syslog'
@log = Syslog.open('patchhomedirmech')
@target = '/System/Library/CoreServices/SecurityAgentPlugins/HomeDirMechanism.bundle/Contents/MacOS/HomeDirMechanism'
@backup_file = '/private/var/root/HomeDirMechanism.backup'
@newfile_path = '/private/var/root/HomeDirMechanism.new'
def our_rescue(msg)
@log.notice(msg)
@log.close
exit 1
end
#####################################################################
# => MAIN
#####################################################################
# Check UID (must be root)
unless Process.euid == 0
raise "You must be root to execute this script."
end
begin
@log.notice("Backing up file: #{@target}")
FileUtils.cp(@target, @backup_file)
rescue => e
our_rescue("Error backing up file: #{e.message}")
end
@debug_strings = `/usr/bin/strings #{@target} | /usr/bin/grep "password.* = %s" 2> /dev/null`
if @debug_strings
@debug_strings = @debug_strings.split("\n")
else
our_rescue("Nothing to patch: target does not contain any relevant debugging strings")
end
begin
@file = File.read(@target)
@newfile = File.new(@newfile_path, 'w')
rescue => e
our_rescue("Error loading file: #{e.message}")
end
begin
@log.notice("Patching file: #{@newfile_path}")
@debug_strings.each do |string|
len = string.length
replacement = ''
len.times { replacement << "\000" }
@file.gsub!(string, replacement)
end
@newfile << @file
@newfile.flush
@newfile.close
rescue => e
our_rescue("Error patching file: #{e.message}")
end
begin
@log.notice("Replacing file: #{@target}")
FileUtils.rm_rf(@target)
FileUtils.move(@newfile_path, @target)
rescue => e
our_rescue("Error replacing file: #{e.message}")
end
begin
@log.notice("Nullfying security logs...")
raise unless system("cat /dev/null > /var/log/secure.log")
@log.notice("Removing archived security logs...")
logs = Dir.glob("/private/var/log/secure*.bz2")
logs.each { |log| FileUtils.rm(log) }
rescue => e
our_rescue("Error deleting log(s): #{e.message}")
end
@log.notice("Done.")
@log.close
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment