⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stackinfo.h

📁 代码给出了Linux系统下蠕虫代码如何通过有漏洞的系统进行蔓延的。
💻 H
字号:
/* File: stackinfo.h
 *
 * Author: Amul Shah
 * Class: ECE 4883
 * Lab:	Bufferoverflow Lab
 * 2003.02.02
 * Purpose: see README
 *
 */

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <netinet/in.h>

//////////////////////////////////////////////////////////
//// Display the return instruction pointer //////////////
//////////////////////////////////////////////////////////

int *stackPtr;
int *framePtr;
int *nextInstructionPtr;

#define SHOW_STACK \
  __asm__("movl %%esp, %0" \
	  : "=r" (stackPtr) ); \
  __asm__("movl %%ebp, %0" \
	  : "=r" (framePtr) ); \
  nextInstructionPtr = framePtr+1; \
\
  printf ("Stack:%x, Frame:%x[%x], Next Instruction:%x[%x]\n", \
	  stackPtr, framePtr, *framePtr, \
            nextInstructionPtr, *nextInstructionPtr);

/*
 * Explanation of SHOW_STACK
 *
 * Inline assembly in C, please consult Inline Assembly with
 * DJGPP at
 * http://www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html

 *
 * Move the value of the stack pointer, %esp, into %0 which
 * refers to stackPtr
 *
  __asm__("movl %%esp, %0"
	  : "=r" (stackPtr) );

 *
 * Move the value of the stack pointer, %ebp, into %0 which
 * refers to framePtr
 *
  __asm__("movl %%ebp, %0"
	  : "=r" (framePtr) );

 *
 * We know that the frame pointer points to the previous frame
 * pointer save on the stack.  The return instruction pointer is
 * ALWAYS saved just "above" the saved frame pointer.  So adding
 * 1 to the offset of the frame pointer (point to a memory address
 * 4 bytes greater; 1 = 4 bytes with INTs) you find the memory
 * address of the return instruction pointer.
 *
  nextInstructionPtr = framePtr+1;

 *
 * Print the contents found. Note: dereference nextInstructionPtr
 *
  printf ("Stack:%x, Frame:%x[%x], Next Instruction:%x[%x]\n",
	  stackPtr, framePtr, *framePtr,
            nextInstructionPtr, *nextInstructionPtr);
 *
 * Question:
 *  Why use global variables?
 * Answer:
 *  The global variables will not impact the local stack declared
 * variable locations.
 */


//////////////////////////////////////////////////////////
//// Inspect the buffer //////////////////////////////////
//////////////////////////////////////////////////////////

