Matt Knox, a talented Ruby instructor and coder, talks about his early days designing and writing adware for Direct Revenue. (Direct Revenue was sued by Eliot Spitzer in 2006 for allegedly surreptitiously installing adware on millions of computers.)
M: [sheepishly] Yes, I did. I got to write half of it in Scheme, which probably means that I deployed more Scheme runtime than anybody else on the planet.
S: Let’s back up a second. Why did you write adware?
M: I was utterly and grindingly broke for a little while. I started working on SPAM filtering software. That work got noticed by [Direct Revenue], who hired me to analyze their distribution chain. For a little while, the site through which all their ads ran was something like top 20 in Alexa. Monstrous, really huge traffic. Maybe 4 or 5 months into my tenure there, a virus came out that was disabling some of the machines that we had adware on. I said, “I know enough C that I could kick the virus off the machines,” and I did. They said “Wow, that was really cool. Why don’t you do that again?” Then I started kicking off other viruses, and they said, “That’s pretty cool that you kicked all the viruses off. Why don’t you kick the competitors off, too?”
It was funny. It really showed me the power of gradualism. It’s hard to get people to do something bad all in one big jump, but if you can cut it up into small enough pieces, you can get people to do almost anything.
S: Did you feel this was the gently sloping path to Hell?
M: Oh yeah! Absolutely. [ laughs ] I actually believe that if you sum up everything I did it comes out positive, if only because I kicked off an awful lot more adware than I installed.
S: What was Direct Revenue’s business model?
M: Their business model was that they would buy a screensaver from somebody, or develop it themselves. It would be some stupid thing like a guy who’s washing their screen. Looks like a window washer guy? They’d say “Hey, if you want this, install our adware and you can have it for free.” An astonishing number of people will do that.
S: What did they call it? I presume they didn’t call it “adware.”
M: The good distributors would say, ‘This is ad-supported software.” Not-so-good distributors actually did distribute through Windows exploits. Also, some adware distributors would sell access. In their licensing terms, the EULA people agree to, they would say “in addition, we get to install any other software we feel like putting
on.” Of course, nobody reads EULAs, so a lot of people agreed to that. If they had, say, 4 million machines, which was a pretty good sized adware network, they would just go up to every other adware distributor and say “Hey! I’ve got 4 million machines. Do you want to pay 20 cents a machine? I’ll put you on all of them.” At the time there was basically no law around this. EULAs were recognized as contracts and all, so that’s pretty much how distribution happened.
S: Your company’s not one of those that would leverage exploits in order to get software on people’s computers?
M: We didn’t, no. Some of the distributors certainly did. If we found out a distributor was doing that, we’d say “Now we’re not going to distribute with you any more,” and we’d try to get off those machines.
The thing that I had a real problem with was the persistence work that I was doing. This made it difficult for competitors to kick us off the machine. It was effectively impossible for a civilian to get us off the machine– unless they went through our uninstall process. You had to go to some web site, download an uninstaller, take a short survey about why they were getting rid of us, and then it would actually remove us and we would also leave a Registry key to make sure we didn’t reinstall. Sadly, some misguided antivirus and anti-adware software would go in and remove that, which therefore meant that we would reinstall again.
S: Can you tell me more about your strategies for persistence?
M: Yes. I should probably first speak about how adware works. Most adware targets Internet Explorer (IE) users because obviously they’re the biggest share of the market. In addition, they tend to be the less-savvy chunk of the market. If you’re using IE, then either you don’t care or you don’t know about all the vulnerabilities that IE has.
IE has a mechanism called a Browser Helper Object (BHO) which is basically a gob of executable code that gets informed of web requests as they’re going. It runs in the actual browser process, which means it can do anything the browser can do– which means basically anything. We would have a Browser Helper Object that actually served the ads, and then we made it so that you had to kill all the instances of the browser to be able to delete the thing. That’s a little bit of persistence right there.
If you also have an installer, a little executable, you can make a Registry entry and every time this thing reboots, the installer will check to make sure the BHO is there. If it is, great. If it isn’t, then it will install it. That’s fine until somebody goes and deletes the executable.
The next thing that Direct Revenue did– actually I should say what I did, because I was pretty heavily involved in this– was make a poller which continuously polls about every 10 seconds or so to see if the BHO was there and alive. If it was, great. If it wasn’t, [ the poller would ] install it. To make sure the poller was less likely to be detected, we developed this algorithm (a really trivial one) for making a random-looking filename that was consistent per machine but was not easy to guess. I think it was the first 6 or 8 characters of the DES-encoded MAC address. You take the MAC address, encode it with DES, take the first six characters and that was it. That was pretty good, except the file itself would be the same binary. If you md5-summed the file it would always be the same everywhere, and it was always in the same location.
Next we made a function shuffler, which would go into an executable, take the functions and randomly shuffle them. Once you do that, then of course the signature’s all messed up. [ We also shuffled ] a lot of the pointers within each actual function. It completely changed the shape of the executable.
We then made a bootstrapper, which was a tiny tiny piece of code written in Assembler which would decrypt the executable in memory, and then just run it. At the same time, we also made a virtual process executable. I’ve never heard of anybody else doing this before. Windows has this thing called Create Remote Thread. Basically, the semantics of Create Remote Thread are: You’re a process, I’m a different process. I call you and say “Hey! I have this bit of code. I’d really like it if you’d run this.” You’d say, “Sure,” because you’re a Windows process– you’re all hippie-like and free love. Windows processes, by the way, are insanely promiscuous. So! We would call a bunch of processes, hand them all a gob of code, and they would all run it. Each process would all know about two of the other ones. This allowed them to set up a ring … mutual support, right?
So we’ve progressed now from having just a Registry key entry, to having an executable, to having a randomly-named executable, to having an executable which is shuffled around a little bit on each machine, to one that’s encrypted– really more just obfuscated– to an executable that doesn’t even run as an executable. It runs merely as a series of threads. Now, those threads can communicate with one another, they would check to make sure that the BHO was there and up, and that the whatever other software we had was also up.
There was one further step that we were going to take but didn’t end up doing, and that is we were going to get rid of threads entirely, and just use interrupt handlers. It turns out that in Windows, you can get access to the interrupt handler pretty easily. In fact, you can register with the OS a chunk of code to handle a given interrupt. Then all you have to do is arrange for an interrupt to happen, and every time that interrupt happens, you wake up, do your stuff and go away. We never got to actually do that, but it was something we were thinking we’d do.
We did create unwritable registry keys and file names, by exploiting an “impedance mismatch” between the Win32 API and the NT API. Windows, ever since XP, is fundamentally built on top of the NT kernel. NT is fundamentally a Unicode system, so all the strings internally are 16-bit counter Unicode. The Win32 API is fundamentally Ascii. There are strings that you can express in 16-bit counted Unicode that you can’t express in ASCII. Most notably, you can have things with a Null in the middle of it.
That meant that we could, for instance, write a Registry key that had a Null in the middle of it. Since the user interface is based on the Win32 API, people would be able to see the key, but they wouldn’t be able to interact with it because when they asked for the key by name, they would be asking for the Null-terminated one. Because of that, we were able to make registry keys that were invisible or immutable to anyone using the Win32 API. Interestingly enough, this was not only all civilians and pretty much all of our competitors, but even most of the antivirus people.
We also wrote a device driver and then a printer driver. When you write a device driver you get to do all sorts of crazy things, even crazier than the things you typically get to do in Windows. This was right around the time that the company [ got sued by Eliot Spitzer and started shrinking ]. They made a somewhat poor business decision at the same time to get visible, and they branded their ads and everything at the same time that they were having me kick all of our competitors off and we were doing all that persistence stuff.
There was also of course Scheme. Eventually, we got sick of writing a new C program every time we wanted to go kick somebody off of a machine. Everybody said, “What we need is something configurable.” I said, “Let’s install a Turing-complete language,” and for that I used tinyScheme, which is a BSD licensed, very small, very fast implementation of Scheme that can be compiled down into about a 20K executable if you know what you’re doing.
Eventually, instead of writing individual executables every time a worm came out, I would just write some Scheme code, put that up on the server, and then immediately all sorts of things would go dark. It amounted to a distributed code war on a 4-10 million-node network.
S: In your professional opinion, how can people avoid adware?
M: Um, run UNIX.
S: [ laughs]
M: We did actually get the ad client working under Wine on Linux.
S: That seems like a bit of a stretch!
M: That was a pretty limited market, I’d say.
S: What is the future for adware?
M: To the extent that advertising is beautifully targeted, it ceases to become advertising is now more informational. The most encouraging example of this is Gmail. I see nothing but Ruby on Rails developer jobs and Scheme developer jobs on Gmail.
S: Does it weird you out that there’s some automated script filtering all your mail?
M: When I think about that, it sometimes troubles me. The good news is that I’ve been on the other side of those automated script things. Their capability is incredibly dangerous, but the actuality tends not to be.
It would have been fairly trivial for me to go spelunking for people’s credit card information or whatever. I had four million nodes. I could have done it without anybody at the company even noticing. I was the guy writing Scheme, so I could have just put a text file somewhere and then made it go away, and there wouldn’t even have been an executable lying around.
But I didn’t. To do that, by definition you have to be willing to become a criminal, and that’s a little bit rare. So I’m not too worried about that. I think that advertising it going to turn into something that’s just a big mess of algorithms, where somebody says “this guy may be interested in this new programming language.”
S: How private is people’s information today?
M: Not at all.
S: Do you think that in our society we delude ourselves into thinking we have more privacy than we really do?
M: Oh, absolutely. If you think about it, when I use a credit card, the security model is the same as that of handing you my wallet and saying, “Take out whatever money you think you want, and then give it back.”
S: …and yet it seems to be working.
M: Most things don’t have to be perfect. In particular, things involving human interactions don’t have to be perfect, because groups of humans have all these self-regulations built in. If you and I have an agreement and you screwed me over badly, you’ve always got in the back of your mind the nagging worry that I’m going to show up on your doorstep with a club and kill you. Because of that, people don’t tend to screw each other too much, right? At least, they try not to. One danger, perhaps, of moving towards an algorithmically driven society is that the algorithms aren’t scared of us showing up and beating them up. The algorithms will do whatever it is that they are designed to do. But mostly I’m not too worried about that.
S: Is there anything else you wanted to comment on?
M: People can have things as good as they are willing to work for. If you want to have a system that’s clean of nasty software, you can do that. If you want to have personal privacy, it’s possible– very hard, but possible. And I think it’s worth it.
|Interview conducted and edited by Sherri Davidoff|
|Copyright 2009, all rights reserved.|