Create singlequerysubscription.bro

Create singlequerysubscription.bro

module osquery;

const broker_port: port = 9999/tcp &redef;
redef exit_only_after_terminate = T;
redef osquery::endpoint_name = "Printer";

global added_acpi_tables: event(host: string, name: string, size: count, md5: string);
global removed_acpi_tables: event(host: string, name: string,size: count,md5: string);
###################################################################################
global added_arp_cache: event(host: string, address: string, mac: string, interface: string);
global removed_arp_cache: event(host: string, address: string, mac: string, interface: string);
###################################################################################
global added_block_devices: event(host: string, name: string,vendor: string, model: string);
global removed_block_devices: event(host: string, name: string,vendor: string, model: string);
###################################################################################
global added_chrome_extensions: event(host: string, name: string,author: string, path:string);
global removed_chrome_extensions: event(host: string, name: string,author: string, path:string);
###################################################################################
global added_cpuid: event(host: string, feature: string, value: string);
global removed_cpuid: event(host: string, feature: string, value: string);
###################################################################################
global added_crontab: event(host: string, hour: count, command: string, path: string);
global removed_crontab: event(host: string, hour: count, command: string, path: string);
###################################################################################
global added_disk_encryption: event(host: string, name: string, uuid: string, encrypted: count);
global removed_disk_encryption: event(host: string, name: string, uuid: string, encrypted: count);
###################################################################################
global added_etc_hosts: event(host: string, address: string, hostnames: string);
global removed_etc_hosts: event(host: string, address: string, hostnames: string);
###################################################################################
global added_etc_protocols: event(host: string, name: string, number: count);
global removed_etc_protocols: event(host: string, name: string, number: count);
###################################################################################
global added_etc_services: event(host: string, name: string, prt: count, protocol: string);
global removed_etc_services: event(host: string, name: string, prt: count, protocol: string);
###################################################################################
global added_file_events: event(host: string, target_path: string, action: string, t: count);
global removed_file_events: event(host: string, target_path: string, action: string, t: count);
###################################################################################
global added_firefox_addons: event(host: string, name: string, source_url: string, location: string);
global removed_firefox_addons: event(host: string, name: string, source_url: string, location: string);
###################################################################################
global added_groups: event(host: string, gid: count, groupname: string);
global removed_groups: event(host: string, gid: count, groupname: string);
###################################################################################
global added_hardware_events: event(host: string, action: string, model: string, vendor: string);
global removed_hardware_events: event(host: string, action: string, model: string, vendor: string);
###################################################################################
global added_interface_address: event(host: string, interface: string, address: string);
global removed_interface_address: event(host: string, interface: string, address: string);
###################################################################################
global added_interface_details: event(host: string, interface: string, mac: string, mtu: count);
global removed_interface_details: event(host: string, interface: string, mac: string, mtu: count);
###################################################################################
global added_kernel_info: event(host: string, version: string, path: string, device: string);
global removed_kernel_info: event(host: string, version: string, path: string, device: string);
###################################################################################
global added_last: event(host: string, username: string, pid: count, h: string);
global removed_last: event(host: string, username: string, pid: count, h: string);
###################################################################################
global added_listening_ports: event(host: string, pid: count, prt: count, protocol: count);
global removed_listening_ports: event(host: string, pid: count, prt: count, protocol: count);
###################################################################################
global added_logged_in_users: event(host: string, user: string, h: string, t: count);
global removed_logged_in_users: event(host: string, user: string, h: string, t: count);
###################################################################################
global added_mounts: event(host: string, device: string, path: string);
global removed_mounts: event(host: string, device: string, path: string);
###################################################################################
global added_opera_extensions: event(host: string, name: string, description: string, author: string);
global removed_opera_extensions: event(host: string, name: string, description: string, author: string);
###################################################################################
global added_os_version: event(host: string, name: string, patch: count, build: string);
global removed_os_version: event(host: string, name: string, patch: count, build: string);
###################################################################################
global added_passwd_changes: event(host: string, target_path: string, action: string);
global removed_passwd_changes: event(host: string, target_path: string, action: string);
###################################################################################
global added_pci_devices: event(host: string, pci_slot: string, driver: string, vendor: string, model: string);
global removed_pci_devices: event(host: string, pci_slot: string, driver: string, vendor: string, model: string);
###################################################################################
global added_process_envs: event(host: string, pid: count, key: string, value: string);
global removed_process_envs: event(host: string, pid: count, key: string, value: string);
###################################################################################
global added_process_memory_map: event(host: string, pid: count, permissions: string, device: string);
global removed_process_memory_map: event(host: string, pid: count, permissions: string, device: string);
###################################################################################
global added_process_open_files: event(host: string, pid: count, fd: string, path: string);
global removed_process_open_files: event(host: string, pid: count, fd: string, path: string);
###################################################################################
global added_process_open_sockets: event(host: string, pid: count, socket: count, protocol: count);
global removed_process_open_sockets: event(host: string, pid: count, socket: count, protocol: count);
###################################################################################
global added_processes: event(host: string, pid: count, name: string, on_disk: string);
global removed_processes: event(host: string, pid: count, name: string, on_disk: string);
###################################################################################
global added_routes: event(host: string, destination: string, source: string, interface: string);
global removed_routes: event(host: string, destination: string, source: string, interface: string);
###################################################################################
global added_shell_history: event(host: string, username: string, command: string);
global removed_shell_history: event(host: string, username: string, command: string);
###################################################################################
global added_smbios_tables: event(host: string, number: count, description: string, size: count);
global removed_smbios_tables: event(host: string, number: count, description: string, size: count);
###################################################################################
global added_system_controls: event(host: string, name: string, oid: string, subsystem: string);
global removed_system_controls: event(host: string, name: string, oid: string, subsystem: string);
###################################################################################
global added_uptime: event(host: string, days: count, hours: count);
global removed_uptime: event(host: string, days: count, hours: count);
###################################################################################
global added_usb_devices: event(host: string, usb_address: count, vendor: string, model: string);
global removed_usb_devices: event(host: string, usb_address: count, vendor: string, model: string);
###################################################################################
global added_user_groups: event(host: string, uid: count, gid: count);
global removed_user_groups: event(host: string, uid: count, gid: count);
###################################################################################
global added_users: event(host: string, username: string, uid: count, gid: count);
global removed_users: event(host: string, username: string, uid: count, gid: count);
###################################################################################

event bro_init()
{
	osquery::enable();
	osquery::subscribe_to_events("/bro/event/");
	osquery::connect("192.168.1.211",broker_port, 2sec);
	##osquery::connect("192.168.1.187",broker_port, 2sec);
	##osquery::connect("192.168.1.33",broker_port, 2sec);
}

event BrokerComm::outgoing_connection_established(peer_address: string, peer_port: port, peer_name: string)
{
	print "BrokerComm::outgoing_connection_establisted", peer_address, peer_port, peer_name;

	osquery::subscribe("osquery::added_acpi_tables","SELECT name,size,md5 FROM acpi_tables",T);
	#osquery::subscribe("osquery::removed_acpi_tables","SELECT name,size,md5 FROM acpi_tables");
	#######################################################################################
	osquery::subscribe("osquery::added_arp_cache","SELECT address,mac,interface FROM arp_cache");
	#osquery::subscribe("osquery::removed_arp_cache","SELECT address,mac,interface FROM arp_cache");
	#######################################################################################
	#osquery::subscribe("osquery::added_block_devices","SELECT name,vendor,model FROM block_devices");
	#osquery::subscribe("osquery::removed_block_devices","SELECT name,vendor,model FROM block_devices");
	#######################################################################################
	#osquery::subscribe("osquery::added_chrome_extensions","SELECT name,author,path FROM chrome_extensions");
	#osquery::subscribe("osquery::removed_chrome_extensions","SELECT name,author,path FROM chrome_extensions");
	########################################################################################
	#osquery::subscribe("osquery::added_cpuid","SELECT feature,value FROM cpuid");
	#osquery::subscribe("osquery::removed_cpuid","SELECT feature,value FROM cpuid");
	#######################################################################################
	#osquery::subscribe("osquery::added_crontab","SELECT hour,command,path FROM crontab");
	#osquery::subscribe("osquery::removed_crontab","SELECT hour,command,path FROM crontab");
	#######################################################################################
	#osquery::subscribe("osquery::added_disk_encryption","SELECT name,uuid,encrypted FROM disk_encryption");
	#osquery::subscribe("osquery::removed_disk_encryption","SELECT name,uuid,encrypted FROM disk_encryption");
	########################################################################################
	#osquery::subscribe("osquery::added_etc_hosts","SELECT address,hostnames FROM etc_hosts");
	#osquery::subscribe("osquery::removed_etc_hosts","SELECT address,hostnames FROM etc_hosts");
	########################################################################################
	#osquery::subscribe("osquery::added_etc_protocols","SELECT name,number FROM etc_protocols");
	#osquery::subscribe("osquery::removed_etc_protocols","SELECT name,number FROM etc_protocols");
	#######################################################################################
	#osquery::subscribe("osquery::added_etc_services","SELECT name,port,protocol FROM etc_services");
	#osquery::subscribe("osquery::removed_etc_services","SELECT name,port,protocol FROM etc_services");
	#######################################################################################
	#osquery::subscribe("osquery::added_file_events","SELECT target_path,action,time FROM file_events");
	#osquery::subscribe("osquery::removed_file_events","SELECT target_path,action,time FROM file_events");
	#######################################################################################
	#osquery::subscribe("osquery::added_firefox_addons","SELECT name,source_url,location FROM firefox_addons");
	#osquery::subscribe("osquery::removed_firefox_addons","SELECT name,source_url,location FROM firefox_addons");
	#######################################################################################
	#osquery::subscribe("osquery::added_groups","SELECT gid,groupname FROM groups");
	#osquery::subscribe("osquery::removed_groups","SELECT gid,groupname FROM groups");
	#######################################################################################
	#osquery::subscribe("osquery::added_hardware_events","SELECT action,model,vendor FROM hardware_events");
	#osquery::subscribe("osquery::removed_hardware_events","SELECT action,model,vendor FROM hardware_events");
	#######################################################################################
	#osquery::subscribe("osquery::added_interface_address","SELECT interface,address FROM interface_address");
	#osquery::subscribe("osquery::removed_interface_address","SELECT interface,address FROM interface_address");
	#######################################################################################
	#osquery::subscribe("osquery::added_interface_details","SELECT interface,mac,mtu FROM interface_details");
	#osquery::subscribe("osquery::removed_interface_details","SELECT interface,mac,mtu FROM interface_details");
	#######################################################################################
	#osquery::subscribe("osquery::added_kernel_info","SELECT version,path,device FROM kernel_info");
	#osquery::subscribe("osquery::removed_kernel_info","SELECT version,path,device FROM kernel_info");
	#######################################################################################
	#osquery::subscribe("osquery::added_last","SELECT username,pid,host FROM last");
	#osquery::subscribe("osquery::removed_last","SELECT username,pid,host FROM last");
	#######################################################################################
	#osquery::subscribe("osquery::added_listening_ports","SELECT pid,port,protocol FROM listening_ports");
	#osquery::subscribe("osquery::removed_listening_ports","SELECT pid,port,protocol FROM listening_ports");
	#######################################################################################
	#osquery::subscribe("osquery::added_logged_in_users","SELECT user,host,time FROM logged_in_users");
	#osquery::subscribe("osquery::removed_logged_in_users","SELECT user,host,time FROM logged_in_users");
	########################################################################################
	#osquery::subscribe("osquery::added_mounts","SELECT device,path FROM mounts");
	#osquery::subscribe("osquery::removed_mounts","SELECT device,path FROM mounts");
	########################################################################################
	#osquery::subscribe("osquery::added_opera_extensions","SELECT name,description,author FROM opera_extensions");
	#osquery::subscribe("osquery::removed_opera_extensions","SELECT name,description,author FROM opera_extensions");
	#######################################################################################
	osquery::subscribe("osquery::added_os_version","SELECT name,patch,build FROM os_version",T);
	#osquery::subscribe("osquery::removed_os_version","SELECT name,patch,build FROM os_version");
	#######################################################################################
	#osquery::subscribe("osquery::added_passwd_changes","SELECT target_path,action FROM passwd_changes");
	#osquery::subscribe("osquery::removed_passwd_changes","SELECT target_path,action FROM passwd_changes");
	#######################################################################################
	#osquery::subscribe("osquery::added_pci_devices","SELECT pci_slot,driver,vendor,model FROM pci_devices");
	#osquery::subscribe("osquery::removed_pci_devices","SELECT pci_slot,driver,vendor,model FROM pci_devices");
	#######################################################################################
	#osquery::subscribe("osquery::added_process_envs","SELECT pid,key,value FROM process_envs");
	#osquery::subscribe("osquery::removed_process_envs","SELECT pid,key,value FROM process_envs");
	#######################################################################################
	#osquery::subscribe("osquery::added_process_memory_map","SELECT pid,permissions,device FROM process_memory_map");
	#osquery::subscribe("osquery::removed_process_memory_map","SELECT pid,permissions,device FROM process_memory_map");
	#######################################################################################
	#osquery::subscribe("osquery::added_process_open_files","SELECT pid,fd,path FROM process_open_files");
	#osquery::subscribe("osquery::removed_process_open_files","SELECT pid,fd,path FROM process_open_files");
	#######################################################################################
	osquery::subscribe("osquery::added_process_open_sockets","SELECT pid,socket,protocol FROM process_open_sockets");
	#osquery::subscribe("osquery::removed_process_open_sockets","SELECT pid,socket,protocol FROM process_open_sockets");
	#######################################################################################
	#osquery::subscribe("osquery::added_processes","SELECT pid,name,on_disk FROM processes");
	#osquery::subscribe("osquery::removed_processes","SELECT pid,name,on_disk FROM processes");
	#######################################################################################
	#osquery::subscribe("osquery::added_routes","SELECT destination,source,interface FROM routes");
	#osquery::subscribe("osquery::removed_routes","SELECT destination,source,interface FROM routes");
	#######################################################################################
	#osquery::subscribe("osquery::added_shell_history","SELECT username,command FROM shell_history");
	#osquery::subscribe("osquery::removed_shell_history","SELECT username,command FROM shell_history");
	#######################################################################################
	osquery::subscribe("osquery::added_smbios_tables","SELECT number,description,size FROM smbios_tables");
	#osquery::subscribe("osquery::removed_smbios_tables","SELECT number,description,size FROM smbios_tables");
	#######################################################################################
	#osquery::subscribe("osquery::added_system_controls","SELECT name,oid,subsystem FROM system_controls");
	#osquery::subscribe("osquery::removed_system_controls","SELECT name,oid,subsystem FROM system_controls");
	#######################################################################################
	#osquery::subscribe("osquery::added_uptime","SELECT days,hours FROM uptime",T);
	#osquery::subscribe("osquery::removed_uptime","SELECT days,hours FROM uptime");
	#######################################################################################
	#osquery::subscribe("osquery::added_usb_devices","SELECT usb_address,vendor,model FROM usb_devices",T);
	#osquery::subscribe("osquery::removed_usb_devices","SELECT usb_address,vendor,model FROM usb_devices");
	########################################################################################
	#osquery::subscribe("osquery::added_user_groups","SELECT uid,gid FROM user_groups");
	#osquery::subscribe("osquery::removed_user_groups","SELECT uid,gid FROM user_groups");
	########################################################################################
	osquery::subscribe("osquery::added_users","SELECT username,uid,gid FROM users");
	#osquery::subscribe("osquery::removed_users","SELECT username,uid,gid FROM users");
	#######################################################################################

}

event BrokerComm::incoming_connection_broken(peer_name: string)
{
	print "BrokerComm::incoming_connection_broken", peer_name;
	terminate();
}
########################### ACPI TABLES ################################################

event added_acpi_tables(host: string, name: string, size: count, md5: string)
{
	print "New acpi_table Entry";
	print fmt("Host = %s Table_name = %s size = %d md5 = %s",host, name, size, md5);
}
event removed_acpi_tables(host: string, name: string,size: count,md5: string)
{
	print "Deleted acpi_table Entry";
	print fmt("Host = %s Table_name = %s size = %d md5 = %s",host, name, size, md5);
}
############################## ARP CACHE ##############################################
event added_arp_cache(host: string, address: string, mac: string, interface: string)
{
	print fmt("Host = %s Address = %s mac = %s Interface = %s",host, address, mac, interface);
}
event removed_arp_cache(host: string, address: string, mac: string, interface: string)
{
	print fmt("Host = %s Address = %s mac = %s Interface = %s",host, address, mac, interface);
}
############################## BLOCK DEVICES ###########################################
event added_block_devices(host: string, name: string,vendor: string, model: string)
{
	print fmt("Host = %s Name = %s Vendor = %s Model = %s",host, name, vendor, model);
}
event removed_block_devices(host: string, name: string,vendor: string, model: string)
{
	print fmt("Host = %s Name = %s Vendor = %s Model = %s",host, name, vendor, model);
}
############################## CHROME EXTENSIONS ##########################################
event added_chrome_extensions(host: string, name: string,author: string, path:string)
{
	print fmt("New entry added");
	print fmt("Host = %s Name = %s Author = %s Path = %s",host, name, author, path);
}
event removed_chrome_extensions(host: string, name: string,author: string, path:string)
{
	print fmt("Entry Removed");
	print fmt("Host = %s Name = %s Author = %s Path = %s",host, name, author, path);
}
############################# CPUID #####################################################
event added_cpuid(host: string, feature: string, value: string)
{
	print fmt("New entry added");
	print fmt("Host = %s Feature = %s Value = %s",host, feature,value);
}
event removed_cpuid(host: string, feature: string, value: string)
{
	print fmt("Entry Removed");
	print fmt("Host = %s Feature = %s Value = %s",host, feature,value);
}
############################ CRONTAB ####################################################
event added_crontab(host: string, hour: count, command: string, path: string)
{
	print fmt("New entry added");
	print fmt("Host = %s Hour = %d Command = %s Path=%s",host, hour, command, path);
}
event removed_crontab(host: string, hour: count, command: string,path: string)
{
	print fmt("Host = %s Hour = %d Command = %s Path=%s",host, hour, command, path);
}
########################### DISK ENCRYPTION ###############################################
event added_disk_encryption(host: string, name: string, uuid: string, encrypted: count)
{
	print fmt("New entry added");
	print fmt("Host = %s Name = %s uuid = %s encrypted=%d",host, name, uuid, encrypted);
}
event removed_disk_encryption(host: string, name: string, uuid: string, encrypted: count)
{
	print fmt("Entry Removed");
	print fmt("Host = %s Name = %s uuid = %s encrypted=%d",host, name, uuid, encrypted);
}
########################### ETC HOSTS ########################################################
event added_etc_hosts(host: string, address: string, hostnames: string)
{
	print fmt("New entry added");
	print fmt("Host = %s Address = %s hostnames = %s ",host, address, hostnames);
}
event removed_etc_hosts(host: string, address: string, hostnames: string)
{
	print fmt("Entry Removed");
	print fmt("Host = %s Address = %s hostnames = %s ",host, address, hostnames);
}
########################### ETC PROTOCOLS #################################################
event added_etc_protocols(host: string, name: string, number: count)
{
	print fmt("New entry added");
	print fmt("Host = %s Name = %s number = %d ",host, name, number);
}
event removed_etc_protocols(host: string, name: string, number: count)
{
	print fmt("Entry Removed");
	print fmt("Host = %s Name = %s number = %d ",host, name, number);
}
########################### ETC SERVICES ##################################################
event added_etc_services(host: string, name: string, prt: count, protocol: string)
{
	print fmt("New entry added");
	print fmt("Host = %s Name = %s prt = %d Protocol = %s ",host, name, prt, protocol);
}
event removed_etc_services(host: string, name: string, prt: count, protocol: string)
{
	print fmt("Entry Removed");
	print fmt("Host = %s Name = %s prt = %d Protocol = %s ",host, name, prt, protocol);
}
########################### FILE EVENTS ####################################################
event added_file_events(host: string, target_path: string, action: string, t: count)
{
	print fmt("New entry added");
	print fmt("Host = %s target_path = %s Action = %s Time = %d",host, target_path,action,t);
}
event removed_file_events(host: string, target_path: string, action: string, t: count)
{
	print fmt("Entry Removed");
	print fmt("Host = %s target_path = %s Action = %s Time = %d",host, target_path,action,t);
}
############################ FIREFOX ADDONS #################################################
event added_firefox_addons(host: string, name: string, source_url: string, location: string)
{
	print fmt("New entry added");
	print fmt("Host = %s Name = %s source_url = %s Locatoin= %s ",host, name, source_url, location);
}
event removed_firefox_addons(host: string, name: string, source_url: string, location: string)
{
	print fmt("Entry Removed");
	print fmt("Host = %s Name = %s source_url = %s Locatoin= %s ",host, name, source_url, location);
}
############################ ADDED GROUPS ###################################################
event added_groups(host: string, gid: count, groupname: string)
{
	print fmt("New entry added");
	print fmt("Host = %s gid = %d groupnumber = %s ",host, gid, groupname);
}
event removed_groups(host: string, gid: count, groupname: string)
{
	print fmt("Entry Removed");
	print fmt("Host = %s gid = %d groupnumber = %s ",host, gid, groupname);
}
############################ HARDWARE EVENTS ##################################################
event added_hardware_events(host: string, action: string, model: string, vendor: string)
{
	print fmt("New entry added");
	print fmt("Host = %s action = %s model = %s  Vendor =%s",host, action, model,vendor);
}
event removed_hardware_events(host: string, action: string, model: string, vendor: string)
{
	print fmt("Entry Removed");
	print fmt("Host = %s action = %s model = %s  Vendor =%s",host, action, model,vendor);
}
########################### INTERFACE ADDRESS ##################################################
event added_interface_address(host: string, interface: string, address: string)
{
	print fmt("New entry added");
	print fmt("Host = %s Interface = %s Address = %s ",host, interface,address);
}
event removed_interface_address(host: string, interface: string, address: string)
{
	print fmt("Entry Removed");
	print fmt("Host = %s Interface = %s Address = %s ",host, interface,address);
}
############################ INTERFACE DETAILS ##################################################
event added_interface_details(host: string, interface: string, mac: string, mtu: count)
{
	print fmt("New entry added");
	print fmt("Host = %s interface= %s mac = %s Mtu =%d ",host, interface,mac,mtu);
}
event removed_interface_details(host: string, interface: string, mac: string, mtu: count)
{
	print fmt("Entry Removed");
	print fmt("Host = %s interface= %s mac = %s Mtu =%d ",host, interface,mac,mtu);
}
############################ KERNEL INFO ####################################################
event added_kernel_info(host: string, version: string, path: string, device: string)
{
	print fmt("New entry added");
	print fmt("Host = %s version = %s path = %s Device =%s",host, version,path,device);
}
event removed_kernel_info(host: string, version: string, path: string, device: string)
{
	print fmt("Entry Removed");
	print fmt("Host = %s version = %s path = %s Device =%s",host, version,path,device);
}
############################# LAST ##########################################################
event added_last(host: string, username: string, pid: count, h: string)
{
	print fmt("New entry added");
	print fmt("Host = %s username = %s pid = %d Host=%s",host, username, pid,h);
}
event removed_last(host: string, username: string, pid: count, h: string)
{
	print fmt("Entry Removed");
	print fmt("Host = %s username = %s pid = %d Host=%s",host, username, pid,h);
}
############################# LISTENING PORTS ################################################
event added_listening_ports(host: string, pid: count, prt: count, protocol: count)
{
	print fmt("New entry added");
	print fmt("Host = %s pid = %d prt = %d Protocol =%d ",host, pid,prt,protocol);
}
event removed_listening_ports(host: string, pid: count, prt: count, protocol: count)
{
	print fmt("Entry Removed");
	print fmt("Host = %s pid = %d prt = %d Protocol =%d ",host, pid,prt,protocol);
}
############################# LOGGED IN USERS #################################################
event added_logged_in_users(host: string, user: string, h: string, t: count)
{
	print fmt("New entry added");
	print fmt("Host = %s User = %s Host = %s Time =%d ",host, user,h,t);
}
event removed_logged_in_users(host: string, user: string, h: string, t: count)
{
	print fmt("Entry Removed");
	print fmt("Host = %s User = %s Host = %s Time =%d ",host, user,h,t);
}
############################ MOUNTS ##########################################################
event added_mounts(host: string, device: string, path: string)
{
	print fmt("New entry added");
	print fmt("Host = %s Device = %s Path = %s ",host, device,path);
}
event removed_mounts(host: string, device: string, path: string)
{
	print fmt("Entry Removed");
	print fmt("Host = %s Device = %s Path = %s ",host, device,path);
}
############################ OPERA EXTENSIONS #################################################
event added_opera_extensions(host: string, name: string, description: string, author: string)
{
	print fmt("New entry added");
	print fmt("Host = %s Name = %s description = %s Author=%s ",host, name,description,author);
}
event removed_opera_extensions(host: string, name: string, description: string, author: string)
{
	print fmt("Entry Removed");
	print fmt("Host = %s Name = %s description = %s Author=%s ",host, name,description,author);
}
############################ OS VERSION ######################################################
event added_os_version(host: string, name: string, patch: count, build: string)
{
	print fmt("New entry added");
	print fmt("Host = %s Name = %s Patch = %d Build = %s ",host, name, patch,build);
}
event removed_os_version(host: string, name: string, patch: count, build: string)
{
	print fmt("Entry Removed");
	print fmt("Host = %s Name = %s Patch = %d Build = %s ",host, name, patch,build);
}
############################ PASSWORD CHANGES ##################################################
event added_passwd_changes(host: string, target_path: string, action: string)
{
	print fmt("New entry added");
	print fmt("Host = %s Target_Path = %s Action = %s ",host, target_path,action);
}
event removed_passwd_changes(host: string, target_path: string, action: string)
{
	print fmt("Entry Removed");
	print fmt("Host = %s Target_Path = %s Action = %s ",host, target_path,action);
}
############################ PCI DEVICES #####################################################
event added_pci_devices(host: string, pci_slot: string, driver: string, vendor: string, model: string)
{
	print fmt("New entry added");
	print fmt("Host = %s PCI_Slot = %s Driver = %s Vendor =%s Model= %s",host, pci_slot,driver,vendor,model);
}
event removed_pci_devices(host: string, pci_slot: string, driver: string, vendor: string, model: string)
{
	print fmt("Entry Removed");
	print fmt("Host = %s PCI_Slot = %s Driver = %s Vendor =%s Model= %s",host, pci_slot,driver,vendor,model);
}
########################### PROCESS EVENTS #####################################################
event added_process_envs(host: string, pid: count, key: string, value: string)
{
	print fmt("New entry added");
	print fmt("Host = %s PID = %d Key = %s Value = %s ",host, pid,key,value);
}
event removed_process_envs(host: string, pid: count, key: string, value: string)
{
	print fmt("Entry Removed");
	print fmt("Host = %s PID = %d Key = %s Value = %s ",host, pid,key,value);
}
########################### PROCESS MOMORY ######################################################
event added_process_memory_map(host: string, pid: count, permissions: string, device: string)
{
	print fmt("New entry added");
	print fmt("Host = %s PID = %d Permissions = %s Device = %s ",host, pid,permissions,device);
}
event removed_process_memory_map(host: string, pid: count, permissions: string, device: string)
{
	print fmt("Entry Removed");
	print fmt("Host = %s PID = %d Permissions = %s Device = %s ",host, pid,permissions,device);
}
########################## PROCESS OPEN FILES ###################################################
event added_process_open_files(host: string, pid: count, fd: string, path: string)
{
	print fmt("New entry added");
	print fmt("Host = %s PID = %d FD = %s Path = %s",host, pid,fd,path);
}
event removed_process_open_files(host: string, pid: count, fd: string, path: string)
{
	print fmt("Entry Removed");
	print fmt("Host = %s PID = %d FD = %s Path = %s",host, pid,fd,path);
}
########################## PROCESS OPEN SOCKETS ####################################################
event added_process_open_sockets(host: string, pid: count, socket: count, protocol: count)
{
	print fmt("New entry added");
	print fmt("Host = %s PID = %d Socket = %d Protocol =%d",host, pid,socket,protocol);
}
event removed_process_open_sockets(host: string, pid: count, socket: count, protocol: count)
{
	print fmt("Entry Removed");
	print fmt("Host = %s PID = %d Socket = %d Protocol =%d",host, pid,socket,protocol);
}
########################## PROCESSES #########################################################
event added_processes(host: string, pid: count, name: string, on_disk: string)
{
	print fmt("New entry added");
	print fmt("Host = %s PID = %d Name = %s on_disk = %s",host, pid,name,on_disk);
}
event removed_processes(host: string, pid: count, name: string, on_disk: string)
{
	print fmt("Entry Removed");
	print fmt("Host = %s PID = %d Name = %s on_disk = %s",host, pid,name,on_disk);
}
########################### ROUTES ########################################################
event added_routes(host: string, destination: string, source: string, interface: string)
{
	print fmt("New entry added");
	print fmt("Host = %s Destination = %s Source = %s Interface = %s ",host, destination,source,interface);
}
event removed_routes(host: string, destination: string, source: string, interface: string)
{
	print fmt("Entry Removed");
	print fmt("Host = %s Destination = %s Source = %s Interface = %s ",host, destination,source,interface);
}
########################### SHELL HISTORY ####################################################
event added_shell_history(host: string, username: string, command: string)
{
	print fmt("New entry added");
	print fmt("Host = %s UserNmae = %s Command = %s ",host, username, command);
}
event removed_shell_history(host: string, username: string, command: string)
{
	print fmt("Entry Removed");
	print fmt("Host = %s UserNmae = %s Command = %s ",host, username, command);
}
############################ SMBIOS TABLES ###################################################
event added_smbios_tables(host: string, number: count, description: string, size: count)
{
	print fmt("New entry added");
	print fmt("Host = %s Number = %d Description = %s Size=%d ",host, number, description,size);
}
event removed_smbios_tables(host: string, number: count, description: string, size: count)
{
	print fmt("Entry Removed");
	print fmt("Host = %s Number = %d Description = %s Size=%d ",host, number, description,size);
}
############################# SYSTEM CONTROLS ###################################################
event added_system_controls(host: string, name: string, oid: string, subsystem: string)
{
	print fmt("New entry added");
	print fmt("Host = %s Name = %s OID = %s Subsystem =%s ",host, name, oid, subsystem);
}
event removed_system_controls(host: string, name: string, oid: string, subsystem: string)
{
	print fmt("Entry Removed");
	print fmt("Host = %s Name = %s OID = %s Subsystem =%s ",host, name, oid, subsystem);
}
############################## UPTIME ###################################################
event added_uptime(host: string, days: count, hours: count)
{
	print fmt("New entry added");
	print fmt("Host = %s Days = %d Hours = %d ",host, days,hours);
}
event removed_uptime(host: string, days: count, hours: count)
{
	print fmt("Entry Removed");
	print fmt("Host = %s Days = %d Hours = %d ",host, days,hours);
}
############################# USB DEVICES ###################################################
event added_usb_devices(host: string, usb_address: count, vendor: string, model: string)
{
	print "New Usb Device Added";
 	print fmt("Host = %s Usb_address = %d Vendor = %s Model = %s",host, usb_address, vendor, model);
}
event removed_usb_devices(host: string, usb_address: count, vendor: string, model: string)
{
	print "Usb Device Removed";
 	print fmt("Host = %s Usb_address = %d Vendor = %s Model = %s",host, usb_address, vendor, model);
}
############################# USER GROUPS ###################################################
event added_user_groups(host: string, uid: count, gid: count)
{
	print fmt("New entry added");
	print fmt("Host = %s UID = %d GID = %d ",host, uid, gid);
}
event removed_user_groups(host: string, uid: count, gid: count)
{
	print fmt("Entry Removed");
	print fmt("Host = %s UID = %d GID = %d ",host, uid, gid);
}
############################# USERS ######################################################
event added_users(host: string, username: string, uid: count, gid: count)
{
	print "New User Added";
 	print fmt("Host = %s UserName = %s UID = %d GID = %d",host, username, uid, gid);
}
event removed_users(host: string, username: string, uid: count, gid: count)
{
	print "User Removed";
 	print fmt("Host = %s UserName = %s UID = %d GID = %d",host, username, uid, gid);
}

error: pathspec 'singlequerysubscription.bro' did not match any file(s) known to git


add missing header fields

add missing header fields

@load global-ext
@load ssh-ext

module SSH;

export {
	# If set to T, this will split inbound and outbound transactions
	# into separate files.  F merges everything into a single file.
	const split_log_file = F &redef;
	# Which SSH logins to record.
	# Choices are: Inbound, Outbound, All
	const logging = All &redef;
}

event bro_init()
	{
	LOG::create_logs("ssh-ext", logging, split_log_file, T);
	LOG::define_header("ssh-ext", cat_sep("\t", "",
	                                      "ts",
	                                      "orig_h", "orig_p",
	                                      "resp_h", "resp_p",
	                                      "status", "direction",
	                                      "country", "region",
	                                      "client", "server", "resp_size"));

	}

event ssh_ext(id: conn_id, si: ssh_ext_session_info)
	{
	local log = LOG::choose("ssh-ext", id$resp_h);

	print log, cat_sep("\t", "\\N",
	                   si$start_time,
	                   id$orig_h, fmt("%d", id$orig_p),
	                   id$resp_h, fmt("%d", id$resp_p),
	                   si$status, si$direction,
	                   si$location$country_code, si$location$region,
	                   si$client, si$server,
	                   si$resp_size);
	}

@load global-ext
@load ssh-ext

module SSH;

export {
	# If set to T, this will split inbound and outbound transactions
	# into separate files.  F merges everything into a single file.
	const split_log_file = F &redef;
	# Which SSH logins to record.
	# Choices are: Inbound, Outbound, All
	const logging = All &redef;
}

event bro_init()
	{
	LOG::create_logs("ssh-ext", logging, split_log_file, T);
	LOG::define_header("ssh-ext", cat_sep("\t", "",
	                                      "ts",
	                                      "orig_h", "orig_p",
	                                      "resp_h", "resp_p",
	                                      "country", "region",
	                                      "client", "server", "resp_size"));

	}

event ssh_ext(id: conn_id, si: ssh_ext_session_info)
	{
	local log = LOG::choose("ssh-ext", id$resp_h);

	print log, cat_sep("\t", "\\N",
	                   si$start_time,
	                   id$orig_h, fmt("%d", id$orig_p),
	                   id$resp_h, fmt("%d", id$resp_p),
	                   si$status, si$direction,
	                   si$location$country_code, si$location$region,
	                   si$client, si$server,
	                   si$resp_size);
	}


http mime metrics

http mime metrics

@load base/frameworks/metrics

redef enum Metrics::ID += {
    HTTP_MIME_METRICS,
};

event bro_init()
{
    Metrics::add_filter(HTTP_MIME_METRICS,
                [$name="all",
                 $break_interval=3600secs
                ]);
}

event HTTP::log_http(rec: HTTP::Info)
{
    if(Site::is_local_addr(rec$id$resp_h)) {
        Metrics::add_data(HTTP_MIME_METRICS, [$str=rec$mime_type], rec$response_body_len);
    }
}

error: pathspec 'http-mime-metrics.bro' did not match any file(s) known to git


remove unneeded file

remove unneeded file

# This Bro script appends JA3 to ssl.log
# Version 1.3 (June 2017)
#
# Authors: John B. Althouse (jalthouse@salesforce.com) & Jeff Atkinson (jatkinson@salesforce.com)
#
# Copyright (c) 2017, salesforce.com, inc.
# All rights reserved.
# Licensed under the BSD 3-Clause license.
# For full license text, see LICENSE.txt file in the repo root  or https://opensource.org/licenses/BSD-3-Clause

module JA3;

export {
redef enum Log::ID += { LOG };
}

type TLSFPStorage: record {
       client_version:  count &default=0 &log;
       client_ciphers:  string &default="" &log;
       extensions:      string &default="" &log;
       e_curves:        string &default="" &log;
       ec_point_fmt:    string &default="" &log;
};

redef record connection += {
       tlsfp: TLSFPStorage &optional;
};

redef record SSL::Info += {
  ja3:            string &optional &log;
# LOG FIELD VALUES ##
#  ja3_version:  string &optional &log;
#  ja3_ciphers:  string &optional &log;
#  ja3_extensions: string &optional &log;
#  ja3_ec:         string &optional &log;
#  ja3_ec_fmt:     string &optional &log;
};

# Google. https://tools.ietf.org/html/draft-davidben-tls-grease-01
const grease: set[int] = {
    2570,
    6682,
    10794,
    14906,
    19018,
    23130,
    27242,
    31354,
    35466,
    39578,
    43690,
    47802,
    51914,
    56026,
    60138,
    64250
};
const sep = "-";
event bro_init() {
    Log::create_stream(JA3::LOG,[$columns=TLSFPStorage, $path="tlsfp"]);
}

event ssl_extension(c: connection, is_orig: bool, code: count, val: string)
{
if ( ! c?$tlsfp )
    c$tlsfp=TLSFPStorage();
    if ( is_orig = T ) {
        if ( code in grease ) {
            next;
        }
        if ( c$tlsfp$extensions == "" ) {
            c$tlsfp$extensions = cat(code);
        }
        else {
            c$tlsfp$extensions = string_cat(c$tlsfp$extensions, sep,cat(code));
        }
    }
}

event ssl_extension_ec_point_formats(c: connection, is_orig: bool, point_formats: index_vec)
{
if ( !c?$tlsfp )
    c$tlsfp=TLSFPStorage();
    if ( is_orig = T ) {
        for ( i in point_formats ) {
            if ( point_formats[i] in grease ) {
            next;
            }
            if ( c$tlsfp$ec_point_fmt == "" ) {
            c$tlsfp$ec_point_fmt += cat(point_formats[i]);
            }
            else {
            c$tlsfp$ec_point_fmt += string_cat(sep,cat(point_formats[i]));
            }
        }
    }
}

event ssl_extension_elliptic_curves(c: connection, is_orig: bool, curves: index_vec)
{
    if ( !c?$tlsfp )
    c$tlsfp=TLSFPStorage();
    if ( is_orig = T  ) {
        for ( i in curves ) {
            if ( curves[i] in grease ) {
            next;
            }
            if ( c$tlsfp$e_curves == "" ) {
                c$tlsfp$e_curves += cat(curves[i]);
            }
            else {
                c$tlsfp$e_curves += string_cat(sep,cat(curves[i]));
            }
        }
    }
}

event ssl_client_hello(c: connection, version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec) &priority=1
{
    if ( !c?$tlsfp )
    c$tlsfp=TLSFPStorage();
    c$tlsfp$client_version = version;
    for ( i in ciphers ) {
        if ( ciphers[i] in grease ) {
            next;
        }
        if ( c$tlsfp$client_ciphers == "" ) {
            c$tlsfp$client_ciphers += cat(ciphers[i]);
        }
        else {
            c$tlsfp$client_ciphers += string_cat(sep,cat(ciphers[i]));
        }
    }
    local sep2 = ",";
    local ja3_string = string_cat(cat(c$tlsfp$client_version),sep2,c$tlsfp$client_ciphers,sep2,c$tlsfp$extensions,sep2,c$tlsfp$e_curves,sep2,c$tlsfp$ec_point_fmt);
    local tlsfp_1 = md5_hash(ja3_string);
    c$ssl$ja3 = tlsfp_1;

# LOG FIELD VALUES ##
#c$ssl$ja3_version = cat(c$tlsfp$client_version);
#c$ssl$ja3_ciphers = c$tlsfp$client_ciphers;
#c$ssl$ja3_extensions = c$tlsfp$extensions;
#c$ssl$ja3_ec = c$tlsfp$e_curves;
#c$ssl$ja3_ec_fmt = c$tlsfp$ec_point_fmt;
#
# FOR DEBUGGING ##
#print "JA3: "+tlsfp_1+" Fingerprint String: "+ja3_string;

}


Dionaea_MySQL Log hinzugefügt.

Dionaea_MySQL Log hinzugefügt.

@load ./dio_log.bro
@load ./dio_mysql_log.bro
const broker_port: port = 9999/tcp &redef;
redef exit_only_after_terminate = T;
redef Broker::endpoint_name = "listener";
global dionaea_connection: event(timestamp: time, id: string, local_ip: addr, local_port: count, remote_ip: addr, remote_port: count, transport: string);
global dionaea_mysql: event(timestamp: time, id: string, local_ip: addr, local_port: count, remote_ip: addr, remote_port: count, transport: string, args: string);
global get_protocol: function(proto_str: string) : transport_proto;

event bro_init() {
    print "dionaea_receiver.bro: bro_init()";
    Broker::enable();
    Broker::listen(broker_port, "0.0.0.0");
    Broker::subscribe_to_events("honeypot/dionaea/");
    print "dionaea_receiver.bro: bro_init() done";
}
event bro_done() {
    print "dionaea_receiver.bro: bro_done()";
}

event dionaea_connection(timestamp: time, id: string, local_ip: addr, local_port: count, remote_ip: addr, remote_port: count, transport: string) {
    local lport: port = count_to_port(local_port, get_protocol(transport));
    local rport: port = count_to_port(remote_port, get_protocol(transport));

    print fmt("dionaea_connection: timestamp=%s, id=%s, local_ip=%s, local_port=%s, remote_ip=%s, remote_port=%s, transport=%s", timestamp, id, local_ip, local_port, remote_ip, remote_port, transport);
    print fmt("converted ports %s %s", lport, rport);
    local rec: Dio::Info = [$ts=timestamp, $id=id, $local_ip=local_ip, $local_port=lport, $remote_ip=remote_ip, $remote_port=rport, $transport=transport];

    Log::write(Dio_mysql::LOG, rec);
}

event dionaea_mysql(timestamp: time, id: string, local_ip: addr, local_port: count, remote_ip: addr, remote_port: count, transport: string, args: string) {
    local lport: port = count_to_port(local_port, get_protocol(transport));
    local rport: port = count_to_port(remote_port, get_protocol(transport));

    print fmt("dionaea_mysql: timestamp=%s, id=%s, local_ip=%s, local_port=%s, remote_ip=%s, remote_port=%s, transport=%s, args=%s", timestamp, id, local_ip, local_port, remote_ip, remote_port, transport, args);
    print fmt("converted ports %s %s", lport, rport);
    local rec: Dio::Info = [$ts=timestamp, $id=id, $local_ip=local_ip, $local_port=lport, $remote_ip=remote_ip, $remote_port=rport, $transport=transport, $args=args];

    Log::write(Dio::LOG, rec);
}

event Broker::incoming_connection_established(peer_name: string) {
    print "-> Broker::incoming_connection_established", peer_name;
}
event Broker::incoming_connection_broken(peer_name: string) {
    print "-> Broker::incoming_connection_broken", peer_name;
}

function get_protocol(proto_str: string) : transport_proto {
    # https://www.bro.org/sphinx/scripts/base/init-bare.bro.html#type-transport_proto
    if (proto_str == "tcp") {
        return tcp;
    }
    if (proto_str == "udp") {
        return udp;
    }
    if (proto_str == "icmp") {
        return icmp;
    }
    return unknown_transport;
}

@load ./dio_log.bro
const broker_port: port = 9999/tcp &redef;
redef exit_only_after_terminate = T;
redef Broker::endpoint_name = "listener";
global dionaea_connection: event(timestamp: time, id: string, local_ip: addr, local_port: count, remote_ip: addr, remote_port: count, transport: string);
global get_protocol: function(proto_str: string) : transport_proto;

event bro_init() {
    print "dionaea_receiver.bro: bro_init()";
    Broker::enable();
    Broker::listen(broker_port, "0.0.0.0");
    Broker::subscribe_to_events("honeypot/dionaea/");
    print "dionaea_receiver.bro: bro_init() done";
}
event bro_done() {
    print "dionaea_receiver.bro: bro_done()";
}

event dionaea_connection(timestamp: time, id: string, local_ip: addr, local_port: count, remote_ip: addr, remote_port: count, transport: string) {
    local lport: port = count_to_port(local_port, get_protocol(transport));
    local rport: port = count_to_port(remote_port, get_protocol(transport));

    print fmt("dionaea_connection: timestamp=%s, id=%s, local_ip=%s, local_port=%s, remote_ip=%s, remote_port=%s, transport=%s", timestamp, id, local_ip, local_port, remote_ip, remote_port, transport);
    print fmt("converted ports %s %s", lport, rport);
    local rec: Dio::Info = [$ts=timestamp, $id=id, $local_ip=local_ip, $local_port=lport, $remote_ip=remote_ip, $remote_port=rport, $transport=transport];

    Log::write(Dio::LOG, rec);
}

event Broker::incoming_connection_established(peer_name: string) {
    print "-> Broker::incoming_connection_established", peer_name;
}
event Broker::incoming_connection_broken(peer_name: string) {
    print "-> Broker::incoming_connection_broken", peer_name;
}

function get_protocol(proto_str: string) : transport_proto {
    # https://www.bro.org/sphinx/scripts/base/init-bare.bro.html#type-transport_proto
    if (proto_str == "tcp") {
        return tcp;
    }
    if (proto_str == "udp") {
        return udp;
    }
    if (proto_str == "icmp") {
        return icmp;
    }
    return unknown_transport;
}


Adds smtp-url.bro

Adds smtp-url.bro

Including this bro script by request, but not activating it by default. Also corrected some deprecated string functions and cleaned up commented out code.

##! A script for handling URLs in SMTP traffic.  This script does
##! two things.  It logs URLs discovered in SMTP traffic.  It
##! also records them in a bloomfilter and looks for them to be
##! visited through HTTP requests.
##!
##! Authors: Aashish Sharma <asharma@lbl.gov>
##!          Seth Hall <seth@icir.org>
##!          Derek Ditch <derek@rocknsm.io>

@load base/utils/urls

module SMTP_URL;

export {
        redef enum Log::ID += { Links_LOG };

        type Info: record {
                ## When the email was seen.
                ts:   time    &log;
                ## Unique ID for the connection.
                uid:  string  &log;
                ## Connection details.
                id:   conn_id &log;
                ## Depth of the email into the SMTP exchange.
                trans_depth: count &log;
                ## The host field extracted from the discovered URL.
                host: string  &log &optional;
                ## URL that was discovered.
                url:  string  &log &optional;
        };

        redef enum Notice::Type += {
                ## A link discovered in an email appears to have been clicked.
                Link_in_Email_Clicked,

                ## An email was seen in email that matched the pattern in
                ## `SMTP_URL::suspicious_urls`
                Suspicious_URL,

                ## Certain file extensions in email links can be watched for
                ## with the pattern in `SMTP_URL::suspicious_file_extensions`
                Suspicious_File_Extension,

                ## URL with a dotted IP address seen in an email.
                Dotted_URL
        };

        const suspicious_file_extensions = /\.([rR][aA][rR]|[eE][xX][eE]|[zZ][iI][pP])$/ &redef;
        const suspicious_urls = /googledocs?/ &redef;

        const ignore_file_types = /\.([gG][iI][fF]|[pP][nN][gG]|[jJ][pP][gG]|[xX][mM][lL]|[jJ][pP][eE]?[gG]|[cC][sS][sS])$/ &redef;

        ## The following
        const ignore_mail_originators: set[subnet] = { } &redef;
        const ignore_mailfroms = /bro@|alerts|reports/ &redef;
        const ignore_notification_emails = {"alerts@example.com", "notices@example.com"} &redef;
        const ignore_site_links = /http:\/\/.*\.example\.com\/|http:\/\/.*\.example\.net/ &redef;
}

# The bloomfilter that stores all of the links seen in email.
global mail_links_bf: opaque of bloomfilter;

redef record connection += {
        smtp_url: Info &optional;
};

event bro_init() &priority=5
        {
        # initialize the bloomfilter
        mail_links_bf = bloomfilter_basic_init(0.00000001, 10000000, "SMTP_URL");

        Log::create_stream(Links_LOG, [$columns=Info]);
        }

function extract_host(name: string): string
        {
        local split_on_slash = split_string(name, /\//);
        return split_on_slash[3];
        }

function log_smtp_urls(c: connection, url: string)
        {
        c$smtp_url = Info($ts   = c$smtp$ts,
                          $uid  = c$uid,
                          $id   = c$id,
                          $trans_depth = c$smtp$trans_depth,
                          $host = extract_host(url),
                          $url  = url);

        Log::write(SMTP_URL::Links_LOG, c$smtp_url);
        }

event SMTP_URL::email_data(f: fa_file, data: string)
        {
        # Grab the connection.
        local c: connection;
        for ( cid in f$conns )
                {
                c = f$conns[cid];
                break;
                }

        if( c$smtp?$mailfrom && ignore_mailfroms in c$smtp$mailfrom )
                {
                return;
                }

        if ( c$smtp?$to )
                {
                for ( to in c$smtp$to )
                        {
                        if ( to in ignore_notification_emails )
                                return;
                        }
                }

        local mail_info = Files::describe(f);
        local urls = find_all_urls(data);
        for ( link in urls )
                {
                if ( ignore_file_types !in link )
                        {
                        bloomfilter_add(mail_links_bf, link);
                        log_smtp_urls(c, link);

                        if ( suspicious_file_extensions in link )
                                {
                                NOTICE([$note = Suspicious_File_Extension,
                                        $msg  = fmt("Suspicious file extension embedded in URL %s from  %s", link, c$id$orig_h),
                                        $sub  = mail_info,
                                        $conn = c]);
                                }

                        if ( suspicious_urls in link )
                                {
                                NOTICE([$note = Suspicious_URL,
                                        $msg  = fmt("Suspicious text embedded in URL %s from  %s", link, c$smtp$uid),
                                        $sub  = mail_info,
                                        $conn = c]);
                                }

                        if ( /([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}.*/ in link )
                                {
                                NOTICE([$note = Dotted_URL,
                                        $msg  = fmt("Embedded IP address in URL %s from  %s", link, c$id$orig_h),
                                        $sub  = mail_info,
                                        $conn = c]);
                                }

                }
        }
}

event file_over_new_connection(f: fa_file, c: connection, is_orig: bool)
        {
        if ( f$source == "SMTP" && c?$smtp &&
             c$id$orig_h !in ignore_mail_originators )
                {
                Files::add_analyzer(f, Files::ANALYZER_DATA_EVENT, [$stream_event=SMTP_URL::email_data]);
                }
        }

event http_message_done(c: connection, is_orig: bool, stat: http_message_stat) &priority=-3
        {
        local str = HTTP::build_url_http(c$http);
        if ( bloomfilter_lookup(SMTP_URL::mail_links_bf, str) > 0 &&
             ignore_file_types !in str &&
             ignore_site_links !in str)
                {
                NOTICE([$note=SMTP_URL::Link_in_Email_Clicked,
                        $msg=fmt("URL %s ", str),
                        $conn=c]);
                }
        }

error: pathspec 'protocols/smtp/smtp-url.bro' did not match any file(s) known to git


Missed a header field for the software-ext log.

@load global-ext
@load weird

module Software;

export {
	# The hosts whose software should be logged.
	# Choices are: LocalHosts, RemoteHosts, AllHosts, NoHosts
	const logging = LocalHosts &redef;

	# In case you are interested in more than logging just local assets
	# you can split the log file.
	const split_log_file = F &redef;

	# Some software can be installed twice on the same server
	# with different major numbers.
	const identify_by_major: set[string] = {
		"PHP",
		"WebSTAR",
	} &redef;

	redef enum Notice += {
		Software_Version_Change,
	};

	# Some software is more interesting when the version changes.  This is
	# a set of all software that should raise a notice when a different version
	# is seen.
	const interesting_version_changes: set[string] = {
		"SSH"
	} &redef;

	# Raise this event from other scripts when software is discovered.
	# This event is actually defined internally in Bro.
	#global software_version_found: event(c: connection, host: addr, s: software, descr: string);

	# Index is the name of the software.
	type software_set: table[string] of software;
	# The set of software associated with an address.
	global host_software: table[addr] of software_set &create_expire=1day &synchronized;
}

event bro_init()
	{
	LOG::create_logs("software-ext", logging, split_log_file, T);
	LOG::define_header("software-ext", cat_sep("\t", "\\N",
	                                           "ts", "host",
	                                           "software", "version",
	                                           "description"));
	}

# Compare two versions.
#   Returns -1 for v1 < v2, 0 for v1 == v2, 1 for v1 > v2.
#   If the numerical version numbers match, the addl string
#   is compared lexicographically.
function software_cmp_version(v1: software_version, v2: software_version): int
	{
	if ( v1$major < v2$major )
		return -1;
	if ( v1$major > v2$major )
		return 1;

	if ( v1$minor < v2$minor )
		return -1;
	if ( v1$minor > v2$minor )
		return 1;

	if ( v1$minor2 < v2$minor2 )
		return -1;
	if ( v1$minor2 > v2$minor2 )
		return 1;

	return strcmp(v1$addl, v2$addl);
	}

function software_endpoint_name(c: connection, host: addr): string
	{
	return fmt("%s %s", host, (host == c$id$orig_h ? "client" : "server"));
	}

# Convert a version into a string "a.b.c-x".
function software_fmt_version(v: software_version): string
	{
	return fmt("%s%s%s%s",
	           v$major >= 0  ? fmt("%d", v$major)   : "",
	           v$minor >= 0  ? fmt(".%d", v$minor)  : "",
	           v$minor2 >= 0 ? fmt(".%d", v$minor2) : "",
	           v$addl != ""  ? fmt("-%s", v$addl)   : "");
	}

# Convert a software into a string "name a.b.cx".
function software_fmt(s: software): string
	{
	return fmt("%s %s", s$name, software_fmt_version(s$version));
	}

event software_new(c: connection, host: addr, s: software, descr: string)
	{
	if ( addr_matches_hosts(host, logging) )
		{
		local log = LOG::get_file_by_addr("software-ext", host, F);
		print log, cat_sep("\t", "\\N",
		                   network_time(), host,
		                   s$name, software_fmt_version(s$version), descr);
		}
	}

# Insert a mapping into the table
# Overides old entries for the same software and generates events if needed.
event software_register(c: connection, host: addr, s: software, descr: string)
	{
	# Host already known?
	if ( host !in host_software )
		host_software[host] = table();

	# If a software can be installed more than once on a host
	# (with a different major version), we identify it by "<name>-<major>"
	if ( s$name in identify_by_major && s$version$major >= 0 )
		s$name = fmt("%s-%d", s$name, s$version$major);

	local hs = host_software[host];
	# Software already registered for this host?
	if ( s$name in hs )
		{
		local old = hs[s$name];

		# Is it a potentially interesting version change
		# and is it a different version?
		if ( s$name in interesting_version_changes &&
		     software_cmp_version(old$version, s$version) != 0 )
			{
			local msg = fmt("%.6f %s switched from %s to %s (%s)",
					network_time(), software_endpoint_name(c, host),
					software_fmt_version(old$version),
					software_fmt(s), descr);
			NOTICE([$note=Software_Version_Change,
			        $msg=msg, $sub=software_fmt(s), $conn=c]);
			}
		}
	else
		{
		event software_new(c, host, s, descr);
		}

	hs[s$name] = s;
	}

event software_version_found(c: connection, host: addr, s: software,
				descr: string)
	{
	if ( addr_matches_hosts(host, logging) )
		event software_register(c, host, s, descr);
	}

########################################
# Below are internally defined events. #
########################################

event software_version_found(c: connection, host: addr, s: software, descr: string)
	{
	if ( addr_matches_hosts(host, logging) )
		event software_register(c, host, s, descr);
	}

event software_parse_error(c: connection, host: addr, descr: string)
	{
	if ( addr_matches_hosts(host, logging) )
		{
		# Here we need a little hack, since software_file is
		# not always there.
		local msg = fmt("%.6f %s: can't parse '%s'", network_time(),
				software_endpoint_name(c, host), descr);

		print Weird::weird_file, msg;
		}
	}

# I'm not going to handle this at the moment.  It doesn't seem terribly useful.
#event software_unparsed_version_found(c: connection, host: addr, str: string)
#	{
#	if ( addr_matches_hosts(host, logging) )
#		{
#		print Weird::weird_file, fmt("%.6f %s: [%s]", network_time(),
#				software_endpoint_name(c, host), str);
#		}
#	}

@load global-ext
@load weird

module Software;

export {
	# The hosts whose software should be logged.
	# Choices are: LocalHosts, RemoteHosts, AllHosts, NoHosts
	const logging = LocalHosts &redef;

	# In case you are interested in more than logging just local assets
	# you can split the log file.
	const split_log_file = F &redef;

	# Some software can be installed twice on the same server
	# with different major numbers.
	const identify_by_major: set[string] = {
		"PHP",
		"WebSTAR",
	} &redef;

	redef enum Notice += {
		Software_Version_Change,
	};

	# Some software is more interesting when the version changes.  This is
	# a set of all software that should raise a notice when a different version
	# is seen.
	const interesting_version_changes: set[string] = {
		"SSH"
	} &redef;

	# Raise this event from other scripts when software is discovered.
	# This event is actually defined internally in Bro.
	#global software_version_found: event(c: connection, host: addr, s: software, descr: string);

	# Index is the name of the software.
	type software_set: table[string] of software;
	# The set of software associated with an address.
	global host_software: table[addr] of software_set &create_expire=1day &synchronized;
}

event bro_init()
	{
	LOG::create_logs("software-ext", logging, split_log_file, T);
	LOG::define_header("software-ext", cat_sep("\t", "\\N",
	                                           "ts", "host",
	                                           "software", "version"));
	}

# Compare two versions.
#   Returns -1 for v1 < v2, 0 for v1 == v2, 1 for v1 > v2.
#   If the numerical version numbers match, the addl string
#   is compared lexicographically.
function software_cmp_version(v1: software_version, v2: software_version): int
	{
	if ( v1$major < v2$major )
		return -1;
	if ( v1$major > v2$major )
		return 1;

	if ( v1$minor < v2$minor )
		return -1;
	if ( v1$minor > v2$minor )
		return 1;

	if ( v1$minor2 < v2$minor2 )
		return -1;
	if ( v1$minor2 > v2$minor2 )
		return 1;

	return strcmp(v1$addl, v2$addl);
	}

function software_endpoint_name(c: connection, host: addr): string
	{
	return fmt("%s %s", host, (host == c$id$orig_h ? "client" : "server"));
	}

# Convert a version into a string "a.b.c-x".
function software_fmt_version(v: software_version): string
	{
	return fmt("%s%s%s%s",
	           v$major >= 0  ? fmt("%d", v$major)   : "",
	           v$minor >= 0  ? fmt(".%d", v$minor)  : "",
	           v$minor2 >= 0 ? fmt(".%d", v$minor2) : "",
	           v$addl != ""  ? fmt("-%s", v$addl)   : "");
	}

# Convert a software into a string "name a.b.cx".
function software_fmt(s: software): string
	{
	return fmt("%s %s", s$name, software_fmt_version(s$version));
	}

event software_new(c: connection, host: addr, s: software, descr: string)
	{
	if ( addr_matches_hosts(host, logging) )
		{
		local log = LOG::get_file_by_addr("software-ext", host, F);
		print log, cat_sep("\t", "\\N",
		                   network_time(), host,
		                   s$name, software_fmt_version(s$version), descr);
		}
	}

# Insert a mapping into the table
# Overides old entries for the same software and generates events if needed.
event software_register(c: connection, host: addr, s: software, descr: string)
	{
	# Host already known?
	if ( host !in host_software )
		host_software[host] = table();

	# If a software can be installed more than once on a host
	# (with a different major version), we identify it by "<name>-<major>"
	if ( s$name in identify_by_major && s$version$major >= 0 )
		s$name = fmt("%s-%d", s$name, s$version$major);

	local hs = host_software[host];
	# Software already registered for this host?
	if ( s$name in hs )
		{
		local old = hs[s$name];

		# Is it a potentially interesting version change
		# and is it a different version?
		if ( s$name in interesting_version_changes &&
		     software_cmp_version(old$version, s$version) != 0 )
			{
			local msg = fmt("%.6f %s switched from %s to %s (%s)",
					network_time(), software_endpoint_name(c, host),
					software_fmt_version(old$version),
					software_fmt(s), descr);
			NOTICE([$note=Software_Version_Change,
			        $msg=msg, $sub=software_fmt(s), $conn=c]);
			}
		}
	else
		{
		event software_new(c, host, s, descr);
		}

	hs[s$name] = s;
	}

event software_version_found(c: connection, host: addr, s: software,
				descr: string)
	{
	if ( addr_matches_hosts(host, logging) )
		event software_register(c, host, s, descr);
	}

########################################
# Below are internally defined events. #
########################################

event software_version_found(c: connection, host: addr, s: software, descr: string)
	{
	if ( addr_matches_hosts(host, logging) )
		event software_register(c, host, s, descr);
	}

event software_parse_error(c: connection, host: addr, descr: string)
	{
	if ( addr_matches_hosts(host, logging) )
		{
		# Here we need a little hack, since software_file is
		# not always there.
		local msg = fmt("%.6f %s: can't parse '%s'", network_time(),
				software_endpoint_name(c, host), descr);

		print Weird::weird_file, msg;
		}
	}

# I'm not going to handle this at the moment.  It doesn't seem terribly useful.
#event software_unparsed_version_found(c: connection, host: addr, str: string)
#	{
#	if ( addr_matches_hosts(host, logging) )
#		{
#		print Weird::weird_file, fmt("%.6f %s: [%s]", network_time(),
#				software_endpoint_name(c, host), str);
#		}
#	}


Create ja3.bro

Create ja3.bro

# This Bro script appends JA3 to ssl.log
# Version 1.2 (March 2017)
#
# Copyright (c) 2017, salesforce.com, inc.
# All rights reserved.
# Licensed under the BSD 3-Clause license.
# For full license text, see LICENSE.txt file in the repo root  or https://opensource.org/licenses/BSD-3-Clause

module JA3;

export {
redef enum Log::ID += { LOG };
}

type TLSFPStorage: record {
       client_version:  count &default=0 &log;
       client_ciphers:  string &default="" &log;
       extensions:      string &default="" &log;
       e_curves:        string &default="" &log;
       ec_point_fmt:    string &default="" &log;
};

redef record connection += {
       tlsfp: TLSFPStorage &optional;
};

redef record SSL::Info += {
  ja3:            string &optional &log;
## LOG FIELD VALUES ##
#  ja3_version:  string &optional &log;
#  ja3_ciphers:  string &optional &log;
#  ja3_extensions: string &optional &log;
#  ja3_ec:         string &optional &log;
#  ja3_ec_fmt:     string &optional &log;
};

const sep = "-";
event bro_init() {
  Log::create_stream(JA3::LOG,[$columns=TLSFPStorage, $path="tlsfp"]);
}

event ssl_extension(c: connection, is_orig: bool, code: count, val: string)
{
if ( ! c?$tlsfp )
    c$tlsfp=TLSFPStorage();
    if ( is_orig = T ) {
        if ( c$tlsfp$extensions == "" ) {
            c$tlsfp$extensions = cat(code);
        }
        else {
            c$tlsfp$extensions = string_cat(c$tlsfp$extensions, sep,cat(code));
        }
    }
}

event ssl_extension_ec_point_formats(c: connection, is_orig: bool, point_formats: index_vec)
{
if ( !c?$tlsfp )
    c$tlsfp=TLSFPStorage();
    if ( is_orig = T ) {
        for ( i in point_formats ) {
        if ( c$tlsfp$ec_point_fmt == "" ) {
            c$tlsfp$ec_point_fmt += cat(point_formats[i]);
            }
      else {
            c$tlsfp$ec_point_fmt += string_cat(sep,cat(point_formats[i]));
            }
        }
    }
}

event ssl_extension_elliptic_curves(c: connection, is_orig: bool, curves: index_vec)
{
    if ( !c?$tlsfp )
    c$tlsfp=TLSFPStorage();
    if ( is_orig = T  ) {
        for ( i in curves ) {
            if ( c$tlsfp$e_curves == "" ) {
                c$tlsfp$e_curves += cat(curves[i]);
          }
            else {
                c$tlsfp$e_curves += string_cat(sep,cat(curves[i]));
          }
        }
    }
}

event ssl_client_hello(c: connection, version: count, possible_ts: time, client_random: string, session_id: string, ciphers: index_vec) &priority=1
{
    if ( !c?$tlsfp )
    c$tlsfp=TLSFPStorage();
    c$tlsfp$client_version = version;
    for ( i in ciphers ) {
        if ( c$tlsfp$client_ciphers == "" ) {
            c$tlsfp$client_ciphers += cat(ciphers[i]);
        }
        else {
            c$tlsfp$client_ciphers += string_cat(sep,cat(ciphers[i]));
      }
    }
    local sep2 = ",";
    local ja3_string = string_cat(cat(c$tlsfp$client_version),sep2,c$tlsfp$client_ciphers,sep2,c$tlsfp$extensions,sep2,c$tlsfp$e_curves,sep2,c$tlsfp$ec_point_fmt);
    local tlsfp_1 = md5_hash(ja3_string);
    c$ssl$ja3 = tlsfp_1;

## LOG FIELD VALUES ##
#c$ssl$ja3_version = cat(c$tlsfp$client_version);
#c$ssl$ja3_ciphers = c$tlsfp$client_ciphers;
#c$ssl$ja3_extensions = c$tlsfp$extensions;
#c$ssl$ja3_ec = c$tlsfp$e_curves;
#c$ssl$ja3_ec_fmt = c$tlsfp$ec_point_fmt;
#
## FOR DEBUGGING ##
#print "JA3: "+tlsfp_1+" Fingerprint String: "+ja3_string;

}

error: pathspec 'bro/ja3.bro' did not match any file(s) known to git


New script for extended SSL analysis.

New script for extended SSL analysis.

Solely used for logging X.509 certificate information at the moment.

# Copyright 2008 Seth Hall <hall.692@osu.edu>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that: (1) source code distributions
# retain the above copyright notice and this paragraph in its entirety, (2)
# distributions including binary code include the above copyright notice and
# this paragraph in its entirety in the documentation or other materials
# provided with the distribution, and (3) all advertising materials mentioning
# features or use of this software display the following acknowledgement:
# ``This product includes software developed by the University of California,
# Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
# the University nor the names of its contributors may be used to endorse
# or promote products derived from this software without specific prior
# written permission.
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

@load global-ext
@load ssl

module KnownCerts;

export {
	const log = open_log_file("known-ssl-certs") &raw_output &redef;

	# The list of all detected certs.  This prevents over-logging.
	global certs: set[addr, port, string] &create_expire=1day &synchronized;

	# The hosts that should be logged.
	const log_hosts: Hosts = LocalHosts &redef;
}

event ssl_certificate(c: connection, cert: X509, is_server: bool)
	{
	# The ssl analyzer doesn't do this yet, so let's do it here.
	add c$service["SSL"];

	if ( !ip_matches_hosts(c$id$resp_h, log_hosts) )
		return;

	lookup_ssl_conn(c, "ssl_certificate", T);
	local conn = ssl_connections[c$id];
	if ( [c$id$resp_h, c$id$resp_p, cert$subject] !in certs )
		{
		add certs[c$id$resp_h, c$id$resp_p, cert$subject];
		print log, cat_sep("\t", "\\N", c$id$resp_h, fmt("%d", c$id$resp_p), cert$subject);
		}
	}

error: pathspec 'ssl-ext.bro' did not match any file(s) known to git


remove outdated enum type

remove outdated enum type

@load global-ext
@load ssl

module SSL_KnownCerts;

export {
	const local_domains = /(^|\.)(osu|ohio-state)\.edu$/ |
	                      /(^|\.)akamai(tech)?\.net$/ &redef;

	# The list of all detected certs.  This prevents over-logging.
	global certs: set[addr, port, string] &create_expire=1day &synchronized;

	# The hosts that should be logged.
	const split_log_file = F &redef;
	const logged_hosts = LocalHosts &redef;

	redef enum Notice += {
		# Raised when a non-local name is found in the CN of a SSL cert served
		# up from a local system.
		SSLExternalName,
		};
}

event bro_init()
{
    LOG::create_logs("ssl-known-certs", All, split_log_file, T);
    LOG::define_header("ssl-known-certs", cat_sep("\t", "\\N", "resp_h", "resp_p", "subject"));
}

event ssl_certificate(c: connection, cert: X509, is_server: bool)
	{
	# The ssl analyzer doesn't do this yet, so let's do it here.
	#add c$service["SSL"];
	event protocol_confirmation(c, ANALYZER_SSL, 0);

	if ( !addr_matches_hosts(c$id$resp_h, logged_hosts) )
		return;

	lookup_ssl_conn(c, "ssl_certificate", T);
	local conn = ssl_connections[c$id];
	if ( [c$id$resp_h, c$id$resp_p, cert$subject] !in certs )
		{
		add certs[c$id$resp_h, c$id$resp_p, cert$subject];
		local log = LOG::get_file_by_id("ssl-known-certs", c$id, F);
		print log, cat_sep("\t", "\\N", c$id$resp_h, fmt("%d", c$id$resp_p), cert$subject);

	    if(is_local_addr(c$id$resp_h))
	        {
	        local parts = split_all(cert$subject, /CN=[^\/]+/);
	        if (|parts| == 3)
	            {
	            local cn = parts[2];
	            if (local_domains !in cn)
	                {
	                NOTICE([$note=SSLExternalName,
	                        $msg=fmt("SSL Cert for %s returned from an internal host - %s", cn, c$id$resp_h),
	                        $conn=c]);
	                }
	            }
	        }
	    }
	}

@load global-ext
@load ssl

module SSL_KnownCerts;

export {
	const local_domains = /(^|\.)(osu|ohio-state)\.edu$/ |
	                      /(^|\.)akamai(tech)?\.net$/ &redef;

	# The list of all detected certs.  This prevents over-logging.
	global certs: set[addr, port, string] &create_expire=1day &synchronized;

	# The hosts that should be logged.
	const split_log_file = F &redef;
	const logged_hosts: Hosts = LocalHosts &redef;

	redef enum Notice += {
		# Raised when a non-local name is found in the CN of a SSL cert served
		# up from a local system.
		SSLExternalName,
		};
}

event bro_init()
{
    LOG::create_logs("ssl-known-certs", All, split_log_file, T);
    LOG::define_header("ssl-known-certs", cat_sep("\t", "\\N", "resp_h", "resp_p", "subject"));
}

event ssl_certificate(c: connection, cert: X509, is_server: bool)
	{
	# The ssl analyzer doesn't do this yet, so let's do it here.
	#add c$service["SSL"];
	event protocol_confirmation(c, ANALYZER_SSL, 0);

	if ( !addr_matches_hosts(c$id$resp_h, logged_hosts) )
		return;

	lookup_ssl_conn(c, "ssl_certificate", T);
	local conn = ssl_connections[c$id];
	if ( [c$id$resp_h, c$id$resp_p, cert$subject] !in certs )
		{
		add certs[c$id$resp_h, c$id$resp_p, cert$subject];
		local log = LOG::get_file_by_id("ssl-known-certs", c$id, F);
		print log, cat_sep("\t", "\\N", c$id$resp_h, fmt("%d", c$id$resp_p), cert$subject);

	    if(is_local_addr(c$id$resp_h))
	        {
	        local parts = split_all(cert$subject, /CN=[^\/]+/);
	        if (|parts| == 3)
	            {
	            local cn = parts[2];
	            if (local_domains !in cn)
	                {
	                NOTICE([$note=SSLExternalName,
	                        $msg=fmt("SSL Cert for %s returned from an internal host - %s", cn, c$id$resp_h),
	                        $conn=c]);
	                }
	            }
	        }
	    }
	}


Blank session_http_info records created on access now. Fix for user-agent logging.  It was recording user-agents backwards from what the user configured.

@load global-ext
@load http-request

# I'm working to remove the dependency on this, but I'm not there yet.
@load http-reply

module HTTP;

# Comment out the next line if you don't have or don't want the malware.com.br
# dataset included.
#@load malware_com_br_block_list-data

export {
	# Open the log files
	global http_ext_log = open_log_file("http-ext") &raw_output &redef;
	global http_malware_log = open_log_file("http-malware") &raw_output &redef;
	global http_ua_log = open_log_file("http-user-agents") &raw_output &redef;
	global http_sql_injections_log = open_log_file("http-sql-injections") &raw_output &redef;

	redef enum Notice += {
		HTTP_Suspicious,
		HTTP_Malware_com_br_Block_List,
		HTTP_SQL_Injection_Attempt,
		HTTP_SQL_Injection_Heavy_Probing,
	};

	# Which webservers to log requests for.
	#   Note that if you choose All or Remote, it will indiscriminately log
	#   your user's host HTTP requests.
	# Choices are: LocalHosts, RemoteHosts, AllHosts
	const log_requests_toward: Hosts = LocalHosts &redef;

	# This is list of subnets containing web servers that you'd like to log their
	# traffic regardless of the "log_requests_toward" variable.
	const ok_to_log: set[subnet] &redef;

	# Which hosts we care about logging user-agents.
	# You probably want to leave this alone becase of high memory use.
	# Choices are: LocalHosts, RemoteHosts, AllHosts
	const log_user_agents_of: Hosts = LocalHosts &redef;

	# This is the regular expression that is used to match URL based SQL injections
	const sql_injection_regex =
		  /[\?&][^[:blank:]\|]+?=[\-0-9%]+([[:blank:]]|\/\*.*?\*\/)*['"]?([[:blank:]]|\/\*.*?\*\/|\)?;)+([hH][aA][vV][iI][nN][gG]|[uU][nN][iI][oO][nN]|[eE][xX][eE][cC]|[sS][eE][lL][eE][cC][tT]|[dD][eE][lL][eE][tT][eE]|[dD][rR][oO][pP]|[dD][eE][cC][lL][aA][rR][eE]|[cC][rR][eE][aA][tT][eE]|[iI][nN][sS][eE][rR][tT])[^a-zA-Z&]/
		| /[\?&][^[:blank:]\|]+?=[\-0-9%]+([[:blank:]]|\/\*.*?\*\/)*['"]?([[:blank:]]|\/\*.*?\*\/|\)?;)+([oO][rR]|[aA][nN][dD])([[:blank:]]|\/\*.*?\*\/)+['"]?[^a-zA-Z&]+?=/
		| /[\?&][^[:blank:]]+?=[\-0-9%]*([[:blank:]]|\/\*.*?\*\/)*['"]([[:blank:]]|\/\*.*?\*\/)*(\-|\+|\|\|)([[:blank:]]|\/\*.*?\*\/)*([0-9]|\(?[cC][oO][nN][vV][eE][rR][tT]|[cC][aA][sS][tT])/
		| /[\?&][^[:blank:]\|]+?=([[:blank:]]|\/\*.*?\*\/)*['"]([[:blank:]]|\/\*.*?\*\/|;)*([oO][rR]|[aA][nN][dD]|[hH][aA][vV][iI][nN][gG]|[uU][nN][iI][oO][nN]|[eE][xX][eE][cC]|[sS][eE][lL][eE][cC][tT]|[dD][eE][lL][eE][tT][eE]|[dD][rR][oO][pP]|[dD][eE][cC][lL][aA][rR][eE]|[cC][rR][eE][aA][tT][eE]|[rR][eE][gG][eE][xX][pP]|[iI][nN][sS][eE][rR][tT]|\()[^a-zA-Z&]/
		| /[\?&][^[:blank:]]+?=[^\.]*?([cC][hH][aA][rR]|[aA][sS][cC][iI][iI]|[sS][uU][bB][sS][tT][rR][iI][nN][gG]|[tT][rR][uU][nN][cC][aA][tT][eE]|[vV][eE][rR][sS][iI][oO][nN]|[lL][eE][nN][gG][tT][hH])\(/;

	# SQL injection probes are considered to be:
	#  1. A single single-quote at the end of a URL with no other single-quotes.
	#  2. URLs with one single quote at the end of a normal GET value.
	const sql_injection_probe_regex =
		  /^[^\']+\'$/
		| /^[^\']+\'&[^\']*$/;
	const sql_injection_probe_threshold = 5;

	# HTTP post data contents that appear suspicious.
	#  This is usually spamming forum postings and the like.
	const suspicious_http_posts =
		/[vV][iI][aA][gG][rR][aA]/ |
		/[tT][rR][aA][mM][aA][dD][oO][lL]/ |
		/[cC][iI][aA][lL][iI][sS]/ |
		/[sS][oO][mM][aA]/ |
		/[hH][yY][dD][rR][oO][cC][oO][dD][oO][nN][eE]/ |
		/[cC][aA][nN][aA][dD][iI][aA][nN].{0,15}[pP][hH][aA][rR][mM][aA][cC][yY]/ |
		/[rR][iI][nN][gG].?[tT][oO][nN][eE]/ |
		/[pP][eE][nN][iI][sS]/ |
		/[oO][nN][lL][iI][nN][eE].?[cC][aA][sS][iI][nN][oO]/ |
		/[rR][eE][mM][oO][rR][tT][gG][aA][gG][eE][sS]/ |
		# more than 4 bbcode style links in a POST is deemed suspicious
		/(url=http:.*){4}/ |
		# more that 4 html links is also suspicious
		/(a.href(=|%3[dD]).*){4}/ &redef;
}

global sql_injection_probes_from: table[addr] of count &default=0 &create_expire=10mins &synchronized;

type http_info: record {
	host: string &default="";
	referer: string &default="";
	user_agent: string &default="";
	proxied_for: string &default="";
};

global http_log_post: set[conn_id] &write_expire=15secs;

function default_http_session_info(id: conn_id): http_info
	{
	local tmp: http_info;
	return tmp;
	}

global session_http_info: table[conn_id] of http_info &default=default_http_session_info &write_expire=15secs;

# remember the set of user agents at an ip address for while
global http_remember_user_agents: table[addr] of string_set &synchronized &create_expire=1hr;

event http_message_done(c: connection, is_orig: bool, stat: http_message_stat) &priority=5
	{
	if ( !is_orig )
		return;

	local id = c$id;
	local s = lookup_http_request_stream(c);
	if ( s$first_pending_request !in s$requests )
		return;

	local msg = get_http_message(s, is_orig);
	local r = s$requests[s$first_pending_request];
	local host = session_http_info[c$id]$host;
	local url = fmt("http://%s%s", host, r$URI);

	if ( addr_matches_hosts(id$resp_h, log_requests_toward) ||
	     id$resp_h in ok_to_log )

		print http_ext_log, cat_sep("\t", "\\N", network_time(),
		                                         id$orig_h,
		                                         fmt("%d", id$orig_p),
		                                         id$resp_h,
		                                         fmt("%d", id$resp_p),
		                                         r$method,
		                                         url,
		                                         session_http_info[c$id]$referer);

	local log_sql=F;
	local direction = "";
	# Detect and log SQL injection attempts in their own log file
	if ( sql_injection_regex in r$URI )
		{
		log_sql=T;
		direction = "outbound";
		if ( is_local_addr(id$resp_h) )
			direction="inbound";
		}
	if ( sql_injection_probe_regex in r$URI )
		{
		log_sql=T;
		direction="PROBE";
		if ( ++sql_injection_probes_from[id$orig_h] >= sql_injection_probe_threshold )
			NOTICE([$note=HTTP_SQL_Injection_Heavy_Probing,
			        $msg=fmt("Heavy probing from %s", id$orig_h),
			        $n=sql_injection_probes_from[id$orig_h],
			        $conn=c]);
		}
	if ( log_sql )
		{
		print http_sql_injections_log, cat_sep("\t", "\\N", network_time(),
		                                 id$orig_h, fmt("%d", id$orig_p),
		                                 id$resp_h, fmt("%d", id$resp_p),
		                                 direction, r$method, url,
		                                 session_http_info[c$id]$referer,
		                                 session_http_info[c$id]$user_agent,
		                                 session_http_info[c$id]$proxied_for);
		NOTICE([$note=HTTP_SQL_Injection_Attempt,
		        $msg=fmt("SQL Injection request: %s -> %s",
		                 numeric_id_string(id), url),
		        $conn=c]);
		}

@ifdef ( MalwareComBr_BlockList )
	if ( MalwareComBr_BlockList in url )
		{
		add http_log_post[id];
		local malware_com_br_msg = fmt("%s %s %s", r$method, url, referrer);
		NOTICE([$note=HTTP_Malware_com_br_Block_List, $msg=malware_com_br_msg, $conn=c]);
		}
@endif
	}

event http_entity_data(c: connection, is_orig: bool, length: count, data: string)
	{
	if ( is_orig &&
	     (c$id in http_log_post || suspicious_http_posts in data) )
		{
		print http_ext_log, fmt("%.6f %s POST data: %s User-Agent: %s Referrer: %s Proxied for: %s",
		                        network_time(), numeric_id_string(c$id), data,
		                        session_http_info[c$id]$user_agent,
		                        session_http_info[c$id]$referer,
		                        session_http_info[c$id]$proxied_for);
		}
	}

event http_header(c: connection, is_orig: bool, name: string, value: string)
	{
	if ( !is_orig ) return;

	if ( c$id !in session_http_info )
		{
		local blah: http_info;
		session_http_info[c$id] = blah;
		}

	if ( name == "REFERER" )
		session_http_info[c$id]$referer = value;

	if ( name == "USER-AGENT" )
		{
		session_http_info[c$id]$user_agent = value;
		if ( addr_matches_hosts(c$id$orig_h, log_user_agents_of) &&
		    (c$id$orig_h !in http_remember_user_agents ||
		     (c$id$orig_h in http_remember_user_agents &&
		      value !in http_remember_user_agents[c$id$orig_h]) ) )
			{
			if ( c$id$orig_h !in http_remember_user_agents )
				http_remember_user_agents[c$id$orig_h] = set();
			add http_remember_user_agents[c$id$orig_h][value];
			print http_ua_log, fmt("%.6f %s %s", network_time(), c$id$orig_h, value);
			}
		}

	if ( name == "HTTP_FORWARDED" ||
	     name == "FORWARDED" ||
	     name == "HTTP_X_FORWARDED_FOR" ||
	     name == "X_FORWARDED_FOR" ||
	     name == "HTTP_X_FORWARDED_FROM" ||
	     name == "X_FORWARDED_FROM" ||
	     name == "HTTP_CLIENT_IP" ||
	     name == "CLIENT_IP" ||
	     name == "HTTP_FROM" ||
	     name == "FROM" ||
	     name == "HTTP_VIA" ||
	     name == "VIA" ||
	     name == "HTTP_XROXY_CONNECTION" ||
	     name == "XROXY_CONNECTION" ||
	     name == "HTTP_PROXY_CONNECTION" ||
	     name == "PROXY_CONNECTION")
		{
		if ( session_http_info[c$id]$proxied_for == "" )
			session_http_info[c$id]$proxied_for = fmt("(%s::%s)", name, value);
		}

	# This is duplicating effort from the http-reply script, but it seems
	# worthwhile to do it here because we don't have to do as many function
	# calls since this is regularly done in http traffic.
	if ( name == "HOST" )
			session_http_info[c$id]$host = value;
	}

@load global-ext
@load http-request

# I'm working to remove the dependency on this, but I'm not there yet.
@load http-reply

module HTTP;

# Comment out the next line if you don't have or don't want the malware.com.br
# dataset included.
#@load malware_com_br_block_list-data

export {
	# Open the log files
	global http_ext_log = open_log_file("http-ext") &raw_output &redef;
	global http_malware_log = open_log_file("http-malware") &raw_output &redef;
	global http_ua_log = open_log_file("http-user-agents") &raw_output &redef;
	global http_sql_injections_log = open_log_file("http-sql-injections") &raw_output &redef;

	redef enum Notice += {
		HTTP_Suspicious,
		HTTP_Malware_com_br_Block_List,
		HTTP_SQL_Injection_Attempt,
		HTTP_SQL_Injection_Heavy_Probing,
	};

	# Which webservers to log requests for.
	#   Note that if you choose All or Remote, it will indiscriminately log
	#   your user's host HTTP requests.
	# Choices are: LocalHosts, RemoteHosts, AllHosts
	const log_requests_toward: Hosts = LocalHosts &redef;

	# This is list of subnets containing web servers that you'd like to log their
	# traffic regardless of the "log_requests_toward" variable.
	const ok_to_log: set[subnet] &redef;

	# Which hosts we care about logging user-agents.
	# You probably want to leave this alone becase of high memory use.
	# Choices are: LocalHosts, RemoteHosts, AllHosts
	const log_user_agents_of: Hosts = LocalHosts &redef;

	# This is the regular expression that is used to match URL based SQL injections
	const sql_injection_regex =
		  /[\?&][^[:blank:]\|]+?=[\-0-9%]+([[:blank:]]|\/\*.*?\*\/)*['"]?([[:blank:]]|\/\*.*?\*\/|\)?;)+([hH][aA][vV][iI][nN][gG]|[uU][nN][iI][oO][nN]|[eE][xX][eE][cC]|[sS][eE][lL][eE][cC][tT]|[dD][eE][lL][eE][tT][eE]|[dD][rR][oO][pP]|[dD][eE][cC][lL][aA][rR][eE]|[cC][rR][eE][aA][tT][eE]|[iI][nN][sS][eE][rR][tT])[^a-zA-Z&]/
		| /[\?&][^[:blank:]\|]+?=[\-0-9%]+([[:blank:]]|\/\*.*?\*\/)*['"]?([[:blank:]]|\/\*.*?\*\/|\)?;)+([oO][rR]|[aA][nN][dD])([[:blank:]]|\/\*.*?\*\/)+['"]?[^a-zA-Z&]+?=/
		| /[\?&][^[:blank:]]+?=[\-0-9%]*([[:blank:]]|\/\*.*?\*\/)*['"]([[:blank:]]|\/\*.*?\*\/)*(\-|\+|\|\|)([[:blank:]]|\/\*.*?\*\/)*([0-9]|\(?[cC][oO][nN][vV][eE][rR][tT]|[cC][aA][sS][tT])/
		| /[\?&][^[:blank:]\|]+?=([[:blank:]]|\/\*.*?\*\/)*['"]([[:blank:]]|\/\*.*?\*\/|;)*([oO][rR]|[aA][nN][dD]|[hH][aA][vV][iI][nN][gG]|[uU][nN][iI][oO][nN]|[eE][xX][eE][cC]|[sS][eE][lL][eE][cC][tT]|[dD][eE][lL][eE][tT][eE]|[dD][rR][oO][pP]|[dD][eE][cC][lL][aA][rR][eE]|[cC][rR][eE][aA][tT][eE]|[rR][eE][gG][eE][xX][pP]|[iI][nN][sS][eE][rR][tT]|\()[^a-zA-Z&]/
		| /[\?&][^[:blank:]]+?=[^\.]*?([cC][hH][aA][rR]|[aA][sS][cC][iI][iI]|[sS][uU][bB][sS][tT][rR][iI][nN][gG]|[tT][rR][uU][nN][cC][aA][tT][eE]|[vV][eE][rR][sS][iI][oO][nN]|[lL][eE][nN][gG][tT][hH])\(/;

	# SQL injection probes are considered to be:
	#  1. A single single-quote at the end of a URL with no other single-quotes.
	#  2. URLs with one single quote at the end of a normal GET value.
	const sql_injection_probe_regex =
		  /^[^\']+\'$/
		| /^[^\']+\'&[^\']*$/;
	const sql_injection_probe_threshold = 5;

	# HTTP post data contents that appear suspicious.
	#  This is usually spamming forum postings and the like.
	const suspicious_http_posts =
		/[vV][iI][aA][gG][rR][aA]/ |
		/[tT][rR][aA][mM][aA][dD][oO][lL]/ |
		/[cC][iI][aA][lL][iI][sS]/ |
		/[sS][oO][mM][aA]/ |
		/[hH][yY][dD][rR][oO][cC][oO][dD][oO][nN][eE]/ |
		/[cC][aA][nN][aA][dD][iI][aA][nN].{0,15}[pP][hH][aA][rR][mM][aA][cC][yY]/ |
		/[rR][iI][nN][gG].?[tT][oO][nN][eE]/ |
		/[pP][eE][nN][iI][sS]/ |
		/[oO][nN][lL][iI][nN][eE].?[cC][aA][sS][iI][nN][oO]/ |
		/[rR][eE][mM][oO][rR][tT][gG][aA][gG][eE][sS]/ |
		# more than 4 bbcode style links in a POST is deemed suspicious
		/(url=http:.*){4}/ |
		# more that 4 html links is also suspicious
		/(a.href(=|%3[dD]).*){4}/ &redef;
}

global sql_injection_probes_from: table[addr] of count &default=0 &create_expire=10mins &synchronized;

type http_info: record {
	host: string &default="";
	referer: string &default="";
	user_agent: string &default="";
	proxied_for: string &default="";
};

global http_log_post: set[conn_id] &write_expire=15secs;
global session_http_info: table[conn_id] of http_info &write_expire=5secs;

# remember the set of user agents at an ip address for while
global http_remember_user_agents: table[addr] of string_set &synchronized &create_expire=1hr;

event http_message_done(c: connection, is_orig: bool, stat: http_message_stat) &priority=5
	{
	if ( !is_orig )
		return;

	local id = c$id;
	local s = lookup_http_request_stream(c);
	if ( s$first_pending_request !in s$requests )
		return;

	local msg = get_http_message(s, is_orig);
	local r = s$requests[s$first_pending_request];
	local host = session_http_info[c$id]$host;
	local url = fmt("http://%s%s", host, r$URI);

	if ( addr_matches_hosts(id$resp_h, log_requests_toward) ||
	     id$resp_h in ok_to_log )

		print http_ext_log, cat_sep("\t", "\\N", network_time(),
		                                         id$orig_h,
		                                         fmt("%d", id$orig_p),
		                                         id$resp_h,
		                                         fmt("%d", id$resp_p),
		                                         r$method,
		                                         url,
		                                         session_http_info[c$id]$referer);

	local log_sql=F;
	local direction = "";
	# Detect and log SQL injection attempts in their own log file
	if ( sql_injection_regex in r$URI )
		{
		log_sql=T;
		direction = "outbound";
		if ( is_local_addr(id$resp_h) )
			direction="inbound";
		}
	if ( sql_injection_probe_regex in r$URI )
		{
		log_sql=T;
		direction="PROBE";
		if ( ++sql_injection_probes_from[id$orig_h] >= sql_injection_probe_threshold )
			NOTICE([$note=HTTP_SQL_Injection_Heavy_Probing,
			        $msg=fmt("Heavy probing from %s", id$orig_h),
			        $n=sql_injection_probes_from[id$orig_h],
			        $conn=c]);
		}
	if ( log_sql )
		{
		print http_sql_injections_log, cat_sep("\t", "\\N", network_time(),
		                                 id$orig_h, fmt("%d", id$orig_p),
		                                 id$resp_h, fmt("%d", id$resp_p),
		                                 direction, r$method, url,
		                                 session_http_info[c$id]$referer,
		                                 session_http_info[c$id]$user_agent,
		                                 session_http_info[c$id]$proxied_for);
		NOTICE([$note=HTTP_SQL_Injection_Attempt,
		        $msg=fmt("SQL Injection request: %s -> %s",
		                 numeric_id_string(id), url),
		        $conn=c]);
		}

@ifdef ( MalwareComBr_BlockList )
	if ( MalwareComBr_BlockList in url )
		{
		add http_log_post[id];
		local malware_com_br_msg = fmt("%s %s %s", r$method, url, referrer);
		NOTICE([$note=HTTP_Malware_com_br_Block_List, $msg=malware_com_br_msg, $conn=c]);
		}
@endif
	}

event http_entity_data(c: connection, is_orig: bool, length: count, data: string)
	{
	if ( is_orig &&
	     (c$id in http_log_post || suspicious_http_posts in data) )
		{
		print http_ext_log, fmt("%.6f %s POST data: %s User-Agent: %s Referrer: %s Proxied for: %s",
		                        network_time(), numeric_id_string(c$id), data,
		                        session_http_info[c$id]$user_agent,
		                        session_http_info[c$id]$referer,
		                        session_http_info[c$id]$proxied_for);
		}
	}

event http_header(c: connection, is_orig: bool, name: string, value: string)
	{
	if ( !is_orig ) return;

	if ( c$id !in session_http_info )
		{
		local blah: http_info;
		session_http_info[c$id] = blah;
		}

	if ( name == "REFERER" )
		session_http_info[c$id]$referer = value;

	if ( name == "USER-AGENT" )
		{
		session_http_info[c$id]$user_agent = value;
		if ( addr_matches_hosts(c$id$resp_h, log_user_agents_of) &&
		    (c$id$orig_h !in http_remember_user_agents ||
		     (c$id$orig_h in http_remember_user_agents &&
		      value !in http_remember_user_agents[c$id$orig_h]) ) )
			{
			if ( c$id$orig_h !in http_remember_user_agents )
				http_remember_user_agents[c$id$orig_h] = set();
			add http_remember_user_agents[c$id$orig_h][value];
			print http_ua_log, fmt("%.6f %s %s", network_time(), c$id$orig_h, value);
			}
		}

	if ( name == "HTTP_FORWARDED" ||
	     name == "FORWARDED" ||
	     name == "HTTP_X_FORWARDED_FOR" ||
	     name == "X_FORWARDED_FOR" ||
	     name == "HTTP_X_FORWARDED_FROM" ||
	     name == "X_FORWARDED_FROM" ||
	     name == "HTTP_CLIENT_IP" ||
	     name == "CLIENT_IP" ||
	     name == "HTTP_FROM" ||
	     name == "FROM" ||
	     name == "HTTP_VIA" ||
	     name == "VIA" ||
	     name == "HTTP_XROXY_CONNECTION" ||
	     name == "XROXY_CONNECTION" ||
	     name == "HTTP_PROXY_CONNECTION" ||
	     name == "PROXY_CONNECTION")
		{
		if ( session_http_info[c$id]$proxied_for == "" )
			session_http_info[c$id]$proxied_for = fmt("(%s::%s)", name, value);
		}

	# This is duplicating effort from the http-reply script, but it seems
	# worthwhile to do it here because we don't have to do as many function
	# calls since this is regularly done in http traffic.
	if ( name == "HOST" )
			session_http_info[c$id]$host = value;
	}