Archive for the ‘Development’ Category

Ruby’s Vulnerability Handling Debacle

Max Caceres | July 1st, 2008 | Filed Under: Development, Disclosure

A bit over a week has now gone by after critical vulnerabilities in ruby’s runtime were announced and a couple of interesting developments occurred:

  • The new official ruby releases which include patches for the vulnerabilities actually break critical functionality. In fact, some of the most popular ruby frameworks segfault with any of these releases.

  • It turns out that the breakage brought by the new releases is not due to the security fixes for Drew Yao’s vulnerabilities, but to other changes that were merged into each release’s branch.

  • No response or timeline from ruby’s maintainers to produce a good release has been made public.

  • In an attempt to provide a workable middle ground, third-parties create their own patches, and so do distributors. Some start from a patched release and then work back through the changes until tests pass, others take the opposite approach and start with a last “known-good” release against which they apply selected patches to plug the security holes. Needles to say, the results of each approach are not equivalent.

Developers relying on any of these frameworks are then faced with a difficult choice: wait an indeterminate amount of time for a good release from the official maintainers (and remain vulnerable in the meantime), or apply a patch from a third-party which may not plug all the security holes, or may include unforeseen bugs. This is clearly a problem. In the meantime maintainers have to scramble to get ruby back to a good state that actually plugs the holes while people complain. Everyone loses.

To some extent this is the other side of security response we sometimes advocate for and now we got a taste of: we want our patches and we want them now! And we got them, but our apps don’t work.

The beauty of open-source is not just that we get stuff for free but that we also get a privileged view into the processes around building and maintaining wildly popular software. This is a great opportunity for us as both security and software people to look into why these processes failed and hopefully learn something. Here are my top 3 takeaways:

Keep a “last-known-good” branch to apply critical patches to. The fact that patches had to be applied to unreleased versions of the code means that it is impossible to measure the impact of the change. IMHO this is the single most important mistake behind this state of affairs. This is almost akin to not using version control. Security problems will pop up unpredictably outside of any planned release schedule, and often require a rapid response. End-users may not be able to afford upgrading to a release with new features and even bug fixes every time this happens. It is then highly desirable that a new release which only includes the necessary security patches is made available, to minimize the risk of getting pwned by a new bug or some defiant kid. Are you ready to release critical patches to all the deployed versions of your software even as you are working on its next version?

Open line of communication with your community. It is hard to believe that passing Rails’ tests isn’t an acceptance requirement for every Ruby release, since Rails is the driving force behind Ruby’s adoption. The success of any platform depends on the applications it supports, without the apps the platform doesn’t matter. Microsoft learnt this a long time ago, and that’s why you’ll see them test third-party apps with new releases and security patches, even though technically is not their responsibility. Who are the relevant members of your community? Are you involving them in your release process?

Be more open about vulnerability details. When the vulnerabilities were originally announced very few details were made available (CVE entries for the vulns have been updated with more details since then, though there’s still no entry for the Bignum bug). Because ruby is an open-source project anybody can go and access their source control system to figure out what was actually patched. The fact that you can should be no news to readers of this blog, as people have been doing the same with binary patches for quite some time. Having direct access to not only source but the full source control system is a luxury! Given that the official release didn’t work it was important to isolate the security fixes, and to easily test if 3rd party patches were effective against the flaws. In fact, one of the test cases showed that the official release missed one of Drew’s patches. Lack of details just made it harder for the people trying to help. Do you have a policy about disclosing vulnerability details in your software? Would partners and customers have enough information to evaluate the impact of your patch to their infrastructure?

Just yesterday Apple released a security update which includes fixes for the ruby vulnerabilities. The patched build appears to deal correctly with all test cases, including the string concatenation case, and with Rails’ tests. The official ruby downloads still have issues with both.

Comment Bubble 12 Comments

Reminiscences about Lua and Mosquito

Wes Brown | June 2nd, 2008 | Filed Under: Development, Navel Gazing

When Ephemeral Security first came up with the concept of the injectable virtual machine over coffee, we had an aggressive schedule to meet.  We needed a proof of concept prototype running within a month in order to meet the submission deadline for Defcon 13.

A perfect language for the task was a glimmer in our eyes, but we did not have the time to implement one.  So we profiled various lightweight environments, and Lua looked quite promising.  It was small, it was easily extensible, and it was portable across many architectures.

Ephemeral Security settled on LibTomCrypt as our cryptography library, as we considered it the gold standard for such software.  It was small, it was efficient, it was well-understood, and it was far easier to use than OpenSSL.  OpenSSL does indeed have cipher functions, but it is strongly oriented towards using them in the context of SSL transactions.  

The other major component was LuaSockets.  We judged that the combination of Lua, LuaSockets, and LibTomCrypt was enough for a proof of concept.  We made the deadline for Defcon submissions with an early prototype, and we had a later version ready for demonstration at the actual presentation.

We hated Lua.  It wasn’t Mosquito Lisp.  We found Lua to be inferior to a language that existed only in our heads at the time.  Although, when we needed a prototype that could hobble across the stage in a month, it was the fastest path from idea to novelty.  And it was also the slowest path from novelty to tool.

