Blog Archives

Browsers’ anti-phishing protections easily defeated


While troubleshooting a user’s mac the other day, I happened to come across a curious line in one of the logs:

Screen Shot 2018-06-11 at 16.28.05

After a bit of digging, it occurred to me that this and the other flags being sent in the process command were possibly Preferences or Settings in the Looking at chrome://settings/privacy revealed, of course, Google’s phishing and malware protection setting, ‘Protect you and your device from dangerous sites’.

Here it is set to ‘On’, which is the default setting:

Screen Shot 2018-06-11 at 16.31.28

A quick test proved that setting it to ‘Off’ produced the `—disable-client-side-phishing-detection’ flag in the browser’s process output. Setting it back to ’On’ and relaunching the browser produced no output, confirming my theory. 

Screen Shot 2018-06-11 at 16.40.39

A quick message to my user also confirmed that he wasn’t aware that phishing protection had been disabled, and to the best of his memory, had not been disabled by himself. 

A simple preference setting
That got me to wondering whether that setting could be turned off programmatically by another, possibly malicious, process. To my surprise, it turns out that it’s trivial to do so. 

All Chromium browsers have a Preferences file located in their Application Support folder. Usually this is within another folder called ‘Default’, but not always. Chrome and Vivaldi, for example, have it there, but Opera (and Opera Developer) store the Preferences file at the root level of their respective support folders. 

The file contains the setting for whether the Phishing protection should be enabled or not. To determine how the preference was encoded in the file, I made a copy of the current Preferences file, toggled the setting, then made another copy. BBEdit’s ‘Find Differences’ function quickly told me the name of the key (if you don’t have BBEdit, you can also use Xcode’s FileMerge to run diffs, though it isn’t as pretty or as full-featured):

Screen Shot 2018-06-11 at 16.56.36

Again, there are differences among browsers. As shown above, Opera uses the key “fraud_protection_enabled” which takes a boolean. Chrome and Vivaldi, on the other hand, use a “safebrowsing” key which takes an array of key-value pairs, with the first item of the array being the key “enabled:”, and taking a bool for its value, like this:





With this information, it’s a pretty simple thing for another process running under your username to write to the Preferences file and turn off the built-in protections. 

What about Safari?
Safari isn’t vulnerable to quite the same tactic as it doesn’t store its preferences in the same way. However, it’s even easier to defeat Safari’s ‘Warn when visiting a fraudulent website’ setting:

Screen Shot 2018-06-11 at 17.44.08

Apple hardened some of Safari’s preferences (like setting the Home page) some time ago to stop adware from making unauthorised changes, but this one is still unprotected in the current public release of macOS High Sierra. A one-liner in Terminal removes the preference:

defaults write WarnAboutFraudulentWebsites 0

Screen Shot 2018-06-11 at 18.04.48

What can you do?
The ease with which these protections can be surreptitiously turned off in all major browsers is a worry. And let’s face it, who would notice if this setting was quietly turned off? In both Chrome and Safari, the change takes effect immediately and does not even require a restart of the browser.

Fortunately, my shareware app DetectX Swift will warn you if browsing protection is off when you run a search and prompt you to turn it back on. To ensure that all insecure pages have been removed after turning the setting back on, DetectX Swift will continue to show the warning until you restart the browser and execute another search.

Screen Shot 2018-06-14 at 12.24.44

The protection covers all the browsers mentioned above. If you’re running some other browser and would like to know if it’s similarly vulnerable, drop a line in the Comments or contact Sqwarq Support and request support for your browser to be added.

Stay safe, folks! 😀


Featured pic: Nature by PichieArt

adware goes old school with cron job

I’ve been wondering for a while now why we see so much adware persisting with nothing much other than easily detected Launch Agents when there’s a variety of other methods available on macOS. Some of those require privileges, like this little known one, but others do not.

Thanks to a DetectX user’s quick reporting, I was able to spot a known offender making good use of the venerable old crontab routine. Set to run on the 4th minute, every second hour, the job fires an executable lurking in the user’s Application Support folder.

A quick look on Google’s VirusTotal confirms what we expected:

Although cron jobs are easy to spot if you go looking for them, this one would probably have stayed hidden away for a while longer if it hadn’t been for the speedy reporting of the user.

DetectX will now find this particular miscreant in its normal search routine, but if you want to check for others, run the Report a Problem to Sqwarq Support function in the Help menu. We’re happy to look through the logs that creates on your Desktop for you, or if you like delving into this kind of thing, check out the DetectX_Swift.Processes.txt file in the logs and search down for where it says ‘User Crontab’ as indicated in the screenshot at the top of this post. If you find anything there that you didn’t put in yourself, it warrants further investigation. Feel free to contact us at Sqwarq support if you need help with that.

Stay safe, folks! 🙂

What’s the difference between DetectX and DetectX Swift?

Since releasing DetectX Swift back in January, a lot of people have been asking me how the new ‘Swift’ version differs from the older one, aside from requiring 10.11 or higher (the original will run on 10.7 or higher).

Well sure, it’s written in Swift — and it’s much swifter, literally, but of course there’s a lot more to it than that.

I’ve finally had a spare moment to enumerate the feature list and create a comparison chart. Although the image above is essentially the same as the one you’ll see at the link address at the moment, there’s still a bunch of features to be added as we go through development of version 1. Thus, be sure to check the latest version of the chart to get the most up-to-date info.

Of course, if you have any questions drop me a comment below, or email me either at Sqwarq or here at Applehelpwriter.

Enjoy 🙂

Mac Media Player’s secret MacKeeper installer

Last week I added MacGo’s Mac Media to DetectX’s search definitions after finding that the installer was delivering MacKeeper on unsuspecting users. After a support call asking me whether the MacGo player itself was malicious, I decided to look into what was going on in a bit more detail.

Downloading the Mac Media Player from the developer’s site rewarded me with a DMG file called Macgo_Mac_Media_Player.dmg, and mounting that revealed the (pictured above).

Examining the package contents of had a few surprises. For one thing, the bundle identifier (a reverse domain-name style string used to uniquely identify an app on macOS) was the oddly titled com.throbber.tipcat, and the executable binary file was named hemorrhoid. Examining both the binary and other files in the Installer bundle revealed some heavily obfuscated code that is really quite unusual to see in anything except malware.

That gave me pause to try and run the Installer in the lldb debugger and see exactly what it was up to, but – also another sign of malware – the appears to have been coded precisely to stop that from being possible. Every time I tried to attach the debugger to the Installer’s process, the installer quit with “status = 45”, a sign that the debugger is being deliberately thwarted.

My next tack was to dump the class names with

otool -oV /Volumes/Installer/ | grep name | awk '{print $3}'

And that revealed some oddities, too. With names like ‘stockyardsStormed’ and ‘DefilersDiesels’ I was sufficiently intrigued to run the installer to completion and see it in action. As the screenshots below from my shareware troubleshooter DetectX and Objective Development’s Little Snitch 4 indicate, the unwary will get a lot more than just a free video player:

Finally, just to confirm my results, I uploaded the to VirusTotal, and found that it was a variant of the InstallCore strain of adware.

That pretty much wraps up the case against the installer, but what about the Mac Media Player app and its related version the Macgo Mac Blu-ray Player Pro? It seemed as far as I could tell that the apps themselves were ‘clean’. However, RB AppChecker Lite reveals that the installer and both the apps are signed with the same Apple Developer ID, ZJ Tech Inc, F9QTW5KSLJ.

That pretty much rules out any possibility that the developers had been unknowingly compromised. Clearly, ZJ Tech are quite happy to distribute their software to customers and do a stealth install of MacKeeper at the same time. Presumably, there’s some financial pay-off for them in doing that. Given that ZJ’s media players also seem to be little more than copies of, it seems there’s pretty good reason enough to avoid using their products.

scan for malware on the command line

Screen Shot 2017-12-20 at 19.23.50

DetectX Swift now has the ability to do command line searches for issues on your mac like malware, keyloggers, browser hijacks and potentially dangerous software, and there’s a number of extra options that are not available when using the user interface. In this post, I’m going to give you a quick tour of the CLI (Command Line Interface) tool with some examples of how to use it (if you haven’t yet grabbed a free copy of DetectX Swift you might want to do that first to play along).

1. Basic scan
Let’s start with a basic scan. To use the CLI search, you need to specify the full path to the app executable. In this example, let’s suppose that the app is in /Applications folder. In that case, you’d need to execute this on the command line:

/Applications/DetectX\\ Swift search

Since that’s a bit of a handful, even using tab completion, you might want to edit your .bash_profile to include a shortcut alias. Here’s mine:

sphil@sphils-iMac-5:~$ cat .bash_profile

alias sudo='sudo '

alias detectx='/Applications/DetectX\\ Swift'

Note the sudo line (and note the extra space in the value). We’re going to need that so that we can pass the alias to sudo when we want to pass certain options to the search. Like…

2. Scan other users
Probably the most important benefit you gain with scanning on the command line rather than from the app’s interface is the ability to scan all, or selected, other users. You can search all users by using sudo and the -a option:

sudo detectx search -a

If you want to restrict the search to one or more users, the -u option allows you to specify a list of shortuser names (comma-delimited):

sudo detectx search -u alice,bob

3. Go deep
If you’d like more verbose output, including how long the search took, try either the vsearch or vvvv commands:

sudo detectx vvvv -a

4. Save the results
You can specify a path to output the results, either in regular text:

sudo detectx vvvv -a ~/Desktop/searchtest.txt

or, by passing the extra -j option, in JSON format:

sudo detectx search -aj ~/Desktop/searchtest.json

Here’s an example of what the formatted JSON file looks like:

Screen Shot 2017-12-20 at 18.05.26

5. Anything else?
There’s a help command that will output the documentation to the command line, and also if you get into the habit of regularly running command line checks, don’t forget to launch the app from time to time in the Finder. Like its predecessor, DetectX, DetectX Swift does a lot of other stuff besides searching that can help track down and remediate problems with your mac, and a large part of that revolves around the way it tracks changes to your system every time you launch it. The CLI tool runs independently of that and won’t give you that kind of feedback or record those changes.

Finally, note that in the release version of DetectX Swift, the CLI tool is only available for a limited period to Home and Unregistered users. Unlimited acccess to the CLI tool requires a Pro or Management license.

Enjoy! 🙂

how to remove MyCouponize adware

MyCouponize is an aggressive adware infection that simultaneously installs itself in Safari, Chrome and Firefox, It hijacks the user’s search and page loads, redirecting them to multiple web sites that advertise scamware and other unwanted junk.

You can remove it easily with DetectX Swift (a free/shareware utility written by myself) as shown in this video. If you prefer reading to watching, here’s the procedure:

1. Run the search in DetectX.

2. Click on the [X] button.
You’ll find this button just above the results table to the right, between the search count and the tick (whitelist) button. It will turn red when you hover over it. When it does so, click it.
Then hit ‘Delete’ to remove all the associated items.
You’ll need to enter a password as some of the items are outside of your user folder.
Press the esc key or click the ‘Cancel’ button on any pop up dialogs that appear.

3. Go to the Profiler
Here we’ll unload the launchd processes that belong to MyCouponize.

Navigate to the user launchd processes section and move the cursor over the item com.MyMacUpdater.agent

Click the ‘Remove x’ button that appears when the line is highlighted.
Wait for the profiler to refresh and then go back to the same section and remove the second process called com.MyCouponize.agent

4. Quit the
This item has already been deleted in step 1, but its process may still be running in memory. If its icon appears in the Dock, right click on it and choose ‘Quit’ from the menu.

4. Finally, go to Safari Preferences’ Extensions tab
Click the uninstall button to remove the MyCouponize extension.

After that, Safari should be in good working order. If you have Chrome, Firefox or possibly other browsers installed, make sure you remove the extensions or Add Ons from those, too.

DetectX and DetectX Swift are shareware and can be used without payment, so go grab yourself a copy over at

DetectX Swift History

DetectX Swift beta has arrived

It’s been unusually quiet on Applehelpwriter these past few months, and the reason is that I’ve been devoting all my time and efforts to the new version of DetectX. The new version is called DetectX Swift because (yeah, you guessed it) I wrote it in Swift and because it’s considerably faster than its older sibling.

DetectX Swift’s got a new interface, but there’s far more going on under the hood. The Search uses some fancy heuristics as well as hard-coded and live update search definitions to ensure it provides the very best in security threat scanning.

The new Profile view employs some super cool dynamic highlighting and lets you inspect the contents not only of directories but also of scripts, plists and other files that could execute troublesome code on your mac.

There’s changes in the History view, too, both in the display and functions. One of the coolest things I like about the new History function is that you can run a diff on any previous run against the latest run, immediately seeing how they differ.

There’s tons more to DetectX Swift, but the best way to find out about it is just to try it. The beta version is free to use for both Home and Commercial users, so just head off over to its home page and grab yourself a copy!

Don’t forget to keep us informed of how it goes. The beta is still in an early stage and more features are slated as it develops, but feel free to tell us about anything that you feel could be done better or things that you’d like to see added.

Share and enjoy! 🙂

getting ready for DetectX Swift

Screen Shot 2017-10-04 at 16.18.14

Pretty soon now I’ll be releasing the first beta of DetectX Swift. Lots more details will be forthcoming over the next few days and weeks, but here’s a quick 1-minute look at how the new Profiler function works and some of the cool things you can do with it.


Terminal tricks for defeating adware

So, your browser is acting up, redirecting you to scamsites, offers for MacKeeper and Mac Cleaner and other unwanted software. You have what is technically known as ‘an adware’ infection. It’s not a virus, it’s not a ‘trojan’ and it’s not a ‘worm’, but it is a nuisance and may well be associated with any of the above. What to do?

Here’s 10 Terminal tricks you can use to help identify and remove adware items. It won’t cover every situation: adware mutates faster than a flu virus on amphetamines, but it will catch 90% of the cases currently out there. For the ones it doesn’t, see the ‘Getting Help’ section at the end of this post.

I’m going to split this up into two phases, ‘Gathering Information’ and ‘Dealing with the Results’. After explaining the first half-dozen commands individually, I’ll then give you one ‘master’ or ‘mother’ command which combines them into a single execution, but you should read through the explanations first so that you know what you’re doing and what to expect.

Gathering Info
First, most adware wants to persist on your mac across logins and restarts, and that means it has to put an executable somewhere where macOS will look on start up. One place most users should be familiar with and check first is the Login Items in System Preferences ‘Users & Groups’ pane. A lot of adware will insert itself there for good measure, but most will almost certainly be in other, trickier to find places.

This is where our first Terminal trick comes in. This Terminal trick will output the contents of the main locations where adware typically hides:

1. List the contents of your Launch* folders:

ls -alF /Lib*/Launch*/ ~/Lib*/Launch*/

That’ll output the contents of three different directories, /Library/LaunchAgents, /Library/LaunchDaemons, and ~/Library/LaunchAgents. If you’re planning on getting help by publishing the results in a public forum like Apple Support Communities, then you might want to use this version, which will scrub your username out of the results:

2. Same trick, redacting personal info:

w=`id -un`;ls -alF /Lib*/Launch*/ ~/Lib*/Launch*/ | sed "s@$w@[redacted]@g"

The output of that command will have a load of files with names like ‘’. To give you an example here’s what mine outputs (note, none of these are adware files; unsurprisingly, my Mac is adware free!).

Slipping a shell script into the /etc/ directory is a common adware trick, so let’s also run this one, which will output any files in /etc/ that have the .sh shell script extension:

3. Find shell scripts in /etc/:

ls -alF /etc/*.sh

(this one won’t contain your user name, so we don’t need to redact anything).

A lot of adware persists by running sneaky little AppleScripts from a shell script. We can detect if any of these are at work with this little spell:

4. List osascript processes targeting your browser:

ps -axo ppid,pid,command | grep 'osascript -e global' | egrep -i "if is_Firefox_running|if is_Safari_running|if is_Chrome_running" | grep -v "grep" | grep -v ' 1 ' | awk '{ print $1, $2}'

All this command outputs is two numbers, perhaps like this:

7783 7792
7783 7825
8978 8987

We’ll discuss what to do with those in the ‘Dealing with Results’ section below.

Next, we want to see what processes are actually running in the background. This will both confirm and possibly add to information we collected earlier. To do this, we need a little trick which looks like the same command twice, but which in fact operates on two different lists of processes:

5. List loaded background processes:

w=`id -un`; r="s@$w@[redacted]@g"; launchctl list | grep -v apple | sed "$r"; sudo launchctl list | grep -v apple | sed "$r"; sudo -K

When you run this one, a list of processes will be output, and then you’ll be asked to supply an Admin password on the command line (where even the key presses won’t be visible when you type). Supply the password and a second list will be produced. We will want to examine both later.

A file name common to a widespread family of adware is, and this can be hidden anywhere in the user or local Library folders, so let’s run this one, too (here we will add the redacting again in case you’re posting the results in a public forum). You’ll need to supply an admin password for this though:

6. Find a common adware executable:

w=`id -un`; sudo find /Library ~/Library -name "**" | sed "s@$w@[redacted]@g"; sudo -K

This one may take a couple of seconds to complete.

That concludes the first step of our info gathering stage, but for convenience, I’m going give you them all again concatenated into one, single ‘mother of all commands’ 😀 string. Even more conveniently, I’ve added code to output the results to a text file on your Desktop, called ‘adware_search.txt’, so after running the code below go look for ~/Desktop/adware_search.txt in Finder. If you’re posting to a public forum, it’s much easier to copy and paste the results from the text editor rather than from Terminal.

If you triple-click anywhere in the block of code below, you can copy and paste the whole block into Terminal and execute all of the commands given above in one fell swoop. Remember you’ll need a password.

7. The ‘Mother’ of all the above:

w=`id -un`; r="s@$w@[redacted]@g"; f="/Users/"$w"/Desktop/adware_search.txt"; ls -alF /Lib*/Launch*/ ~/Lib*/Launch*/ /Users/Shared /usr/local/bin | sed "$r" >> "$f"; printf "\n\n/etc:\n" >> "$f";ls -alF /etc/*.sh 2>/dev/null >> "$f"; printf "\n\n# osacript processes:\n" >> "$f"; ps -axo ppid,pid,command | grep 'osascript -e global' | egrep -i "if is_Firefox_running|if is_Safari_running|if is_Chrome_running" | grep -v "grep" | grep -v ' 1 ' | awk '{ print $1, $2}' | sed "$r" >> "$f"; printf "\n\n# User launchd:\n" >> "$f"; launchctl list | grep -v apple | sed "$r" >> "$f"; printf "\n\n# Root launchd:\n" >> "$f"; sudo launchctl list | grep -v apple | sed "$r" >> "$f"; printf "\n\n# Find\n" >> "$f"; sudo find /Library ~/Library -name "**" | sed "$r" >> "$f"; sudo -K

Interlude: Playing Safe
Before we move on to dealing with the results, I want to stress that you don’t want to be deleting files that you’re not sure of. Good practice is to move files to a temporary Quarantine folder, or at least move them to but don’t empty the Trash.

Even better practice is to make sure you have an up-to-date, bootable backup disk as well as a Time Machine backup, so that you can easily recover your system if you make a mistake and delete something you shouldn’t.

Dealing with the results
Looking at the output of the first Terminal command given above (Trick 1 or 2), how can you tell which are good and which are bad? In a lot of cases, you’ll recognise the app or developer name. TunnelBear, for example. “Sure, yeah, I’ve got that” and so on. Others, however, will look and sound weird, like these (all genuine adware file names):


Google anything you’re not sure of, and see if it’s already been identified as adware. See ‘Getting Help’ at the end of this post if you’re not sure.

Walking up & down the tree
Assuming you’ve found some candidates for removal, the next job is to find the parent and child processes associated with each. We do that with a couple more Terminal tricks.

For the first one, we want to find any process that contains the same name as our suspected adware. For each suspect, take the unique part of the name for your search term. With this one we can put all our candidates in one command like so:

8. Search for your target’s family members:

w=`id -un`; ps -axo ppid,pid,command | egrep -i "glutting_Panagia| pPHGASlN | phellonic" | grep -v ' 1 ' | grep -v grep | sed "s@$w@[redacted]@g"

Note the part after egrep -i that’s inside quote marks. Each search term is separated between a vertical bar, aka the pipe character. Note that the terms themselves are not inside quote marks individually. One pair of double-quote marks is used to encapsulate all terms.

So to use the command above replace “glutting_Panagia| pPHGASlN | phellonic” with “search term 1 | search term 2 | search term 3”, where ‘search term n’ is your search term. Of course, you can have more or less than three search terms. Just add or remove as required.

When you examine the results, so long as the first number is not ‘1’ (it shouldn’t be if you executed the command correctly, as all those should have been excluded), follow the file path shown under the ‘Command’ column using either Finder or the Terminal. If you’re sure you’ve found a baddie, send it to the Trash or your quarantine folder! If you’re not sure, see ‘Getting Help’ below.

You will need to construct and run the next command separately for each suspect. The output will give you the path to the binary being executed by the plist. In many cases, you’ll have already found that from the previous commands, but in some cases – particularly if the plist has failed for some reason or if the binary isn’t running when you do your search – it won’t. This one’s the trickiest because you’re going to have to construct most of it yourself. Here’s an example (this is actually a legitimate file, but it will serve for our purposes):

cat /Library/LaunchAgents/com.razer.rzupdater.plist | grep -iA3 program

Let’s look at how that command is structured:

9. Find more children:

cat [path to file] | grep -iA3 program

You get the ‘path to file’ part from the results of your /Library/Launch* searches, and there’s no harm in practising this one on good files to get used to the output. For each item you search, it should return something that looks like this:

Here we see the path to the executable that the plist is launching. If this were a bad guy, I’d be straight over there to send him where he belongs, too.

After working through all your suspects with Trick 8, now take a look at the results of the command to output shell script file names from /etc/ (Trick 3). If there were any results at all (hopefully there wasn’t), you’re going to have to open that file in a text editor and determine whether it is malicious or not. This is the hardest part for the novice, because there’s certainly plenty of reasons to have a shell script in /etc/ depending on what 3rd party software you’re running. I can only repeat here what I have said above: see the ‘Getting Help’ section below if in any doubt.

Next, let’s take a look at the results for the osascript processes (Trick 4). Hopefully, you got no results, but if you had two sets of numbers outputted like this:

7783 7792

then the first number is the parent process ID, and the second number is the child ID. We want to find and eliminate both the parent (again, so long as this number is not ‘1’) and the child.

Take the first number and execute this in Terminal

10. More parents on the loose:

ps [number]

Take a note of the path that’s shown and ensure it doesn’t belong to a legitimate app that you recognise. Again, if in doubt, ask Google, or see ‘Getting Help’ below.

Now, do the same with the second number, the child process. Work through however many numbers were output, ‘quarantining’ as you go.

Almost there! Take a look at the output of the two launchd lists (Trick 5). You should have a good idea by now which ones are suspect and which are OK. You may have found the paths to any suspicious ones already, but if not, we’ll use the same command as we just used with the osascript processes. Here’s the output on my machine of the Trick 5 command (all legitimate) for comparison:

We’re only interested in the first number (the second one is status code). For any suspicious process, take the first number shown in the list, and use the Trick 10 command on these to find the parent file path (you know what to do with the ones that aren’t legitimate!).

If there is only a ‘-‘ dash instead of a number, it means that process is or was loaded but is not currently running. That dash may or may not be followed by another number that is not ‘0’. That number is just an error code and isn’t really relevant to us here. For any of your suspects that have failed like that, hopefully the info you gathered earlier will give you some clues (if not, see ‘Getting Help’ next).

Finally, anything found in the ‘find’ command (Trick 6) is almost certainly malware. Of course, be mindful that it’s entirely possible a legit’ script could accidentally have a name clash and be called, but it’s highly unlikely and definitely should be examined closely. Also, if you see that the path is within an application bundle like this …Contents/MacOS/, don’t hesitate to pull the trigger on that one.

Getting Help
I want to repeat that doing this safely and effectively takes practice and experience, and you should in no way be surprised that, if you don’t have that experience, you’re not sure whether something you’re looking at is good or bad, or that you go through all of this and still can’t find the problem. There’s some fairly obscure ways that adware and other malware can infest and persist on your mac that only experts will be able to advise you on. Throughout this post I’ve glossed over a few situations where you’ll draw a blank, and that’s because most of the other techniques for spotting malware require that experience.

To ameliorate this, I wrote an app called DetectX Swift to deal with this and many other things, and you can download it and use it without any requirement to pay. You can also use it to get personal, free-of-charge, help from me through the Help > Report a Problem to Sqwarq Support if your troubles persist.

Let me be clear why I don’t charge for this personal service: the payoff for me is I get to improve my app’s heuristics from what I learn about infections that DetectX doesn’t automatically detect. All information is kept strictly confidential and I do not sell or use your email address or other information for any marketing purposes whatsoever.

If you want to read more about me, also see the about page on DetectX’s parent site,

Happy hunting! 🙂

Related Posts
scan for malware on the command line


%d bloggers like this: