📄 nasl_packet_forgery.c
字号:
}tree_cell * set_tcp_elements(lex_ctxt * lexic){ char * pkt = get_str_local_var_by_name(lexic, "tcp"); struct ip * ip = (struct ip*)pkt; int pktsz = get_local_var_size_by_name(lexic, "tcp"); struct tcphdr * tcp; tree_cell * retc; char * data = get_str_local_var_by_name(lexic, "data"); int data_len = get_local_var_size_by_name(lexic, "data"); char * npkt; if( pkt == NULL ) { nasl_perror(lexic, "set_tcp_elements : Invalid value for the argument 'tcp'\n"); return NULL; } if(ip->ip_hl * 4 > pktsz) tcp = (struct tcphdr*)(pkt + 20); /* ip->ip_hl is bogus, we work around that */ else tcp = (struct tcphdr*)(pkt + ip->ip_hl * 4); if(pktsz < UNFIX(ip->ip_len)) return NULL; if(data_len == 0) { data_len = UNFIX(ip->ip_len) - (ip->ip_hl * 4) - (tcp->th_off * 4); data = (char*)((char*)tcp + tcp->th_off * 4); } npkt = emalloc(ip->ip_hl * 4 + tcp->th_off * 4 + data_len); bcopy(pkt, npkt, UNFIX(ip->ip_len)); ip = (struct ip*)(npkt); tcp = (struct tcphdr*)(npkt + ip->ip_hl * 4); tcp->th_sport = htons(get_int_local_var_by_name(lexic, "th_sport", ntohs(tcp->th_sport))); tcp->th_dport = htons(get_int_local_var_by_name(lexic, "th_dport", ntohs(tcp->th_dport))); tcp->th_seq = htonl(get_int_local_var_by_name(lexic, "th_seq", ntohl(tcp->th_seq))); tcp->th_ack = htonl(get_int_local_var_by_name(lexic, "th_ack", ntohl(tcp->th_ack))); tcp->th_x2 = get_int_local_var_by_name(lexic, "th_x2", tcp->th_x2); tcp->th_off = get_int_local_var_by_name(lexic, "th_off", tcp->th_off); tcp->th_flags = get_int_local_var_by_name(lexic, "th_flags", tcp->th_flags); tcp->th_win = htons(get_int_local_var_by_name(lexic, "th_win", ntohs(tcp->th_win))); tcp->th_sum = get_int_local_var_by_name(lexic, "th_sum", 0); tcp->th_urp = get_int_local_var_by_name(lexic, "th_urp", tcp->th_urp); bcopy(data, (char*)tcp + tcp->th_off * 4, data_len); if(get_int_local_var_by_name(lexic, "update_ip_len", 1) != 0) { ip->ip_len = ip->ip_hl * 4 + tcp->th_off * 4 + data_len; ip->ip_sum = 0; ip->ip_sum = np_in_cksum((u_short *)pkt, ip->ip_hl * 4); } if(tcp->th_sum == 0) { struct pseudohdr pseudoheader; char * tcpsumdata = emalloc(sizeof(struct pseudohdr) + data_len + (data_len % 2) ); struct in_addr source, dest; source.s_addr = ip->ip_src.s_addr; dest.s_addr = ip->ip_dst.s_addr; bzero(&pseudoheader, sizeof(pseudoheader)); pseudoheader.saddr.s_addr=source.s_addr; pseudoheader.daddr.s_addr=dest.s_addr; pseudoheader.protocol = IPPROTO_TCP; pseudoheader.length = htons(sizeof(struct tcphdr) + data_len); bcopy((char *) tcp,(char *) &pseudoheader.tcpheader,sizeof(struct tcphdr)); /* fill tcpsumdata with data to checksum */ bcopy((char *) &pseudoheader, tcpsumdata ,sizeof(struct pseudohdr)); bcopy((char *) data, tcpsumdata + sizeof(struct pseudohdr), data_len ); tcp->th_sum = np_in_cksum((unsigned short *)tcpsumdata,sizeof(pseudoheader) + data_len ); efree(&tcpsumdata ); } retc = alloc_tree_cell(0, NULL); retc->type = CONST_DATA; retc->size = (ip->ip_hl * 4) + (tcp->th_off * 4) + data_len; retc->x.str_val = npkt; return retc;}tree_cell * dump_tcp_packet(lex_ctxt * lexic){ int i = 0; u_char * pkt; while((pkt = (u_char*)get_str_var_by_num(lexic, i++)) != NULL) { int a=0; struct ip * ip = (struct ip*)pkt; struct tcphdr * tcp = (struct tcphdr *)(pkt + ip->ip_hl * 4); int j; int limit; char * c; limit = get_var_size_by_num(lexic, i - 1); printf("------\n"); printf("\tth_sport : %d\n", ntohs(tcp->th_sport)); printf("\tth_dport : %d\n", ntohs(tcp->th_dport)); printf("\tth_seq : %u\n", (unsigned int)ntohl(tcp->th_seq)); printf("\tth_ack : %u\n", (unsigned int)ntohl(tcp->th_ack)); printf("\tth_x2 : %d\n", tcp->th_x2); printf("\tth_off : %d\n",tcp->th_off); printf("\tth_flags : "); if(tcp->th_flags & TH_FIN){printf("TH_FIN");a++;} if(tcp->th_flags & TH_SYN){if(a)printf("|");printf("TH_SYN");a++;} if(tcp->th_flags & TH_RST){if(a)printf("|");printf("TH_RST");a++;} if(tcp->th_flags & TH_PUSH){if(a)printf("|");printf("TH_PUSH");a++;} if(tcp->th_flags & TH_ACK){if(a)printf("|");printf("TH_ACK");a++;} if(tcp->th_flags & TH_URG){if(a)printf("|");printf("TH_URG");a++;} if(!a)printf("0"); else printf(" (%d)", tcp->th_flags); printf("\n"); printf("\tth_win : %d\n", ntohs(tcp->th_win)); printf("\tth_sum : 0x%x\n", tcp->th_sum); printf("\tth_urp : %d\n", tcp->th_urp); printf("\tData : "); c = (char*)((char*)tcp+sizeof(struct tcphdr)); if(UNFIX(ip->ip_len)>(sizeof(struct ip)+sizeof(struct tcphdr))) for(j=0;j<UNFIX(ip->ip_len)-sizeof(struct ip)-sizeof(struct tcphdr) && j < limit;j++) printf("%c", isprint(c[j])?c[j]:'.'); printf("\n"); printf("\n"); } return NULL;}/*--------------[ UDP ]--------------------------------------------*/struct pseudo_udp_hdr{ struct in_addr saddr; struct in_addr daddr; char nothing; char proto; unsigned short len; struct udphdr udpheader;};tree_cell * forge_udp_packet(lex_ctxt * lexic){ tree_cell * retc; struct ip * ip = (struct ip *)get_str_local_var_by_name(lexic, "ip"); if(ip != NULL) { char * data = get_str_local_var_by_name(lexic, "data"); int data_len = get_local_var_size_by_name(lexic, "data"); u_char * pkt; struct ip * udp_packet; struct udphdr * udp; pkt = emalloc(sizeof(struct udphdr)+ip->ip_hl*4+sizeof(struct udphdr) + data_len); udp_packet = (struct ip*)pkt; udp = (struct udphdr*)(pkt + ip->ip_hl*4); udp->uh_sport = htons(get_int_local_var_by_name(lexic, "uh_sport", 0)); udp->uh_dport = htons(get_int_local_var_by_name(lexic, "uh_dport", 0)); udp->uh_ulen = htons(get_int_local_var_by_name(lexic, "uh_ulen", data_len + sizeof(struct udphdr))); /* printf("len : %d %s\n", len, data);*/ if(data_len != 0 && data != NULL)bcopy(data, (pkt + ip->ip_hl * 4 + sizeof(struct udphdr)), data_len); udp->uh_sum = get_int_local_var_by_name(lexic, "uh_sum", 0); bcopy((char*)ip, pkt, ip->ip_hl*4); if(udp->uh_sum == 0) { struct pseudo_udp_hdr pseudohdr; struct in_addr source, dest; char * udpsumdata = (char*)emalloc(sizeof(struct pseudo_udp_hdr) + (data_len % 2 ? data_len + 1 : data_len)); source.s_addr = ip->ip_src.s_addr; dest.s_addr = ip->ip_dst.s_addr; bzero(&pseudohdr, sizeof(struct pseudo_udp_hdr)); pseudohdr.saddr.s_addr = source.s_addr; pseudohdr.daddr.s_addr = dest.s_addr; pseudohdr.proto = IPPROTO_UDP; pseudohdr.len = htons(sizeof(struct udphdr) + data_len); bcopy((char*)udp, (char*)&pseudohdr.udpheader, sizeof(struct udphdr)); bcopy((char*)&pseudohdr, udpsumdata, sizeof(pseudohdr)); if(data != NULL) { bcopy((char*)data, udpsumdata + sizeof(pseudohdr), data_len ); } udp->uh_sum = np_in_cksum((unsigned short*)udpsumdata, 12 + sizeof(struct udphdr) + data_len); efree(&udpsumdata); } if(UNFIX(udp_packet->ip_len) <= udp_packet->ip_hl * 4) { int v = get_int_local_var_by_name(lexic, "update_ip_len", 1); if(v != 0) { udp_packet->ip_len = FIX(ntohs(udp->uh_ulen)+(udp_packet->ip_hl*4)); udp_packet->ip_sum = 0; udp_packet->ip_sum = np_in_cksum((u_short*)udp_packet, udp_packet->ip_hl*4); } } retc = alloc_tree_cell(0, NULL); retc->type = CONST_DATA; retc->x.str_val = (char*)pkt; retc->size = 8 + ip->ip_hl * 4 + data_len; return retc; } else printf("Error ! You must supply the 'ip' argument !\n"); return NULL;}tree_cell * get_udp_element(lex_ctxt * lexic){ tree_cell * retc; char * udp; char * element; struct ip * ip; int ipsz; struct udphdr * udphdr; int ret; udp = get_str_local_var_by_name(lexic, "udp"); ipsz = get_local_var_size_by_name(lexic, "udp"); element = get_str_local_var_by_name(lexic, "element"); if(udp == NULL || element == NULL ) { printf("get_udp_element() usage :\n"); printf("element = get_udp_element(udp:<udp>,element:<element>\n"); return NULL; }ip = (struct ip*)udp;if(ip->ip_hl * 4 + sizeof(struct udphdr) > ipsz) return NULL; udphdr = (struct udphdr*)(udp+ip->ip_hl*4);if(!strcmp(element, "uh_sport")) ret = ntohs(udphdr->uh_sport);else if(!strcmp(element, "uh_dport")) ret = ntohs(udphdr->uh_dport);else if(!strcmp(element, "uh_ulen")) ret = ntohs(udphdr->uh_ulen);else if(!strcmp(element, "uh_sum")) ret = ntohs(udphdr->uh_sum);else if(!strcmp(element, "data")) { int sz; retc = alloc_tree_cell(0, NULL); retc->type = CONST_DATA; sz = ntohs(udphdr->uh_ulen) - sizeof(struct udphdr); if(ntohs(udphdr->uh_ulen) - ip->ip_hl * 4 - sizeof(struct udphdr) > ipsz) sz = ipsz - ip->ip_hl * 4 - sizeof(struct udphdr); retc->x.str_val = emalloc(sz); retc->size = sz ; bcopy(udp + ip->ip_hl*4 + sizeof(struct udphdr), retc->x.str_val, sz); return retc; } else { printf("%s is not a value of a udp packet\n", element); return NULL; } retc = alloc_tree_cell(0, NULL); retc->type = CONST_INT; retc->x.i_val = ret; return retc;}tree_cell * set_udp_elements(lex_ctxt * lexic){ struct ip * ip = (struct ip*)get_str_local_var_by_name(lexic, "udp"); int sz = get_local_var_size_by_name(lexic, "udp"); char * data = get_str_local_var_by_name(lexic, "data"); int data_len = get_local_var_size_by_name(lexic, "data"); if( ip != NULL ) { char * pkt = emalloc(sz + data_len); struct udphdr * udp; tree_cell * retc; int old_len; if(ip->ip_hl * 4 + sizeof(struct udphdr) > sz) return NULL; if(data != NULL) { sz = ip->ip_hl * 4 + sizeof(struct udphdr) + data_len; pkt = emalloc(sz); bcopy(ip, pkt, ip->ip_hl * 4 + sizeof(struct udphdr)); } else { pkt = emalloc(sz); bcopy(ip, pkt, sz); } ip = (struct ip *)pkt; if(data != NULL) { ip->ip_len = FIX(sz); ip->ip_sum = 0; ip->ip_sum = np_in_cksum(ip, ip->ip_hl * 4); } udp = (struct udphdr*)(pkt + ip->ip_hl * 4); udp->uh_sport = htons(get_int_local_var_by_name(lexic, "uh_sport", ntohs(udp->uh_sport))); udp->uh_dport = htons(get_int_local_var_by_name(lexic, "uh_dport", ntohs(udp->uh_dport))); old_len = ntohs(udp->uh_ulen); udp->uh_ulen = htons(get_int_local_var_by_name(lexic, "uh_ulen", ntohs(udp->uh_ulen))); udp->uh_sum = get_int_local_var_by_name(lexic, "uh_sum", 0); if(data != NULL) { bcopy(data, pkt + ip->ip_hl * 4 + sizeof(struct udphdr), data_len); udp->uh_ulen = htons(sizeof(struct udphdr) + data_len); } if(udp->uh_sum == 0) { struct pseudo_udp_hdr pseudohdr; struct in_addr source, dest; int len = old_len - sizeof(struct udphdr); char * udpsumdata; char * ptr = NULL; if(data != NULL) { len = data_len; } if(len > 0) { ptr = (char*)udp + sizeof(struct udphdr); } udpsumdata = (char*)emalloc(sizeof(struct pseudo_udp_hdr) + (len % 2 ? len + 1 : len)); source.s_addr = ip->ip_src.s_addr; dest.s_addr = ip->ip_dst.s_addr; bzero(&pseudohdr, sizeof(struct pseudo_udp_hdr)); pseudohdr.saddr.s_addr = source.s_addr; pseudohdr.daddr.s_addr = dest.s_addr; pseudohdr.proto = IPPROTO_UDP; pseudohdr.len = htons(sizeof(struct udphdr) + len); bcopy((char*)udp, (char*)&pseudohdr.udpheader, sizeof(struct udphdr)); bcopy((char*)&pseudohdr, udpsumdata, sizeof(pseudohdr)); if(ptr != NULL) { bcopy((char*)ptr, udpsumdata + sizeof(pseudohdr), len ); } udp->uh_sum = np_in_cksum((unsigned short*)udpsumdata, 12 + sizeof(struct udphdr) + len); efree(&udpsumdata); } retc = alloc_tree_cell(0, NULL); retc->type = CONST_DATA; retc->size = sz; retc->x.str_val = pkt; return retc; } else printf("Error ! You must supply the 'udp' argument !\n"); return NULL;}tree_cell * dump_udp_packet(lex_ctxt * lexic){ int i = 0; u_char * pkt; while((pkt = (u_char*)get_str_var_by_num(lexic, i++)) != NULL) { struct udphdr * udp = (struct udphdr*)(pkt+sizeof(struct ip)); int j; char * c; int limit = get_var_size_by_num(lexic, i - 1); printf("------\n"); printf("\tuh_sport : %d\n", ntohs(udp->uh_sport)); printf("\tuh_dport : %d\n", ntohs(udp->uh_dport)); printf("\tuh_sum : 0x%x\n", udp->uh_sum); printf("\tuh_ulen : %d\n", ntohs(udp->uh_ulen)); printf("\tdata : "); c = (char*)(udp + sizeof(struct udphdr)); if(udp->uh_ulen > sizeof(struct udphdr)) for(j=0;j<(ntohs(udp->uh_ulen)-sizeof(struct udphdr)) && j < limit;j++) printf("%c", isprint(c[j])?c[j]:'.'); printf("\n"); } return NULL;}/*--------------[ ICMP ]--------------------------------------------*/tree_cell* forge_icmp_packet(lex_ctxt* lexic){ tree_cell *retc = NULL; struct ip *ip; struct ip *ip_icmp; int ip_sz; struct icmp *icmp; char *data, *p; int len; u_char *pkt; int t; ip = (struct ip*)get_str_local_var_by_name(lexic, "ip"); ip_sz = get_local_var_size_by_name(lexic, "ip"); if (ip != NULL) { data = get_str_local_var_by_name(lexic, "data"); len = data == NULL ? 0 : get_var_size_by_name(lexic, "data"); t = get_int_local_var_by_name(lexic, "icmp_type", 0); if(t == 13 || t == 14) len += 3 * sizeof(time_t); if(ip->ip_hl * 4 > ip_sz) return NULL; pkt = emalloc(sizeof(struct icmp) + ip_sz + len); ip_icmp = (struct ip*) pkt; bcopy(ip, ip_icmp, ip_sz); if(UNFIX(ip_icmp->ip_len) <= (ip_icmp->ip_hl * 4)) { if (get_int_local_var_by_name(lexic, "update_ip_len", 1) != 0) { ip_icmp->ip_len = FIX(ip->ip_hl*4 + 8 + len); ip_icmp->ip_sum = 0; ip_icmp->ip_sum = np_in_cksum((u_short*)ip_icmp, ip->ip_hl*4); } } p = (char*)(pkt + (ip->ip_hl*4)); icmp = (struct icmp*)p; icmp->icmp_code = get_int_local_var_by_name(lexic, "icmp_code", 0); icmp->icmp_type = t; icmp->icmp_seq = htons(get_int_local_var_by_name(lexic, "icmp_seq", 0)); icmp->icmp_id = htons(get_int_local_var_by_name(lexic, "icmp_id", 0)); if(data != NULL)bcopy(data, &(p[8]), len); if(get_int_local_var_by_name(lexic, "icmp_cksum", -1) == -1 ) icmp->icmp_cksum = np_in_cksum((u_short *) icmp, len + 8); else icmp->icmp_cksum = htons(get_int_local_var_by_name(lexic, "icmp_cksum", 0)); retc = alloc_tree_cell(0, NULL); retc->type = CONST_DATA; retc->x.str_val = (char*)pkt; retc->size = ip_sz + len + 8; } else nasl_perror(lexic, "forge_icmp_packet: missing 'ip' parameter\n"); return retc;}tree_cell * get_icmp_element(lex_ctxt * lexic){ struct icmp * icmp; char * p; if((p = get_str_local_var_by_name(lexic, "icmp")) != NULL) { char * elem = get_str_local_var_by_name(lexic, "element"); int value; struct ip * ip = (struct ip*)p; tree_cell * retc; icmp = (struct icmp*)(p+ip->ip_hl*4); if( elem == NULL ) return NULL; if(!strcmp(elem, "icmp_id"))value = ntohs(icmp->icmp_id); else if(!strcmp(elem, "icmp_code"))value = icmp->icmp_code; else if(!strcmp(elem, "icmp_type"))value = icmp->icmp_type;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -