package com.netifera.platform.net.internal.services.detection.basic; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.regex.Pattern; import com.netifera.platform.net.services.detection.INetworkServiceDetector; import com.netifera.platform.net.services.detection.INetworkServiceDetectorProvider; import com.netifera.platform.net.services.detection.INetworkServiceTrigger; import com.netifera.platform.util.HexaEncoding; import com.netifera.platform.util.PortSet; import com.netifera.platform.util.patternmatching.ISessionPattern; import com.netifera.platform.util.patternmatching.Regex; import com.netifera.platform.util.patternmatching.SessionPattern; // one class, one dream public class BasicDetectorProvider implements INetworkServiceDetectorProvider { private INetworkServiceDetector newDetector(final String protocol, final PortSet ports, final ISessionPattern pattern) { return new INetworkServiceDetector() { public Map<String, String> detect(String clientData, String serverData) { return pattern.match(clientData, serverData); } public PortSet getPorts() { return ports; } public String getProtocol() { return protocol; } @Override public String toString() { return ports.toString() + "/" + protocol + "\n" + pattern.toString(); } }; } private INetworkServiceDetector newDetector(String protocol, ISessionPattern detector) { return newDetector(protocol, new PortSet("0-65535"), detector); } private INetworkServiceDetector newDetector(String protocol, PortSet ports, String triggerPattern, String responsePattern, String serviceType, String product, Object versionGroup, Object os) { Regex triggerRegex = new Regex(triggerPattern); Regex responseRegex = new Regex(responsePattern); responseRegex.add("serviceType", serviceType); responseRegex.add("product", product); if (os instanceof String) { responseRegex.add("os", (String)os); if (((String) os).matches(".*indow.*")) responseRegex.add("arch", "i386"); // FIXME x86_64 } else if (os instanceof Integer) { responseRegex.add((Integer)os, "os"); } if (versionGroup != null) { if (versionGroup instanceof String) { responseRegex.add("version", (String)versionGroup); } else if (versionGroup instanceof Integer) { responseRegex.add((Integer)versionGroup, "version"); } } return newDetector(protocol,ports,new SessionPattern(triggerRegex, responseRegex)); } private INetworkServiceDetector newDetector(String protocol, PortSet ports, Pattern triggerPattern, Pattern responsePattern, String serviceType, String product, Object versionGroup, Object os) { Regex triggerRegex = new Regex(triggerPattern); Regex responseRegex = new Regex(responsePattern); responseRegex.add("serviceType", serviceType); responseRegex.add("product", product); if (os instanceof String) { responseRegex.add("os", (String)os); if (((String) os).matches(".*indow.*")) responseRegex.add("arch", "i386"); } else if (os instanceof Integer) { responseRegex.add((Integer)os, "os"); } if (versionGroup != null) { if (versionGroup instanceof String) { responseRegex.add("version", (String)versionGroup); } else if (versionGroup instanceof Integer) { responseRegex.add((Integer)versionGroup, "version"); } } return newDetector(protocol,ports,new SessionPattern(triggerRegex, responseRegex)); } private INetworkServiceDetector newDetector(String protocol, String triggerPattern, String responsePattern, String serviceType, String product, Object versionGroup, Object os) { return newDetector(protocol, new PortSet("0-65535"), triggerPattern, responsePattern, serviceType, product, versionGroup, os); } private INetworkServiceDetector newDetector(String protocol, Pattern triggerPattern, Pattern responsePattern, String serviceType, String product, Integer versionGroup, Object os) { return newDetector(protocol, new PortSet("0-65535"), triggerPattern, responsePattern, serviceType, product, versionGroup, os); } private INetworkServiceTrigger newTrigger(final String protocol, final PortSet ports, final byte[] bytes) { return new INetworkServiceTrigger() { public byte[] getBytes() { return bytes; } public PortSet getPorts() { return ports; } public String getProtocol() { return protocol; } @Override public String toString() { return ports.toString() + "/" + protocol + " " + HexaEncoding.bytes2hex(bytes); } }; } public List<INetworkServiceDetector> getClientDetectors() { List<INetworkServiceDetector> answer = new ArrayList<INetworkServiceDetector>(); // HTTP proxy Regex regex = Regex.caseInsensitive("^GET http[s]?://.* HTTP/1\\.[01].*User-Agent: ([^\\r\\n]+)[\\r\\n].*"); regex.add("serviceType", "HTTP Proxy"); regex.add(1, "product"); answer.add(newDetector("tcp", new PortSet("80-89,8000-8999,1080-1089,3128"), new SessionPattern(regex, null))); // HTTP regex = Regex.caseInsensitive("^GET .* HTTP/1\\.[01].*User-Agent: ([^\\r\\n]+)[\\r\\n].*"); regex.add("serviceType", "HTTP"); regex.add(1, "product"); answer.add(newDetector("tcp", new PortSet("80"), new SessionPattern(regex, null))); // FTP regex = Regex.caseInsensitive("^USER .*"); regex.add("serviceType", "FTP"); answer.add(newDetector("tcp", new PortSet("21"), new SessionPattern(regex, null))); // SSH regex = Regex.caseInsensitive("^SSH-.*OpenSSH_([\\w.]+)\\s+([^\\x00\\r\\n]*).*"); regex.add("serviceType", "SSH"); regex.add("product", "OpenSSH"); regex.add(1, "version"); regex.add(2, "os"); answer.add(newDetector("tcp", new SessionPattern(regex, null))); regex = Regex.caseInsensitive("^SSH-\\d\\.\\d-([^\\r\\n\\x00]*)"); regex.add("serviceType", "SSH"); regex.add(1, "product"); answer.add(newDetector("tcp", new SessionPattern(regex, null))); // POP3 regex = Regex.caseInsensitive("^USER .*"); regex.add("serviceType", "POP3"); answer.add(newDetector("tcp", new PortSet("110"), new SessionPattern(regex, null))); // MSN regex = new Regex("^VER \\d+ MSN.*CVR \\d+ [^ ]* (.*) (MSN[^ ]*) ([\\d.]*) .*USR \\d+ [^ ]* . ([^\\r\\n]+)[\\r\\n].*"); regex.add("serviceType", "MSN"); regex.add(1, "os"); regex.add(2, "product"); regex.add(3, "version"); regex.add(4, "username"); answer.add(newDetector("tcp", new PortSet("1863"), new SessionPattern(regex, null))); // Jabber (Google Talk) regex = new Regex("^<\\?xml version='1\\.0' \\?><stream:stream to\\='gmail.com' .*"); regex.add("serviceType", "Jabber"); regex.add("product", "Google Talk"); answer.add(newDetector("tcp", new PortSet("5222"), new SessionPattern(regex, null))); // IRC regex = new Regex("^^NICK ([^\\r\\n]+)[\\r\\n].*"); regex.add("serviceType", "IRC"); regex.add(1, "username"); answer.add(newDetector("tcp", new SessionPattern(regex, null))); // Telnet regex = Regex.caseInsensitive("^(\\xff[\\xfb\\xfc\\xfd].)+.*"); // IAC + (WILL|WONT|DO) // TODO 'SB' option? regex.add("serviceType", "Telnet"); answer.add(newDetector("tcp", new SessionPattern(regex, null))); // Sun RPC Call // FIXME these detectors are too generic, they match netbios /* answer.add(newDetector("udp", ".*", "^.{4}" // XID + "\\x00\\x00\\x00\\x00" // Call + "\\x00\\x00\\x00." // version + ".{4}" // program + "\\x00\\x00\\x00." // program version + "\\x00\\x00...*", // procedure "RPC", null, null, null)); answer.add(newDetector("tcp", ".*", "^(.{4})?" // fragment? + ".{4}" // XID + "\\x00\\x00\\x00\\x00" // Call + "\\x00\\x00\\x00." // version + ".{4}" // program + "\\x00\\x00\\x00." // program version + "\\x00\\x00...*", // procedure "RPC", null, null, null)); */ // SSL answer.add(newDetector("tcp", ".*", "^\\x16" + // Handshake "\\x03\\x01" + // TLS 1.0 ".." + // len // Handshake "\\x01" + // Client Hello "..." + // len "\\x03\\x01" + // TLS 1.0 ".*", "SSL", null, "TLSv1", null)); answer.add(newDetector("tcp", ".*", "^\\x16" + // Handshake "\\x03\\x00" + // SSL 3.0 ".." + // len // Handshake "\\x01" + // Client Hello "..." + // len "\\x03\\x00" + // SSL 3.0 ".*", "SSL", null, "SSLv3", null)); // DNS // FIXME /* answer.add(newDetector("tcp", ".*", "^.." + // len ".." + // id "\\x00." + // flags (Query) // FIXME auth? ".." + // q "\\x00\\x00...." + //RRs "(\\x03\\w+)+\\x00" + // name "\\x00\\xfc" + // AXFR // XXX "\\x00\\x01" + // Internet ".*", // FIXME "DNS", null, null, null)); */ // Real Time Streaming Protocol regex = Regex.caseInsensitive("^\\p{Upper}+ rtsp:\\/\\/ RTSP/1\\.0.*User-Agent: ([^\\r\\n]+)[\\r\\n].*"); regex.add("serviceType", "RTSP"); regex.add(1, "product"); answer.add(newDetector("tcp", new SessionPattern(regex, null))); /* // Radius answer.add(newDetector("udp", new PortSet("1812"), ".*", "^\\x01" + // AccessRequest "." + // ID "\\x00." + // len ".{16}.*", // authentificator, ... "Radius", null, null, null)); // TODO version // ISAKMP answer.add(newDetector("udp", new PortSet("500"), ".*", "^.{16}" // 2 cookies + ".\\x10.{10}.*", // payload, version (0x10 = 1.0), type + flags + id + len "ISAKMP", null, null, null)); // TODO version */ return answer; } @SuppressWarnings("boxing") public List<INetworkServiceDetector> getServerDetectors() { List<INetworkServiceDetector> answer = new ArrayList<INetworkServiceDetector>(); // SSH // FIXME james: regex matching major.minor version? answer.add(newDetector("tcp", ".*", "^SSH-.*dropbear_([.\\w]+).*", "SSH", "Dropbear", 1, null)); answer.add(newDetector("tcp", ".*", "^SSH-.*Sun_SSH.*", "SSH", null, null, "SunOS")); answer.add(newDetector("tcp", ".*", "^SSH-.*OSU.*", "SSH", null, null, "OpenVMS")); // TODO get proc type? // james answer.add(newDetector("tcp", ".*", "^SSH-.*OpenSSH_([.\\w]+).*", "SSH", "OpenSSH", 1, null)); answer.add(newDetector("tcp", ".*", "^SSH-.*Cisco-(\\d+\\.\\d+).*", "SSH", "Cisco SSH", 1, "Cisco IOS")); answer.add(newDetector("tcp", ".*", "^SSH-.*", "SSH", null, null, null)); // FTP // see http://en.wikipedia.org/wiki/List_of_FTP_servers answer.add(newDetector("tcp", ".*", "^220.*FileZilla Server version (\\d[-.\\w ]+)\\r\\n.*", "FTP", "FileZilla", 1, "Windows")); answer.add(newDetector("tcp", ".*", "^220.*Microsoft FTP Service \\(Version (\\d[^)]+).*", "FTP", "Microsoft FTPD", 1, "Windows")); answer.add(newDetector("tcp", ".*", "^220[ -]Microsoft FTP Service\\r\\n.*", "FTP", "Microsoft FTPD", null, "Windows")); answer.add(newDetector("tcp", ".*", "^220[ -]Serv-U FTP[ -]Server v(\\d\\S+) ... WinSock .*", "FTP", "Serv-U FTPD", 1, "Windows")); answer.add(newDetector("tcp", ".*", "^220-Serv-U FTP Server for Winsock\\r\\n.*", "FTP", "Serv-U FTPD", null, "Windows")); answer.add(newDetector("tcp", ".*", "^220-SECURE FTP SERVER VERSION ([\\d.]+).*", "FTP", "Serv-U FTPD", null, "Windows")); answer.add(newDetector("tcp", ".*", "^220[- ].*FTP server \\(Version (wu-[-.\\w]+).*", "FTP", "WU-FTPD", 1, "Unix")); answer.add(newDetector("tcp", ".*", "^220-\\r\\n220 .* FTP server \\(Version ([-.+\\w()]+)\\) ready\\.\\r\\n.*", "FTP", "WU-FTPD", 1, "Unix")); answer.add(newDetector("tcp", ".*", "^220 ProFTPD (\\d\\S+) Server.*", "FTP", "ProFTPD", 1, "Unix")); answer.add(newDetector("tcp", ".*", "^220 .*ProFTP.*", "FTP", "ProFTPD", null, "Unix")); answer.add(newDetector("tcp", ".*", "^220 \\(vsFTPd ([-.\\w]+)\\)\\r\\n.*", "FTP", "vsftpd", 1, "Unix")); answer.add(newDetector("tcp", ".*", "^220 .* FTP server \\(GNU inetutils ([\\d.]+)\\) ready\\.\\r\\n.*", "FTP", "GNU inetutils", 1, "Unix")); answer.add(newDetector("tcp", ".*", "^220 Cisco \\(([\\d.]+)\\) FTP server ready\\r\\n.*", "FTP", "Cisco FTPD", 1, "Cisco IOS")); answer.add(newDetector("tcp", ".*", "^220 .* Server \\(vftpd ([\\d.]+)\\) ready\\.\\r\\n.*", "FTP", "VFTPD", 1, "Windows")); answer.add(newDetector("tcp", ".*", "^220 .*\\(Version (\\d.\\d)/OpenBSD.*", "FTP", "OpenBSD FTPD", 1, "OpenBSD")); // XXX or can it run in other OS too? answer.add(newDetector("tcp", ".*", "^220---------- Welcome to Pure-FTPd (\\[\\p{Alpha}+\\] )*----------\\r\\n.*", "FTP", "Pure-FTPd", null, null)); answer.add(newDetector("tcp", ".*", "^220 .* FTP server \\(Compaq Tru64 UNIX Version ([\\d.]+)\\) ready\\.\\r\\n.*", "FTP", "Compaq FTPD", 1, "Tru64")); // FIXME isn't it OS version? answer.add(newDetector("tcp", ".*", "^220-[A-Z0-9]*FTP[A-Z0-9]*1 IBM FTP CS(:?\\/\\d+)? (V\\d+R[\\d+\\.]+) at .*, [\\d:]+ on [\\d-]+\\.\\r\\n.*", "FTP", "IBM FTP", 1, "z/OS")); // TODO use R(elease) to detect AS/400, OS/390, z/OS // james answer.add(newDetector("tcp", ".*", "^220-[A-Z0-9]*FTP[A-Z0-9]*1 IBM VM Level (\\d+) at .*, [\\d:]+ .*\\r\\n.*", "FTP", "IBM FTP", 1, "z/VM")); answer.add(newDetector("tcp", ".*", "^220 HP ARPA FTP Server \\[.{8}\\] \\(C\\) Hewlett-Packard .*\\r\\n.*", "FTP", "HP ARPA FTP", null, "HP-UX")); // TODO OS version? // james answer.add(newDetector("tcp", ".*", "^220 MPE\\/iX File Transfer Protocol Server \\[.{8}\\] \\(C\\) Hewlett-Packard .*\\r\\n.*", "FTP", "HP MPE/iX FTP", null, "HP-UX")); // TODO OS version? // james answer.add(newDetector("tcp", ".*", "^220 JD FTP Server Ready.?\\r\\n.*", "FTP", "Hewlett-Packard FTP Print Server", null, "HP Jetdirect Printer")); answer.add(newDetector("tcp", ".*", "^220 .* FTP server \\((?:Revision [\\d.]+ )?Version wuftpd-([^ ]+).*\\) ready\\.\\r\\n.*", "FTP", "WU-FTPD", 1, null)); // TODO fingerprint OS by build version answer.add(newDetector("tcp", ".*", "^220-QTCP at .*", "FTP", "FTP", null, "AS/400")); // TODO get hostname answer.add(newDetector("tcp", Pattern.compile("^USER .*\n.*", Pattern.MULTILINE|Pattern.DOTALL|Pattern.CASE_INSENSITIVE), Pattern.compile("^220.*\n(331|530).*", Pattern.MULTILINE|Pattern.DOTALL), "FTP", null, null, null)); answer.add(newDetector("tcp", Pattern.compile(".*"), Pattern.compile("^220.*FTP.*", Pattern.MULTILINE|Pattern.DOTALL|Pattern.CASE_INSENSITIVE), "FTP", null, null, null)); answer.add(newDetector("tcp", new PortSet("21"), ".*", "^220.*", "FTP", null, null, null)); // IMAP answer.add(newDetector("tcp", ".*", "^\\* OK [-.\\w]+ IMAP4rev1 MDaemon (\\d[-.\\w]+) .*", "IMAP", "Alt-N MDaemon", 1, "Windows")); answer.add(newDetector("tcp", ".*", "^\\* OK Domino IMAP4 Server Release (\\d[-.\\w]+) +ready.*", "IMAP", "Lotus Domino", 1, null)); answer.add(newDetector("tcp", ".*", "^\\* OK Domino IMAP4 Server Build V([\\w_]+ Beta \\w+) ready.*", "IMAP", "Lotus Domino", 1, null)); answer.add(newDetector("tcp", ".*", "^\\* OK Microsoft Exchange IMAP4rev1 server version ([-.\\w]+) .*", "IMAP", "Microsoft Exchange IMAP4rev1 server", 1, "Windows")); answer.add(newDetector("tcp", ".*", "^\\* OK Microsoft Exchange 2000 IMAP4rev1 server version (\\d[-.\\w]+) \\([-.\\w]+\\) ready\\.\\r\\n.*", "IMAP", "Microsoft Exchange 2000 IMAP4rev1 server", 1, "Windows")); // XXX second group is OS? what format? answer.add(newDetector("tcp", ".*", "^\\* OK Microsoft Exchange .*", "IMAP", "Microsoft Exchange IMAP server", null, "Windows")); answer.add(newDetector("tcp", ".*", "^\\* OK IMAP4rev1 server ready at \\d\\d/\\d\\d/\\d\\d \\d\\d:\\d\\d:\\d\\d \\r\\n.*", "IMAP", "MailEnable Professional", null, "Windows")); answer.add(newDetector("tcp", ".*", "^\\* OK.* Courier.*IMAP.*", "IMAP", "Courier", null, null)); answer.add(newDetector("tcp", ".*", "^\\* OK.*[Dd]ovecot.*", "IMAP", "Dovecot", null, "Unix")); answer.add(newDetector("tcp", ".*", "^\\* OK CommuniGate Pro IMAP Server ([\\w.]+) .*ready.*", "IMAP", "CommuniGate Pro", 1, null)); answer.add(newDetector("tcp", ".*", "^\\* OK.*", "IMAP", null, null, null)); // TOR answer.add(newDetector("tcp", "^GET /tor/(server|status)/.*\\r\\nHost: .*\\r\\n\\r\\n$", "^HTTP/1\\.0 200 OK.*application/octet[_\\-]stream.*", "TOR", null, null, null)); answer.add(newDetector("tcp", ".*", "^HTTP/1\\.0 503 Directory busy, try again later.*", "TOR", null, null, null)); answer.add(newDetector("tcp", ".*", "^HTTP/1\\.0 200 OK.*signed-directory.*published.*nrecommended-software.*", "TOR", null, null, null)); // HTTP Proxy answer.add(newDetector("tcp", "^CONNECT .*", "^HTTP/1\\.[01](200|503).*", "HTTP Proxy", null, null, null)); Regex regex = Regex.caseInsensitive("^HTTP/1\\.[01].*Proxy-Agent: ([^\\r\\n]*)[\\r\\n].*"); regex.add("serviceType", "HTTP Proxy"); regex.add(1, "product"); answer.add(newDetector("tcp", new SessionPattern(null, regex))); // HTTP answer.add(newDetector("tcp", ".*Host: ([^\\r\\n]+)[\\r\\n].*", "^HTTP/1\\.0 \\d\\d\\d .*\\r\\nServer: Tomcat Web Server/(\\d[-.\\w ]+) \\( ([^)]+) \\)\\r\\n.*", "HTTP", "Apache Tomcat", 1, 2)); answer.add(newDetector("tcp", ".*", "^HTTP/1\\.0 \\d\\d\\d .*\\r\\nServer: Tomcat Web Server/(\\d[-.\\w ]+)\\r\\n\\r\\n.*", "HTTP", "Apache Tomcat", 1, null)); // FIXME ' ' answer.add(newDetector("tcp", ".*", "^HTTP/1\\.0 \\d\\d\\d .*\\r\\nServlet-Engine: Tomcat Web Server/(\\d[-.\\w]+) .*", "HTTP", "Apache Tomcat", 1, null)); answer.add(newDetector("tcp", ".*", "^HTTP/1\\.[01].*Server: Apache\\/([-.\\w]+) +HP-UX_Apache-based_Web_Server.*\\r\\n.*", "HTTP", "HP-UX Apache", 1, "HP-UX")); answer.add(newDetector("tcp", ".*", "^HTTP/1\\.[01].*Server: HP-UX_Apache-based_Web_Server\\/([-.\\w]+) .*\\r\\n.*", "HTTP", "HP-UX Apache", 1, "HP-UX")); answer.add(newDetector("tcp", ".*", "^HTTP/1\\.[01].*[Ss]erver: IBM_HTTP_Server.* Apache\\/([^ \\t\\r\\n]+).*\\r\\n.*", "HTTP", "IBM Apache", 1, null)); // FIXME IBM_HTTP_Server version? answer.add(newDetector("tcp", ".*", "^HTTP/1\\.[01].*[Ss]erver: IBM_HTTP_Server.*", "HTTP", "IBM Apache", null, null)); answer.add(newDetector("tcp", ".*", "^HTTP/1\\.[01].*Server: Rapidsite\\/Apa\\/([^ \\t\\r\\n]+).*", "HTTP", "Rapidsite Apache", 1, "HP-UX")); // HP-UX 11i Apache-based Web Server answer.add(newDetector("tcp", ".*", "^HTTP/1\\.[01].*Server: MIT Web Server Apache\\/([^ \\t\\r\\n]+).*\\r\\n.*", "HTTP", "MIT Apache", 1, null)); // FIXME IBM_HTTP_Server version? answer.add(newDetector("tcp", ".*", "^HTTP/1\\.[01].*Server: Apache\\/([^ \\t\\r\\n]+).*\\r\\n.*", "HTTP", "Apache", 1, null)); // FIXME IBM_HTTP_Server version? answer.add(newDetector("tcp", ".*", "^HTTP/1\\.[01].*Server: Apache.*", "HTTP", "Apache", null, null)); answer.add(newDetector("tcp", ".*", "^HTTP/1\\.[01].*\\r\\nServer: Microsoft-IIS/([-.\\w]+)\\r\\n.*", "HTTP", "Microsoft IIS", 1, "Windows")); answer.add(newDetector("tcp", ".*", "^HTTP/1\\.[01].*\\r\\nServer: mini_httpd/(\\d+\\.\\d+).*", "HTTP", "Acme mini_httpd", 1, null)); answer.add(newDetector("tcp", ".*", "^HTTP/1\\.[01].*level.15.*", "HTTP", "Cisco IOS", null, "Cisco IOS")); answer.add(newDetector("tcp", ".*", "^HTTP/1\\.[01].*\\r\\nServer: cisco-IOS.*", "HTTP", "Cisco IOS", null, "Cisco IOS")); answer.add(newDetector("tcp", ".*", "^HTTP/1\\.0 \\d+ [\\w ]+\\r\\n.*\\r\\nExpires: Thu, 16 Feb 1989 00:00:00 GMT(\\r\\n){2}.*", "HTTP", "Cisco IOS", null, "Cisco IOS")); answer.add(newDetector("tcp", ".*", "^HTTP/1\\.[01].*Server: lighttpd/([-.\\w]+)\\r\\n.*", "HTTP", "lighttpd", 1, null)); answer.add(newDetector("tcp", ".*", "^HTTP/1\\.[01].*Server: nginx/([-.\\w]+)\\r\\n.*", "HTTP", "nginx", 1, null)); answer.add(newDetector("tcp", ".*", "^HTTP/1\\.[01].*Server: Mongrel ([-.\\w]+)\\r\\n.*", "HTTP", "Mongrel", 1, null)); answer.add(newDetector("tcp", ".*", "^HTTP/1\\.[01].*Server: Lotus-Domino\\r\\n.*", "HTTP", "Lotus Domino", null, null)); answer.add(newDetector("tcp", ".*", "^HTTP/1\\.[01].*Server: Cerberian Service\\r\\n.*", "HTTP", "Cerberian", null, null)); //answer.add(newDetector("tcp", ".*", "^HTTP/1\\.[01].*Server: ENI-Web/([^ \\t\\r\\n]+).*\\r\\n.*", "HTTP", "ENI", 1, null)); answer.add(newDetector("tcp", ".*", "^HTTP/1\\.[01].*Server: AV-TECH (.*) Video Web Server\\n.*", "HTTP", "AV-TECH Video", null, 1)); // FIXME OS answer.add(newDetector("tcp", ".*", "^HTTP/1\\.[01].*Server: JRun Web Server\\/([\\d.]+)\\r\\n.*", "HTTP", "Adobe JRun", 1, null)); // J2EE application server answer.add(newDetector("tcp", ".*", "^HTTP/1\\.[01].*Server: NetPort Software ([\\d.]+)\\r\\n.*", "HTTP", "Intel NetPort", 1, "Windows")); answer.add(newDetector("tcp", ".*", "^HTTP/1\\.1 403 Forbidden \\( The server denied the specified Uniform Resource Locator \\(URL\\). Contact the server administrator. \\)\\r\\n.*", "HTTP", "Microsoft IIS with ISA Server", null, "Windows")); answer.add(newDetector("tcp", ".*", "^HTTP/1\\.[01].*\\r\\nServer: HTTPd-WASD\\/(\\d\\.\\d\\.\\d) [\\w\\/]+( \\w+)?\\r\\n.*", "HTTP", "WASD", 1, "OpenVMS")); // TODO proc regex = Regex.caseInsensitive("^HTTP/1\\.[01].*\\r\\nServer: (HP.Chai\\w+)\\/([\\d.]+)\\r\\n.*"); // FIXME not only Jetdirect? regex.add("serviceType", "HTTP"); regex.add(1, "product"); regex.add(2, "version"); regex.add("os", "HP Printer"); answer.add(newDetector("tcp", new SessionPattern(null, regex))); answer.add(newDetector("tcp", new SessionPattern(null, regex))); //regex = Regex.caseInsensitive("^HTTP/1\\.[01].*\\r?\\n[Ss]erver: ([^\\/ \\t\\r\\n]+)(?i:-?Web)? *(?i:Server)?\\/([^ \\/\\t\\r\\n]+).*\\r?\\n.*"); regex = Regex.caseInsensitive("^HTTP/1\\.[01].*\\r?\\n[Ss]erver: ([^\\/ \\t\\r\\n]+)\\/([^ \\/\\t\\r\\n]+).*\\r?\\n.*"); regex.add("serviceType", "HTTP"); regex.add(1, "product"); regex.add(2, "version"); answer.add(newDetector("tcp", new SessionPattern(null, regex))); // FIXME //regex = Regex.caseInsensitive("^HTTP/1\\.[01].*\\r?\\n[Ss]erver: +([\\p{Graph} ]+)(:?\\/.*)?\\r?\\n.*"); // FIXME space ' '? regex = Regex.caseInsensitive("^HTTP/1\\.[01].*\\r?\\n[Ss]erver: +([^\\/\\t\\r\\n ][^\\/\\t\\r\\n]*)(:?\\/.*)?\\r?\\n.*"); regex.add("serviceType", "HTTP"); regex.add(1, "product"); answer.add(newDetector("tcp", new SessionPattern(null, regex))); /* Regex clientRegex = Regex.caseInsensitive(".*(Host: ([^\\r\\n]+)[\\r\\n])?.*"); clientRegex.add(2, "hostname"); regex = Regex.caseInsensitive("^HTTP/1\\.[01].*(Server: ([^\\r\\n]+)[\\r\\n])?.*"); regex.add("serviceType", "HTTP"); regex.add(2, "product"); answer.add(newDetector("tcp", new SessionPattern(null, regex))); */ answer.add(newDetector("tcp", ".*", "^HTTP/1\\.[01].*", "HTTP", null, null, null)); // HTTPS // FIXME has sens? not better HTTP + TLSv1|SSL tag? answer.add(newDetector("tcp", ".*", ".*<title>400 Bad Request<\\/title>.*Your browser sent a request that this server could not understand\\..*", "HTTPS", "Apache", null, null)); // Real Time Streaming Protocol regex = Regex.caseInsensitive("^RTSP/1\\.0.*\\r\\nServer: QTSS\\/([\\d.]+) \\(.*Build\\/([^;]+);.*Platform\\/([^;]+).*\\)\\r\\n.*"); regex.add("serviceType", "RTSP"); regex.add("product", "QuickTime Streaming Server"); // Apple's commercial streaming server delivered as part of Mac OS X Server regex.add(1, "version"); regex.add(2, "build"); regex.add(3, "os"); // MacOSX answer.add(newDetector("tcp", new SessionPattern(null, regex))); regex = Regex.caseInsensitive("^RTSP/1\\.0.*\\r\\nServer: DSS\\/([\\d.]+) \\(.*Build\\/([^;]+);.*Platform\\/([^;]+).*\\)\\r\\n.*"); regex.add("serviceType", "RTSP"); regex.add("product", "Darwin Streaming Server"); regex.add(1, "version"); regex.add(2, "build"); regex.add(3, "os"); // Windows, Linux, and Solaris answer.add(newDetector("tcp", new SessionPattern(null, regex))); // POP3 regex = new Regex("^\\+OK <.*@([-.\\w]+)>.*XMail ([\\d-.]+) .*"); regex.add("serviceType", "POP3"); regex.add("product", "XMail"); regex.add(2, "version"); regex.add(1, "hostname"); regex.add("os", "Windows"); answer.add(newDetector("tcp", new SessionPattern(null, regex))); answer.add(newDetector("tcp", ".*", "^\\+OK Welcome to MailEnable POP3 Server.*", "POP3", "MailEnable", null, "Windows")); answer.add(newDetector("tcp", ".*", "^\\+OK.*MailEnable.*POP3.*", "POP3", "MailEnable", null, "Windows")); answer.add(newDetector("tcp", ".*", "^\\+OK ready <\\d{1,5}\\.10\\d{8}@([-.\\w]+)>\\r\\n.*", "POP3", "Qualcomm Qpopper pop3d", null, null)); answer.add(newDetector("tcp", ".*", "^\\+OK Lotus Notes POP3 server version ([-.\\w]+) ready.*", "POP3", "Lotus Domino", 1, null)); answer.add(newDetector("tcp", ".*", "^\\+OK Lotus Notes POP3 server version Release ([-.\\w]+) ready.*", "POP3", "Lotus Domino", 1, null)); answer.add(newDetector("tcp", ".*", "^\\+OK.*Lotus Notes POP3.*", "POP3", "Lotus Domino", null, null)); answer.add(newDetector("tcp", ".*", "^\\+OK Microsoft Exchange Server 2003 POP3 server version ([\\d.]+) \\(([\\w-_.]+)\\) ready\\.\\r\\n.*", "POP3", "Microsoft Exchange 2003 POP3D", 1, "Windows")); // XXX 2nd group is OS?what format? answer.add(newDetector("tcp", ".*", "^\\+OK Microsoft Exchange 2000 POP3 server version (\\S+).* ready\\.\\r\\n.*", "POP3", "Microsoft Exchange 2000 POP3", 1, "Windows")); answer.add(newDetector("tcp", ".*", "^\\+OK Microsoft Exchange POP3 server version (\\S+) ready\\r\\n.*", "POP3","Microsoft Exchange POP3D", 1, "Windows")); answer.add(newDetector("tcp", ".*", "^\\+OK.*Exchange.*POP3.*", "POP3", "Microsoft Exchange POP3", null, "Windows")); // XXX 2nd group is OS?what format? answer.add(newDetector("tcp", ".*", "^\\+OK ([-.\\w]+) POP MDaemon (\\S+) ready <MDAEMON.*", "POP3", "MDaemon", 2, "Windows")); answer.add(newDetector("tcp", ".*", "^\\+OK ([-.\\w]+) POP MDaemon ready using UNREGISTERED SOFTWARE ([\\d.]+) <MDAEMON.*", "POP3", "MDaemon", 2, "Windows")); answer.add(newDetector("tcp", ".*", "^\\+OK.*POP MDaemon.*", "POP3", "MDaemon", null, "Windows")); answer.add(newDetector("tcp", ".*", "^\\+OK GroupWise POP3 server ready\\r\\n.*", "POP3", "Novell GroupWise", null, null)); answer.add(newDetector("tcp", ".*", "^\\+OK Qpopper \\(version ([\\d.]+)\\) at .* starting\\..*", "POP3", "Qpopper", 1, null)); answer.add(newDetector("tcp", ".*", "^\\+OK.*[Dd]ovecot.*", "POP3", "Dovecot", null, "Unix")); regex = new Regex("^\\+OK <.*@([-.\\w]+)>.*"); regex.add("serviceType", "POP3"); regex.add(1, "hostname"); answer.add(newDetector("tcp", new PortSet("110"), new SessionPattern(null, regex))); answer.add(newDetector("tcp", new PortSet("110"), ".*", "^\\+OK.*", "POP3", null, null, null)); // SMTP regex = new Regex("^220[ -]([-.\\w]+) .*Sendmail ([-.\\w]+)/.*"); regex.add("serviceType", "SMTP"); regex.add("product", "Sendmail"); regex.add(2, "version"); regex.add(1, "hostname"); answer.add(newDetector("tcp", new SessionPattern(null, regex))); regex = new Regex("^220.*Sendmail ([-.\\w]+)/.*"); // can this happen? no hostname regex.add("serviceType", "SMTP"); regex.add("product", "Sendmail"); regex.add(1, "version"); answer.add(newDetector("tcp", new SessionPattern(null, regex))); answer.add(newDetector("tcp", ".*", "^220.*Sendmail.*", "SMTP", "Sendmail", null, null)); answer.add(newDetector("tcp", ".*", "^220.*MailGate.*", "SMTP", "MailGate", null, "Windows")); regex = new Regex("^220 <.*@([-.\\w]+)>.*XMail ([\\d-.]+) .*"); regex.add("serviceType", "SMTP"); regex.add("product", "XMail"); regex.add(2, "version"); regex.add(1, "hostname"); regex.add("os", "Windows"); answer.add(newDetector("tcp", new SessionPattern(null, regex))); answer.add(newDetector("tcp", ".*", "^220.*XMail.*", "SMTP", "XMail", null, "Windows")); regex = new Regex("^220[ -]([-.\\w]+) ESMTP MDaemon (\\d[-.\\w]+);.*"); regex.add("serviceType", "SMTP"); regex.add("product", "MDaemon"); regex.add(2, "version"); regex.add(1, "hostname"); regex.add("os", "Windows"); answer.add(newDetector("tcp", new SessionPattern(null, regex))); regex = new Regex("^220[ -]([-.\\w]+) Kerio MailServer ([-.\\w]+) ESMTP.*"); regex.add("serviceType", "SMTP"); regex.add("product", "Kerio"); regex.add(2, "version"); regex.add(1, "hostname"); // regex.add("os", "Windows"); answer.add(newDetector("tcp", new SessionPattern(null, regex))); regex = new Regex("^220[ -]([-.\\w]+) Microsoft E?SMTP MAIL Service, Version: ([-.\\w]+) ready.*"); regex.add("serviceType", "SMTP"); regex.add("product", "Microsoft Exchange"); regex.add(2, "version"); regex.add(1, "hostname"); regex.add("os", "Windows"); answer.add(newDetector("tcp", new SessionPattern(null, regex))); regex = new Regex("^220[ -]([-.\\w]+) Mercury/32 v([-.\\w]+) ESMTP server ready.*"); regex.add("serviceType", "SMTP"); regex.add("product", "Mercury/32"); regex.add(2, "version"); regex.add(1, "hostname"); regex.add("os", "Windows"); answer.add(newDetector("tcp", new SessionPattern(null, regex))); regex = new Regex("^220[ -]([-.\\w]+) .*[Pp]ost[Ff]ix.*"); regex.add("serviceType", "SMTP"); regex.add("product", "Postfix"); regex.add(1, "hostname"); answer.add(newDetector("tcp", new SessionPattern(null, regex))); regex = new Regex("^220[ -]([-.\\w]+) E?SMTP \\(spam is not appreciated\\)\\r\\n.*"); regex.add("serviceType", "SMTP"); regex.add(1, "hostname"); regex.add("product", "Postfix"); answer.add(newDetector("tcp", new SessionPattern(null, regex))); answer.add(newDetector("tcp", ".*", "^220.*IMail.*", "SMTP", "IMail", null, "Windows")); answer.add(newDetector("tcp", ".*", "^220.*Exchange.*", "SMTP", "Microsoft Exchange", null, "Windows")); answer.add(newDetector("tcp", ".*", "^220.*MailEnable.*", "SMTP", "MailEnable", null, "Windows")); answer.add(newDetector("tcp", ".*", "^220.*Lotus Domino.*", "SMTP", "Lotus Domino", null, null)); answer.add(newDetector("tcp", ".*", "^220[ -].* ESMTP Exim ([\\d.]+) .*\\r\\n.*", "SMTP", "Exim", 1, null)); // TODO save compilation date in a tag answer.add(newDetector("tcp", ".*", "^220.*[Pp]ost[Ff]ix.*", "SMTP", "Postfix", null, null)); answer.add(newDetector("tcp", ".*", "^220 .* ESMTP \\(spam is not appreciated\\)\\r\\n.*", "SMTP", "Postfix", null, null)); answer.add(newDetector("tcp", ".*", "^220 ([^\\s]+) V([-.\\w]+), (OpenVMS V[-.\\w]+(?: VAX)?) ready.*", "SMTP", "VMS SMTP", 2, 3)); //TODO: add hostname [and arch?] answer.add(newDetector("tcp", ".*", "^220 ([^\\s]+) Symantec Mail Security .*\\r\\n.*", "SMTP", "Symantec Mail Security for Microsoft Exchange", null, "Windows")); regex = new Regex("^220[ -]([-.\\w]+) E?SMTP.*"); regex.add("serviceType", "SMTP"); regex.add(1, "hostname"); answer.add(newDetector("tcp", new SessionPattern(null, regex))); answer.add(newDetector("tcp", Pattern.compile(".*"), Pattern.compile("^(220.*\n250|220.*SMTP|412 .*smtp|554.*mail|554.*smtp|220 .*mail).*", Pattern.MULTILINE|Pattern.DOTALL|Pattern.CASE_INSENSITIVE), "SMTP", null, null, null)); answer.add(newDetector("tcp", new PortSet("25"), ".*", "^220.*", "SMTP", null, null, null)); // MySQL answer.add(newDetector("tcp", ".*", "^.\\x00\\x00\\x00\\x0a([-\\w._]*)\\x00.*", "MySQL", "MySQL", 1, null)); // (access not allowed from this host, should tag) answer.add(newDetector("tcp", ".*", "^.\\x00\\x00\\x00\\xff\\x6a\\x04.*", "MySQL", "MySQL", null, null)); // MISC answer.add(new OracleDetector()); answer.add(new MSSQLDetector()); // Remote Desktop (3389) answer.add(newDetector("tcp", ".*", "^\\x03\\x00\\x00[\\x0b\\x11].*", "RDP", null, null, "Windows")); // FIXME no all 3389 are windows! /* Remote Desktop Protocol: - Aqua Connect became the first company to license and implement RDP server for the Mac OS X platform, thus allowing users to connect to the Mac OS X server with Microsoft's RDP. - xrdp is an open source implementation of the RDP server available for Unix-like operating systems. */ // VNC answer.add(newDetector("tcp", "", "^RFB.*", "VNC", null, null, null)); // FIXME "" // DNS version response answer.add(newDetector("udp", ".*", ".*\\x07version\\x04bind.*\\x00\\x10\\x00\\x03\\x00\\x00\\x00\\x00\\x00[\\x04-\\x15][\\x03-\\x14]([-\\w._ ]{3,20}).*", "DNS", "ISC Bind", 1, null)); answer.add(newDetector("udp", ".*", ".*\\x07version\\x04bind.*[\\x03-\\x14]([-\\w._ ]{3,20})$", "DNS", "ISC Bind", 1, null)); answer.add(newDetector("udp", ".*", ".*\\x07version\\x04bind.*[\\x03-\\x14]BIND ([-\\w._]{3,20})$", "DNS", "ISC Bind", 1, null)); answer.add(newDetector("udp", ".*", ".*\\x07version\\x04bind.*", "DNS", null, null, null)); answer.add(newDetector("tcp", ".*", "^.." + // len ".." + // id "\\x80." + // flags (Response) ".{8}" + // q + RRs ".*(\\x00.\\x00\\x01)+.*", // any Internet Type "DNS", null, null, null)); // DNS response answer.add(newDetector("udp", ".*", ".*\\x81\\x80\\x00.\\x00.\\x00.\\x00.*\\x00\\x01\\x00\\x01.*", "DNS", null, null, null)); // DNS response refused (restrict to port 53 because this rule is too generic) answer.add(newDetector("udp", new PortSet("53"), ".*", "^.." + // id "\\x81\\x85" + // flags (Response Refused + Recursion) "\\x00{8}.*", // q + RRs (should be all 0 if refused, right?) "DNS", null, null, null)); // mDNS answer.add(newDetector("udp", new PortSet("5353"), ".*", "^.{4}" + "[\\x00\\x84].{8}.*(i[pP]hone|i[tT]ouch).*", "mDNS", null, null, 1)); answer.add(newDetector("udp", new PortSet("5353"), ".*", "^.{4}" + "[\\x00\\x84].{8}.*", "mDNS", null, null, null)); // TODO review snmp // james // SNMP regex = new Regex(".*public.*\\x2b\\x06\\x01\\x02\\x01\\x01\\x01...(.*)"); regex.add("serviceType", "SNMPv1"); regex.add("password", "public"); regex.add(1, "banner"); answer.add(newDetector("udp", new SessionPattern(null, regex))); regex = new Regex("^0.\\x02\\x01\\x00\\x04\\x06public\\xa2.*"); regex.add("serviceType", "SNMPv1"); regex.add("password", "public"); answer.add(newDetector("udp", new SessionPattern(null, regex))); // XDMCP answer.add(newDetector("udp", ".*", "^\\x00\\x01\\x00\\x05..\\x00\\x00..(\\w+)..(\\d+) user.*", "XDMCP", "dtlogin", 2, "Unix")); answer.add(newDetector("udp", ".*", "^\\x00\\x01\\x00[\\x08\\x0c].{8}.+", "XDMCP", null, null, "Unix")); //answer.add(newDetector("udp", ".*", "^\\x00\\x01\\x00\\x0e.*", "XDMCP", null, null, "Unix")); // UPnP regex = new Regex(".*\\r\\nLocation:\\s*http://(.+):(\\d+)/.*\\r\\nServer:\\s*([^\r]+)\\r\\n.*"); regex.add("serviceType", "UPnP"); regex.add(3, "product"); answer.add(newDetector("udp", new SessionPattern(null, regex))); // Radius 'Access-Reject' packet answer.add(newDetector("udp", new PortSet("1812"), ".*", "^\\x03.*", "Radius", null, null, null)); // SIP answer.add(newDetector("udp", new PortSet("5060"), ".*", "^SIP/2.0 200 OK[\\r\\n].*Server: (.*)[\\r\\n]", "SIP", null, null, null)); // FIXME review regex // james answer.add(newDetector("udp", new PortSet("5060"), ".*", "^SIP/.*", "SIP", null, null, null)); // PCAnywhere answer.add(newDetector("tcp", ".*", "^\\x00X\\x08\\x00\\}\\x08\\r\\n\\x00\\.\\x08.*\\.\\.\\.\\r\\n", "PCAnywhere", "PCAnywhere", null, "Windows")); // IRC answer.add(newDetector("tcp", "^NICK.*", "^NOTICE AUTH.*", "IRC", null, null, null)); answer.add(newDetector("tcp", "^NICK.*", "^:.* \\d\\d\\d .*", "IRC", null, null, null)); answer.add(newDetector("tcp", ".*", "^:Welcome!.+@.+ NOTICE \\* :psyBNC([\\d.-]+)\\r\\n.*", "IRC", "psyBNC", 1, null)); // NetBIOS //FIXME could also be tcp? //FIXME should set OS to Windows? //FIXME we're matching the transaction id 7908 that we send in the trigger, this wont work for passive detection regex = new Regex("^\\x79\\x08.\\x00\\x00\\x00\\x00.*\\x00\\x21\\x00\\x01.{7}([^\\x00]+)\\x00.*"); regex.add("serviceType", "NetBIOS-NS"); regex.add(1, "hostname"); answer.add(newDetector("udp", new SessionPattern(null, regex))); answer.add(newDetector("udp", ".*", "^\\x79\\x08.*BROWSE.*", "NetBIOS-NS", null, null, null)); answer.add(newDetector("udp", ".*", "^\\x79\\x08.\\x00\\x00\\x00\\x00.*", "NetBIOS-NS", null, null, null)); answer.add(newDetector("udp", ".*", "^\\x05\\x00\\x0d\\x03.*", "NetBIOS-SSN", null, null, null)); answer.add(newDetector("udp", ".*", "^\\x83\\x00.*", "NetBIOS-SSN", null, null, null)); answer.add(newDetector("tcp", ".*", "^\\x82\\x00\\x00\\x00.*", "NetBIOS-SSN", null, null, null)); // Microsoft-DS (SMB) //FIXME should set OS to Windows? /* answer.add(newDetector("tcp", ".*", "^\\x00\\x00\\x00.\\xffSMBr\\x00\\x00\\x00\\x00\\x88\\x01@\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00@\\x06\\x00\\x00\\x01\\x00\\x11\\x07\\x00.\n\\x00\\x01\\x00\\x04\\x11\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\xfd\\xe3\\x03\\x00.*", "Microsoft-DS", null, null, "Microsoft Windows Longhorn")); answer.add(newDetector("tcp", ".*", "^\\x00\\x00\\x00.\\xffSMBr\\x00\\x00\\x00\\x00\\x88\\x01@\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00@\\x06\\x00\\x00\\x01\\x00\\x11\\x07\\x00.\n\\x00\\x01\\x00\\x04\\x11\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\xfd\\xe3\\x00\\x00.*", "Microsoft-DS", null, null, "Microsoft Windows XP")); answer.add(newDetector("tcp", ".*", "^\\x00\\x00\\x00.\\xffSMBr\\x00\\x00\\x00\\x00\\x88\\x01@\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00@\\x06\\x00\\x00\\x01\\x00\\x11\\x07\\x00.2\\x00\\x01\\x00\\x04A\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\xfd\\xf3\\x00\\x00.*", "Microsoft-DS", null, null, "Microsoft Windows 2000")); answer.add(newDetector("tcp", ".*", "^\\x00\\x00\\x00.\\xffSMBr\\x00\\x00\\x00\\x00\\x88\\x01@\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00@\\x06\\x00\\x00\\x01\\x00\\x11\\x07\\x00.2\\x00\\x01\\x00\\x04.\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\xfd\\xf3\\x01\\x00.*", "Microsoft-DS", null, null, "Microsoft Windows 2003")); answer.add(newDetector("tcp", ".*", "^\\x00\\x00\\x00.\\xffSMBr\\x00\\x00\\x00\\x00\\x88\\x01@\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00@\\x06\\x00\\x00\\x01\\x00\\x11\\x07\\x00.[}2]\\x00\\x01\\x00\\x04A\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\xfd[\\xe3\\xf3]\\x00\\x00.*", "Microsoft-DS", null, null, "Microsoft Windows 2000")); */ answer.add(newDetector("tcp", ".*", "\\x00\\x00\\x00\\x55\\xff\\x53\\x4d\\x42\\x72\\x00.*", "Microsoft-DS", null, null, null)); answer.add(newDetector("tcp", ".*", "^.....SMB.*", "Microsoft-DS", null, null, null)); answer.add(newDetector("tcp", ".*", "^\\x00\\x00\\x00\\x65.*", "Microsoft-DS", null, null, null)); // RPC Reply //FIXME these detectors are too generic //FIXME we're matching the transaction id 12345678 that we send in the trigger, this wont work for passive detection answer.add(newDetector("udp", ".*", "\\x12\\x34\\x56\\x78" // "^.{4}" // XID + "\\x00\\x00\\x00\\x01" // Reply + "\\x00\\x00\\x00[\\x00\\x01]" // replyState + ".{12}.*", // verifier + acceptState (12x'0' most of the time) "RPC", null, null, null)); answer.add(newDetector("tcp", ".*", "^(.{4})?" // fragment (optional) + "\\x12\\x34\\x56\\x78" // ".{4}" // XID + "\\x00\\x00\\x00\\x01" // Reply + "\\x00\\x00\\x00[\\x00\\x01]" // replyState + ".{12}.*", // verifier + acceptState (12x'0' most of the time) "RPC", null, null, null)); // Telnet // TODO suboption (ff fa .* -> ff f0)? // FIXME is "^(\\xff.*)|$" really useful? answer.add(newDetector("tcp", "^(\\xff.*)|$", "^(?:\\xff[\\xfb\\xfd\\xfe].)+.*(\\r\\n){2}User Access Verification(\\r\\n){2}(Username|Password): .*", "Telnet", null, null, "Cisco")); answer.add(newDetector("tcp", "^(\\xff.*)|$", "^(?:\\xff[\\xfb\\xfd\\xfe].)+.*", "Telnet", null, null, null)); // IAC + (WILL|DO|DON'T) answer.add(newDetector("tcp", "^(\\xff.*)|$", ".*Telnet is disabled now.*", "Telnet", null, null, null)); answer.add(newDetector("tcp", new PortSet("23,2000-2063"), "^(\\xff.*)|$", "^(?:[\\p{Print}\\p{Blank}]*\\r\\n)+[\\p{Print}\\p{Blank}]*", "Telnet", null, null, null)); // 2000-2063: 64 serial lines on a Cisco terminal servers // FIXME not limit to only that range? // TODO "^(?:\\xff[\\xfb\\xfd\\xfe].)+.*(\\r\\n){2}Password required, but none set\\r\\n.*" // TODO "^(?:\\xff[\\xfb\\xfd\\xfe].)+.*(\\r\\n){2}SunOS 5.\\d+\\r\\n.*" // TODO "^(?:\\xff[\\xfb\\xfd\\xfe].)+.*\\r\\nHP-UX\ [^ ]+ (.*)(\\r\\n){2}.*" // Whois answer.add(newDetector("tcp", new PortSet("43"), ".*", ".*Whois.*(?i:server|data).*\\n.*", "Whois", null, null, null)); answer.add(newDetector("tcp", new PortSet("43"), ".*", "^NOTICE AND TERMS OF USE: You are not authorized to access or query our WHOIS\\ndatabase.*", "Whois", null, null, null)); answer.add(newDetector("tcp", new PortSet("43"), ".*", "^\\nquery: .*\\n\\n# KOREAN\\n\\n.*", "Whois", null, null, null)); // SSL answer.add(newDetector("tcp", ".*", "^\\x16" + // Handshake "\\x03\\x01" + // TLS 1.0 ".." + // len // Handshake "\\x02" + // Server Hello "..." + "\\x03\\x01" + // TLS 1.0 ".*", "SSL", null, "TLSv1", null)); // TODO v1.0 answer.add(newDetector("tcp", ".*", "\\x16" +// Handshake "\\x03\\x00" + // SSL 3.0 ".." + // len // Handshake "\\x02" + // Server Hello "..." + "\\x03\\x00" + // SSL 3.0 ".*", "SSL", null, "SSLv3", null)); // LDAP answer.add(newDetector("tcp", new PortSet("389"), ".*", "^0.\\x02\\x01.\\w.*", "LDAP", null, null, null)); // Kerberos v5 answer.add(newDetector("udp", new PortSet("88"), ".*", "^.{10}\\x05.*", "Kerberos", null, "5", null)); // Radius answer.add(newDetector("udp", new PortSet("1812"), ".*", "^[\\x02\\x0b]" + // AccessAccept|AccessChallenge "." + // ID "\\x00." + // len ".{16}.*", // authentificator, ... "Radius", null, null, null)); // TODO version // ISAKMP answer.add(newDetector("udp", new PortSet("500"), ".*", "^.{16}" + // 2 cookies "." + // payload "\\x10" + // version (0x10 = 1.0) ".{10}.*", // type + flags + id + len "ISAKMP", null, null, null)); return answer; } public List<INetworkServiceTrigger> getTriggers() { List<INetworkServiceTrigger> answer = new ArrayList<INetworkServiceTrigger>(); answer.add(newTrigger("tcp", new PortSet("21,990"), "USER ftp\r\n".getBytes())); answer.add(newTrigger("tcp", new PortSet("80,81,88,1080,8000,8080-8081,8118,8888,443"), "GET / HTTP/1.0\r\n\r\n".getBytes())); // answer.add(newTrigger("tcp", new PortSet("1433"), HexaEncoding.hex2bytes("1201003400000000000015000601001b000102001c000c0300280004ff080000c20000004d5353514c53657276657200ac070000"))); answer.add(newTrigger("tcp", new PortSet("3306"), "\n\n\n\n\n".getBytes())); ByteBuffer buffer = ByteBuffer.allocate(512); buffer.put(HexaEncoding.hex2bytes( // TNS Header "005a" + // packet len "0000" + "01" + // packet type CONNECT "00" + "0000" + // Connect Packet "0136 012c 0000 0800 7fff a30a 0000 0100" + "0020" + // len of data "003a" + // offset of data "00000000 00 00 00000000 00000000" + "000006fc00000002" + "0000000000000000" // padding for alignment? )); buffer.put("(CONNECT_DATA=(COMMAND=version))".getBytes()); buffer.flip(); byte[] trigger = new byte[buffer.remaining()]; buffer.get(trigger); answer.add(newTrigger("tcp", new PortSet("1521-1529"), trigger)); // answer.add(newTrigger("tcp", new PortSet("1521"), HexaEncoding.hex2bytes("00 A6 00 00 01 00 00 00 01 34 01 2C 00 00 08 00 7F FF 4F 98 00 00 00 01 00 84 00 22 00 00 00 00 01 01 28 44 45 53 43 52 49 50 54 49 4F 4E 3D 28 43 4F 4E 4E 45 43 54 5F 44 41 54 41 3D 28 53 49 44 3D 74 65 73 74 29 28 43 49 44 3D 28 50 52 4F 47 52 41 4D 3D 29 28 48 4F 53 54 3D 5F 5F 6A 64 62 63 5F 5F 29 28 55 53 45 52 3D 29 29 29 28 41 44 44 52 45 53 53 3D 28 50 52 4F 54 4F 43 4F 4C 3D 74 63 70 29 28 48 4F 53 54 3d 31 36 32 2e 32 37 2e 35 39 2e 31 33 35 29 28 50 4F 52 54 3D 31 35 32 31 29 29 29"))); answer.add(newTrigger("tcp", new PortSet("3389"), HexaEncoding.hex2bytes("0300000b06e00000000000"))); answer.add(newTrigger("tcp", new PortSet("25,465"), "HELO mail\r\n".getBytes())); answer.add(newTrigger("tcp", new PortSet("110,143,995"), "\r\n".getBytes())); // just to get some response // MSSQL answer.add(newTrigger("tcp", new PortSet("1433"), new byte[] { 0x12, 0x01, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x06, 0x01, 0x00, 0x1b, 0x00, 0x01, 0x02, 0x00, 0x1c, 0x00, 0x0c, 0x03, 0x00, 0x28, 0x00, 0x04, (byte) 0xff, 0x08, 0x00, 0x01, 0x55, 0x00, 0x00, 0x00, 0x4d, 0x53, 0x53, 0x51, 0x4c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x00, 0x4e, 0x53, 0x46, 0x4f })); // DNS version answer.add(newTrigger("udp", new PortSet("53"), HexaEncoding.hex2bytes("0006010000010000000000000776657273696f6e0462696e640000100003"))); // RPC proc-0 Call /* 111:rpcbind, 2049:nfs, 4045:nlockmgr * some services are binded below 1024: rquotad, mountd, status (not always respected on Solaris) * repartition is between 600-1000 but closer to mod[100] i.e.: 796,799,809,812,995,998 * Linux repartition is pretty random (up to 65535...) * by default in 32770-32850 on Solaris < 10 */ PortSet rpcPortSet = new PortSet("111,2049,4045,32771-32850"); // TODO add HPUX default portrange answer.add(newTrigger("udp", rpcPortSet, HexaEncoding.hex2bytes( "12345678 00000000 00000002" + //"000186a0 00000002" + // recognized by wireshark "00000000 00000000" + // protocol correct but not analyzed by wireshark "00000000 0000000000000000 0000000000000000"))); answer.add(newTrigger("tcp", rpcPortSet, HexaEncoding.hex2bytes( "80000028" + // fragment header: last frame "12345678 00000000 00000002" + //"000186a0 00000002" + "00000000 00000000" + "00000000 0000000000000000 0000000000000000"))); // SNMPv1 public answer.add(newTrigger("udp", new PortSet("161"), HexaEncoding.hex2bytes( "302602010004067075626c6963a119" + "02041f3c1d65" + "020100020100300b300906052b060102010500"))); // "3082002f02010004067075626c6963a082002002044c33a756020100020100308200103082000c06082b060102010105000500")); //"0082002f" //"0201000406"+"7075626c6963"+"a082002002044c33a756020100020100308200103082000c06082b060102010105000500")); // XDMCP answer.add(newTrigger("udp", new PortSet("177"), HexaEncoding.hex2bytes("0001000200090100065a6172646f5a"))); // OP_QUERY //answer.add(newTrigger("udp", new PortSet("177"), HexaEncoding.hex2bytes("0001000d00000000000000")); // OP_KEEPALIVE // Radius // NOTE: after receiving that Access-Request packet, the radius server will wait 4seconds before reply) answer.add(newTrigger("udp", new PortSet("1812"), HexaEncoding.hex2bytes("0100001400000000000000000000000000000000"))); // UPnP (Universal Plug and Play) version // FIXME only LAN answer.add(newTrigger("udp", new PortSet("1900"), "M-SEARCH * HTTP/1.1\r\nST: ssdp:all\r\nMX: 4000\r\nMAN: \"ssdp:discover\"\r\n\r\n".getBytes())); // SIP answer.add(newTrigger("udp", new PortSet("5060"), "".getBytes())); // NetBIOS answer.add(newTrigger("udp", new PortSet("135-139"), HexaEncoding.hex2bytes("79 08 00 00 00 01 00 00 00 00 00 00 20 43 4b 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 00 00 21 00 01"))); // Microsft-DS (SMB) answer.add(newTrigger("tcp", new PortSet("445"), HexaEncoding.hex2bytes("00 00 00 85 FF 53 4D 42 72 00 00 00 00 18 53 C8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FE 00 00 00 00 00 62 00 02 50 43 20 4E 45 54 57 4F 52 4B 20 50 52 4F 47 52 41 4D 20 31 2E 30 00 02 4C 41 4E 4D 41 4E 31 2E 30 00 02 57 69 6E 64 6F 77 73 20 66 6F 72 20 57 6F 72 6B 67 72 6F 75 70 73 20 33 2E 31 61 00 02 4C 4D 31 2E 32 58 30 30 32 00 02 4C 41 4E 4D 41 4E 32 2E 31 00 02 4E 54 20 4C 4D 20 30 2E 31 32 00"))); // SSH answer.add(newTrigger("tcp", new PortSet("22"), "SSH-2.0-OpenSSH".getBytes())); // Telnet answer.add(newTrigger("tcp", new PortSet("23"), HexaEncoding.hex2bytes( "ff fb 03" // Will Suppress Go Ahead //"ff fc 25" + //"ff fc 26" + //"ff fc 01" + //"ff fc 21" + //"ff fc 24" ))); // to detect services with banner when we don't need any trigger // Finger, NNTP answer.add(newTrigger("tcp", new PortSet("79,119"), new byte[0])); // dont send anything, just have this here so it will connect to ports 22,23 return answer; } }