Lua seemed to make simple things complicated, and the misuse of tables for both arrays and objects made things harder than they should have been.  Lua also did not have solid and reliable primitives for I/O.  It was really awkward to work with.  From our perspective, it had a poor debugger, poor I/O, poor architecture, and a poor C API.  It was a good extension language, but it was difficult to extend.  Our cryptography code was solid, but affiliation could not be gotten to work reliably on top of LuaSockets.

But it did the job, and we had a very small environment suitable for second stage injection as a proof of concept.  It was a sickening irony that the projector that Defcon provided did not work with my Powerbook, and we had to borrow a laptop from the audience to do our presentation.  So we never did get to do a demo of the Lua-based MOSREF in at Defcon 13.

We learned several lessons from that particular adventure:

  • Always make sure the laptop works with the projector provided ahead of time
  • We needed an I/O oriented virtual machine and language
  • Concepts that are simple in idea can be devilishly complex when we get to details

The next year, we did much better with Mosquito Lisp, thanks to what we learned from using Lua.

For those of you curious about it, here are the presentation slides, and the source code

EDIT: ‘We’ adjusted to Ephemeral Security in reference to LibTomCrypt to clarify that is is not a statement or belief held by Matasano Security.

Comment Bubble 16 Comments

Why Injectable Virtual Machines?

Wes Brown | April 17th, 2008 | Filed Under: Development

In hindsight, rather than write a post about injectable virtual machine specifications, I should have started off with the rationale behind the whole concept and explained what they are to provide context to the readers. In this post, when we speak of virtual machines, we are discussing bytecode virtual machines such as UCSD Pascal’s p-Code machine, or the Java Virtual Machine.

All what an exploit by itself does is open the door to allow attacks in the form of payloads. To do something useful, we need a payload which is a block of code that is injected and then does tasks for us. Sometimes an exploit is tightly coupled with the payload, but it is important to keep the two components distinct organizationally.

There are different classes of payloads akin to the classes of exploitable vulnerabilities. The oldest and most well known is the traditional shellcode. Shellcode is commonly written in machine code and many spawn a command shell to allow the attacker to interact with the operating system. However, they are static, inflexible, and targeted to one execution environment. Machine code needs to be written to the specific architecture of the victim. It can break with patches or other changes to the environment.

Another common payload is the syscall proxy. The attacker sends messages to the proxy to execute system calls. This is more flexible than the traditional shellcode as it allows the attacker to dynamically react to the situation in the target execution environment. A major weakness is that the driving logic is on the attacker side, and this can make it fragile.  Examples of software that uses this technique include CORE IMPACT and Metasploit.

DLL Injection is another payload technique, and its advantage lies leveraging the existing program code and libraries in memory. This allows easy implementation of higher level features. Logic can be placed on the target side, rather than relying on a proxy. However, it is static and it is usually Windows specific.

Another payload type that I find very interesting are exploit compilers. This is typically an intelligent compiler with retargetable backends that are written in a high level language. A notable example of this is Dave Aitel’s CANVAS. It offers a very nice abstraction of lower level code, and is very flexible. However, capabilities are often fixed at compile-time.

This brings us to a payload type that I have been researching: injectable virtual machines, which are bytecode executing environments as a payload. The driving logic is in the bytecode which can be embedded in the payload, or transmitted remotely.

Typical advantages are:

  • Compact. A well structured bytecode language is more compact than machine code. Once the cost in memory space is paid for the virtual machine, the actual program to be executed can be much smaller than equivalent machine code.
  • Machine independent. A well written virtual machine can abstract enough that bytecode can execute regardless of the underlying architecture. There are some limitations here, such as the difference between syscall proxying on a Unix versus Windows system, but this can be abstracted by yet another layer.
  • Dynamic. Because it is a virtual machine, ‘in flight missile repair’ can be conducted, changing the entire characteristic of the program environment. This is especially useful with one-shot exploits.
  • Assimiliation. Due to the inherent flexibility of virtual machines, this payload type is free to incorporate other techniques such as those mentioned earlier.  A syscall proxy can be implemented, and DLL injection can be used to provide the virtual machine with functionality.

Bytecode virtual machines have a long history that dates back past the more common modern ones such as Python or Java. By looking at the early examples that ran in very constrained computing environments, we can transfer what we learn to a similiar context.

This post should hopefully help provide more context for the readers to understand the raison d’etre behind injectable virtual machines and my research. As always, I welcome feedback and comments.

Comment Bubble 5 Comments

Cigital Ponders: Is Penetration Testing Security Testing?

Dave G. | April 9th, 2008 | Filed Under: Development, Industry Punditry

My initial response was: duhhhhhhhh

My second response was: uhm yes.

My third response was: Maybe I should read past the subject before I respond.

The short answer is still in the yes category.

The longer answer is that it is a form of security testing.

The blogging (and now featuring blockquotes) answer is:

Some people start “Security Testing” by buying and using a pen-test tool on project. Such tools uncover security vulnerabilities (though they seldom help with root cause analysis or even obtaining double-digit code coverage).

I would argue that uncovering security vulnerabilities is a major motivation for security testing. or Security Testing. Or even “Security Testing”. It is great to talk about Root Cause Analysis and code coverage, but i’ll take single digit code coverage over zero digit code coverage. Pen test tools are what I like to call Least Common Denominator testing. It will find the flaws you can expect an unsophisticated attacker to uncover. It is an excellent place for people who are “just getting started”. Because they don’t have anything in place, and want to hit the ground quickly. Rather than quote the next piece, I will try to sum it up. It is a classic security debate about blackbox/white box and requirements. If you read this blog you have heard it 1000 times and/or you already don’t read my posts.

The point I will nit pick on is:

Because black box tools to a large extent run canned tests they will not satisfy my security testing goal (see previous entry) of having run tests that one traces back to requirements. ‘Requirements that one created as a result of doing risk analysis that determines exactly what behaviors (and their impacts) should be avoided were the software attacked. Arguably, security folk have “cached” this risk analysis and these implicit requirements in the pen testing tool. Fine, this is that small benefit that I mentioned pen tests do provide. And, they DO find bugs. Again, this is at best a degenerate case of security testing in the same way running a fuzz testing tool is a degenerate way of conducting functional testing.

I’m really not sure this is “cached” or arguable. These tools discover flaws that are generally applicable to 99% of the requirements applications that need to get tested. Of course there are exceptions. But those are generally, you know, exceptions. Pen-test tools are useful. They identify a lot of vulnerability quickly and in a cost effective manner. Even if some of the flaws it finds aren’t applicable to a given app, most of them will be. And you can always say “Not going to fix it” for the flaws you don’t care about.Finally, your tests shouldn’t be limited to the tests that map back to requirements. Maybe that is controversial, but honestly, most of the times security requirements are:

  1. Poorly documented
  2. Vague or Poorly articulated
  3. Non existent (Especially if you are in the “just getting started” phase)

When you are specific about security requirements, you are in the battle of staying current against attacks. When you are vague about security requirements, you become test cases become all inclusive.SDLC is great. If you are just getting started, you need to be pragmatic.

My final response: Pen test tools are not pen tests. both are forms of security testing. If the question is, “Is it enough?” or “Do these things work?”, then we have a different conversation.

Comment Bubble 2 Comments

Requirements for Injectable Virtual Machines

Wes Brown | March 14th, 2008 | Filed Under: Development

Much of the last two or three years of my research time has been devoted to the concept of injectable virtual machines and using them in a penetration testing context.  I’ve found that once created, they tend to be handy tools that solve other problems too outside of the original intended design goals, such as secure code deployment using lightweight portable virtual machines.