// This function was built to read overflowed buffers that
// have stack smaching code akin to that found in "Smashing
// the stack for fun and profit."
void inspect_buffer(void *buffer, int printextra)
{
  int	*redirect_ptr,		// Point to the buffer as an int array
    	offset,			// The offset used in the attack

        nop_begin,              // Offset of NOP sled
        nop_end,                // end of NOP sled + first instruction

        addr_begin,             //
        addr_end;              //

  char	nop = (char) 0x90,	// NOP character
    	*code_ptr;		// character typed pointer of the array


  int i, length;

  if ( printextra )
    {
      printf("Print Buffer\n");
      length = strlen ( (char *) buffer ) / 4;
      for ( i =0; i < length; i++ )
	{
	  if ( i%8 == 0 ) printf ("\n");
	  printf("%x ", ((int *) buffer)[i]);
	}
      printf("\n");
    }


  redirect_ptr = (int*) buffer;	// Point to the begining of the array
  code_ptr = (char *) buffer;
  offset = *redirect_ptr;	// You can grab the offset value from the
  				// 0th element of the array

  // do we start with the NOP sled?
  if ( nop == *code_ptr )       // YES
    {
      nop_begin = (int) code_ptr;

      // loop through the NOP sled until you hit the first non-NOP
      // the beginning of the buffer to the code_ptr's position is
      // the length of the NOP sled which you are hoping to land in.
      while ( nop == *(code_ptr++) );
      nop_end = (int) code_ptr;
      printf("\tTargetting range %x to %x\t\t[%d byte range]\n", 
	     nop_begin, nop_end, nop_end - nop_begin - 1);



      if ( printextra )
	{
	  printf("Print NOP sled\n");
	  length =  (nop_end - nop_begin)/4 + (nop_begin - nop_end)%4;
	  for ( i =0; i < length; i++ )
	    {
	      if ( i%8 == 0 ) printf ("\n");
	      printf("%x ", ((int *) buffer)[i]);
	    }
	  printf("\n");
	}



      /*
	CONCEPT since you use the code_ptr to find the end of the NOP
	sled, the pointer now points to the code segment. Which leaves
	you without the offset value and the memory range where the 
	offset is written to the stack.
	To get the range and value of the offset, you must realize that
	there is no spoon. ;)  The shellcode segment is not constant.
	Therefore, you want to loop until you have found the first memory
	location that has the same value consecutively.
       */
      // first you must byte align the integer pointer
      redirect_ptr = code_ptr - ( nop_end - nop_begin )%4;

      if ( printextra )
	{
	  printf("\tcode_ptr:%x, byte align:%d, redirect_ptr:%x [%d]\n",
		 code_ptr, ( nop_end - nop_begin ) % 4, redirect_ptr,
		 ((unsigned int)redirect_ptr) % 4 );
	}

      offset = *(redirect_ptr++);
      while ( offset != *redirect_ptr ) 
	{
	  offset = *(redirect_ptr++);
	}
      offset = *(redirect_ptr++);
      addr_begin = (int) --redirect_ptr;

      while ( offset == *(redirect_ptr++) )
	{
 	  // do nothing
	}


      addr_end = (int) redirect_ptr;
      printf("\tStack Overwrite from %x to %x\t[%d byte range]\n", 
	     addr_begin, addr_end, addr_end - addr_begin + 4);

      if ( printextra )
	{
	  printf("Printing memory addresses\n");
	  length = (addr_end - addr_begin + 4)/4 ;
	  for ( i =0; i < length; i++ )
	    {
	      if ( i%8 == 0 ) printf ("\n");
	      printf("%x ", (redirect_ptr-length)[i]);
	    }
	  printf("\n");
	}


      printf("\t%x <= %x < %x?\t\t", nop_end, offset, nop_begin); 
      printf("%d <= %d < %d\n\n", 
	     nop_end - nop_begin, offset - nop_begin, nop_begin - nop_begin); 

    }
}

/* Question:
 *  Why do we need both inspect_buffer AND SHOW_STACK?
 * Answer:
 *  While inspect_buffer will tell us if we have properly
 * targeted our binary code, it does not tell us if we
 * overwrote the return pointer. SHOW_STACK will show us
 * that we indeed have overwritten the return pointer.
 */



















////////// IGNORE THIS MACRO /////////////////////////////////////////
// it's just a hack to let me look above and below the frame pointer//
//////////////////////////////////////////////////////////////////////

#define SHOW_STACK_EX \
  __asm__("movl %%esp, %0" \
	  : "=r" (stackPtr) ); \
  __asm__("movl %%ebp, %0" \
	  : "=r" (framePtr) ); \
  nextInstructionPtr = framePtr+1; \
\
  printf ("Stack:%x, Frame:%x[%x], Next Instruction:%x[%x]\n", \
	  stackPtr, framePtr, *framePtr, \
            nextInstructionPtr, *nextInstructionPtr); \
  printf ("%x, %x, %x, %x, %x, %x, %x\n", *(framePtr-1), *(framePtr-2), *(framePtr-3), *(framePtr-4), *(framePtr-5), *(framePtr-6), *(framePtr-7)); \
  printf ("%x, %x, %x, %x, %x, %x, %x\n", *(framePtr+1), *(framePtr+2), *(framePtr+3), *(framePtr+4), *(framePtr+5), *(framePtr+6), *(framePtr+7));






⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -