Thursday, January 29, 2009

Coding Heresy: shellcode in software developement

One of the odd things about coding is that you are taught to follow some sort of moral code. Your professors are high priests that try to teach you right from wrong. For example, “global variables” are a well-known “evil”, and it’s morally wrong to use them.

Another heresy is using “shellcode” in the course of normal software development. Shellcode is the opaque array of bytes that hackers include in the buffers that they overflow, which give them a remote command shell on the victim machine. However, you can also use the idea to execute bits of assembly language code in a portable manner within software projects.

Today, you have the same x86 processor underneath Windows, Linux, and Macintosh. However, there is no easy way to write assembly language for all these systems. The syntax ‘gcc’ uses to assemble code is different than the Microsoft syntax. What you write as “mov %ebx, %eax” under gcc becomes “mov eax, ebx” in the Microsoft syntax.

The obvious solution to this problem is to assemble the code only once, then dump the resulting bytes into your project.

I’m currently writing a password cracker. I want to run the password cracking code on all the machines in my home, and I have Linux, Windows, and Mac OS X systems. I also want to it to use SSE instructions, which are 5 times faster than normal code. SSE code must be programmed in assembly language.

To write the assembly language functions, I use Microsoft’s assembler. I don’t use the resulting functions, but instead dump their raw bytes. I then use those raw bytes in the code.

This is shown below with a simple function that returns ‘1’ if SSE is supported by the processor, and ‘0’ if SSE is not supported. This uses the assembly language instruction "cpuid".
unsigned cpu_supports_sse2()
{
static unsigned char cpu_supports_sse2_shellcode[] = {
0x53, /*push ebx*/
0x33, 0xC0, /*xor eax,eax*/
0x0F, 0xA2, /*cpuid*/
0x83, 0xF8, 0x01, /*cmp eax,1*/
0x73, 0x04, /*jae continue*/
0x33, 0xC0, /*xor eax,eax*/
0xEB, 0x0F, /*jmp end*/
/*continue:*/
0xB8, 0x01,0x00,0x00,0x00, /*mov eax,1*/
0x0F, 0xA2, /*cpuid*/
0x8B, 0xC2, /*mov eax,edx*/
0xC1, 0xE8, 0x1A, /*shr eax,1Ah*/
0x83, 0xE0, 0x01, /*and eax,1*/
/*end:*/
0x5B, /*pop ebx*/
0xC3 /*ret*/
};
return ((unsigned (*)())cpu_supports_sse2_shellcode)();
}


As you can see, this code will compile and run the same whether or not it’s a gcc compiler for Mac OS X and Linux, or Microsoft’s compilers for Windows. As far as the compilers can figure out, it’s just an array of bytes. (I include the original assembly language as comments, but these are ignored by the compiler).

Elsewhere in my code, I do the same thing for the SSE version of the password cracking routine. In one file, I call the following function:
crypto_ntmd4_sse(data_block);

In another file, I define the symbol as an array of bytes:
unsigned char crypto_ntmd4_sse[] = {
0x55,0x8b,0x6c,0x24, 0x08,0x53,0x56,0x57,
0x66,0x0f,0x6f,0x45, 0x90,0x8b,0x45,0x90,
0x66,0x0f,0x6f,0x4d, 0xa0,0x8b,0x5d,0xa0,
...


This function is over 2-kilobytes long, so I don’t hand disassemble it like I did the last one, but rest assured, those bytes are x86 code.

The heresy works because C is an “unmanaged” language. It knows the difference between “code” and “data”, but you can easily confuse it to think that “data” is “code”. It will happily jump to your data.

Code auditing tools should know the difference. They should be able to detect that something heretical is going on and put up warnings. Likewise, security tools might notice that the program is executing code within the “data” segment.

As a result of this heresy, I’ve got a nice little program that compiles cleanly on all the systems, without any hassle (such as the hell that is Cygwin).

What happens if I want to change the assembly language routine? The first answer is “I usually don’t”. That’s what makes assembly language different from other source. Your frequently edit C software, but you avoid touching assembly language routines. If you want to make a change, you usually end up rewriting the routine from scratch. In any event, I still have the assembly source, it’s just conditionally compiled into an unused function. If I want to change it, I’ll just manually copy the bytes out again. Here is the cpuid function source:
#ifdef _MSC_VER
unsigned __declspec(naked) msvc_cpu_supports_sse2()
{
_asm {
push ebx
xor eax, eax
cpuid
cmp eax, 1
jae xcontinue
xor eax, eax
jmp end
xcontinue:
mov eax, 1
cpuid
mov eax, edx
shr eax,1Ah
and eax,1
end:
pop ebx
ret
}
}
#endif


The last question is how this works with non-x86 processors. The answer to that is easy. For the ‘cpuid’ function that tests for SSE, you replace it with a version that simply does a “return 0;”. For the actual cracking function, you simply use the non-SSE version written in normal C. Thus, my program runs just fine on a PowerPC version of the Macintosh, but a lot slower. I’ll have to figure out an AltiVec version eventually, probably sometime after I get the GPU version up and running.

Saturday, January 17, 2009

Password cracking vs. CPU throttling

I can't crack passwords for long on my laptop because it quickly overheats.

I show the process to the right using a program called "RMClock" that detects CPU throttling. The bottom graph shows temperature, the top graph shows speed. When I start the password cracking software, the temperature rises quickly to the maximum. It reaches the maximum temperature and begins to throttle in only 10 seconds.

My CPU is a 1.86 Core 2 Duo. When it overheats, it gets clocked down slightly to 1.6-GHz. When the overheating problems gets worse, the clock is lowered again to 0.8-GHz. When it cools off, the speed jumps up again until it overheats again, then it jumps down. It keeps going up and down like this forever (or until I the cracking software).

Curiously, the laptop normally runs underclocked at 0.8-GHz, even when idle. It waits for me to run a program to boost it up to the full speed of 1.86-GHz.

Using both cores doesn't necessarily make my laptop crack passwords faster -- it just spends more time throttled due to heat.

My desktop doesn't have this problem. It's got 4-cores chugging away at 2.4-GHz and it's not exceeding 56-degrees. The problem, it seems, is that the cooling on the Mac Book Air sucks (or rather, blows). I put my hand on the back near the vents and I can barely feel the hot air coming out. This laptop is sexy as all get out, so of course I have to keep it, but it's got a lot of limitations as a computer.

UPDATE: Apparently, this overheating problem is well-known, and occurs under MacOS X as well as Windows. It's mentioned in the Wikipedia entry on the MacBook Air

UPDATE: Apparently, the solution for me is "undervolting". I can use the RMclock utility mentioned above, or the "CoolBook" utility under Mac OS X to artificially lower the voltage of the processor. Small changes in the voltage result in large decreases in the power consumption, and hence heat. Of course, in theory, this will make my machine less stable. At 1.86-GHz, the default voltage is 1.05v. I lowered this to the minimum of 0.925v, and the system seems perfectly stable and a lot cooler.

UPDATE: I ported the code to Mac OS X and ran it. Like Windows, the processor runs at 800-MHz, and jumps up to 1.86-GHz under load. Unlike Windows, a command-line utility like my password cracker doesn't seem to be recognized as load, so won't bump up the speed. Thus, the passwords are being cracked at 800-MHz.


Friday, January 16, 2009

Quick, someone explain what branding and a corporate icon is to John Gruber, he doesn't seem to know....

http://daringfireball.net/linked/2009/01/16/enderle

Applying Gruber logic to his own blog he is pretty dumb, I mean he isn't on fire (I assume), and his blog wasn't founded by an ACTUAL fireball.

UPDATE: John Gruber just broke the story: The Burger King mascot, "The King" is not actually from royal blood. In the mean time we are all waiting for the Apple board to tell us that Steve Jobs is sick...like they promised...

Wednesday, January 07, 2009

Rats, foiled

I was in Japan over the holidays. I attempted to use my BofA card. Their fraud controls assumed something was wrong, and locked the card. In order to unlock it, I needed to visit a branch and show 2 pieces of ID.

I went to the local branch. They verified my ID, then called the same phone number I called to unlock the card. When she called in, the employee helping me identified herself saying "this is employee Alice Smith 2955".

Ah hah! She identified herself with an assigned 4-digit number. Now I have the number and can impersonate her!

However, this turned out to be the wrong department. She had to call another one to unlock the card. This time she said "this is employee Alice smith 6878".

Rats, it's not a fixed number. I tried to ask her what the number signified, and she quickly answered "I can't go into that". So, there is a complex system behind this, complex enough that she won't discuss it.

She had her computer in front of her. I'm assuming sort of intranet application whereby she applies for a temporary ID by clicking on a button, that the person on the other end quickly types in, popping up the name on their terminal that they can verify.

The interesting thing is that she could not be authenticated via the phone system. It's amazing that we've progressed this far in technology yet the phone system is still so far behind. On the other hand, anti-government paranoids (such as myself) want an anonymous phone system, so while I'm surprised phones have poor security, I'm also glad.

Friday, January 02, 2009

Versign's Bad Response to the MD5-SSL Crisis

I'm reading this blog by Verisign in response to the MD5-SSL problem (which is mostly Verisign's fault). I'm amused by this item:
Q: These researchers have discussed their desire to maintain secrecy so that the hammer of legal action couldn't be used to prevent publication. Does VeriSign intend to sue these researchers?
A: Security researchers who behave ethically have no reason to fear legal action from VeriSign. Since its inception VeriSign has been one of the world's leading forces for online security, and the company has consistently used its resources and expertise to assist online security's progress. In fact, VeriSign is itself a white-hat security research firm …, and we understand the concept of "ethical hacking." We're disappointed that these researchers did not share their results with us earlier, but we're happy to report that we have completely mitigated this attack.
This is not true. A white-hat organization is no more likely to behave responsibly than any other company.

