1<?php 2/******************************************************************************* 3** Basic Analysis and Security Engine (BASE) 4** Copyright (C) 2004 BASE Project Team 5** Copyright (C) 2000 Carnegie Mellon University 6** 7** (see the file 'base_main.php' for license details) 8** 9** Project Leads: Kevin Johnson <kjohnson@secureideas.net> 10** Sean Muller <samwise_diver@users.sourceforge.net> 11** Built upon work by Roman Danyliw <rdd@cert.org>, <roman@danyliw.com> 12** 13** Purpose: Common Functions 14******************************************************************************** 15** Authors: 16******************************************************************************** 17** Kevin Johnson <kjohnson@secureideas.net 18** 19******************************************************************************** 20*/ 21 22function GetSensorIDs($db) 23{ 24 $result = $db->baseExecute("SELECT sid FROM sensor;"); 25 26 while( $myrow = $result->baseFetchRow() ) { 27 $sensor_ids[] = $myrow[0]; 28 } 29 30 $result->baseFreeRows(); 31 32 return $sensor_ids; 33} 34 35function GetSensorName($sid, $db) 36{ 37 $name = ""; 38 39 $temp_sql = "SELECT sid, hostname, interface, filter FROM sensor WHERE sid='".$sid."'"; 40 $tmp_result = $db->baseExecute($temp_sql); 41 if ( $tmp_result ) 42 { 43 $myrow = $tmp_result->baseFetchRow(); 44 $name = $myrow[1].':'.$myrow[2]; 45 if ( $myrow[3] != "" ) 46 $name = $name.':'.$myrow[3]; 47 } 48 $tmp_result->baseFreeRows(); 49 50 return $name; 51} 52 53function GetVendor($mac) 54{ 55 $mac = str_replace(":", "", $mac); 56 $mac = substr($mac, 0, 6); 57 $vendor = 'unknown'; 58 59 if (@$fp = fopen("base_mac_prefixes.map", "r")) { 60 while (!feof($fp)) { 61 $line = fgets($fp); 62 if (strcmp($mac, substr($line, 0, 6)) == 0) 63 $vendor = substr($line, 7, strlen($line)-8); 64 } 65 fclose($fp); 66 } 67 else 68 return "can't open vendor map"; 69 70 return $vendor; 71} 72 73function InputSafeSQL (&$SQLstr) 74/* Removes the escape sequence of \' => ' which arise when a variable containing a '-character is passed 75 through a POST query. This is needed since otherwise the MySQL parser complains */ 76{ 77 $SQLstr = str_replace("\'", "'", $SQLstr); 78 $SQLstr = str_replace("\\\"", "\"", $SQLstr); 79} 80 81 82function PrintProtocolProfileGraphs ($db) 83{ 84 $tcp_cnt = TCPPktCnt($db); 85 $udp_cnt = UDPPktCnt($db); 86 $icmp_cnt = ICMPPktCnt($db); 87 $portscan_cnt = PortscanPktCnt($db); 88 $layer4_cnt = $tcp_cnt + $udp_cnt + $icmp_cnt + $portscan_cnt; 89 90 if ( $tcp_cnt > 0 ) 91 { 92 $tcp_percent = round($tcp_cnt/$layer4_cnt*100); 93 if ( $tcp_percent == 0 ) 94 $tcp_percent_show = "< 1"; 95 else 96 $tcp_percent_show = $tcp_percent; 97 } 98 else 99 { 100 $tcp_percent = 0; 101 $tcp_percent_show = "0"; 102 } 103 104 if ( $udp_cnt > 0 ) 105 { 106 $udp_percent = round($udp_cnt/$layer4_cnt*100); 107 if ( $udp_percent == 0 ) 108 $udp_percent_show = "< 1"; 109 else 110 $udp_percent_show = $udp_percent; 111 } 112 else 113 { 114 $udp_percent = 0; 115 $udp_percent_show = "0"; 116 } 117 118 if ( $icmp_cnt > 0 ) 119 { 120 $icmp_percent = round($icmp_cnt/$layer4_cnt*100); 121 if ( $icmp_percent == 0 ) 122 $icmp_percent_show = "< 1"; 123 else 124 $icmp_percent_show = $icmp_percent; 125 } 126 else 127 { 128 $icmp_percent = 0; 129 $icmp_percent_show = 0; 130 } 131 132 if ( $portscan_cnt > 0 ) 133 { 134 $portscan_percent = round($portscan_cnt/$layer4_cnt*100); 135 if ( $portscan_percent == 0 ) 136 $portscan_percent_show = "< 1"; 137 else 138 $portscan_percent_show = $portscan_percent; 139 } 140 else 141 { 142 $portscan_percent = 0; 143 $portscan_percent_show = "0"; 144 } 145 146 if ( $tcp_percent > 0 ) $color = "#FF0000"; else $color="#CCCCCC"; 147 $rem_percent=100-$tcp_percent; 148 echo '<TABLE WIDTH="100%" BORDER=0> 149 <TR><TD>TCP<A HREF="base_qry_main.php?new=1'. 150 '&layer4=TCP&num_result_rows=-1&sort_order=time_d&submit='._QUERYDBP.'"> 151 ('.$tcp_percent_show.'%)</A></TD><TD></TD></TR></TABLE> 152 <TABLE class="summarygraph" WIDTH="100%" BORDER=1 CELLSPACING=0 CELLPADDING=0> 153 <TR><TD ALIGN=CENTER BGCOLOR="'.$color.'" WIDTH="'.$tcp_percent.'%"> </TD>'; 154 if ( $tcp_percent > 0 ) echo '<TD BGCOLOR="#CCCCCC" WIDTH="'.$rem_percent.'%"> </TD>'; 155 echo '</TR></TABLE>'; 156 157 if ( $udp_percent > 0 ) $color = "#FF0000"; else $color="#CCCCCC"; 158 $rem_percent=100-$udp_percent; 159 echo '<TABLE WIDTH="100%" BORDER=0> 160 <TR><TD>UDP<A HREF="base_qry_main.php?new=1'. 161 '&layer4=UDP&num_result_rows=-1&sort_order=time_d&submit='._QUERYDBP.'"> 162 ('.$udp_percent_show.'%)</A></TD><TD></TD></TR></TABLE> 163 <TABLE class="summarygraph" WIDTH="100%" BORDER=1 CELLSPACING=0 CELLPADDING=0> 164 <TR><TD ALIGN=CENTER BGCOLOR="'.$color.'" WIDTH="'.$udp_percent.'%"> </TD>'; 165 if ( $udp_percent > 0 ) echo '<TD BGCOLOR="#CCCCCC" WIDTH="'.$rem_percent.'%"> </TD>'; 166 echo '</TR></TABLE>'; 167 168 if ( $icmp_percent > 0 ) $color = "#FF0000"; else $color="#CCCCCC"; 169 $rem_percent=100-$icmp_percent; 170 echo '<TABLE WIDTH="100%" BORDER=0> 171 <TR><TD>ICMP<A HREF="base_qry_main.php?new=1'. 172 '&layer4=ICMP&num_result_rows=-1&sort_order=time_d&submit='._QUERYDBP.'"> 173 ('.$icmp_percent_show.'%)</A></TD><TD></TD></TR></TABLE> 174 <TABLE class="summarygraph" WIDTH="100%" BORDER=1 CELLSPACING=0 CELLPADDING=0> 175 <TR><TD ALIGN=CENTER BGCOLOR="'.$color.'" WIDTH="'.$icmp_percent.'%"> </TD>'; 176 if ( $icmp_percent > 0 ) echo '<TD BGCOLOR="#CCCCCC" WIDTH="'.$rem_percent.'%"> </TD>'; 177 echo '</TR></TABLE>'; 178 179 echo '<CENTER><HR NOSHADE WIDTH="70%"></CENTER>'; 180 181 if ( $portscan_percent > 0 ) $color = "#FF0000"; else $color="#CCCCCC"; 182 $rem_percent=100-$portscan_percent; 183 echo '<TABLE WIDTH="100%" BORDER=0> 184 <TR><TD>'._PORTSCAN.' 185 <A HREF="base_qry_main.php?new=1'. 186'&layer4=RawIP&num_result_rows=-1&sort_order=time_d&submit='._QUERYDBP.'">('.$portscan_percent_show.'%)</A> 187 </TD><TD></TD></TR></TABLE> 188 <TABLE class="summarygraph" WIDTH="100%" BORDER=1 CELLSPACING=0 CELLPADDING=0> 189 <TR><TD ALIGN=CENTER BGCOLOR="'.$color.'" WIDTH="'.$portscan_percent.'%"> </TD>'; 190 if ( $portscan_percent > 0 ) echo '<TD BGCOLOR="#CCCCCC" WIDTH="'.$rem_percent.'%"> </TD>'; 191 echo '</TR></TABLE>'; 192} 193 194function BuildIPFormVars($ipaddr) 195{ 196 return ''. 197 '&ip_addr%5B0%5D%5B0%5D=+&ip_addr%5B0%5D%5B1%5D=ip_src&ip_addr%5B0%5D%5B2%5D=%3D'. 198 '&ip_addr%5B0%5D%5B3%5D='.$ipaddr. 199 '&ip_addr%5B0%5D%5B8%5D=+&ip_addr%5B0%5D%5B9%5D=OR'. 200 '&ip_addr%5B1%5D%5B0%5D=+&ip_addr%5B1%5D%5B1%5D=ip_dst&ip_addr%5B1%5D%5B2%5D=%3D'. 201 '&ip_addr%5B1%5D%5B3%5D='.$ipaddr. 202 '&ip_addr%5B1%5D%5B8%5D=+&ip_addr%5B1%5D%5B9%5D=+'; 203} 204 205function BuildSrcIPFormVars($ipaddr) 206{ 207 return ''. 208 '&ip_addr%5B0%5D%5B0%5D=+&ip_addr%5B0%5D%5B1%5D=ip_src&ip_addr%5B0%5D%5B2%5D=%3D'. 209 '&ip_addr%5B0%5D%5B3%5D='.$ipaddr. 210 '&ip_addr%5B0%5D%5B8%5D=+&ip_addr%5B0%5D%5B9%5D=+'; 211} 212 213function BuildDstIPFormVars($ipaddr) 214{ 215 return ''. 216 '&ip_addr%5B0%5D%5B0%5D=+&ip_addr%5B0%5D%5B1%5D=ip_dst&ip_addr%5B0%5D%5B2%5D=%3D'. 217 '&ip_addr%5B0%5D%5B3%5D='.$ipaddr. 218 '&ip_addr%5B0%5D%5B8%5D=+&ip_addr%5B0%5D%5B9%5D=+'; 219} 220 221function BuildUniqueAddressLink($addr_type, $raw = "" ) 222{ 223 return '<A HREF="base_stat_uaddr.php?addr_type='.$addr_type.$raw.'">'; 224} 225 226function BuildUniqueAlertLink($raw) 227{ 228 return '<A HREF="base_stat_alerts.php'.$raw.'">'; 229} 230 231function BuildAddressLink($ipaddr, $netmask) 232{ 233 return '<A HREF="base_stat_ipaddr.php?ip='.rawurlencode($ipaddr). 234 '&netmask='.$netmask.'">'; 235} 236 237/* Adds another blank row to a given criteria element */ 238function AddCriteriaFormRow ( &$submit, $submit_value, &$cnt, &$criteria_array, $max ) 239{ 240 $submit = $submit_value; 241 242 ++$cnt; 243 InitArray($criteria_array[$cnt-1], $max, 0, ""); 244} 245 246function IPProto2str($ipproto_code) 247{ 248 switch($ipproto_code) 249 { 250 case 0: 251 return "IP"; 252 case 1: 253 return "ICMP"; 254 case 2: 255 return "IGMP"; 256 case 4: 257 return "IPIP tunnels"; 258 case 6: 259 return "TCP"; 260 case 8: 261 return "EGP"; 262 case 12: 263 return "PUP"; 264 case 17: 265 return "UDP"; 266 case 22: 267 return "XNS UDP"; 268 case 29: 269 return "SO TP Class 4"; 270 case 41: 271 return "IPv6 header"; 272 case 43: 273 return "IPv6 routing header"; 274 case 44: 275 return "IPv6 fragmentation header"; 276 case 46: 277 return "RSVP"; 278 case 47: 279 return "GRE"; 280 case 50: 281 return "IPSec ESP"; 282 case 51: 283 return "IPSec AH"; 284 case 58: 285 return "ICMPv6"; 286 case 59: 287 return "IPv6 no next header"; 288 case 60: 289 return "IPv6 destination options"; 290 case 92: 291 return "MTP"; 292 case 98: 293 return "Encapsulation header"; 294 case 103: 295 return "PIM"; 296 case 108: 297 return "COMP"; 298 case 255: 299 return "Raw IP"; 300 default: 301 return $ipproto_code; 302 } 303} 304 305function TCPOption2str($tcpopt_code) 306/* per RFC 1072, 1323, 1644 */ 307{ 308 switch($tcpopt_code) 309 { 310 case 2: /* TCPOPT_MAXSEG - maximum segment*/ 311 return "(2) MSS"; 312 case 0: /* TCPOPT_EOL */ 313 return "(0) EOL"; 314 case 1: /* TCPOPT_NOP */ 315 return "(1) NOP"; 316 case 3: /* TCPOPT_WSCALE (rfc1072)- window scale factor */ 317 return "(3) WS"; 318 case 5: /* TCPOPT_SACK (rfc1072)- selective ACK */ 319 return "(5) SACK"; 320 case 4: /* TCPOPT_SACKOK (rfc1072)- selective ACK OK */ 321 return "(4) SACKOK"; 322 case 6: /* TCPOPT_ECHO (rfc1072)- echo */ 323 return "(6) Echo"; 324 case 7: /* TCPOPT_ECHOREPLY (rfc1072)- echo reply */ 325 return "(7) Echo Reply"; 326 case 8: /* TCPOPT_TIMESTAMP (rfc1323)- timestamps */ 327 return "(8) TS"; 328 case 9: /* RFC1693 */ 329 return "(9) Partial Order Connection Permitted"; 330 case 10: /* RFC1693 */ 331 return "(10) Partial Order Service Profile"; 332 case 11: /* TCPOPT_CC (rfc1644)- CC options */ 333 return "(11) CC"; 334 case 12: /* TCPOPT_CCNEW (rfc1644)- CC options */ 335 return "(12) CCNEW"; 336 case 13: /* TCPOPT_CCECHO (rfc1644)- CC options */ 337 return "(13) CCECHO"; 338 case 14: /* RFC1146 */ 339 return "(14) TCP Alternate Checksum Request"; 340 case 15: /* RFC1146 */ 341 return "(15) TCP Alternate Checksum Data"; 342 case 16: 343 return "(16) Skeeter"; 344 case 17: 345 return "(17) Bubba"; 346 case 18: /* Subbu and Monroe */ 347 return "(18) Trailer Checksum Option"; 348 case 19: /* Subbu and Monroe */ 349 return "(19) MD5 Signature"; 350 case 20: /* Scott */ 351 return "(20) SCPS Capabilities"; 352 case 21: /* Scott */ 353 return "(21) Selective Negative Acknowledgements"; 354 case 22: /* Scott */ 355 return "(22) Record Boundaries"; 356 case 23: /* Scott */ 357 return "(23) Corruption Experienced"; 358 case 24: /* Sukonnik */ 359 return "(24) SNAP"; 360 case 25: 361 return "(25) Unassigned"; 362 case 26: /* Bellovin */ 363 return "(26) TCP Compression Filter"; 364 default: 365 return $tcpopt_code; 366 } 367} 368 369function IPOption2str($ipopt_code) 370{ 371 switch($ipopt_code) 372 { 373 case 7: /* IPOPT_RR */ 374 return "RR"; 375 case 0: /* IPOPT_EOL */ 376 return "EOL"; 377 case 1: /* IPOPT_NOP */ 378 return "NOP"; 379 case 0x44: /* IPOPT_TS */ 380 return "TS"; 381 case 0x82: /* IPOPT_SECURITY */ 382 return "SEC"; 383 case 0x83: /* IPOPT_LSRR */ 384 return "LSRR"; 385 case 0x84: /* IPOPT_LSRR_E */ 386 return "LSRR_E"; 387 case 0x88: /* IPOPT_SATID */ 388 return "SID"; 389 case 0x89: /* IPOPT_SSRR */ 390 return "SSRR"; 391 } 392} 393 394function ICMPType2str($icmp_type) 395{ 396 switch ($icmp_type) 397 { 398 case 0: /* ICMP_ECHOREPLY */ 399 return "Echo Reply"; 400 case 3: /* ICMP_DEST_UNREACH */ 401 return "Destination Unreachable"; 402 case 4: /* ICMP_SOURCE_QUENCH */ 403 return "Source Quench"; 404 case 5: /* ICMP_REDIRECT */ 405 return "Redirect"; 406 case 8: /* ICMP_ECHO */ 407 return "Echo Request"; 408 case 9: 409 return "Router Advertisement"; 410 case 10: 411 return "Router Solicitation"; 412 case 11: /* ICMP_TIME_EXCEEDED */ 413 return "Time Exceeded"; 414 case 12: /* ICMP_PARAMETERPROB */ 415 return "Parameter Problem"; 416 case 13: /* ICMP_TIMESTAMP */ 417 return "Timestamp Request"; 418 case 14: /* ICMP_TIMESTAMPREPLY */ 419 return "Timestamp Reply"; 420 case 15: /* ICMP_INFO_REQUEST */ 421 return "Information Request"; 422 case 16: /* ICMP_INFO_REPLY */ 423 return "Information Reply"; 424 case 17: /* ICMP_ADDRESS */ 425 return "Address Mask Request"; 426 case 18: /* ICMP_ADDRESSREPLY */ 427 return "Address Mask Reply"; 428 case 19: 429 return "Reserved (security)"; 430 case 20: 431 return "Reserved (robustness)"; 432 case 21: 433 return "Reserved (robustness)"; 434 case 22: 435 return "Reserved (robustness)"; 436 case 23: 437 return "Reserved (robustness)"; 438 case 24: 439 return "Reserved (robustness)"; 440 case 25: 441 return "Reserved (robustness)"; 442 case 26: 443 return "Reserved (robustness)"; 444 case 27: 445 return "Reserved (robustness)"; 446 case 28: 447 return "Reserved (robustness)"; 448 case 29: 449 return "Reserved (robustness)"; 450 case 30: 451 return "Traceroute"; 452 case 31: 453 return "Datagram Conversion Error"; 454 case 32: 455 return "Mobile Host Redirect"; 456 case 33: 457 return "IPv6 Where-Are-You"; 458 case 34: 459 return "IPv6 I-Am-Here"; 460 case 35: 461 return "Mobile Registration Request"; 462 case 36: 463 return "Mobile Registration Reply"; 464 case 37: 465 return "Domain Name Request"; 466 case 38: 467 return "Domain Name Reply"; 468 case 39: 469 return "SKIP"; 470 case 40: 471 return "Photuris"; 472 default: 473 return $icmp_type; 474 } 475} 476 477function ICMPCode2str($icmp_type, $icmp_code) 478{ 479 if ( $icmp_type == 3 ) 480 { 481 switch ($icmp_code) 482 { 483 case 0: /* ICMP_NET_UNREACH */ 484 return "Network Unreachable"; 485 case 1: /* ICMP_HOST_UNREACH */ 486 return "Host Unreachable"; 487 case 2: /* ICMP_PROT_UNREACH */ 488 return "Protocol Unreachable"; 489 case 3: /* ICMP_PORT_UNREACH */ 490 return "Port Unreachable"; 491 case 4: /* ICMP_FRAG_NEEDED */ 492 return "Fragmentation Needed/DF set"; 493 case 5: /* ICMP_SR_FAILED */ 494 return "Source Route failed"; 495 case 6: /* ICMP_NET_UNKNOWN */ 496 return "Network Unknown"; 497 case 7: /* ICMP_HOST_UNKNOWN */ 498 return "Host Unknown"; 499 case 8: /* ICMP_HOST_ISOLATED */ 500 return "Host Isolated"; 501 case 9: /* ICMP_NET_ANO */ 502 return "Network ANO"; 503 case 10: /* ICMP_HOST_ANO */ 504 return "Host ANO"; 505 case 11: /* ICMP_NET_UNR_TOS */ 506 return "Network Unreach TOS"; 507 case 12: /* ICMP_HOST_UNR_TOS */ 508 return "Host Unreach TOS"; 509 case 13: /* ICMP_PKT_FILTERED */ 510 return "Packet Filtered"; 511 case 14: /* ICMP_PREC_VIOLATION */ 512 return "Precedence violation"; 513 case 15: /* ICMP_PREC_CUTOFF */ 514 return "Precedence cut off"; 515 default: 516 return $icmp_code; 517 } 518 } 519 elseif ( $icmp_type == 5 ) 520 { 521 switch ($icmp_code) 522 { 523 case 0: 524 return "Redirect datagram for network/subnet"; 525 case 1: 526 return "Redirect datagram for host"; 527 case 2: 528 return "Redirect datagram for ToS and network"; 529 case 3: 530 return "Redirect datagram for Tos and host"; 531 default: 532 return $icmp_code; 533 } 534 } 535 elseif ( $icmp_type == 9 ) 536 { 537 switch ($icmp_code) 538 { 539 case 0: 540 return "Normal router advertisement"; 541 case 16: 542 return "Does not route common traffic"; 543 default: 544 return $icmp_code; 545 } 546 } 547 elseif ( $icmp_type == 11 ) 548 { 549 switch ($icmp_code) 550 { 551 case 0: 552 return "TTL exceeded in transit"; 553 case 1: 554 return "Fragment reassembly time exceeded"; 555 default: 556 return $icmp_code; 557 } 558 } 559 elseif ( $icmp_type == 12 ) 560 { 561 switch ($icmp_code) 562 { 563 case 0: 564 return "Pointer indicates error"; 565 case 1: 566 return "Missing a required option"; 567 case 2: 568 return "Bad length"; 569 default: 570 return $icmp_code; 571 } 572 } 573 elseif ( $icmp_type == 40 ) 574 { 575 switch ($icmp_code) 576 { 577 case 0: 578 return "Bad SPI"; 579 case 1: 580 return "Authentication failed"; 581 case 2: 582 return "Decompression failed"; 583 case 3: 584 return "Decryption failed"; 585 case 4: 586 return "Need authentication"; 587 case 5: 588 return "Need authorization"; 589 default: 590 return $icmp_code; 591 } 592 } 593 else 594 return $icmp_code; 595} 596 597function PrintPayloadChar( $char, $output_type ) 598{ 599 if ( $char >= 32 && $char <= 127 ) 600 { 601 if ( $output_type == 2 ) 602 return chr($char); 603 else 604 return htmlspecialchars(chr($char)); 605 } 606 else 607 return '.'; 608} 609 610function PrintBase64PacketPayload ( $encoded_payload, $output_type ) 611{ 612 /* strip out the <CR> at the end of each block */ 613 $encoded_payload = str_replace("\n", "", $encoded_payload); 614 615 $payload = base64_decode($encoded_payload); 616 $len = strlen($payload); 617 $s = " "._LENGTH." = ".strlen($payload)."\n"; 618 619 for ($i = 0; $i < strlen($payload); $i++ ) 620 { 621 if ( $i % 16 == 0 ) 622 { 623 /* dump the ASCII characters */ 624 if ( $i != 0 ) 625 { 626 $s = $s.' '; 627 for ($j = $i-16; $j < $i; $j++ ) 628 $s = $s.PrintPayloadChar(ord($payload[$j]), $output_type); 629 } 630 $s = $s.sprintf("\n%03x : ", $i); 631 } 632 633 $s = $s.sprintf("%s ", bin2hex($payload[$i]) ); 634 } 635 636 /* print the remained of any ASCII chars */ 637 if ( ($i % 16) != 0 ) 638 { 639 for ( $j = 0; $j < 16 - ($i % 16); $j++) 640 $s = $s.' '; 641 642 $s = $s.' '; 643 644 for ( $j = $len - ($i % 16); $j < $len; $j++ ) 645 $s = $s.PrintPayloadChar(ord($payload[$j]), $output_type); 646 } else { 647 $s = $s.' '; 648 for ( $j = $len - 16; $j < $len && $j > 0; $j++ ) 649 $s = $s.PrintPayloadChar(ord($payload[$j]), $output_type); 650 } 651 652 return $s; 653} 654 655function PrintAsciiPacketPayload ( $encoded_payload, $output_type ) 656{ 657 return wordwrap($encoded_payload, 70); 658} 659 660function PrintHexPacketPayload ( $encoded_payload, $output_type ) 661{ 662 /* strip out the <CR> at the end of each block */ 663 $encoded_payload = str_replace("\n", "", $encoded_payload); 664 $payload = $encoded_payload; 665 666 $len = strlen($payload); 667 $s = " "._LENGTH." = ".(strlen($payload)/2)."\n"; 668 669 for ($i = 0; $i < strlen($payload); $i += 2 ) 670 { 671 if ( $i % 32 == 0 ) 672 { 673 /* dump the ASCII characters */ 674 if ( $i != 0 ) 675 { 676 $s = $s.' '; 677 for ($j = $i-32; $j < $i; $j+=2 ) 678 { 679 $t = hexdec($payload[$j].$payload[$j+1]); 680 $s = $s.PrintPayloadChar($t, $output_type); 681 } 682 } 683 $s = $s.sprintf("\n%03x : ", $i/2); 684 } 685 $s = $s.sprintf("%s%s ", $payload[$i], $payload[$i+1] ); 686 } 687 688 /* space through to align end of hex dump */ 689 if ( $i % 32 ) 690 for ( $j = 0; $j < 32 - ($i % 32); $j+=2) 691 $s = $s.' '; 692 693 $s = $s.' '; 694 695 /* print the ASCII decode */ 696 if ( $i % 32 ) 697 $start = $len - ($i % 32); 698 else 699 $start = $len - 32; 700 701 for ( $j = $start; $j < $i; $j+=2 ) 702 { 703 $t = hexdec($payload[$j].$payload[$j+1]); 704 $s = $s.PrintPayloadChar($t, $output_type); 705 } 706 707 return $s; 708} 709 710// ************************************************************************************ 711function PrintCleanHexPacketPayload( $encoded_payload, $output_type ) 712{ 713 $len = strlen($encoded_payload); 714 $s = ''; 715 $count = 0; 716 for ($i = 0; $i < $len; $i += 2 ) 717 { 718 /* dump the ASCII characters */ 719 $t = hexdec($encoded_payload[$i].$encoded_payload[$i+1]); 720 $s_tmp = PrintCleanPayloadChar($t, $output_type); 721 722 /* Join together several sequential non-ASCII characters displaying their count 723 * in one line. It makes easyer to look through payload in plain display mode. 724 * If current character is '<br>' and this is not last character of payload 725 * increment counter, else output non-ASCII count and flush counter. 726 */ 727 if ( ($s_tmp == '<br>') && !($i+2 == $len) ) { 728 $count++; 729 } else { 730 if ($count > 1) 731 $s .= '<DIV class="nonascii">['. $count .' non-ASCII characters]</DIV>'; 732 elseif ($count == 1) 733 $s .= '<br>'; 734 $s .= $s_tmp; 735 $count = 0; 736 } 737 } 738 return $s; 739} 740 741function PrintCleanPayloadChar( $char, $output_type ) 742{ 743 if ( $char >= 32 && $char <= 127 ) 744 { 745 if ( $output_type == 2 ) 746 return chr($char); 747 else 748 return htmlspecialchars(chr($char)); 749 } 750 else 751 return '<br>'; 752} 753 754// ************************************************************************************ 755 756function PrintPacketPayload($data, $encode_type, $output_type) 757{ 758 if ( $output_type == 1 ) 759 printf("\n<PRE>\n"); 760 761 /* print the packet based on encoding type */; 762 if ( $encode_type == "1" ) 763 $payload = PrintBase64PacketPayload($data, $output_type); 764 else if ($encode_type == "0" ) 765 { 766 if ( isset($_GET['asciiclean']) && ($_GET['asciiclean'] == 1) || ( (isset($_COOKIE['asciiclean']) && $_COOKIE['asciiclean'] == "clean") && (!isset($_GET['asciiclean'])) ) ) 767 { 768 // Print clean ascii display 769 $payload = PrintCleanHexPacketPayload($data, $output_type); 770 } 771 else 772 { 773 $payload = PrintHexPacketPayload($data, $output_type); 774 } 775 } 776 else if ($encode_type == "2" ) 777 $payload = PrintAsciiPacketPayload($data, $output_type); 778 779 if ( $output_type == 1 ) 780 echo "$payload\n</PRE>\n"; 781 782 return $payload; 783} 784 785function GetQueryResultID($submit, &$seq, &$sid, &$cid) 786{ 787 /* extract the sid and cid from the $submit variable of the form 788 #XX-(XX-XX) 789 | | | 790 | | |--- cid 791 | |------ sid 792 |---------- sequence number of DB lookup 793 */ 794 795 $submit = strstr($submit, "#"); 796 $submit = str_replace("#", "", $submit); 797 $submit = str_replace("(", "", $submit); 798 $submit = str_replace(")", "", $submit); 799 $tmp = explode("-", $submit); 800 /* Since the submit variable is not cleaned do so here: */ 801 $seq = CleanVariable($tmp[0], VAR_DIGIT); 802 $sid = CleanVariable($tmp[1], VAR_DIGIT); 803 $cid = CleanVariable($tmp[2], VAR_DIGIT); 804} 805 806function ExportPacket($sid, $cid, $db) 807{ 808 GLOBAL $action, $action_arg; 809 810 /* Event */ 811 $sql2 = "SELECT signature, timestamp FROM acid_event WHERE sid='".$sid."' AND cid='".$cid."'"; 812 $result2 = $db->baseExecute($sql2); 813 $myrow2 = $result2->baseFetchRow(); 814 815 $s = "------------------------------------------------------------------------------\n"; 816 $s = $s."#($sid - $cid) [$myrow2[1]] ".BuildSigByID($myrow2[0], $db, 2)."\r\n"; 817 818 $sql4 = "SELECT hostname, interface, filter FROM sensor WHERE sid='".$sid."'"; 819 $result4 = $db->baseExecute($sql4); 820 $myrow4 = $result4->baseFetchRow(); 821 822 $result4->baseFreeRows(); 823 $result2->baseFreeRows(); 824 825 /* IP */ 826 $sql2 = "SELECT ip_src, ip_dst, ". 827 "ip_ver, ip_hlen, ip_tos, ip_len, ip_id, ip_flags, ip_off, ip_ttl, ip_csum, ip_proto". 828 " FROM iphdr WHERE sid='".$sid."' AND cid='".$cid."'"; 829 830 $result2 = $db->baseExecute($sql2); 831 $myrow2 = $result2->baseFetchRow(); 832 $layer4_proto = $myrow2[11]; 833 834 if ( $myrow2[0] != "" ) 835 { 836 $sql3 = "SELECT * FROM opt WHERE sid='".$sid."' AND cid='".$cid."' AND opt_proto='0'"; 837 $result3 = $db->baseExecute($sql3); 838 $num_opt = $result3->baseRecordCount(); 839 840 $s = $s."IPv$myrow2[2]: ". 841 baseLong2IP($myrow2[0])." -> ". 842 baseLong2IP($myrow2[1])."\n". 843 " hlen=$myrow2[3] TOS=$myrow2[4] dlen=$myrow2[5] ID=$myrow2[6]". 844 " flags=$myrow2[7] offset=$myrow2[8] TTL=$myrow2[9] chksum=$myrow2[10]\n"; 845 846 if ( $num_opt > 0 ) 847 { 848 $s = $s." Options\n"; 849 for ( $i = 0; $i < $num_opt; $i++) 850 { 851 $myrow3 = $result3->baseFetchRow(); 852 $s = $s." #".($i+1)." - ".IPOption2str($myrow3[4])." len=$myrow3[5]"; 853 if ( $myrow3[5] != 0 ) 854 $s = $s." data=$myrow3[6]"; 855 $s = $s."\n"; 856 } 857 } 858 859 $result3->baseFreeRows(); 860 } 861 $result2->baseFreeRows(); 862 863 /* TCP */ 864 if ( $layer4_proto == "6" ) 865 { 866 $sql2 = "SELECT tcp_sport, tcp_dport, tcp_seq, tcp_ack, tcp_off, tcp_res, tcp_flags, tcp_win, ". 867 " tcp_csum, tcp_urp FROM tcphdr WHERE sid='".$sid."' AND cid='".$cid."'"; 868 $result2 = $db->baseExecute($sql2); 869 $myrow2 = $result2->baseFetchRow(); 870 871 $sql3 = "SELECT * FROM opt WHERE sid='".$sid."' AND cid='".$cid."' AND opt_proto='6'"; 872 $result3 = $db->baseExecute($sql3); 873 $num_opt = $result3->baseRecordCount(); 874 875 $s = $s."TCP: port=$myrow2[0] -> dport: $myrow2[1] flags="; 876 877 if ( ($myrow2[6] & 128) != 0 ) $s = $s.'2'; else $s = $s.'*'; 878 if ( ($myrow2[6] & 64 ) != 0 ) $s = $s.'1'; else $s = $s.'*'; 879 if ( ($myrow2[6] & 32) != 0 ) $s = $s.'U'; else $s = $s.'*'; 880 if ( ($myrow2[6] & 16 ) != 0 ) $s = $s.'A'; else $s = $s.'*'; 881 if ( ($myrow2[6] & 8) != 0 ) $s = $s.'P'; else $s = $s.'*'; 882 if ( ($myrow2[6] & 4 ) != 0 ) $s = $s.'R'; else $s = $s.'*'; 883 if ( ($myrow2[6] & 2 ) != 0 ) $s = $s.'S'; else $s = $s.'*'; 884 if ( ($myrow2[6] & 1 ) != 0 ) $s = $s.'F'; else $s = $s.'*'; 885 886 $s = $s." seq=$myrow2[2]\n". 887 " ack=$myrow2[3] off=$myrow2[4] res=$myrow2[5] win=$myrow2[7] urp=$myrow2[9] ". 888 "chksum=$myrow2[8]\n"; 889 890 if ( $num_opt != 0) 891 { 892 $s = $s." Options:\n"; 893 for ( $i = 0; $i < $num_opt; $i++) 894 { 895 $myrow3 = $result3->baseFetchRow(); 896 $s = $s." #".($i+1)." - ".TCPOption2str($myrow3[4])." len=$myrow3[5]"; 897 if ( $myrow3[5] != 0 ) 898 $s = $s." data=".$myrow3[6]; 899 $s = $s."\n"; 900 } 901 } 902 903 $result2->baseFreeRows(); 904 $result3->baseFreeRows(); 905 } 906 907 /* UDP */ 908 if ( $layer4_proto == "17" ) 909 { 910 911 $sql2 = "SELECT * FROM udphdr WHERE sid='".$sid."' AND cid='".$cid."'"; 912 $result2 = $db->baseExecute($sql2); 913 $myrow2 = $result2->baseFetchRow(); 914 915 $s = $s."UDP: port=$myrow2[2] -> dport: $myrow2[3] len=$myrow2[4]\n"; 916 917 $result2->baseFreeRows(); 918 } 919 920 /* ICMP */ 921 if ( $layer4_proto == "1" ) 922 { 923 $sql2 = "SELECT icmp_type, icmp_code, icmp_csum, icmp_id, icmp_seq FROM icmphdr ". 924 "WHERE sid='".$sid."' AND cid='".$cid."'"; 925 $result2 = $db->baseExecute($sql2); 926 $myrow2 = $result2->baseFetchRow(); 927 928 $s = $s."ICMP: type=".ICMPType2str($myrow2[0])." code=".ICMPCode2str($myrow2[0],$myrow2[1])."\n". 929 " checksum=$myrow2[2] id=$myrow2[3] seq=$myrow2[4]\n"; 930 931 $result2->baseFreeRows(); 932 } 933 934 /* Print the Payload */ 935 $sql2 = "SELECT data_payload FROM data WHERE sid='".$sid."' AND cid='".$cid."'"; 936 $result2 = $db->baseExecute($sql2); 937 938 /* get encoding information and detail_level on the payload */ 939 $sql3 = 'SELECT encoding, detail FROM sensor WHERE sid='.$sid; 940 $result3 = $db->baseExecute($sql3); 941 $myrow3 = $result3->baseFetchRow(); 942 943 $s = $s."Payload: "; 944 945 $myrow2 = $result2->baseFetchRow(); 946 if ( $myrow2 ) 947 { 948 /* print the packet based on encoding type */ 949 $s = $s.PrintPacketPayload($myrow2[0], $myrow3[0], 2)."\n"; 950 951 $result3->baseFreeRows(); 952 } 953 else 954 { 955 /* Don't have payload so lets print out why by checking the detail level */ 956 957 /* if have fast detail level */ 958 if ( $myrow3[1] == "0" ) 959 $s = $s."Fast logging used so payload was discarded\n"; 960 else 961 $s = $s."none\n"; 962 } 963 964 $result2->baseFreeRows(); 965 966 return $s; 967} 968 969function ExportPacket_summary($sid, $cid, $db, $export_type = 0) 970{ 971 GLOBAL $action, $action_arg; 972 973 /* Event */ 974 $sql2 = "SELECT signature, timestamp FROM acid_event WHERE sid='".$sid."' AND cid='".$cid."'"; 975 $result2 = $db->baseExecute($sql2); 976 $myrow2 = $result2->baseFetchRow(); 977 978 $alert_timestamp = $myrow2[1]; 979 $alert_sig = BuildSigByID($myrow2[0], $db, 2); 980 981 $result2->baseFreeRows(); 982 983 /* IP */ 984 $src_ip = $dst_ip = $src_port = $dst_port = ""; 985 $sql2 = "SELECT ip_src, ip_dst, ip_proto". 986 " FROM iphdr WHERE sid='".$sid."' AND cid='".$cid."'"; 987 988 $result2 = $db->baseExecute($sql2); 989 $myrow2 = $result2->baseFetchRow(); 990 991 $layer4_proto = ""; 992 if ( $myrow2[0] != "" ) 993 { 994 $src_ip = baseLong2IP($myrow2[0]); 995 $dst_ip = baseLong2IP($myrow2[1]); 996 $layer4_proto = $myrow2[2]; 997 } 998 $result2->baseFreeRows(); 999 1000 /* TCP */ 1001 if ( $layer4_proto == "6" ) 1002 { 1003 $sql2 = "SELECT tcp_sport, tcp_dport FROM tcphdr WHERE sid='".$sid."' AND cid='".$cid."'"; 1004 $result2 = $db->baseExecute($sql2); 1005 $myrow2 = $result2->baseFetchRow(); 1006 1007 if ( $export_type == 0 ) 1008 { 1009 $src_port = ":".$myrow2[0]." -> "; 1010 $dst_port = ":".$myrow2[1]; 1011 } 1012 else 1013 { 1014 $src_port = $myrow2[0]; 1015 $dst_port = $myrow2[1]; 1016 } 1017 1018 $result2->baseFreeRows(); 1019 } 1020 1021 /* UDP */ 1022 if ( $layer4_proto == "17" ) 1023 { 1024 1025 $sql2 = "SELECT * FROM udphdr WHERE sid='".$sid."' AND cid='".$cid."'"; 1026 $result2 = $db->baseExecute($sql2); 1027 $myrow2 = $result2->baseFetchRow(); 1028 1029 if ( $export_type == 0 ) 1030 { 1031 $src_port = ":".$myrow2[2]." -> "; 1032 $dst_port = ":".$myrow2[3]; 1033 } 1034 else 1035 { 1036 $src_port = $myrow2[2]; 1037 $dst_port = $myrow2[3]; 1038 } 1039 1040 $result2->baseFreeRows(); 1041 } 1042 1043 /* ICMP */ 1044 if ( $layer4_proto == "1" ) 1045 { 1046 if ( $export_type == 0 ) 1047 $src_ip = $src_ip." -> "; 1048 $src_port = $dst_port = ""; 1049 } 1050 1051 /* Portscan Traffic */ 1052 if ( $layer4_proto == "255" ) 1053 { 1054 if ( $export_type == 0 ) 1055 $src_ip = $src_ip." -> "; 1056 } 1057 1058 if ( $export_type == 0 ) 1059 { 1060 $s = sprintf("#%d-%d| [%s] %s%s%s%s %s\r\n", 1061 $sid, $cid, $alert_timestamp, 1062 $src_ip, $src_port, $dst_ip, $dst_port, 1063 $alert_sig); 1064 } 1065 else /* CSV format */ 1066 { 1067 $s = sprintf("\"%d\", \"%d\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\"\r\n", 1068 $sid, $cid, $alert_timestamp, 1069 $src_ip, $src_port, $dst_ip, $dst_port, 1070 $alert_sig); 1071 } 1072 1073 return $s; 1074} 1075 1076function base_header($url) { 1077 header($url); 1078 exit; 1079} 1080 1081 1082function base_microtime() 1083{ 1084 list($usec, $sec) = explode(" ", microtime()); 1085 return ((float)$usec + (float)$sec); 1086} 1087