Logo




Subscribe:
RSS 2.0 | Atom 1.0
Categories:

Sign In


[Giagnocavo]Michael::Write()

 Monday, March 08, 2004
Nothing is secure

One thing to keep in mind is that nothing that I know of in this world is secure.  I'm not just talking about software.  Dictionary.com defines secure as “free from danger or attack”.  Can you think of ANYTHING that meets that definition?  Leave a comment and win a prize if you can.

Security is about probabilities.  “How secure is X?” is often asked.  Does that mean if we use ultra-high encryption that it's impossible for someone to break through?  If I chose a 256-bit key right now and encrypted my data with it, is my data secure?  Remember, it's *possible* that someone could guess a 256-bit key in one shot.  The probability of that is usually extremely low, although if I picked a key of all zeros a system might try that to start off and thus win in one turn.

So, when choosing your defenses and making your tradeoffs, always consider the probabilities of a certain attack occuring.  Wasting time “bulking up” defenses in one area while ignoring weaker areas is like optimizing code that isn't slowing your system down: pointless and a waste of time.  You will never have something that's “secure”.

Code | Security
Monday, March 08, 2004 6:48:27 PM UTC  #    Comments [0]  |  Trackback

Cracking code - Part 2: Other simple attacks

In part 1, we attacked the code by stopping it at a known point, the “invalid code“ message box.  From there, we were able to trace up to where a decision was made as to the validity of our serial/code, and change that logic around.

Going through someone else's compiled x86 code can be somewhat like going through your server's logs to find some specific information.  Most people don't start with log entry 0 and read each one.  We filter the logs, look for error entries, etc.  Depending on what we do know about the events we are looking for, we can find the related entries in different ways.  The same applies when going through code.  Here are two other simple things that we could do to SimpleCode.exe to break it:

Strings
We could search for all strings, and then look for “good“ strings, something we'd expect to see when our code is valid.  OllyDbg can dump these strings and search them, and then take us to the places where they are used.  From there, we can track up and see where/why that code wasn't called.

Our input
Every program needs to take our input, then somehow validate it.  If we enter some data that's easily recognizable (like “AAAA”), we can set a breakpoint on memory access to that location.  From there we can figure out what's being done to our input, which is useful for reverse engineering -- creating a “keygen”.  Having a keygen is much more valuable, because we don't need to make binary patches and modify the executable.  Between different versions of the software, the key validation will probably remain the same.  If we know how to generate our own keys, we have a “one size fits all” attack.

Code | Security
Monday, March 08, 2004 6:01:59 PM UTC  #    Comments [0]  |  Trackback

Vault - great source control

I just found a great product, Vault.  Vault is a source control system written entirely in .NET.  The main advantage of it is that it's easy-to-use, and also important, easy-to-setup.  I tried using VSS, really, I did!  But wow, it's really poor.  Getting things working correctly even on my local machine was a pain, not to mention on the LAN or over the Internet.  Vault took all of 5 minutes to install on an Internet-based development server, and works quite well -- as well as anything that has to interface with VS.NET can.  As well, if you're just looking for a system for your local machine, it's free for one user.  Very cool!

Code | Misc. Technology
Monday, March 08, 2004 5:36:33 PM UTC  #    Comments [0]  |  Trackback

Who do they think they are?

http://www.korea.net/menu/government/newscontent.asp?Number=20040307006

Last time I checked, this wasn't part of the states.

Misc
Monday, March 08, 2004 6:25:33 AM UTC  #    Comments [0]  |  Trackback

 Sunday, March 07, 2004
I've been Scobleized!

Scoble linked to me!  Around 2AM or so.  And now by 11AM, I've had over 500 visits (and some new subscribers)!  And this is on a Sunday.  Very cool.  Time to turn on the caching.

Personal
Sunday, March 07, 2004 5:07:35 PM UTC  #    Comments [1]  |  Trackback

Fixing dasBlog with intraVnews

I use intraVnews (www.intraVnews.com) to read RSS feeds.  It's free, and most importantly, it's integrated into Outlook.  However, I was having trouble getting intraVnews to read my blog's RSS feed.  I emailed intraVnews support (which is VERY good) and found out that intraVnews DOES have a problem with some dasBlog feeds.

The issue is that intraVnews sends an HTTP HEAD request to the RSS feed first, to see if it has changed.  A HEAD request is just like a GET, except that only the HTTP headers are returned.  Well, dasBlog uses a web service (.ASMX) to render the XML.  ASP.NET doesn't allow HEAD requests to ASMX files and will error.  If you have customErrors on (I think this is the default for dasBlog?), instead of a 500 internal service error, you get a 302 Found -- a redirection to an error page.  intraVnews then decides to throw this out.

Just by turning customErrors off in the web.config, the normal HTTP error will be returned, and intraVnews treats this just fine.  Thanks to intraVnews for pointing this out, and Rex Swain, for his cool HTTPView page, which lets you see exactly what's coming back in an HTTP response.

Misc. Technology
Sunday, March 07, 2004 5:01:25 PM UTC  #    Comments [0]  |  Trackback

 Tuesday, March 02, 2004
Cracking code - Part 1

Update 2004-03-07: Added screenshots.

Read the intro to find out why I'm writing this.

Alright, before we get into attacking .NET, let's see how it's done against common Win32 programs in x86.  First, you'll need a good disassembler/debugger.  I recommend OllyDbg.  It's very easy to use, and does a good analysis of the code, which helps us out quite a bit.  SoftICE is another alternative, but it's low-level, harder to use, and it costs $1000.  People tend to use this when they want to debug something like a device driver, or make a patch for Windows.

Here's the executable I wrote for this sample: SimpleCode.exe (44 KB) and if you feel like cheating, the source code: SimpleCode.cpp.txt (1.28 KB).  It's very simple.  In fact, the whole purpose is to validate the user code -- there's no real content that's protected.  However, it will be enough to learn from.  Also note that it only runs on Windows 2000 and above.  If you aren't using that OS, upgrade :), or get the code and fix it, or email me for a version you can use.

So, let's open OllyDbg and make sure the analysis options are on (Alt-O, check all of them out).  Now, load SimpleCode.exe.  OllyDbg loads and disassembles the code.  You now have a console window open, and a bunch of x86 on your screen.  Let's run through the program (F9).  Enter 4 chars for your serial, and 4 for your activation code (no checking is done, so you'll screw up the program if you enter more data).  A message box appears telling us the code is invalid:


That's our way in, for this example.  We know that somewhere before the message box was shown, our activation code was tested.  So, let's go breakpoint at the message box.  Restart SimpleCode (Ctrl-F2).  Right click in the main window and select Search for -> All intermodule calls.  In the new window, type MessageBox.  You'll see two calls to MessageBoxA.  A real program would have many more.  Right click one of the calls and select “Set breakpoint on every call to MessageBoxA”. 


Run the program and enter fake serial/activation again.  The program breaks at “00401163  |.  FF15 DC804000 CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA“.  If we look up a bit, we can see that the arguments loaded are for the invalid serial.  This is the message box we want.  Go into breakpoints (Alt-B) and disable both breakpoints.  Now, the opcode right after the MessageBoxA call is C3, RETN, the end of the function.  Considering the code for this function is very short (21 lines), it should contain only the “bad” code -- code we don't want executing.  Press F8 to step over that call.  Dismiss the message box.  Notice you can press “;“ to add comments to lines.  It'd be good to mark this line with something like “Return from displaying bad message box.“, just in case we get lost later on.  In many programs, there will be many interesting points, so good commenting is key.


If you're going to be doing real attacking, you need to learn some X86.  Important things are CALL, RETN, the various jumps, and comparisons.  Because most likely, somewhere inside your target program, a check is performed and then a corresponding action is taken.  If we can reverse the logic, then we can make the program think correct data was entered when it wasn't (and the opposite: correct data will be considered incorrect).

Now we're about to return to the point that called this function.  Press F7 to see where that takes us.  Now we're on “00401274  |.  8B4C24 3C     MOV ECX,DWORD PTR SS:[ESP+3C]“.  The line above that is the callsite of the “bad display function“.  Comment it as such.  Look around.  OllyDbg should display some arrows indicating jumps and targets.  If it doesn't go into debugging options and check your settings. 

Notice that the callsite of the bad function is a jump target from “00401259  |. /74 14         JE SHORT SimpleCo.0040126F“.  If we take the jump, we end up calling the bad function.  If we don't we RETN (look at the line right above the bad callsite).  Sounds interesting.  Set a breakpoint on that JE instruction, restart, run and enter the data.


JE means “jump if equal“.  It's opposite is JNE (jump if not equal).  Our program is stopped right now at a JE, and OllyDbg says the jump will be taken.  Since the jump goes someplace bad, we don't want it to happen.  Press space.  This opens the reassembler.  Change the JE to JNE and press assemble.  OllyDbg patches the in-memory executable. 


Let's see what happens.  If we're lucky, this will call the “good“ code.  If not, we just patched something else and the program at the best is going to do something strange, but most likely will crash and burn.  Press F9.



What's that?  Thanks for activating?  Why, you're quite welcome!  That jump did it.  Wasn't that easy?  And we didn't have to learn much X86 at all.  To save your changes, we'll need to restart (OllyDbg will complain since the breakpoint code was patched and changed) and goto the breakpoint and re-patch.  This time, right click and select “Copy to executable -> All modifications”.  Now we've got a patched program.

This was extremely easy (it was a very simple program!), and just demonstrates one way that someone could attack your code.  It's also an inflexible attack (a binary patch, versus finding the algorithm), so if a new version is released, we need to debug and patch it again.  Hope you learned something!

Update 2004-3-8: Part 2 now available.

Code | Security
Tuesday, March 02, 2004 7:20:18 PM UTC  #    Comments [7]  |  Trackback

Cracking code - Introduction

To defend, you must have some idea of what you're defending, and who and what you're defending against, specifically, which attacks.  Failure do understand and know these things means that your defense will most likely not be effective, and could in fact decrease your security.  Here's an example:

Near where I live, thieves were stealing cars that people parked in the street.  The neighbourhood committee decided that they'd stop this.  The solution they implemented was to put gates at all entrances and exits of their area, and have guards that only allow cars with a particular sticker get through.  This makes people FEEL more secure.  However, for the cost (guardhouses and gates construction, guard salaries), it's not as effective as it could be.  A thief can still walk in just as easily (gates only block roads), and when driving a stolen car out, the guards will see the car and sticker, recognize it, and let them leave.  If they had thought about how thieves operated, then they would have realised this and done something more effective, perhaps hiring the same number of guards, but setting them on a patrol, instead of just sitting at their posts.  With unlimited resources, they could do both things, and give each member a special remote key-code to unlock the gate when they are driving.  However, the tradeoff in cost and convenience is too high for them.

This is how security is, in the physical and electronic worlds.  We have many possibilities, each with their tradeoffs.  Deciding which measures to implement requires us to understand how our opponent is going to operate, as well as the details of how exactly our defenses work.

In this series, I'm going to show you how to crack simple code.  I'm going to make a series of samples to try this out on (to avoid DMCA problems with real code), so as to get a feel of what crackers do to code.  It is not going to be in-depth or show how to become a master cracker.  Just enough so that we could attack a simple Windows/.NET program's licensing key system, which is a common theme in software protection.

Continue to Part 1, where we'll crack some simple code...

Code | Security
Tuesday, March 02, 2004 5:26:40 PM UTC  #    Comments [5]  |  Trackback

 Monday, March 01, 2004
Processing HTML into safe HTML with .NET - Part 3

Now that I've decided on which library to use, I'll describe the actual code.

We already know that HTML, esp. in Internet Explorer, provides many attack vectors.  And new versions of the browser could add another tag or attribute that can execute code.  So we need to use a whitelist, not a blacklist.

Next, there are many more legit users than attackers.  So when dangerous content is detected, it needs to be removed -- we can't just blow up and tell the user not to hack us.  The number of false positives could actually be rather high, since some people are going to use Word and end up with a lot of tags and who knows what else.  And finally, users could accidentally paste something that's potentially dangerous.  Yelling at them, or even telling them to fix their code isn't going to work, since they're maybe not even aware that HTML exists.

So, here's the code:
SafeHtml.cs.txt (3.28 KB).  It's very short and easy, thanks to the HtmlAgilityPack.  The processing of style tags is pretty weak (simple replacements), but should do the trick.  Enjoy!

Update 2004-Mar-04: Forgot to handle <A href=”scriptType:code...”>.  Be sure to add that if you use this code in production.

Code | Security
Monday, March 01, 2004 7:14:24 PM UTC  #    Comments [0]  |  Trackback

Processing HTML into safe HTML with .NET - Part 2

Following up from part 1, I reviewed three different libraries:

HTMLDocument is a commercial component ($249 per dev, inc. source code).  The other two are libraries written by some cool people at Microsoft and include source code.

SgmlReader is basically an XmlReader that can handle HTML.  To write, we need to use an XmlWriter, and that can mess up the HTML, and we don't want that.  SgmlReader seems like it'd be ok if all we wanted to do is determine if there's unsafe content and then return false, but that's not what we need.

However, both HtmlAgilityPack and HTMLDocument read HTML and create a DOM out of it, allowing you to modify it and write the HTML back out.  This is what we need.  I briefly looked over both libraries to see which one I want to program against.  I gave them both an equal rating to start off with, but the scales rapidly tipped in favour of one library.

HTMLDocument definately loses as far as API niceness and robustness.  Some problems:
  • Inconsistency when loading data into the HtmlDocument.  If you have a string, it needs to go in the constructor, otherwise, use an instance method.
  • Enums (both of them) are prefixed with “e”.  Why?
  • Lack of types.  There are four types total.  That's all.  No HtmlAttribute.  No HtmlElementCollection.  Nothing like that.
  • Weak-typed collections.  ArrayLists and HashTables are used as the collections, instead of strongly-typed collections.  So you must cast, and if you insert an unsupported object, then it will throw an exception  when writing the HTML.  Not very robust.
  • And the silliest thing of all: No encoding support.  Worse than that, FORCED ASCII.  If you open a file, their code opens a stream, manually passing ASCII encoding.  No BOM detection, no system default, just ASCII.  Ouch.
These things made me seriously doubt how professional a library HTMLDocument is.  Most of these things are ultra-simple to fix.  If I was forced to use this, I'd have to buy the source code just to make it right.  It seems like it's purpose is to demonstrate how not to construct a class library.

What's more is that HtmlAgilityPack doesn't have any of these flaws.  In fact, it seems like it's actually a missing piece of the base class libraries.  Superbly done.  Writing code against it was so easy and natural.  I'm extremely impressed.  Even the documentation is much more complete (it comes with a 180KB HTML Help file, compared to HTMLDocument's 36KB HTML Help file).

Hands-down-winner: HtmlAgilityPack.
Code | Security
Monday, March 01, 2004 6:54:09 PM UTC  #    Comments [0]  |  Trackback

Business Untelligence: Supply and Duhmand

Since I'm about to leave Guatemala after living here for over six years, I thought I'd jot down some experiences as to remember them.  I'm not making this up.

At a store, my father asked for some soap.  He was told that they currently did not have any, and that they wouldn't for two weeks.  My father suggested that if they were selling so much soap, perhaps they'd order more.  The storekeep smiled and said “Well actually, we never sell soap for the second half of the month.  Our records show that we only sell soap for the first two weeks and then none for the rest of the month.  So, we only buy for the first two weeks.”

I went to buy a microwave at the biggest Sony distributor in the country.  In the front of the store they had a very interesting microwave with some really advanced features.  I asked how much it was, and was told that I couldn't buy it, since they didn't have any.  When I pointed out to the salesperson that they did, in fact, have one, and it was right there, he said “That's our display unit.  If we sold that, we wouldn't be able to show it to other customers.”

Humour
Monday, March 01, 2004 2:29:43 PM UTC  #    Comments [0]  |  Trackback

 Sunday, February 29, 2004
Learning MSIL

I was going to write a series about learning MSIL (Microsoft Intermediate Language, or simply “IL“), and then get into more advanced topics.  However, I found a good tutorial (and no doubt there's more if I use Google for am minute) at CodeGuru, called MSIL Tutorial.  It should be enough to get people up to some speed.

I'll be writing some articles about how people actually attack programs, starting with nice x86 assembler, and then showing how attacks against .NET programs can use many of the same vectors.  I'll show how, even with some weak obfuscation (and by weak I mean pretty much every product currently available), crackers still have an easier time on .NET than on native x86/Win32.  Then I'll talk about some mitigation techniques that can be used to make things somewhat harder.

Code | Security | IL
Sunday, February 29, 2004 5:43:53 PM UTC  #    Comments [2]  |  Trackback

McDonalds home delivery and amazing service

One thing about living in Guatemala is that McDonalds has a delivery service.  I don't think they do in Canada or the states.  I wouldn't usually write this, but they had some awesome service today.  My nephew stayed at my house last night, and this morning we called for a Happy Meal.  He is collecting the current toy line, so we asked for a specific part. 

Well, when the delivery guy showed up, they had the wrong one.  I figured we'd go later and change it.  A few minutes later, McDonalds calls to apologize for the mistake and invites us to come by to change the toy.  An hour later, they show up at my house, just to deliver the new toy and apolgize again.  WOW!  That'd be impressive in most countries, but it's doubly so in Guatemala, where the concept of customer service is pretty much non-existant.

Personal
Sunday, February 29, 2004 5:32:28 PM UTC  #    Comments [0]  |  Trackback

IMEs and MUIs

Every day I get a few hits from people using Google to find information on IMEs.  Judging from their search queries, I'm guessing they want to install an IME.  If you are one of these people, try this to start off:
http://www.google.com/search?hl=en&lr=&ie=UTF-8&oe=UTF-8&q=site%3Amicrosoft.com+IME

MUIs (Multilingual User Interace) Packs are extremely awesome.  They REALLY enhance Office.  However for some <adjective> reason, you can't easily get them.  I have them since they're included in my MSDN subscription.  Otherwise, see these links for requirements:
http://www.google.com/search?hl=en&lr=&ie=UTF-8&oe=UTF-8&q=site%3Amicrosoft.com+MUI

Hopefully someday Microsoft will make ONLY English language versions, depending on enhanced MUI packs for localization.

Misc. Technology
Sunday, February 29, 2004 4:01:55 PM UTC  #    Comments [0]  |  Trackback

Remoting and multithreading

The other day I got an interesting email.  A client who we had written a payment processing system was having trouble with MQSeries (shudder), and was pinning the blame on our system.  The issue was that when MQSeries dispatched a message that eventually timed out (30 seconds), the payment server blocked until the timeout was returned.

At first, we thought that MQSeries was to blame.  After all, it's a most annoying piece of software (it starts up around 30 processes for some reason).  There's a reason that IBM's consulting division makes so much money :).  But we thought that serializing all connections was a bit bad, even for IBM.

Remoting seemed unlikely.  After all, how could anything be scalable if remoting used only one thread?  After some tests, we found out the cause.

Apparently there is a bug in remoting.  Or perhaps it's by design.  The result is that it appears as if remoting tries to keep one and only one thread per CPU active.  This could be a performance benefit, assuming your thread is using the CPU.  However, when your thread blocks, for instance, calling Thread.Sleep for more than a few hundred miliseconds, or calling WaitOne with an indefinite timout, remoting releases a new thread.  This is actually a decent scenario for most things, since it assures your CPUs are operating at the highest efficiency.

The problem was the MQSeries was being called via a MC++ interop library.  (IBM didn't have a .NET library when we wrote this, and apparently their new .NET library for MQSeries is pretty bad.)  Since it's unknown what happens inside of a P/Invoke request, no thread is released.

The ideal workaround would be to let remoting know that a new thread should be released.  However, I'm unsure of how to do this (or if it's even possible), and thus, the workaround is to manually multithread your server-side code where needed.

Code
Sunday, February 29, 2004 3:07:31 PM UTC  #    Comments [0]  |  Trackback