Archive for the ‘New Findings’ Category

And Now For A Few Words About HP’s “Scrawlr”

Mike Tracy | June 26th, 2008 | Filed Under: Defenses, Malware, New Findings

1.

Some of my favorite reads (there are others) have recently written about about Scrawlr and some of what I have read has been critical. Critical enough? Depending on your level of pedantry with respect to webapp security and/or free software, probably not.

Stop that. Right now. Overlook the limitations of the tool that was released, realize that this is a closely targeted thing designed to help alleviate a specific problem. Go back and think a little harder about what is going on and why this is actually A Good Thing(tm).

This scanner, released as part of the advisory, is specifically designed to help people who run websites that have been targeted by this ongoing and massive SQL injection attack shore things up. The tool has limitations. Quoted from a text file included with the Scrawlr package:


This is a free tool and is intended to find SQL Injection vulnerabilities on pages that hackers can discover using a simple crawler or google query. This application mimics a search engine crawler and lacks the advanced crawling and auditing features of tools such as WebInspect, DevInspect, QAInspect, and AMP. Thus Scrawlr will only find SQL Injection vulnerabilities on GET Parameters; Scrawler will not submit forms, nor audit them. The list below summarizes the limitations:

  • 1500 Max Crawled URLs
  • No Script parsing during crawl
  • No Flash parsing during crawl
  • No form submissions during crawl (No POST Parameters)
  • Only simple proxy support
  • No authentication or login functionality
  • Does not check for blind SQL injection

The scanner is built to look for things being indexed by search engines. If those sites are fixed, 99.999% of the problem should go away.

Trying to compare Scrawlr to a full blown SQL Injection scanning tool is like comparing a letter opener to a Swiss Army Knife. Sure, you can do other things with a letter opener (and some of you probably want to slit my throat for that simile. That’s fine, use the knife) —- but its stated purpose is to open letters.

2.

The limitations aren’t that bad. Take the biggest one, authentication. I tried it. For the vast majority of sites, “authentication” means “HTTP forms that set cookies”. For those types of sites, it was easy to get the tool to operate against sites “post authentication”. (I didn’t try for basic/ntlm/digest —- I don’t have a ready test subject. I’d be surprised if it worked.)

Using burp suite do the following:

  1. Login to the application using a web browser
  2. record the Cookie: header
  3. in burp go into the Proxy -> Options tabs
  4. go to the “match and replace” section
  5. add a new header
    • Type: request-header
    • Match: ^Accept.*$
    • Replace: Cookie:
  6. point Scrawlr at your running proxy

Basically, just replacing the Accept: */* header that Scrawlr sends with a Cookie header.

Yay! A free tool that people can use to see if their sites are vulnerable to mischief. Plus! A free code scanner and a free sort of maybe web application firewall to help them protect themselves. Your old ASP sites are now safe from all this ruckus.

3.

I spent some time talking about this with colleagues (colleague n. drinking buddy) at ChiSec last night [if you weren’t there it was a blast and you should come to the next one -ed.] and as much as I love the idea behind this, consternation is bubbling beneath the surface.

What I’m having trouble understanding are the motivations of Microsoft and HP and their estimation of how effective this will actually be. This is either Defense In Depth’s red-headed stepchild cum marketing ploy or… Not sure I actually see an “or”. Half-baked code analyzer (ok I don’t really know that but…)? Check. Web Application Firewall Lite? Check. Hey! Get the guys at SPI to throw in a cripple-ware SQL injection scanner and we’re all set to at least appear like we are trying in some way to maybe have a chance at helping a person or two.

Great!

I want a count of the owners of target audience websites who actually read the advisory, understand it, realize they are affected and then actually use any of the schwag provided to help them solve their problems.

Microsoft seems like a good egg for going to all this trouble and HP gets their name on it. Maybe people will come sniffing around for a “real” security tool or two. Humbug I say!

In the end, motivations are incidental. I’m really just interested in seeing how effective this is.

Comment Bubble 5 Comments

This New Vulnerability: Dowd’s Inhuman Flash Exploit

Thomas Ptacek | April 15th, 2008 | Filed Under: New Findings, This Old Vulnerability

The evidence is now overwhelming that Mark Dowd was, in fact, sent back through time to kill the mother of the person who will grow up to challenge SkyNet. Please direct your attention to Dowd’s 25-page bombshell on a Flash bytecode attack.

Some context. Reliable Flash vulnerabilities are catastrophes. In 2008, we have lots of different browsers. We have different versions of the OS, and we have Mac users. But we’ve only got one Flash vendor, and everyone has Flash installed. Why do you care about Flash exploits? Because in the field, any one of them wins a commanding majority of browser installs for an attacker. It is the Cyberdyne Systems Model 101 of clientsides.

So that’s pretty bad-ass. But that’s not why the fate of humanity demands that we hunt down Dowd and dissolve him in molten steel.

Look at the details of this attack. It’s a weaponized NULL pointer attack that desynchronizes a bytecode verifier to slip malicious ActionScript bytecode into the Flash runtime. If you’re not an exploit writer, think of it this way: you know that crazy version of Super Mario Brothers that Japan refused to ship to the US markets because they thought the difficulty would upset and provoke us? This is the exploit equivalent of that guy who played the perfect game of it on YouTube.

Let’s break it down a bit:

p2.png

Start with the vulnerability.

It’s an integer overflow, but not a simple one.

When the Flash runtime reads in scene data from a SWF file, there’s a numeric field that, when bounds-checked, is interpreted as a signed number, but when used is treated as unsigned. So there are values the field can take that are treated as tiny and innocuous at time-of-check, but actually evaluate as huge numbers at time-of-use.

A by-the-numbers integer overflow normally knocks the bounds checking off a strncpy or memcpy call, turning code that carefully copies, say, 1k of memory into code that will copy 2 megs of data, splattering it all over process memory. Not here. Instead, Flash uses the malicious number as a count of bytes to allocate.

When you ask Flash to allocate several gigs of memory all at once, the allocation fails, returning NULL. Attempt to use that NULL address and you will crash the program. This happens all the time in real code. Many crashes are traceable to NULL pointers. And, since nothing (usually) lives at NULL, NULL pointer crashes are usually code for “not exploitable”.

Not this time. Flash forgets to check that allocation failed, a ludicrously common error. It then uses that pointer with an offset controlled by the attacker. NULL isn’t valid. NULL plus 1024 isn’t valud. But NULL + 0x8f71ba90 is, as is NULL + N for any N that addresses valid memory.

To this address, controlled by attackers via wild offset, Flash writes a value that is also controlled by the attacker. This is the write32 pattern: a vulnerability that gives the attacker the means to set any one value in memory to a value of their choosing. Game over.

p1.png

Except not quite.

The exploit doesn’t actually get to offset an arbitrary number of bytes from 0. A complicated set of conditions constrains the address it writes to and the value it gives it.

The the actual write occurs via a structure offset. Flash is hardcoded to translate your offset into another number. Working offsets, as it turns out, will be greater than 0x80000000, and will be evenly divisible by 12 after 4 is added to them. Note: I thought I was hardcore when I wrote shellcode with no lowercase letters for the IMAP vulnerability in the ’90s.

That’s not all. The value that Flash will write to the wild pointer isn’t totally controlled by the attacker either. It’s cast up from a 16 bit integer to a 32 bit integer, and has another variable subtracted to it. This is the point in the report that I started giggling uncontrollably, embarassing myself at the coffee shop.

The net result of this silliness is that it’s hard to do what attackers normally do with a write32 vulnerability, which is to clobber a function’s address with a pointer back to their buffer, so that their shellcode is called when the clobbered function is called. So Dowd’s exploit takes things in a different direction, and manipulates the ActionScript bytecode state.

ActionScript bytecode state; yeah, about that. ActionScript is Javascript that controls Flash animations. But the Javascript system used by Flash is pretty advanced; for performance, it transforms Javascript into bytecodes for a VM. For a bytecode VM, ActionScript is pretty tight; its runtime stack is integrated with the CPU’s runtime stack. The memory it uses to execute code is the same memory that the Flash C-code runtime uses to manage its own state.

ActionScript is a register-based VM, meaning that its bytecode instructions concern themselves chiefly with moving values in and out of memory slots that simulate CPU registers. Those registers live in the runtime stack and are accessed by indexing. Meaning, a malicious Flash bytecode instruction can index its way to an arbitrary address on the system stack. Game over.

p3.png

Except not quite.

You can’t just inject malicious bytecodes.

Flash players have to execute bytecode sklorked directly off of web pages, most of which are controlled by organized criminals. So Flash doesn’t execute arbitrary bytecodes; they’re verified before execution. The verifier ensures, among other things, that register accesses from the bytecode stream reference valid register slots.

But. For performance, the Flash VM is broken into a two-pass system with a verifier that validates bytecode (time-of-check) and an executive that later evaluates it (time-of-use). And the interpretation of bytecode differs at time-of-check and time-of-use. Here’s the situation:

  • The verifier ignores undefined bytecodes.

  • The verifier keeps a table in memory that defines how long any one bytecode instruction is.

  • The bytecode length table is a valid target of the NULL pointer overwrite.

  • The executive has totally different machinery for interpeting bytecode.

Clobber the right value in the length table, and you can make an unused bytecode instruction that the verifier ignores seem much longer than it is. The “extra” bytes slip past the verifier. But they don’t slip past the executive, which has no idea that the unused bytecode has trailing bytes. If those trailing bytes are themselves valid bytecode, Flash will run them. Unverified. Giving them access to the whole system stack. Game over.

p4.png

Except not quite.

The Koopa shell on the second platform is a trap and if you touch it you die.

Ok actually there’s no catch. Dowd’s exploit uses a NULL pointer write32 to knock the locks off the bytecode interpreter in Flash, so that his SWF file can run bytecode that will rewrite the system stack.

But, just to rub it in, or because this stuff just comes natural to you when you are manufactured by a malicious cluster of supercomputers inside SkyNet instead of nurtured by loving human parents, Dowd gives himself additional constraints.

To wit: his exploit must (because he’s messing with us) corrupt the Flash runtime, rewrite it to execute his trojan, and leave it running steady as if nothing had happened. Meaning:

  • His modification to the verifier can’t break existing instructions.

  • His bytecode has to swap values into the stack instead of clobbering them directly.

  • Portions of his shellcode have to run as both Flash bytecode and an X86 first-stage shellcode boot.

p5.png

Two fun details.

First, even though IE and Firefox use different Flash builds, the addressing inside them is compatible. The exploit works in both places.

Second, Flash isn’t compiled with ASLR. So the attack works on Vista.

Mass casualty. Go Flash!

Comment Bubble 101 Comments

Adam Bozanich Did Not Uncover An NSA IPsec Conspiracy: Diffie Hellman Parameter Validation Explained

Thomas Ptacek | September 25th, 2007 | Filed Under: Defenses, New Findings, Uncategorized

introduction

Alice and Bob want to arrange a tryst. Bob’s wife Eve is sniffing their Instant Messenger traffic.

No problem! Alice and Bob will encrypt their messages with AES-256-CBC. Eve won’t be able to decode the traffic before the heat death of the universe.

One small problem: what AES key to use? Actually: not a small problem. No matter what key Alice comes up with, she can’t send it to Bob without exposing it. She can’t encrypt the key; chicken and egg.

number theory f.t.w.

There’s a solution to this problem. Alice and Bob will run the Diffie-Hellman protocol (DH) to securely exchange a key.

Alice and Bob agree on a prime number p, and a smaller number g with a special relationship with p ([1]). These are parameters to Diffie Hellman. “23” and “7” are valid p and g parameters. So are “37” and “5”. They aren’t secret. Think of them like a “version” of DH that Alice and Bob agree to use.

For the sake of argument, Alice and Bob agree on “37, 5” DH.

Bust out your calculator. I’ll be Bob.

Generate a random number a, modulo 37 (divide your number by 37 and a is the remainder).

I’ll do the same thing to generate a different b.

Now take your a and make A. Raise 5 to the a‘th power, modulo 37 (in Ruby, do “(5 ** a) % 37”. I’ll do the same with b to make B.

A is your public key. a is your private key. Send me A. I’ll send you B. It’s 29.

Take 29 and raise it to the a‘th power mod 37 (I don’t know what a is; it’s your private key, so I can’t tell you what you’ll get.) That’s “(B ** a) % 37” in Ruby. I’ll do the same with B.

We just arrived at the same number. Was your private key 7? We came up with 8. Was your private key 26? We came up with 27. 27 is our session key.

Funny thing about our session key: you know it, and I know it, but Eve can’t know it. Even though we did this computation out in the open. This is the deep magic, yo.

quick aside:

Well OK, Eve totally knows what number we came up with, because we used a ridiculously small p. Instead of 37, 5, try this:

FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1
29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD
EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245
E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED
EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D
C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F
83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D
670C354E 4ABC9804 F1746C08 CA237327 FFFFFFFF FFFFFFFF

Just use 2 as g. Remember now that your private key a is a random number modulo this huge p. It will also be huge.

Raising a number to a power modulo another number is modular exponentiation (modexp). A modexp is straightforward to compute.

The opposite of exponentiation is a logarithm. Taking a log mod another number is a discrete logarithm. Discrete logs are extremely hard to solve. With large enough numbers, “racing heat death of the universe” hard; “every atom in the Solar System is a computer trying to solve it, still unsolvable” hard.

So you have two closely related operations, exponentiation and logarithm mod p, one of which is easy to compute and one of which is hard. This is a cryptographic building block and the foundation of DH.

back to alice and bob

We got 26 for our session key. Let’s say we MD5 the text value of “26”, to get “4e732ced3463d06de0ca9a15b6153677”. Tack a “0x” at the front of that value, and we now have a 128 bit number we can use as an AES key. Eve can’t know we came up with 26, and so can’t know what the MD5 of the session key is, and so doesn’t know what our AES key is.

Problem solved! Cue arbitrary foreshadowing device. We’ll come back to this.

what adam bozanich found

Adam works for Mu Security. Mu is writing an IKE fuzzer. IKE is a key exchange protocol for IPSec. IKE is probably one of the worst protocols ever to come out of the IETF, and I’m not going to explain it.

What you need to know is that IKE generates the keys that secure dynamically-keyed IPSec tunnels (layer-3 VPNs), and that IKE uses DH to do that.

Adam remembers a DH gotcha. When Alice and Bob run DH, they have to be careful not to allow any of the parameters —- p, g, A, or B —- be zero or one mod p.

Why’s that? Bust out your 37, 5 DH math again. Alice’s session key computation is “(B ** a) % 37”. Bob sends B. If B is 1, the session key is… wait for it… 1. If B is 0, it’s 0. No matter what Alice’s private key is.

If Eve sees a public key that works out to 0 or 1 mod p, Eve knows what the session key was; it’s zero or one. Remember that there are infinitely many values that work out to 0 or 1 mod p. 0 is 0 mod 37. So is 37. So is 74. And so on. Bob could have sent any one of those bad public key values.

Alice and Bob are supposed to check for this. Adam looked at a bunch of IKE implementations. None of them did.

context

This is a well-known problem. It’s in Eric Rescorla’s DH RFC. It’s in an ANSI standard. You can’t use p - 1 mod p either. You also have to be careful with g; broken values will generate subgroups, not the entire group. And real DH implementations have optimizations that can be attacked mathematically if you’re not careful.

Just because it’s well known doesn’t mean people won’t make the mistake. That’s why Nate and I pointed the problem out last year (almost to the day!).

The general class of problems we’re talking about is parameter validation. You attack them by looking at the messages a protocol exchanges, and sending malicious bad values that will break the computation.

Are you a security researcher? Go look for some of these bugs. They rock. More in a sec.

but back to adam

So it’s interesting that IKE implementations don’t validate parameters, but it’s not particularly meaningful.

IKE Bob can send IKE Alice a bad public key. This key will cause Eve to know the session key Bob and Alice use. But why would Bob do this? He’s negating his own security!

Eve can try to inject a bad public key into the session. But so what? If Bob and Alice don’t agree on A and B, the public keys, they can’t run DH. Maybe a different attacker, Mallory, can get between Alice and Bob and proxy the messages. She’ll be a “man in the middle”.

In this case, Mallory wins. No matter what parameters you use and what bugs your code has, Mallory beats DH. This is a basic challenge with DH. The solution involves more crypto.

DH is a useful building block, but protocols that use DH usually depend on some other operation to ensure security. For instance, DH SSL uses RSA certificates to beat Mallory. DH is useful to SSL; it gives you perfect forward secrecy by not tying your SSL session key to a fixed RSA key that can be compromised. But DH SSL depends on RSA for security.

So it’s not a good sign that IKE implementations aren’t smart enough to do parameter validation. But it doesn’t make much of a difference. The “vulnerability” allows an IKE participant to elect an insecure session.

accident? or… murder!

Adam wants to take this somewhere. So he writes a blog post suggesting that the uniform weakness of IKE implementations could be evidence of a conspiracy.

I don’t think he’s being entirely serious, but here’s his argument: the NSA —- no wait, it’s 2007, let’s make it the RIAA —- demands the ability to snoop on everyone’s IPSec sessions. They get all the IKE vendors to ship backdoored IKE agents. On some secret signal, the IKE agent will send public keys that work out to 0 mod p, and the RIAA can break these sessions with the sniffers they’ve installed at every exchange point on the Internet.

There’s a reason this is silly besides the fact that it involves backdooring one of the least important security mechanisms on the Internet: it’s a dumb attack.

Mallory knows p and g. So does Seth, the secops guy. Mallory can watch for A and B values that are 0 mod p. So can Seth. Why would the RIAA install a secret backdoor you could write an IDS signature for?

There are much more subtle things you can do to backdoor DH. Start with, IKE implementations can just be backdoored with a known private key value, or a root backdoor private key and an algorithm for generating variants of it. Move on from there.

This isn’t a conspiracy. This is just ignorance.

and I know that because…?

Because this vulnerability happens all over the place.

Take SRP for example. SRP is a derivative of DH. Alice is a client, Bob is a server. Alice and Bob know Alice’s password. Alice generates a public key that is related to the SHA-1 hash of the password. Alice and Bob do a DH exchange to prove Alice knows the password, and if the exchange works, Alice wins.

Mallory sends Bob a public key of 0 mod p. Mallory wins. She can log in as Alice without knowing Alice’s password.

This vulnerability is well known. It’s in the RFC for SRP. But I’ve tested SRP implementations written by smart security people, and they’ve had this vulnerability. (Due credit: I got this trick from Trevor Perrin, via Nate Lawson).

Compare the SRP vulnerability to the DH vulnerability. The SRP parameter validation problem is really, really bad. It’s auth bypass. The DH vulnerability is just a dumb way to backdoor an IKE agent.

well played, adam

IKE is a mess of a protocol. Crypto parameter validation attacks are totally underappreciated. Adam’s blog post is cool. It was smart of him to check for this, and interesting that he found it.

and what have we learned?

Not much about IKE. It’s as secure as you thought it was before you heard about Adam’s finding.

Hopefully a lot about crypto, though. Like I said, we wrote a post last year talking about parameter validation tricks for DH, SRP, Elliptic Curve, and RSA.

Forget about algorithmic attacks and advances in factorization and quantum computers. Parameter validation attacks are a systems flaw; systems depend on code, and code is riddled with bugs. All bugs are vulnerabilities. Most… any? cryptosystems will be beaten by stupid bugs like this.

Go look for them!


[1]: g is a primitive root modulo p. For values of x from 0 to p - 1, raise g to x modulo p. If g is a primitive root modulo p, you’ll end up with every number between 1 and p - 1, in some order. For instance, the following Ruby snippet asks if 3 is a primitive root mod 37.

lst = [] ; 0.upto(36) {|d| lst << ((3 ** d) % 37)} ; lst.sort

elicits the following output:

[1, 1, 1, 3, 3, 4, 4, 7, 7, 9, 9, 10, 10, 11, 11, 
 12, 12, 16, 16, 21, 21, 25, 25, 26, 26, 27, 27, 28, 
 28, 30, 30, 33, 33, 34, 34, 36, 36]

2’s missing. So’s 5 and 6, etc. 3 is not a primitive root mod 37. Now try 5:

lst = [] ; 0.upto(36) {|d| lst << ((3 ** d) % 37)} ; lst.sort

[1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 
 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 
 29, 30, 31, 32, 33, 34, 35, 36]

All the numbers between 1 and 36 are there. 5 is primitive root mod 37.

Why is this important? Because if you’re working with a 1024 bit prime, you want session key values to possibly be any one of those 1024 bit values. Another word for “primitive root” is generator. Generators generate the entire group of values mod p. Bad values of g generate subgroups, with fewer than 1024 bits of possible values. The worst g values generate only two possible values!

Comment Bubble 7 Comments

Robert Hansen Loses His Sh*t Over Google Gadgets

Thomas Ptacek | August 22nd, 2007 | Filed Under: Disclosure, New Findings

  1. RSnake discovers that Google gadgets can be coerced into rendering arbitrary Javascript tags, and reports it to Google.

  2. Google responds, in effect, “that’s one of the reasons why they live under gmodules.com”, continuing, “If you do find a way of executing this code from the context of a google.com domain, though, please let us know.”

  3. RSnake decries a “slap in the face”, saying “Google needs to figure out what XSS is used for”. Attackers can set up phishing sites on “Google-branded domains”.

Um, RSnake.

  1. Phishers can create “Google branding” on any site they want. That “Google branding” is just a GIF. Pretty sure Javascript anywhere can put it on the screen.

  2. That same “vulnerability” appears to be present on Blogspot. Presumably, on Typepad, Livejournal, and Wordpress as well.

  3. Last time I saw a Bank of America phish, the logo wasn’t drawn in Windows Paint. I didn’t blame Bank of America.

  4. Likewise, I’m not sure it’s hard for phishers to find or create infected domain names that start with the letter ‘g’.

What, exactly, do you want them to do? I like your stuff and all that, and if it’ll make you happy, I’ll bribe Dave to give you a Pwnie for “best Google hack” over this —- but, am I wrong about this? Or are you?

Comment Bubble 19 Comments

Cheating Process Scheduler Algorithms

Thomas Ptacek | July 12th, 2007 | Filed Under: New Findings, Uncategorized

Via Slashdot:

You’re a bad guy sharing a Linux server with a bunch of good people. All of you are running processes and those processes share access to the CPU by working in 10-100 millisecond time slices. This is called multitasking.

You don’t want to share because you’re bad. So unlike the good people, your processes:

  1. Figure out how long a timeslice is in cycles

  2. Sync themselves to the start of a clock tick with a scheduling no-op nanosleep()

  3. Execute for fewer instructions than is allocated to a process time slice.

  4. Yield back to the scheduler with another nanosleep().

The result, on many OSs, is that the scheduler basically doesn’t “notice” you ran. You get an unfair share of scheduler resources, or even monopolize the CPU.

Yawn.

A question: anyone researching attacks against hypervisor scheduling algorithms? Nobody shares an OS kernel with other people anymore, but in a few years everyone will share iron in side-by-side VMs. I mean, apart from things like Linux KVM virtualization (which is just processes, so is presumably affected somehow).

Comment Bubble No Comments

C++: A Cautionary Tale, or, 1 Hour Of Your Black Hat Trip is Spoken For

Thomas Ptacek | July 12th, 2007 | Filed Under: New Findings, Uncategorized

[Update 7/12]

This post touched a nerve on Reddit. C++ programmers, unsurprisingly, have some issues with this post. Go read the Reddit comments; they’re excellent. And then vote my post up!

1.

Almost 10 years ago, during the dot-com bubble, I did what many security pros before and after me did and “gave up on security” to “go do something meaningful” [∗]. I was at Network Associates (after they bought Secure Networks), and David Meltzer, my alter-ego at ISS, recruited me into a startup along with Danny Dulai and Tim Newsham. We wanted to build the chat system of the future, and we ended up with application-layer multicast streaming media. In 1999. We were a bit ahead of our time [∗∗].

This is good to know because it will help you avoid ever starting a discussion with me about reliable multicast protocols (down with forward error correction!) or source-specific multicast routing (down with source-specific multicast routing!). But why I bring it up is, we wrote it in C++. We wrote a lot of C++. A lot. We used ACE. Used ACE before? You know how much C++ we were swimming in. A lot of C++. Template-y, Boost-y, Alexandrescu-understandingy C++.

2.

Now this is a security blog, and so I’m supposed to be using this time to make a point about security, and that point is this: the notion that C++ is a more secure language than C is a myth. C++ gives you a dynamically-resizeable string class, which makes it less likely that you are going to write the splitvt overflow. But it also gives you a dozen new features which, if you use them wrong, segfault your program.

3.

Take exceptions. C++ has built-in support for exceptions; when something horrible happens, you “throw” a variable that any stack frame up the call chain can “catch”. This is better than returning a cryptic error code, because you can’t forget to check it.

But. When you throw an exception, you effectively “abort” your current function, and all the functions in the call chain up to the point where the exception was caught. If any of these functions aren’t written to anticipate getting preemptively aborted, and hold on to a pointer or a chunk of memory, you’ve got a memory lifecycle bug.

This problem is well known to the C++ community. Herb Sutter wrote a famous article about it, which invented the notion of “exception-safe” C++ programming. Joel Spolsky wrote a JoelOnSoftware about it. There’s a debate about whether C++ exceptions are evil.

But it’s not well known problem to the security community. A year or so ago, Mark Dowd found yet another Sendmail vulnerability. Sendmail is written in C, not C++, but it uses Unix signals and “longjmp” to emulate C++ exceptions, and (it’s Sendmail, after all) isn’t written exception-safe. You can trigger a timeout exception, and Sendmail will retain an invalid pointer into the stack that it would have cleared out if the exception hadn’t occurred. That pointer can be used to scribble over stack frames.

Any time you have a language feature, and you have to think about writing code to be “that-language-feature-safe”, you have a security problem. Because that feature is creating bug classes. Bug classes are bad. Splitvt? That’s a bug. Stack overflows? Bug class. Stack overflows cost the industry over $700MM. Exception-safety problems? Bug class. One that C++ introduces.

4.

Want another example? Destructors. Mark Dowd and John McDonald wrote a blog post about it a few months back. Do you audit code at your job? It’s one of the top #10 most valuable blog posts of the year. Long story short? If you call “delete[]” instead of “delete” —- which is an exceedingly common C++ error —- you’ve introduced a potential vulnerability. Like integer overflows, a bug class.

5.

Here’s another example: the STL. STL (or, more properly, the Standard C++ Library) is the collection of container classes C++ provides. In C, if you want a hash table, you have to implement it yourself. In C++ —- bad example. But if you want a red-black tree with the same API as a hash table, it’s provided for you. Also linked lists, resizeable arrays, and something called a dequeue (prounced “woon”). The STL is one of the great features of C++.

It’s also a reliability disaster. Here’s why: STL containers try to hide pointers from you. Instead of pointers, you get “iterators”, which are objects with a variety of interesting methods and generic functions that operate on them and all sorts of other fancy gunk and at the end of the day it’s all just 1500 lines of C++ template code wrapping: a pointer.

STL tries to avoid the most common pointer bugs, like walking off the end of an array into bad memory. But some bugs can’t be avoided. So for instance: if you modify an STL map (which is a red-black tree) [∗∗∗] vector or dequeue, you invalidate all your outstanding iterators. Modifying a red-black tree container potentially repositions the nodes they pointed to, and all that fancy OOP gunk aside, iterators are just pointers, not magic. If you hold references to those invalid iterators, they now point to invalid addresses.

This is an absurdly common problem. I’m an OK developer, if I do say so myself, but Danny Dulai, Kneel Fachan, and Tim Newsham are just fucking insanely talented developers and they ran into these problems, just like me.

And again, this problem is well known in C++-world (there’s a whole very excellent book about it). But it’s not well known in the security community. And when you screw it up, it’s potentially exploitable.

6.

C++ gives you a resizeable string, so you won’t write splitvt. But in 2007, code vulnerabilities don’t look like splitvt anymore, ever. We’ve moved on, through off-by-one errors into integer overflows and now uninitialized variables. On balance, the bug classes C++ introduces are way scarier than the ones it takes off the table.

So, to kick off our series of posts about which Black Hat talks you should be going to this year, I’m going to recommend this one. Mark Dowd and John McDonald, on stage, talking about the ways C++ screws software security that you hadn’t thought of before. “Recommend” is an understatement. If you get paid to find vulnerabilities in code, this is the most valuable talk at the conference this year.

See you there!


[∗] For the most recent example of this phenomenon, see Dug Song.

[∗∗] This is marketing-speak for “wrong”; you can say the same thing for a batter’s swing when he takes a strike.

[∗∗∗] Deleting map nodes invalidates some iterators in a map, but adding nodes doesn’t. Breathing on a dequeue invalidates iterators.

Comment Bubble 31 Comments

Joanna: We Can Detect BluePill. Let Us Prove It!

Thomas Ptacek | June 27th, 2007 | Filed Under: Defenses, New Findings, Uncategorized

Nate Lawson, spilling the beans on our some of our Black Hat plans:

“The crux of the matter is that a perfect emulator of any sufficiently complex system would have to be a bug-free program, and we don’t know how to write those yet,” he argued. “The important thing to consider when writing a rootkit is what layer to implement it at. Joanna chose “entire x86 PC”, which we argue is too big a cross-section.”

Joanna, we respectfully request terms under which you’d agree to an “undetectable rootkit detection challenge”. We’ll concede almost anything reasonable; we want the same access to the (possibly-)infected machine than any antivirus software would get.

The backstory:

  • Dino Dai Zovi, under Matasano colors, presented a hypervisor rootkit (“Vitriol”) for Intel’s VT-X extensions at Black Hat last year, at the same time as Joanna presented BluePill for AMD’d SVM.

  • We concede: Joanna’s rootkit is coolor than ours. I particularly liked using the debug registers to grab network traffic out of the drivers. We stopped weaponizing Vitriol.

  • Peter Ferrie, the Symantec branch of our Black Hat team, releases a kick-ass paper on hypervisor detection. Peter’s focus is on fingerprinting software hypervisors (like VMWare), but he also comes up with a clever way to detect hardware virtualization.

  • Nate Lawson, Dino, and I are, simultaneously, working on hardware rootkit detection techniques.

  • Nate, Peter, Dino, and I join up to defend our thesis at Black Hat: if you surreptitiously “hyperjack” an OS, enabling hardware virtualization (or replacing or infecting an existing hypervisor), you introduce so many subtle changes in system behavior —- timing and otherwise —- that you’re bound to be detectable.

And so the stage is set for our Black Hat talk.

For the record: I’m the least scary member of this particular team, but have likely written the most code (by LOC) behind the talk. Obviously, Dino’s Vitriol work is what made it possible for us to figure this stuff out, and Joanna’s BluePill work —- which we haven’t seen —- is what makes it interesting.

I’ll have more to say in the coming weeks.

Comment Bubble 9 Comments

Theo de Raadt: Intel CORE 2 Bugs “Assuredly” Exploitable From Userland

Thomas Ptacek | June 27th, 2007 | Filed Under: New Findings, Uncategorized

Our commenters will be more useful than I will on this post, but:

Theo de Raadt on Intel CORE 2:

These processors are buggy as hell, and some of these bugs don't just
cause development/debugging problems, but will *ASSUREDLY* be
exploitable from userland code.

Errata he calls out specifically:

AI65

When the temperature reaches an invalid temperature the CPU does not generate a Thermal interrupt even if a programmed threshold is crossed.

I don’t see how this is a security concern; maybe he meant AI56, which gives unpredictable behavior if you change the attributes of a PTE without fixing up the TLB; AI64 involves system management mode and AI67 involves VTX.

AI79

During a series of REP (repeat) store instructions a store may try to dispatch to memory prior to the actual completion of the instruction. This behavior depends on the execution order of the instructions, the timing of a speculative jump and the timing of an uncacheable memory store. […] When this erratum occurs, the processor may live lock and/or result in a system hang.

Unless the behavior depends on system memory inaccessible to userland, this could imply userland crasher exploit.

AI43

When a logical processor writes to a non-dirty page, and another logical- processor either writes to the same non-dirty page or explicitly sets the dirty bit in the corresponding page table entry, complex interaction with internal processor activity may cause unpredictable system behavior […] and hang.

Two userland processes on two different cores can race each other and hang the system?

AI39

When request for data from Core 1 results in a L1 cache miss, the request is sent to the L2 cache. If this request hits a modified line in the L1 data cache of Core 2, certain internal conditions may cause incorrect data to be returned to the Core 1.

Where the word “incorrect data” is errata code for “Zuul’s return as the Sta-Puft Marshmellow Man” —- two cores race each other, and a process gets the wrong cache line.

AI90

If code segment limit is set close to the end of a code page, then due to this erratum the memory page Access bit (A bit) may be set for the subsequent page prior to general protection fault on code segment limit. […] a non-accessed page which is present in memory and follows a page that contains the code segment limit may be tagged as accessed.

Theo says this is exploitable on operating systems other than OBSD; the A bit signals the VM system that a page has been accessed by the hardware.

AI99

Code #PF (Page Fault exception) is normally handled in lower priority order relative to both code #DB (Debug Exception) and code Segment Limit Violation #GP (General Protection Fault). Due to this erratum, code #PF may be handled incorrectly, if all of the following conditions are met:

  • A PDE (Page Directory Entry) is modified without invalidating the corresponding TLB (Translation Look-aside Buffer) entry

  • Code execution transitions to a different code page such that both:

    • The target linear address corresponds to the modified PDE

    • The PTE (Page Table Entry) for the target linear address has an A (Accessed) bit that is clear

  • One of the following simultaneous exception conditions is present following the code transition:

    • Code #DB and code #PF

    • Code Segment Limit Violation #GP and code #PF

Software may observe either incorrect processing of code #PF before code Segment Limit Violation #GP or processing of code #PF in lieu of code #DB.


We’ll have more to say about chip errata this month.

Comment Bubble 2 Comments

Details on Dino’s QuickTime Advisory (With Code Snippet)

Thomas Ptacek | May 1st, 2007 | Filed Under: Apple, Disclosure, New Findings, Uncategorized

As Dave noted, Apple has released a patch for Dino’s QuickTime finding. 3Com followed up with their advisory. Direct your attention to the nut graf:

The flaw exists within the QuickTime Java extensions (QTJava.dll), specifically the routine toQTPointer() exposed through quicktime.util.QTHandleRef. A lack of sanity checking on the parameters passed to this routine, through the Java Virtual Machine (JVM), allows an attacker to write arbitrary values to memory.

What this is saying:

  • If you have the QuickTime for Java extensions installed (in other words, if you have QuickTime installed),

  • then a Java applet will be allowed to construct and play with QuickTime objects, which are backed with unprotected C code,

  • and specifically, some of those objects wrap pointers to memory tracked by a dynamic C library,

  • and unfortunately those objects are not careful enough with the values passed to them by Java code,

  • so Java applets can overwrite arbitrary process memory directly,

  • which they should never be able to do, because keeping Java applet code from touching memory directly is the whole point of the applet sandbox.

The vulnerability appears to be an integer overflow. Translated to minimal Java code (say, the init method of an applet), it reads:

// Initialize QT
QTSession.open();

// Get a handle to anything
byte b[] = new byte[1 /*arbitrary*/];
QTHandle h = new QTHandle(b);

// Turn the handle into a pointer object. The
// large negative value throws off bounds checking.
QTPointerRef p = h.toQTPointer(-2000000000 /*off*/, 10 /*size*/);

// Write to it.
p.copyFromArray(0 /*offset*/, b /*source*/, 0, 1 /*length*/);

In applet form, this reliably crashes my browsers. It is both deliberately and organically far from being useful to an attacker. Note that without comments, it’s 5 lines of code.

Get this one patched quickly! From the ZDI advisory and the QTJava documentation it looks like it takes very little time to figure this one out.

[Update: 11:00PM EST]

Read carefully and note that ZDI’s advisory confirms QuickTime for Vista is vulnerable.

Comment Bubble 26 Comments

BREAKING: The Bug Report That Would Not Die: Dino’s Finding Works In IE7

Thomas Ptacek | April 24th, 2007 | Filed Under: Apple, Defenses, Disclosure, Industry Punditry, New Findings

This just in: anonymous sources at 3Com confirm Dino’s QuickTime vulnerability is exploitable in IE7 and IE6 on Windows XP.

Watch this space for details (Is XPSP2+DEP reliably exploitable? You can’t run IE7 on XPSP1 —- so, probably! Vista?) as they’re made available to us.

I think we can now safely conclude: this is a hell of a finding. Way to go, Dino!

Irony Alert

Consider the possibility that the one platform this vulnerability won’t work against is Windows Vista.

[Update: 4/25]

As usual, the comments on this post are much more valuable than anything I’ve written. Rosyna Keller and Skywing are discussing the protection mechanisms in IE6/IE7 (anyone know what the equivalent protections are in Safari? Oh, wait…).

More importantly, our source at 3Com has re-confirmed that IE6 and IE7 are vulnerable to this attack. More details about the vulnerability as they become available.

[Update: 4/27]

I’m simply deleting comments that say things like “XXX is not vulnerable” or “YYY is vulnerable” without evidence.

Comment Bubble 32 Comments

Who We Are

Matasano is a team of internationally respected security experts who have led security efforts at @stake, Microsoft, ISS, Secure Computing, Arbor Networks, Secure Networks, Bloomberg, Sandia Labs, and others. Read more about our team and how we can help you today.