Register FAQ / Rules Forum Spy Search Today's Posts Mark Forums Read
Go Back   MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Apr 6, 2012, 04:40 PM   #1
mhoward84
macrumors newbie
 
Join Date: May 2011
Terminal variable set from 'defaults' command

Hi, I am trying to write the standard output of the defaults command to a variable. When I do the following
VAR1=$( defaults read ~/.MacOSX/environment/DYLD_INSERT_LIBRARIES )

then

echo $VAR1

I simply get a blank line then the command prompt. I also can't redirect the output to a document.

Is there any way to do this with this command? Thanks in advance
mhoward84 is offline   0 Reply With Quote
Old Apr 6, 2012, 06:27 PM   #2
chown33
macrumors 603
 
Join Date: Aug 2009
Break It Down. The problem may not be what you think it is.

First, check that your syntax is correct for the inner command:
Code:
defaults read ~/.MacOSX/environment/DYLD_INSERT_LIBRARIES
If you just paste that into a Terminal window, what is the output? Post it, please, including any error messages.

If the output isn't what you expect, please describe what you expected, and how you decided that the posted defaults command-line is what should work.

Also describe exactly what you're trying to do. If you're trying to read the environment.plist file, looking for a DYLD_INSERT_LIBRARIES entry, perhaps related to the Flashback trojan, then please say that's what you're trying to do. Because if that's what you're trying to do, your syntax is wrong. You should start by reading the man page for the defaults command. You might also read about PListBuddy (google it).

EDIT
Article with correct examples of defaults commands:
http://arstechnica.com/apple/news/20...-infection.ars

Last edited by chown33; Apr 6, 2012 at 06:48 PM.
chown33 is offline   0 Reply With Quote
Old Apr 7, 2012, 04:12 PM   #3
mhoward84
Thread Starter
macrumors newbie
 
Join Date: May 2011
Thanks for the response chown.
I want to build a script that I can distribute to customers that will examine the results of this command and the other 2 and verify that the trojan isn't installed.

Upon further examination it appears it might just be easier to download someone else's script and distribute it or use some of their script to construct my own.
mhoward84 is offline   0 Reply With Quote
Old Apr 7, 2012, 04:38 PM   #4
subsonix
macrumors 68030
 
Join Date: Feb 2008
Quote:
Originally Posted by mhoward84 View Post
Upon further examination it appears it might just be easier to download someone else's script and distribute it or use some of their script to construct my own.
defaults writes to stderr, you need to direct it to stdout. It might also make sense to pipe it to: grep -E "( does not exist)$" or something before you assign it to a variable, also use meaningful names for variables.

Code:
DYLD=$(defaults read ~/.MacOSX/environment DYLD_INSERT_LIBRARIES 2>&1 | grep -E "( does not exist)$")
# similar for the other tests

if [ -n "$DYLD" ] && [ -n "$SAFARI" ] && [ -n "$FIREFOX" ]
then
    echo "ok"
else
    echo "Oh noes!"
fi
Edit: I have not tested this on a machine that has this trojan, keep that in mind. It might actually be better to do it manually to be sure instead of taking the risk of a false positive or worse, a false negative.

Last edited by subsonix; Apr 7, 2012 at 08:03 PM. Reason: fixed
subsonix is offline   0 Reply With Quote
Old Apr 7, 2012, 05:53 PM   #5
chown33
macrumors 603
 
Join Date: Aug 2009
Quote:
Originally Posted by subsonix View Post
defaults writes to stderr, you need to direct it to stdout.
It does write to stdout, when invoked correctly, on a plist value that exists, in a plist or domain that exists.

If invoked incorrectly, or on a plist file or domain that doesn't exist, or with a key that doesn't exist, the stdout stream contains no bytes.

It only writes error messages to stderr, like many other Unix/Posix commands. In this design, the fact that nothing is written to stdout is intended to mean "no such thing", usually coupled with a non-zero exit status (shell: $?).

For example, if the cat command is invoked to cat a file that doesn't exist, the stdout stream gets no bytes, the stderr stream gets an error message, and cat's exit status is not-success (i.e. non-zero).

Try these:
Code:
defaults read com.apple.TextEdit; echo $?
defaults read com.apple.TextEdit WidthInChars; echo $?
defaults read com.apple.TextEdit ExplodingPenguin; echo $?


----------

