I'm please to announce that the first Native Client exploit from outside Google has been submitted as Issue 23<http://code.google.com/p/nativeclient/issues/detail?id=23>to the project site. User defend.the.world found an inner-sandbox escape due to a defect in the validator. The validator was checking for calls through registers, as in this two-byte call: 83 e2 e0 and $0xffffffe0,%edx ff d2 call %edx but erroneously permitting similar calls through memory using this addressing mode: 83 e2 e0 and $0xffffffe0,%edx ff 12 call *(%edx) The and mask required by the validator aligns the address in the register, but not the address in the memory location pointed to by the register, thereby allowing a control transfer to an arbitrary byte location in the untrusted text segment. For example, it could transfer control to a syscall instruction embedded in the middle of an instruction previously identified by the validator.
Fixing this defect is relatively simple via a patch to ncv/ncvalidate.c to restrict the addressing modes allowed for this kind of call or jump: bash-3.2$ diff -Naur ORIG/ncvalidate.c ncvalidate.c --- ORIG/ncvalidate.c 2008-12-12 22:28:16.000000000 -0800 +++ ncvalidate.c 2008-12-12 22:38:04.000000000 -0800 @@ -482,6 +482,10 @@ /* check all the opcodes. */ if (jmpopcode[0] != 0xff) break; if ((modrm_reg(mrm) != 2) && (modrm_reg(mrm) != 4)) break; + /* Issue 32: disallow unsafe call/jump indirection */ + /* example: ff 12 call (*edx) */ + /* Reported by defend.the.world on 11 Dec 2008 */ + if (modrm_mod(mrm) != 3) break; if (oropcode[0] != 0x81) break; if (andopcode[0] != 0x81) break; /* check modrm bytes of or and and instructions */ @@ -536,6 +540,10 @@ /* In GROUP5, 2 => call, 4 => jmp */ if (jmpopcode[0] != 0xff) break; if ((modrm_reg(mrm) != 2) && (modrm_reg(mrm) != 4)) break; + /* Issue 32: disallow unsafe call/jump indirection */ + /* example: ff 12 call (*edx) */ + /* Reported by defend.the.world on 11 Dec 2008 */ + if (modrm_mod(mrm) != 3) break; if (targetreg == kReg_ESP) break; if (andopcode[0] != 0x83) break; /* check modrm bytes of or and and instructions */ bash-3.2$
Note that we are fixing both the five and 14-byte versions of ValidateIndirect, even though only the five-byte version is used. This fix will be included in our next set of downloads.
> I'm please to announce that the first Native Client exploit from outside
> Google has been submitted as Issue
> 23<http://code.google.com/p/nativeclient/issues/detail?id=23>to the
> project site. User defend.the.world found an inner-sandbox escape due
> to a defect in the validator. The validator was checking for calls through
> registers, as in this two-byte call:
> 83 e2 e0 and $0xffffffe0,%edx
> ff d2 call %edx
> but erroneously permitting similar calls through memory using this
> addressing mode:
> 83 e2 e0 and $0xffffffe0,%edx
> ff 12 call *(%edx)
> The and mask required by the validator aligns the address in the register,
> but not the address in the memory location pointed to by the register,
> thereby allowing a control transfer to an arbitrary byte location in the
> untrusted text segment. For example, it could transfer control to a syscall
> instruction embedded in the middle of an instruction previously identified
> by the validator.
> Fixing this defect is relatively simple via a patch to ncv/ncvalidate.c to
> restrict the addressing modes allowed for this kind of call or jump:
> bash-3.2$ diff -Naur ORIG/ncvalidate.c ncvalidate.c
> --- ORIG/ncvalidate.c 2008-12-12 22:28:16.000000000 -0800
> +++ ncvalidate.c 2008-12-12 22:38:04.000000000 -0800
> @@ -482,6 +482,10 @@
> /* check all the opcodes. */
> if (jmpopcode[0] != 0xff) break;
> if ((modrm_reg(mrm) != 2) && (modrm_reg(mrm) != 4)) break;
> + /* Issue 32: disallow unsafe call/jump indirection */
> + /* example: ff 12 call (*edx) */
> + /* Reported by defend.the.world on 11 Dec 2008 */
> + if (modrm_mod(mrm) != 3) break;
> if (oropcode[0] != 0x81) break;
> if (andopcode[0] != 0x81) break;
> /* check modrm bytes of or and and instructions */
> @@ -536,6 +540,10 @@
> /* In GROUP5, 2 => call, 4 => jmp */
> if (jmpopcode[0] != 0xff) break;
> if ((modrm_reg(mrm) != 2) && (modrm_reg(mrm) != 4)) break;
> + /* Issue 32: disallow unsafe call/jump indirection */
> + /* example: ff 12 call (*edx) */
> + /* Reported by defend.the.world on 11 Dec 2008 */
> + if (modrm_mod(mrm) != 3) break;
> if (targetreg == kReg_ESP) break;
> if (andopcode[0] != 0x83) break;
> /* check modrm bytes of or and and instructions */
> bash-3.2$
> Note that we are fixing both the five and 14-byte versions of
> ValidateIndirect, even though only the five-byte version is used. This fix
> will be included in our next set of downloads.
The command-line validator is not being very helpful in this case. Someplace
in the middle of the output you omitted, it said something about multiple
text sections, which it doesn't like, because it's worried about holes. When
the validator is invoked by sel_ldr, it turns out that the sections have
already been loaded into memory, and are passed in for validation as a
single contiguous region.
> Problems:
> 0 illegal instructions
> 0 bad jump targets
> 0 illegal unprotected indirect jumps (including ret)
> 0 instruction alignment defects
> 0 segmentation errors
> 0 bad prefix
> 0 bad instruction length
> 0 missing full stop
> 0 internal errors
> 0 bad cpu
> Validated d:\test\nacl\haha_release.nexe
> d:\test\nacl\haha_release.nexe: 0.000000 0.015000
> Cheers,
> Daniel
> On 13 déc, 17:42, Brad Chen <bradc...@google.com> wrote:
> > I'm please to announce that the first Native Client exploit from outside
> > Google has been submitted as Issue
> > 23<http://code.google.com/p/nativeclient/issues/detail?id=23>to the
> > project site. User defend.the.world found an inner-sandbox escape due
> > to a defect in the validator. The validator was checking for calls
> through
> > registers, as in this two-byte call:
> > 83 e2 e0 and $0xffffffe0,%edx
> > ff d2 call %edx
> > but erroneously permitting similar calls through memory using this
> > addressing mode:
> > 83 e2 e0 and $0xffffffe0,%edx
> > ff 12 call *(%edx)
> > The and mask required by the validator aligns the address in the
> register,
> > but not the address in the memory location pointed to by the register,
> > thereby allowing a control transfer to an arbitrary byte location in the
> > untrusted text segment. For example, it could transfer control to a
> syscall
> > instruction embedded in the middle of an instruction previously
> identified
> > by the validator.
> > Fixing this defect is relatively simple via a patch to ncv/ncvalidate.c
> to
> > restrict the addressing modes allowed for this kind of call or jump:
> > bash-3.2$ diff -Naur ORIG/ncvalidate.c ncvalidate.c
> > --- ORIG/ncvalidate.c 2008-12-12 22:28:16.000000000 -0800
> > +++ ncvalidate.c 2008-12-12 22:38:04.000000000 -0800
> > @@ -482,6 +482,10 @@
> > /* check all the opcodes. */
> > if (jmpopcode[0] != 0xff) break;
> > if ((modrm_reg(mrm) != 2) && (modrm_reg(mrm) != 4)) break;
> > + /* Issue 32: disallow unsafe call/jump indirection */
> > + /* example: ff 12 call (*edx) */
> > + /* Reported by defend.the.world on 11 Dec 2008 */
> > + if (modrm_mod(mrm) != 3) break;
> > if (oropcode[0] != 0x81) break;
> > if (andopcode[0] != 0x81) break;
> > /* check modrm bytes of or and and instructions */
> > @@ -536,6 +540,10 @@
> > /* In GROUP5, 2 => call, 4 => jmp */
> > if (jmpopcode[0] != 0xff) break;
> > if ((modrm_reg(mrm) != 2) && (modrm_reg(mrm) != 4)) break;
> > + /* Issue 32: disallow unsafe call/jump indirection */
> > + /* example: ff 12 call (*edx) */
> > + /* Reported by defend.the.world on 11 Dec 2008 */
> > + if (modrm_mod(mrm) != 3) break;
> > if (targetreg == kReg_ESP) break;
> > if (andopcode[0] != 0x83) break;
> > /* check modrm bytes of or and and instructions */
> > bash-3.2$
> > Note that we are fixing both the five and 14-byte versions of
> > ValidateIndirect, even though only the five-byte version is used. This
> fix
> > will be included in our next set of downloads.
Is it just me or is this exploit actually using the nacljmp as it
appears in the research paper ?
and %eax, 0xffffffe0
jmp *(%eax)
At the same time, the research paper states “we disallow memory
addressing modes on indirect jmp and call instructions“. So it looks
like the nacljmp in the research paper should be:
> The command-line validator is not being very helpful in this case. Someplace
> in the middle of the output you omitted, it said something about multiple
> text sections, which it doesn't like, because it's worried about holes. When
> the validator is invoked by sel_ldr, it turns out that the sections have
> already been loaded into memory, and are passed in for validation as a
> single contiguous region.
Maybe this explains why I've always liked hexadecimal. Sadly there are two
different common assembler syntaxes for x86 and I can't keep them straight.
Thanks for pointing out this inconsistency. We will fix this when we next
revise the paper.
On Tue, Dec 16, 2008 at 1:52 AM, dan <reynaud.dan...@gmail.com> wrote:
> Ok, thanks Brad.
> Is it just me or is this exploit actually using the nacljmp as it
> appears in the research paper ?
> and %eax, 0xffffffe0
> jmp *(%eax)
> At the same time, the research paper states "we disallow memory
> addressing modes on indirect jmp and call instructions". So it looks
> like the nacljmp in the research paper should be:
> and %eax, 0xffffffe0
> jmp %eax
> The rest of my random thoughts have been posted here:
> On 16 déc, 05:22, Brad Chen <bradc...@google.com> wrote:
> > The command-line validator is not being very helpful in this case.
> Someplace
> > in the middle of the output you omitted, it said something about multiple
> > text sections, which it doesn't like, because it's worried about holes.
> When
> > the validator is invoked by sel_ldr, it turns out that the sections have
> > already been loaded into memory, and are passed in for validation as a
> > single contiguous region.
On Tue, Dec 16, 2008 at 1:52 AM, dan <reynaud.dan...@gmail.com> wrote:
> Ok, thanks Brad.
> Is it just me or is this exploit actually using the nacljmp as it
> appears in the research paper ?
> and %eax, 0xffffffe0
> jmp *(%eax)
> At the same time, the research paper states "we disallow memory
> addressing modes on indirect jmp and call instructions". So it looks
> like the nacljmp in the research paper should be:
> and %eax, 0xffffffe0
> jmp %eax
> The rest of my random thoughts have been posted here:
> On 16 déc, 05:22, Brad Chen <bradc...@google.com> wrote:
>> The command-line validator is not being very helpful in this case.
Someplace
>> in the middle of the output you omitted, it said something about multiple
>> text sections, which it doesn't like, because it's worried about holes.
When
>> the validator is invoked by sel_ldr, it turns out that the sections have
>> already been loaded into memory, and are passed in for validation as a
>> single contiguous region.
>> Brad Chen
-- bennet s yee
i usually don't capitalize due to mild tendonitis
Bennet and I just confirmed your insight that our paper contained a
typographical error. What we intended to convey was that the accepted
instruction sequence for a nacljmp should be:
and %eax, 0xffffffe0
jmp *%eax
rather than
and %eax, 0xffffffe0
jmp *(%eax)
The former makes no memory reference to compute the target address, while
the latter does. We will update the paper accordingly in an upcoming
release.
Thank you again!
David
On Tue, Dec 16, 2008 at 10:31 AM, Bennet Yee (余仕斌) <b...@google.com> wrote:
> $ i=dan.s; cat $i; as $i
> .globl foo
> foo: and %eax, 0xffffffe0
> jmp %eax
> dan.s: Assembler messages:
> dan.s:3: Error: suffix or operands invalid for `jmp'
> $ i=dan2.s; cat $i; as $i
> .globl foo
> foo: and %eax, 0xffffffe0
> jmp (%eax)
> dan2.s: Assembler messages:
> dan2.s:3: Warning: indirect jmp without `*'
> $ i=dan3.s; cat $i; as $i
> .globl foo
> foo: and %eax, 0xffffffe0
> jmp *(%eax)
> $
> -bsy
> On Tue, Dec 16, 2008 at 1:52 AM, dan <reynaud.dan...@gmail.com> wrote:
> > Ok, thanks Brad.
> > Is it just me or is this exploit actually using the nacljmp as it
> > appears in the research paper ?
> > and %eax, 0xffffffe0
> > jmp *(%eax)
> > At the same time, the research paper states "we disallow memory
> > addressing modes on indirect jmp and call instructions". So it looks
> > like the nacljmp in the research paper should be:
> > and %eax, 0xffffffe0
> > jmp %eax
> > The rest of my random thoughts have been posted here:
> > On 16 déc, 05:22, Brad Chen <bradc...@google.com> wrote:
> >> The command-line validator is not being very helpful in this case.
> Someplace
> >> in the middle of the output you omitted, it said something about
> multiple
> >> text sections, which it doesn't like, because it's worried about holes.
> When
> >> the validator is invoked by sel_ldr, it turns out that the sections have
> >> already been loaded into memory, and are passed in for validation as a
> >> single contiguous region.
> >> Brad Chen
> --
> bennet s yee
> i usually don't capitalize due to mild tendonitis