# # This script was written by Noam Rathaus # # See the Nessus Scripts License for details # # Changes by rd : issue an alert only if some relation # has been found. # if(description) { script_id(10201); script_version ("$Revision$"); name["english"] = "Relative IP Identification number change"; script_name(english:name["english"]); desc["english"] = " The remote host uses non-random IP IDs, that is, it is possible to predict the next value of the ip_id field of the ip packets sent by this host. An attacker may use this feature to determine traffic patterns within your network. A few examples (not at all exhaustive) are: 1. A remote attacker can determine if the remote host sent a packet in reply to another request. Specifically, an attacker can use your server as an unwilling participant in a blind portscan of another network. 2. A remote attacker can roughly determine server requests at certain times of the day. For instance, if the server is sending much more traffic after business hours, the server may be a reverse proxy or other remote access device. An attacker can use this information to concentrate his/her efforts on the more critical machines. 3. A remote attacker can roughly estimate the number of requests that a web server processes over a period of time. Solution : Contact your vendor for a patch Risk factor : Low"; script_description(english:desc["english"]); summary["english"] = "Relative IP Identification number change"; script_summary(english:summary["english"]); script_category(ACT_GATHER_INFO); script_copyright(english:"This script is Copyright (C) 1999 SecuriTeam"); family["english"] = "General"; script_family(english:family["english"]); script_dependencies("nmap_osfingerprint.nes", "snmp_sysDesc.nasl"); exit(0); } # # The script code starts here # # localhost results are bogus if(islocalhost())exit(0); os = get_kb_item("Host/OS"); if(os) { if(ereg(pattern:"Solaris|Linux Kernel 2\.4", string:os, icase:TRUE))exit(0); } else { os = get_kb_item("SNMP/sysDesc"); if(os) { if(ereg(pattern:"SunOS|Linux 2\.4", string:os))exit(0); } } srcaddr = this_host(); dstaddr = get_host_ip(); IPH = 20; IP_LEN = IPH; ip = forge_ip_packet( ip_v : 4, ip_hl : 5, ip_tos : 0, ip_len : IP_LEN, ip_id : 0xABA, ip_p : IPPROTO_TCP, ip_ttl : 255, ip_off : 0, ip_src : srcaddr, ip_dst : dstaddr); port = get_host_open_port(); if(!port)port = 137; tcpip = forge_tcp_packet( ip : ip, th_sport : port, th_dport : port, th_flags : 0, th_seq : 0xF1C, th_ack : 0, th_x2 : 0, th_off : 5, th_win : 512, th_urp : 0); filter = string("tcp and src host ", dstaddr, " and dst host ", srcaddr, " and dst port ", port); relative = "-1"; answer_count = 0; for(i=0;i<10;i=i+1){ r[i]=""; o[i]=""; } for (packet_count = 0; packet_count < 10; packet_count = packet_count + 1) { result = send_packet(tcpip, pcap_active:TRUE, pcap_filter:filter); if ((packet_count > 3) && (answer_count == 0)) { exit(0); } if (result) { ip_id = get_ip_element(ip:result, element:"ip_id"); if(ip_id != 0 ) { answer_count = answer_count + 1; if (relative == "-1") { relative = ip_id; } else { if(ip_id > relative){ max = ip_id; min = relative; } else { max = relative; min = ip_id; } relative = max - min; r[answer_count-1] = relative; o[answer_count-1] = ip_id; relative = ip_id; } } } } ok = 1; if(answer_count) { # # Added by rd : # # # if the ids are relative, then, we have a relation such as : # # # n = n + m # i + 1 i # # # with n = i'th ip_id # i # # # # so, we have : # # n = n + k*m # i + k i # # # So it's pretty easy to find if ip_ids are relatives or not. # ni = 0; m = 0; start = 0; for(i=0;i<10;i=i+1) { if(o[i]){ start = i; ni = o[i]; i = 10; } } for(i=start+1;i<10;i=i+1) { if(o[i]) { if(o[i] > ni) { mx = o[i]; mn = ni; } else { mx = ni; mn = o[i]; } m = mx - mn; start = i; i = 10; } } ok = 1; for(i=start+1;i<10;i=i+1) { if(o[i]) { if(o[i] > ni) { mx = o[i]; mn = ni; } else { mx = ni; mn = o[i]; } km = mx - mn; # # n = n + k x m # k i # # This implies that km % m = 0 # if(km % m){ ok = 0; i = 1000; } } } # # end of rd's addition # # if(ok)security_warning(0); }