Quote:
Originally Posted by mhoward84 View Post
Upon further examination it appears it might just be easier to download someone else's script and distribute it or use some of their script to construct my own.
This seems like a good idea, especially if you're not extremely familiar with writing shell scripts that need to deal with error conditions.
chown33 is offline   0 Reply With Quote
Old Apr 7, 2012, 06:14 PM   #6
subsonix
macrumors 68030
 
Join Date: Feb 2008
Quote:
Originally Posted by chown33 View Post
It does write to stdout, when invoked correctly, on a plist value that exists, in a plist or domain that exists.

If invoked incorrectly, or on a plist file or domain that doesn't exist, or with a key that doesn't exist, the stdout stream contains no bytes.

It only writes error messages to stderr, like many other Unix/Posix commands.
Right, but in this case the idea is to catch the case where a plist does not exist so stderr needs to be redirected to assign it to the variable. The non existence of these plist files is the only case we know about. Likewise for the removal, a script can't be made by the information posted by Fsecure since the exact output is not known.
subsonix is offline   0 Reply With Quote
Old Apr 7, 2012, 06:44 PM   #7
subsonix
macrumors 68030
 
Join Date: Feb 2008
Quote:
Originally Posted by chown33 View Post
This seems like a good idea, especially if you're not extremely familiar with writing shell scripts that need to deal with error conditions.
Really? If you are not capable of writing it, how are you going to assess that the script you are using is correct? The best is to follow the exact instructions given by Fsecure.
subsonix is offline   0 Reply With Quote
Old Apr 7, 2012, 07:20 PM   #8
chown33
macrumors 603
 
Join Date: Aug 2009
Quote:
Originally Posted by subsonix View Post
Right, but in this case the idea is to catch the case where a plist does not exist so stderr needs to be redirected to assign it to the variable. The non existence of these plist files is the only case we know about.
I'm not following your logic.

If you didn't redirect and grep the stderr stream, the value assigned to the variable is "" (empty string). How is that not a definitive indicator that there is either no such file, or no such key?

It's conceivable that the file does exist, and the key exists with a value of "" (empty string), and this would not be a uniquely detectable condition. I'm not seeing how it's harmful, though, since it means DYLD_INSERT_LIBRARIES is defined to be the empty string. How is that harmful?


If it were strictly necessary to detect "no such file or no such key", then checking the exit status of 'defaults' is simpler:
Code:
example=$(defaults read ~/.MacOSX/environment DYLD_INSERT_LIBRARIES 2>/dev/null || echo "###")
If defaults has any non-zero exit status (i.e. no such file or no such key), then example will be assigned the string "###" (any other distinctive string would suffice). It's not necessary to parse the stderr messages looking for a grep pattern. Using the exit status of defaults is sufficient in this case.

I also see that your example is still using the wrong syntax for defaults [1]. So it will behave as if the file and/or key doesn't exist, producing a false negative.


Quote:
Likewise for the removal, a script can't be made by the information posted by Fsecure since the exact output is not known.
It is entirely possible to script the "use the path retrieved from the plist" procedure using PListBuddy. It's also possible using defaults and awk. I'm not going to suggest it's trivial, or even simple (as such scripts go). It is, however, quite possible to get the value assigned to DYLD_INSERT_LIBRARIES and do something with that pathname.

I surmise that Fsecure simply isn't interested in producing a free solution, since they explicitly say that non-advanced users should contact their support.

There may even be a better choice of scripting language than bash. Perhaps python or perl.

Personally, I'm not going to spend a lot of time on it, because none of the Mac users I know personally have this infection, and the ones I talked to recently are well aware of how to avoid it.


[1] according to this Fsecure web page and this one.

----------

Quote:
Originally Posted by subsonix View Post
Really? If you are not capable of writing it, how are you going to assess that the script you are using is correct? The best is to follow the exact instructions given by Fsecure.
You're right, I rescind my suggestion.

The best strategy is to not compound one mistake with another, and to not trust scripts posted from unknown sources, no matter how good they might look at first glance.
chown33 is offline   0 Reply With Quote
Old Apr 7, 2012, 07:33 PM   #9
subsonix
macrumors 68030
 
Join Date: Feb 2008
Quote:
Originally Posted by chown33 View Post
I'm not following your logic.

If you didn't redirect and grep the stderr stream, the value assigned to the variable is "" (empty string). How is that not a definitive indicator that there is either no such file, or no such key?

It's conceivable that the file does exist, and the key exists with a value of "" (empty string), and this would not be a uniquely detectable condition. I'm not seeing how it's harmful, though, since it means DYLD_INSERT_LIBRARIES is defined to be the empty string. How is that harmful?
Calm down, I'm using an example that fits the code in post 1 and explicitly test the condition posted by Fsecure.