Requirements design can be an iterative process, and after working on several implementations of the injectable virtual machine, the following requirements were codified:

  • Compact.  This is the biggest requirement: that the implementation be compact.  How compact you need it to be depends entirely on what you want to do with it.  But in general, the smaller the footprint, the more you can do with it.  In the past, I’ve targeted 64K-128K of payload size, and considered that pretty good.  But the smaller the implementor makes it, the more likely it is to be useful in more contexts such as first stage injection.  This also extends to the libraries and bytecode that is generated for the virtual machine, as the virtual machine by itself is useless without logic to drive it.  This is why I’m targeting a much smaller payload size in my next implementation, of a few kilobytes.
  • Portability.  This is another huge design goal that I think many people who operate in this space miss out on.  The implementation of the virtual machine should be portable between platforms.  Behaviors should be as similar as possible and abstracted out so as not to distract the programmer-user from the task at hand.  A task such as opening a socket on a Windows machine should work on a Unix machine as well.  When we have multiple implementations of a virtual machine, we run into the risk of different behaviors, defeating the entire purpose of a portable bytecode virtual machine.
  • Dynamic.  The virtual machine should be dynamic.  We should be able to modify the behavior of the program and language while executing.  By being self-modifying, the language and core functionality can start out very small, but be extended upon.  Features that are not needed early in the process such as garbage collection can be added.  Squeeze a payload in, and watch it expand, much like a ship in the bottle.
  • Secure.  Using the virtual machine for injection purposes should never introduce a state of insecurity to the target machine or network!  While it is all but impossible to make a virtual machine immune to examination by a local user who controls the machine, the virtual machine should not be easily attackable from the outside or use a cleartext control channel.
  • Elegance.  This cannot be understated.  While it is easy to write a functional and spartan language for the purpose, it is not going to be pleasant for the programmer.  Programmers are happiest when they have a language that does not get in their way.  If the language and virtual machine environment does not have this characteristic, then people are not going to use this tool.  Elegant design also lends itself well to other desired traits such as dynamism and compactness.
  • I will be taking a critical eye at the implementations that I have worked on in the past and contrasting it with these requirements, where they succeeded and where they failed.  If you, my dear reader, feel that additional requirements should be applied, let me know!

    Comment Bubble 6 Comments

    Exploring Protocols 2: Writing some tools

    Eric Monti | October 28th, 2007 | Filed Under: Development, Reversing

    In this much delayed installment I’d like to expand on my last one entitled “Exploring Protocols 1″. This is going to be a long one, folks. I guess the big delay in getting this out resulted in a backlog of all the things I wanted to cover. The discussion veers into tools and samples some simple code for dissecting unfamiliar PDUs. There’s more to the “protocol tool” category than just dissecting, of course. But it’s usually the first step and this post will try to focus mostly on it.

    The protocol exploration and tools journey often starts out something like this:

    1. Got an unknown or little known protocol we’d like to learn more about and maybe mess with.

    2. Think: “Hey, self… Wireshark has lots of decodes. Lets check it out.” Then one of two things often happens:

    • Turns out it is a protocol wireshark DOES decode. “Nice! But what if we want to actively or passively mess with it? Wireshark is a sniffer…”

    or…

    • Turns out this is a protocol wireshark doesn’t know about. But it does seem to have a framework for building new ones? Shouldn’t be too hard to just plug in a new decode… should it?

    Let me be clear before going any further with this: Wireshark is fantastic! I use it ALL the time. I don’t have to tell anyone who’s ever used it how long and impressive it’s list of features and dissectors is. It’s gotten a great reputation and it’s well deserved.
    But I’ve not had much luck using Wireshark’s framework to add new dissectors or make use of existing ones in other programs. The dissectors Wireshark supports are written in C and compiled in at build time [** see note] Sure it uses pcap and there’s numerous pcap based tools for packet mangling/manipulation. That might warrant the effort, but WireShark is first and foremost a sniffer, and we need to do a lot more than sniff protocols. Its dissectors aren’t yet as easy as on might like to make available in other programs. Every time I’ve looked into it I end up deciding to just end up writing my own tools from scratch. The reasons will probably become evident as I go on.
    ** Note: this may be in the process of changing. The Wireshark folks are beginning to implement a LUA interpreter right into the sniffer. LUA is an embedded programming language. It’s cool stuff, but so far it’s still pretty new in Wireshark and it’s still just intended as a tool for developing C dissectors.

    But anyway… back to my numbers:

    3. What’s needed a more flexible framework. “This is not the wheel I am looking for. Reinvent!!!”
    Ok so bear with me. I’m going to jump ahead to the tools and talk some about the techniques I’ve used to attack the problem above in the real world. I’ll digress a bit and yammer seemingly pointlessly about a few iSCSI details too.

    Yes, we’ll need a protocol to talk about. For simplicity (… ok well, “reference” anyway) we’re going to stick with iSCSI from the first installment. Wireshark actually dissects iSCSI quite completely. This may defeat the point of the discussion about exploring unknown protocols for some, but for now it’s still a good thing since we can actually compare what Wireshark can do with what we build with our own toolchain.

    Let’s start with a simple iSCSI PDU hexdump for reference:

    iSCSI pdu sample hexdump
    Our initial goal was to figure out a bit about the format. I talked about that in the last post. Check out the last “Exploring Protocols 1“. Now we’ll try to dissect iSCSI PDU’s in a manner similar to Wireshark.

    In the not too distant past, I would have probably used C/C++ for this. This is mostly because C/C++ has ’structs’ and pointers. The ’struct’ lets you describe binary data to your program by defining fields as elements a structure. Using the structure as the type for a pointer variable lets you apply the structure to a buffer in memory like an overlay. This is pretty obvious stuff to anybody who does any C coding at all, but not everybody does. This simple feature is really powerful and efficient. I still get a few goosebumps when my structures “lay over” properly.

    Here is an example of a trivial iSCSI_dissector in C. This sample program is not too robust, but serves as a good starting point. I used a structure borrowed and adapted from linux-iscsi-3.6.3. You should be able to compile this program with “gcc -o iscsi_dissect iscsi_dissect.c” on any *ix and maybe windows. First lets just look at the structure defined for the header:
    iSCSI C structure
    The structure for the header defines the fields and sizes based on what the iSCSI RFC calls for. The size of the datatype (uint*_t) defines the width of the field.

    There are some funky field alignment issues that the linux-iscsi header structure doesn’t try to fully address in the BHS structure definition, though.

    This is just nitpicking (bitpicking?) and may distract a little from protocol dissection, but lets take a quick look again at the first four bytes from the RFC 3720 syntax description. This time, the structure elements from linux-iscsi are lined up with each field from the RFC description.

    BHS_with_vars.jpg

    Neither the ‘opcode’ nor ‘flags’ elements in the structure are supposed to take up an entire byte in the BHS if you read the RFC “literally”.

    The Basic Header Segment as defined in the RFC has a null bit, followed by an ‘I’ bit, a 6-bit opcode, and a single ‘F’ (final) bit followed by 7 bits allocated as “opcode specific”, or as linux-iscsi called it, “reserved”.

    10.2.1.1  I
    
    For request PDUs, the I bit set to 1 is an immediate delivery
    marker.
    
    10.2.1.2.  Opcode
    
    The Opcode indicates the type of iSCSI PDU the header
    encapsulates.
    ...

    So the first two bits should always be “0 0″ or “0 1″. Why the first bit is not used is unclear, but in obvservation of iSCSI it seems like it’s always set to ‘0′.

    So what about that 6-bit opcode after ‘F’? Well if you look closely in the spec, you wont find any op-code higher than the number ‘63′ (or 0×3f in hex). Why? Because at least 7 bits are needed to store for the number 64 (or 0×40 hex) and higher. So there can never be more than 63 types of opcode represented in the “Opcode” field alone. Like so:

    63 is "0 0 1 1 1 1 1 1" in bits
    64 is "0 1 0 0 0 0 0 0"

    There’s another similar (but different) situation right after this one:

    10.2.1.3.  Final (F) bit
    
    When set to 1 it indicates the final (or only) PDU of a
    sequence.
    
    10.2.1.4.  Opcode-specific Fields
    
    These fields have different meanings for different opcode
    types.

    The basic header segment is just a template for all the types of header segments. They’re all defined in the RFC too. If you read up on them, it turns in several cases the remaining 7 bits in the the ‘[F][rsvd1]’ byte for are used for other flags. In some cases it’s really “reserved”. In other cases it’s used for codes that are significant to the specific segment type. Sometimes the meaning of the ‘F’ bit even gets changed.

    It’s a common practice not to define every single bit in a field separately and just combine them in one byte. When using the structure, you’d just use bitwise operations against various values to set, check and clear individual bits.

    Protocols often try to squeeze a use out of every single bit. This can give rise to occasional situations where a weird alignment issue like the ‘rsvd1′ or ‘opcode’ ones can result in unexpected behaviors. Depending on the implementation and what assumptions the developer makes, assigning values to anything after the ‘I’ or ‘F’ might inadvertently get set or cleared. This type of thing can might have dangerous side effects.

    Queue haunted house organ music...

    Ok… don’t know and can’t think of any even remotely dangerous iSCSI opcode or rsvd1 side effects. I and F seem pretty benign to me just from reading the RFC and theres probably no case short of a grotesquely bad implementation where they’d get clobbered by their neighboring values. The spooky music is… um… just to get in the Halloween spirit. Yea! Happy Halloween everybody!

    So, here’s what the output from iscsi_dissect.c looks like (cleaned up slightly for display):

    Dissecting iSCSI frame: (Actual PDU Length = 136 bytes)
    Format is big endian so the hex order matches wire.
    Opcode:        = 36 : (0x24)
    Flags:         = 128 : (0x80)
    Op-Specific1   = 0 : (0x00)
    Op-Specific2   = 0 : (0x00)
    TotalAHSLen:   = 0 : (0x00)
    DataSegmentLen = 85 : (0x000055)
    LUN:      hex: = 0000000000000000
    InitTaskTag:   = 1 : (0x00000001)
    Opcode Specific Fields in hex:
    ff ff ff ff 00 00 00 02 00 00 00 02 00 00 00 03 00
    00 00 00 00 00 00 00 00 00 00 00
    
    Data segment strings: (segment length: 88 bytes):
    TargetName=iqn.2009-08.com.splatomatic:storage.lvmx00
    TargetAddress=192.168.1.10:3260,1x00
    x00
    x00
    x00

    The struct -> buffer overlay used in the C program is simple and kind-of elegant. Structures are also nice since they can serve as a short-hand for describing the format of messages we’re trying to figure out.

    This version also resembles the way most actual iSCSI implementations probably work. For grey/black-box security testing, this can be an advantage. You may gain insights that will help you find where implementation flaws lurk in the real product. Using the same language that as actual implementation can arguably let you get closer to the same thought processes the developers used. If there was a point to that random ranting about partial use of bit-fields within bytes, that was it. The rant should also serve as a case study in following useless random rabbit-holes too early in the exploration phase. Which is another good lesson on exploring protocols and would make a good blog-post by itself. I’m sure most people have already dropped out of this overly long post by now. Too bad for them, they’ll totally miss out on the best part.

    Ok… for some, the problem with C is that, well, it can be too rigid. I personally think that higher level interpreted languages are better for doing exploratory work like this. As you’re examining unfamiliar and possibly undocumented protocols or formats, you’re constantly refining your idea of what your structures should look like and what you want to do with them. You don’t want to have to stop and recompile for every change. You *really* dont want to find yourself having to redesign your tools several times over.

    One of the frustrating things about writing quick/dirty tools from scratch for fault testing or fuzzing is first getting rid of faults in your own testing tools. Usually the quicker and dirtier your C is, the harder it becomes to work with. There are lots of programmers out there that this is may not be a problem for. They probably stopped reading a while ago too. But even they end up relying on abstraction to some extent.

    My experience has been that using higher level languages gives you more freedom to experiment and you get a lot of relatively stable free abstraction already without having to build it yourself. To put it bluntly, you can get away with more, for longer, usually with less code. On the other hand, all that abstraction can get in your way sometimes when you need to get closer to the wire, but this isn’t as big of a deal as people make it out to be.

    So lets see how we could have written a similar dissector/decoder in an interpreted language. I’m going to use Ruby. Ruby is nice. It has some particularly useful qualities for protocol exploration (besides just being “nice”):

    • It’s an interpreted scripting language. We can make modifications and tweaks on the fly much more easily. No recompiling necessary.
    • Ruby code is very portable. Very few problems getting your code to work on different platforms.
    • It’s got built in large numbers, a string data-type that doubles as a raw buffer, and lots of other free and generally well designed classes methods for for doing all sorts of commonly useful things. All in all this makes for fewer things to screw up as you’re cobbling something together quickly (as I tend to need to).
    • Modular design is, I think, actually harder *not* to do with Ruby. Keeping things modular when developing exploratory tools will mean that exploration phase actually yields highly useable code that we can adapt very easily down the road.
    • Did I mention Ruby is nice?

    One thing ruby doesn’t really do without add-ons is ’structures’. The way Ruby uses references to objects is similar to pointers. Actually, Ruby’s references definitely harken back to C/C++, the language it’s written in. But the similarities aren’t completely linear. It’s also a moot point because what really helps protocol design is ’structs’.

    “But somebody must have done something about this by now!”, you say? Actually several have. One such thing is called BitStruct. I’ve been using it a lot. Not only does BitStruct let you map out binary structures in a way similar to C’s ’struct’, but it’s goes further. It is really handy for keeping track of and getting at useful field-related information you’re likely to want. Things like descriptions, sizes, offsets, and even display format are all available as parts of a hash and through free methods. Extending the hash-based design for say “annotations” is as easy as tying new elements to a field’s hash. Bit-struct also has its own free (if somehwat rudimentary) ‘inspect’ and ‘inspect_detailed’ methods for dissecting your structures in human readable format. There’s a ‘describe’ class method that returns a human-readable description of the format itself. BitStruct has some alignment quirks of its own, but like C’s structs you can work around them.

    Take a look at this code. It’s a lot more descriptive than the C struct version. The descriptions are actually part of the code, not comments. The formats for fields are specified right in the structure too!

    iSCSI_bitstruct.jpg

    Unlike the C version, the rest of the code is really short. So short I’ll paste it all too:

    iSCSI_bitstruct_rest.jpg

    So here is the iSCSI_dissector in Ruby. Getting BitStruct is a prerequisite ofcourse. Here’s how we run it and what our output looks like:

    $ ruby ./iscsi_dissect.rb
    
    -- Header Dissection --
    Type: ISCSI_bhs:
    Decode:
    I bit                = 0
    Opcode               = 36
    F bit                = 1
    Opcode-specific 1    = 0x00
    Opcode-specific 2    = 0x00
    Opcode-specific 3    = 0x00
    TotalAHSLength       = 0
    DataSegmentLength    = 85
    LUN or Op-specific   = 0x0000000000000000
    Initiator Task Tag   = 1
    Opcode-specific 4-12 = "377377377377�00�00�00
    �02�00�00�00�02�00�00�00�03�00�00�00�00
    �00�00�00�00�00�00�00�00"
    Data Segment Body    = "TargetName=iqn.2009-08.com.splatomatic:storage.lvm�00TargetAddress=192.168.1.10:3260,1�00�00�00�00"
    
    -- Data Segment Body --
    TargetName=iqn.2009-08.com.splatomatic:storage.lvmTargetAddress=192.168.1.10:3260,1

    In fairness to C, I obviously didn’t do as much work on displaying the data segment but could have. I let ‘inspect’ take care of it to illustrate what it does (and doesn’t do).
    It’s interesting to note that the dissector framework in Wireshark uses an similar notion of “adding fields” not unlike BitStruct’s. The sniffer needs easy and generalized access to a bunch of packet and protocol related meta-information used for displaying lots of different protocols, filtering, and so on. Abstracting fields makes a lot of sense for a sniffer and most of the reasons why match up for protocol reversing and prototyping.

    So there you have it. In general, I tend to use Ruby over C for this stuff. It used to be Perl. It’s not because I think I have figured out all the typical implementation gotchas or that I don’t have anything to gain by “getting closer to the wire/implementation” either. It’s more because I’m lazy and/or slammed most of the time. It’s also been fun learning and using Ruby more.

    If you prefer C/C++, then use it instead.
    Python? great!
    Perl? go for it!
    LUA? Why not! We all may be doing it soon.
    .NET? that’s swell!
    Java? … really?
    KSH? yea! That might even win you a beer!
    WSH? um… wow! ok (but definitely no beer).

    Whatever… don’t listen to me or anybody else, just use what you know and/or like and/or want to learn more of.

    I guess if there’s been a point to the C versus Ruby thing, it’s that the real key is the end result. Language wars are for people with more free time on their hands than I have. If a language feels like it slows you down, then it’s probably not the right one. I say “get it done” first. If it makes you feel better, just call your early forays “prototyping”. You can always rewrite it in something else once you know how the protocol works. I do sometimes. To an extent, I sometimes think of “C vs. Ruby or Perl” that way, but in practice, I tend to use the four letter languages most of the time.

    Anyway, back to the general topic of protocol exploration, and in summary:

    For this and the last installment I’ve been talking about iSCSI; a protocol with pretty good RFC documentation and some open source code guiding us along the process of understanding and dissecting PDU’s. I’ll be talking about tackling lesser understood and undocumented protocols more in future posts. If iSCSI had been totally undocumented we’d have to figure a lot out on our own. Frankly, iSCSI could take a while to understand if it weren’t so well documented. It’s a pretty complicated protocol as far as they go. I’ve only scratched the surface by talking about the BHS.

    I’ve gotten some kind words and gentle nudges to get me back to writing this from one or two of you and I want to say again “Thanks for the feedback!”. It should not have taken so long to get the 2nd installment out.

    Comment Bubble 5 Comments

    Visual Cryptanalysis

    Thomas Ptacek | August 25th, 2007 | Filed Under: Defenses, Development, Uncategorized

    Daniel J. Bernstein visualizes ciphers by rendering their DAGs —- an intermediate representation, as would be used by a compiler as a step towards generating object code.

    (If you’re not familiar with the concept, a DAG is just a tree where a node can have more than one parent. Single inheritance: tree. Multiple inheritance: DAG. If you are familiar with the concept, I apologize for saying “a DAG is just a tree…”).

    How cool is this? For starters: I must have this poster. Here’s a snippet of MD5:

    md5.png

    And of SHA-256:

    sha.png

    More substantively, from the (short) paper:

    The right half of the SHA-1 graph is the SHA-1 message expansion, and the right half of the SHA-256 graph is the more complex SHA-256 message expansion; for comparison, the MD5 graph has many long edges, allowing an attacker to effortlessly pierce deep into the heart of the MD5 computation.

    Using visualization tools to find vulnerabilities has been in vogue among the RCE crowd for years now. It’s the whole idea behind Halvar’s excellent BinNavi tool. Now here’s an example of how cryptographers have been using the same idea.

    […] I certainly can’t claim that the tools have saved time in cryptanalysis. But I think that the tools will save time in cryptanalysis, automating several tedious tasks that today are normally done by hand.

    Worth watching. Funny quote:

    [M]y initial experiments with bit DAGs for MD5 have crashed every standard drawing tool that I’ve tried. My own drawing tools are much more careful in their use of memory.

    Ok, maybe it’s only funny if you’ve tried to do large layouts in Graphviz before, or wrote your own crappy graph layout code.

    Comment Bubble 3 Comments

    Exploring Protocols - Part 1

    Eric Monti | June 20th, 2007 | Filed Under: Development, Reversing

    In the process of doing software security analysis, it is pretty common to encounter unknown network protocols or file formats that are part of the attack surface you’re investigating.
    Not too long ago, we wrote a post entitled Reversing a ZLib-obfuscated? Network Protocol where we talked about reversing an undocumented protocol to look for security weaknesses. We got several good questions about some of our deductions about the protocol as we picked it apart. I’d like to take the opportunity to talk more about protocol reversing in general and hopefully help explain how that deduction process works while getting some broader coverage on the subject in.

    This will be the first of at least 2 blog posts. I’m going to start by discussing building blocks and see where that takes us. In the early phases of talking about this process, I’m not making a distinction between whether a protocol is “unknown” because of lack of documentation or because it’s simply “unknown to you/me” because we’re unfamiliar with it. Of course an undocumented protocol is going to be tricker to reverse. If there’s a point to these initial posts, it’s that working with documented protocols helps us understand the undocumented ones.

    To illustrate some basic protocol dissection ideas, I’m going to talk about iSCSI. I mostly picked iSCSI since I happen to be working with it at the moment and it makes a pretty good case study.

    In this post we’ll:
    1. Talk a little bit about what iSCSI is and what it’s for.
    2. Use Wireshark to find a iSCSI PDU and isolate it.
    3. Compare the raw PDU to the specification.
    4. Talk a bit about how this all relates to protocol reversing.

    In a nutshell iSCSI is:

    … SCSI over IP. It’s designed as a low cost solution for network attached storage. A storage server (say a NAS appliance) exports storage as “targets” on any TCP/IP network to which clients (aka “initiators”) connect. Once attached by connecting and logging on, the initiator’s OS sees the target as a hard drive and treats it as a block device. Filesystem drivers ride on top of the device as they would any other SCSI device. Besides file access, an initiator can arbitrarily partition and format the target using its allocated space.

    Sounds a bit crazy from a security perspective, right? Well, just bear in mind that that iSCSI is not intended as a replacement for CIFS or NFS at all. iSCSI is first and foremost designed as an alternative to more expensive fiber channel NAS solutions by using cheaper gig-ethernet and possibly leveraging a company’s existing network infrastructure. The iSCSI spec is also apparently designed to be used over other transports besides TCP/IP.

    We’re interested in what iSCSI looks like on the wire. This is not undocumented or new territory. Wireshark has iSCSI decoding capabilities way above and beyond the simple dissection tools we’re going to get into for iSCSI. We’re not going to use those decodes much for this discussion, though. Building our own tools gives us more intimate knowledge than relying on Wireshark will. We also want to have some building blocks for doing things later like fault injection if our exploration leads us that way.

    iSCSI’s a good case study for protocol exploration since it’s not exactly a “common” network protocol, but has pretty decent documentation and specifications available in RFC’s. Picking it apart with some guidance helps illustrate some common network protocol concepts and we can double-check things against the actual specification to make sure we’re getting them right.

    Here’s a hexdump of an isolated iSCSI PDU as it appears on the wire:

    pdu-hd.png
    I isolated this using Wireshark and saved it as a as a file to work with. iSCSI uses TCP/3260 as its transport. The pcap filter for this is “tcp port 3260″. Here’s how I did that:

    Isolating a single TCP Data Segment In Wireshark

    Now that we’ve isolated a sample, the next step is making sense out of the raw PDU. If this were an undocumented protocol, this would be the part where we opened it in a hex editor and started trying to separate chunks into boundaries based on educated guesswork, assisted by good conversion tools. Actually that’s just one way. Probably the most basic one.
    This involves a lot of educated guesswork and is not always a straightforward process. We’re still talking about the guesswork, not doing it (yet).
    Here’s the basic header syntax of an iSCSI PDU as defined in RFC 3720 (yep there it is… we could stop now, but where’s the fun in that)

    iscsi-bhs.png

    This type of breakout basically represents how we’d like to be able to understand a network protocol. It’s very rare, even at best, that you’ll actually figure out what every field is for in an undocumented protocol. Just getting fields broken up so you can make sense out of most of them is what you’re usually going after initially. As you start to make sense of other things later, the things you may have originally passed over can gain context.

    This RFC explains the various fields pretty well and covers much more than just that. There’s more information in there than we are even likely to need. This raises a good point. Before you start “reversing” anything, always make sure it isn’t documented somewhere or implemented in something you can pull apart.
    Using the spec to guide us, we’re going to try to understand this header and see what our captured PDU says. We’ll need to write a tool for this.

    In the next post, we’ll:
    1. Write a C dissector to emulate Wireshark decodes.
    2. Write a Ruby dissector to approximate the C version.
    3. Discuss some pros and cons of each.
    4. Discuss some of the general things we can learn and how they can be applied to reversing truly unknown protocols.

    Comment Bubble 7 Comments

    Windows Remote Memory Access Though FireWire

    Thomas Ptacek | February 9th, 2007 | Filed Under: Defenses, Development, Uncategorized

    Maximillian Dornseif made a splash at CanSec in 2005 by hijacking Linux and OS X machines using a malicious iPod and the FireWire port. As it turns out, the “link layer” for FireWire —- OHCI, which is roughly to FireWire what Ethernet would be to 1000bTX if it included a standard programming interface —- supports direct DMA to host physical memory. You can plug a FireWire device in to a machine and read or write arbitrary physical memory locations.

    OHCI Diagram

    Get a sense of what this looks like for an “attacker” from Maximillian’s own presentation. Then, note the table of systems “compatible” with the attack:

    • OS X (supports read/write)

    • FreeBSD (supports read/write)

    • Linux (supports write)

    • Windows 2000 (crashes)

    • Windows XP (no support)

    The reason Maximillian’s attack doesn’t seem to work against Windows XP is that OHCI specifies “Asynchronous Filter” and “Physical Filter” CSRs (a CSR is a hardware ioctl, by the way); if these CSRs are set to zero, the FireWire chipset will reject requests to access host physical memory. According to the spec, they default to zero. Windows doesn’t set them. So, by default, Windows disallows FireWire DMA.

    I think this is pretty well known, but the attack does work against Windows (at least, pre-Vista). For instance, Adam Boileau showed that you can fake up a config ROM for yourself that, when read by the Windows host, will open up the filter CSRs. His attack basically advertises his machine as requiring DMA access, and Windows complies.

    An attractive thing about both Maximillian’s and Adam’s attacks are that they’re implemented in Python; both quickly wrap the Linux or OSX FireWire APIs with Python bindings and then speak FireWire to the target with Python scripts.

    I’m not particularly interested in “owning” my Windows box with FireWire, because I own my Windows box already. But I am interested in surreptitiously debugging my kernel and user processes that are aggressively rigged for anti-debugging. So I bought a $20 FireWire PCI card, and got Nate Lawson to talk me through disabling the OHCI Physical Request filters.

    CSRs for PCI devices are mapped into memory; the host will typically map a block of address space just for the CSRs, which Windows will tell you about if you click on “Driver Details”; you want the smaller, 2-4k address range.

    Unix and Windows ioctls have indexes or codes. In mapped memory, CSRs have offsets. The offsets we care about are 0x100 and 0x108 (the high and low 32 bits of the 64 bit AsynchronousRequestFilter) and 0x110 and 0x108 (the 64 bit PhysicalRequestFilter). Windows says my OHCI CSRs live at 0xdfbf8800 (phy addresses, not kernel virts). So I want to write 0xdfbf8900, 0xdfbf8908, 0xdfbf8910, and 0xdfbf8918; I simply want them to be 0xFFFFFFFF.

    You can do this from any ring 0 code, or you can just use kd:

    !dc dfbf8900        # see if they're already set
    !ed dfbf8910 ffffffff
    !ed dfbf8918 ffffffff   # set the physical request filters
    g
    

    … and now Maximillian’s code will work against Vista (you can then disable kd with kdbgctrl.exe if you need to).

    Note that a FireWire bus reset will clear these registers; the Windows OHCI driver will set the AsyncRequestFilter, but not the PhysicalRequestFilter, so you’ll need to repeat this process —- in particular, and annoyingly, every time you close your FireWire IOKit object on OSX. I got around this problem by writing a quick proxy from TCP to FireWire, which holds the object open and (so far) prevents the bus reset from getting me.

    Obligatory “what does this let me do” graf? Adam and Maximillian explain it better, but the answer is, uh, anything? The FireWire chipset autonomously DMA’s host memory; if the kernel can’t keep the chipset’s CSRs configured to reject physical DMA requests, it can’t do anything to stop me from rewriting bits of the kernel or stealing crypto secrets out of memory.

    Comment Bubble 8 Comments

    Dead Giveaways of Thoughtless User Interfaces

    Thomas Ptacek | December 9th, 2006 | Filed Under: Development, Uncategorized

    Submitted for your consideration:

    There are “features” (or design choices, or flourishes) that are acid tests of how thoughtful and in-tune a development team is.

    For example: consider an MP3 player that sorts a playlist by artist in alphabetical order. Acid test: is the article “the” disregarded, or do all the bands that start with “the” clump together?

    A security product example: when timestamps are displayed, are they displayed in ctime() format, like “Thu Nov 24 18:22:48 1986”? Even when the event happened 20 minutes ago, or yesterday, or when the problem domain doesn’t care about seconds precision?

    Another example: when traffic stats are displayed, are they presented in bytes-precision, as if the UI just did “sprintf(output, “%Lu”, counter)”, even in the (overwhelmingly common) cases where I just want to compare KB, or MB, or GB numbers?

    Talk amongst yourselves.

    Comment Bubble 6 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.