I was Mike Lynn's co-worker during the Cisco scandal. You would assume that since Cisco is a "white-hat" company, they would not threaten Mike Lynn, but they did.

Errata Security gave a presentation a couple years ago about TippingPoint vulnerabilities. You would assume that since TippingPoint also is a white-hat organization, that that wouldn't repress researchers, but they did. We got a lot of pressure to cancel the talk, including the FBI showing up at our offices threatening us.

The problem with both Cisco and TippingPoint is not with the "organization" but with "individuals". In both cases, individuals made bad decisions. It is easy for individuals to delude themselves into thinking that their case is special, that the ethical rules don't apply to them. Unless there is a strong leader to squash them, they will go off the rails and do something bad. In Cisco's case, for example, their CSO was on vacation; had he been at work during the crisis, chances are good that he wouldn't have allowed Cisco to behave badly.

Tim Callan's blog does not fill me with confidence. This is the worst possible failure Verisign could have, short of public disclosure of their private keys. Callan isn't demonstrating that Verisign understands the gravity of the situation. He is instead spinning the situation, making Verisign look good and the researchers look bad. He is not behaving as a white-hat organizations should behave. If he is willing to attack the researchers AFTER the fact, what guarantee do we have that he wouldn't have attacked the researchers BEFORE the presentation?

The researchers behaved perfectly and responsibly. Their worry about being suppressed was justified, and their secrecy was an appropriate response. The very fact that Versign could quickly fix the problem in a day, but malicious hackers would need at least a month to replicate the feat, means that notifying Verisign ahead of time wasn't needed.

UPDATE: Adam Shostack points out this Wired blog which says:
Callan confirms Versign was contacted by Microsoft, but he says the NDA prevented the software-maker from providing any meaningful details on the threat. "We're a little frustrated at Verisign that we seem to be the only people not briefed on this," he says.

I'm not sure what "meaningful details" Verisign needed. We guessed the meaningful details only from the public data, although we made the mistake of assuming that Versign wasn't stupid enough to still be using MD5, and therefore guessed that it was a botnet running 6 months attacking SHA-1 (rather than 200 PS3 running a couple of days).

That article also quotes him:
"All the information that we have is that MD5 is not any kind of significant or meaningful risk today," Callan adds.
It's been a meaningful risk since 2005. The moment the first MD5 hash collision became public, Verisign should have moved quickly to stop using MD5. Callan has a reasonable argument that it takes time to stop using MD5, but 4 years was much more than they needed. They should have also fixed the fact that they are vulnerable to hash collisions (which, apparently, Verisign is still vulnerable to, but only the NSA has the resources to actually exploit this at the moment).

UPDATE: It gets worse. Verisign was notified of the full details. Tim Callan lied. Versign was notified of "successful generation of colliding x509 certificates signed by real certificate authorities which still use MD5" and "that RapidSSL and FreeSSL (also owned by Geotrust) use MD5 and are vulnerable to this attack".
http://www.phreedom.org/blog/2009/verisign-and-responsible-disclosure/