Quote:
Originally Posted by chown33 View Post
If it were strictly necessary to detect "no such file or no such key", then checking the exit status of 'defaults' is simpler:
Code:
example=$(defaults read ~/.MacOSX/environment DYLD_INSERT_LIBRARIES 2>/dev/null || echo "###")
If defaults has any non-zero exit status (i.e. no such file or no such key), then example will be assigned the string "###" (any other distinctive string would suffice). It's not necessary to parse the stderr messages looking for a grep pattern. Using the exit status of defaults is sufficient in this case.
Technically correct, and you could come up with 5 or more different ways of doing it, the point was to replicate what was known exactly.

Quote:
Originally Posted by chown33 View Post
I also see that your example is still using the wrong syntax for defaults [1]. So it will behave as if the file and/or key doesn't exist, producing a false negative.
Yeah that's correct I simply copy pasted it from the first post.

Quote:
Originally Posted by chown33 View Post
It is entirely possible to script the "use the path retrieved from the plist" procedure using PListBuddy. It's also possible using defaults and awk. I'm not going to suggest it's trivial, or even simple (as such scripts go). It is, however, quite possible to get the value assigned to DYLD_INSERT_LIBRARIES and do something with that pathname.

I surmise that Fsecure simply isn't interested in producing a free solution, since they explicitly say that non-advanced users should contact their support.

There may even be a better choice of scripting language than bash. Perhaps python or perl.

Personally, I'm not going to spend a lot of time on it, because none of the Mac users I know personally have this infection, and the ones I talked to recently are well aware of how to avoid it.
Golf clap.
subsonix is offline   0 Reply With Quote
Old Apr 7, 2012, 07:57 PM   #10
chown33
macrumors 603
 
Join Date: Aug 2009
Quote:
Originally Posted by subsonix View Post
Yeah that's correct I simply copy pasted it from the first post.
Except you lost the ~.

OP:
Code:
VAR1=$( defaults read ~/.MacOSX/environment/DYLD_INSERT_LIBRARIES )
Your revised code:
Code:
DYLD=$(defaults read /.MacOSX/environment DYLD_INSERT_LIBRARIES 2>&1 | grep -E "( does not exist)$")
chown33 is offline   0 Reply With Quote
Old Apr 7, 2012, 08:05 PM   #11
subsonix
macrumors 68030
 
Join Date: Feb 2008
Quote:
Originally Posted by chown33 View Post
Except you lost the ~.
Thanks.

You almost never post code.
subsonix is offline   0 Reply With Quote
Old Apr 9, 2012, 01:16 PM   #12
chown33
macrumors 603
 
Join Date: Aug 2009
Source for an Objective-C app that checks for infection:
https://github.com/jils/FlashbackChecker
(For OS version 10.5 and up)

Via this article on Ars Technica.


I wonder how many of the affected Macs are running an OS and Java version so old they can't be updated? Or on hardware so old they can't be updated?

If they're not updatable, this malware is a persistent threat to those machines. The only easy prevention mechanism would be the "disable Java" checkbox in Safari's security preferences window.
chown33 is offline   0 Reply With Quote
Old Apr 9, 2012, 02:25 PM   #13
subsonix
macrumors 68030
 
Join Date: Feb 2008
Quote:
Originally Posted by chown33 View Post
I wonder how many of the affected Macs are running an OS and Java version so old they can't be updated? Or on hardware so old they can't be updated?
Turning off Java in the browser should take care of that. I have had it turned off for several years without noticing any difference, I can probably count the instances on one hand where it had to be turned on explicitly for some reason.

Last edited by subsonix; Apr 9, 2012 at 02:32 PM. Reason: hand
subsonix is offline   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Similar Threads
thread Thread Starter Forum Replies Last Post
How to set defaults for default operating system? ugr Windows, Linux & Others on the Mac 1 Mar 4, 2014 07:39 PM
Terminal Command to Set File Permissions SahtuDEC Mac OS X Server, Xserve, and Networking 3 Feb 28, 2014 12:24 AM
Defaults -- FocusFollowsMouse for terminal mac2x OS X Mavericks (10.9) 4 Dec 15, 2013 11:25 PM
Defaults write not working? (editing trackpad PLIST in Terminal) changes don't apply Ancandis OS X 0 Oct 8, 2013 02:47 AM
How to set environmental variable? hajime Mac Basics and Help 3 Sep 28, 2013 09:33 PM

Forum Jump

All times are GMT -5. The time now is 07:35 PM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC