SAP Services detection via nmap probes -------------------------------------- - [SAP Services detection via nmap probes](#sap-services-detection-via-nmap-probes) - [How nmap can help us](#how-nmap-can-help-us) - [SAP existing support in nmap](#sap-existing-support-in-nmap) * [Version and service detection](#version-and-service-detection) - [How to generate and test probes](#how-to-generate-and-test-probes) - [How to handle scan port range](#how-to-handle-scan-port-range) * [Port generation tool](#port-generation-tool) * [What about port customization by the admin?](#what-about-port-customization-by-the-admin) - [How a scan looks like with custom SAP probes](#how-a-scan-looks-like-with-custom-sap-probes) - [Issues encountered: SSL](#issues-encountered-ssl) - [What can be improved](#what-can-be-improved) - [What to do next with that information?](#what-to-do-next-with-that-information) - [Conclusion](#conclusion) - [Authors](#authors) This article aims at showing how to improve the capability of the nmap network scanner to detect SAP services. This is by no mean a complete and 100% exact way of doing service detection as a lot of corner cases exist that are not covered in this text. If you want a more comprehensive way to do SAP services detection and even much more, the [ERPScan Monitoring Suite](https://erpscan.com/products/erpscan-security-monitoring-suite-for-sap/) is a good starting point with its port scanner feature. ## How nmap can help us Our goal is to detect every network service exposed by SAP servers. Those servers are complex beasts with numerous components exposed to the network by default and each of these components potentially has vulnerabilities. So we want to send specific network probes to detect the presence of these services and then better assess if a service is vulnerable or not. Nmap is an open source network port scanner that can do many things and especially service detection via fingerprints. We will explain how one could implement a SAP-aware port scanner with this tool. ## SAP existing support in nmap First, if you look closely at the official nmap release you will notice that there are some traces of SAP support. It is actually very sparse and can be confirmed by scanning a real SAP server: ``` Nmap scan report for 172.16.30.29 Host is up (0.00018s latency). Not shown: 65508 closed ports PORT STATE SERVICE VERSION 1128/tcp open soap gSOAP 2.7 3201/tcp open cpq-tasksmart? 3299/tcp open saprouter? 3301/tcp open unknown 3901/tcp open nimsh? 4901/tcp open sybase-adaptive Sybase Adaptive Server 4902/tcp open sybase-backup Sybase Backup Server 4903/tcp open unknown 8101/tcp open http SAP Message Server httpd release 745 30101/tcp open unknown 30102/tcp open unknown 30103/tcp open unknown 30104/tcp open unknown 30107/tcp open unknown 30108/tcp open unknown 30111/tcp open http BaseHTTPServer 0.3 (Python 2.7.10) 30116/tcp open unknown 40000/tcp open safetynetp? 40001/tcp open unknown 40002/tcp open unknown 40080/tcp open http SAP Internet Graphics Server httpd 46287/tcp open status 1 (RPC #100024) 50000/tcp open http SAP WebDispatcher 50001/tcp open ssl/http SAP WebDispatcher 50004/tcp open unknown 50007/tcp open unknown 50013/tcp open soap gSOAP 2.7 50014/tcp open ssl/soap gSOAP 2.7 50020/tcp open unknown 50113/tcp open soap gSOAP 2.7 50114/tcp open ssl/soap gSOAP 2.7 ``` The columns SERVICE and VERSION shows us plenty of unknown or improperly named fields. This situation can be improved if we analyze each unknown port/protocol. If you dig a bit more you'll find that Core Security researcher Martin Gallo wrote much more improved support for SAP proprietary protocol (available at [corelabs-nmap-service-probes.txt](https://www.coresecurity.com/system/files/publications/2016/05/corelabs-nmap-service-probes.txt)) that does smarter stuff like extracting technical server information from answers. That is a very good starting point and as we included some of these probes we enlarged the support a bit more. ### Version and service detection Nmap key file for service detection is `nmap-service-probes` (stored in `/usr/share/nmap/` for Linux installation). The format is quite self-explanatory for its main features. Let us consider one of the simplest example: ``` Probe TCP NULL q|| match sajpoin m|SAP_Cluster_Manager| p/SAP Java Cluster Join Service/ ``` The `Probe` line describes the TCP payload that we send to the server. In this case, we connect to the TCP port without sending any TCP payload after the 3-way handshake. The next line beginning with `match` describes what we want to check from the server's answer. A match is final, the parser won't check another match for the given probe (as long as we don't use `softmatch`). In this example, we look for the ASCII string `SAP_Clutser_Manager` via a regular expression. If the expression is matched, then nmap tags the matching port with the product name "SAP Java Cluster Join Service". That probe can be used many times for all those protocols that are based on the first message sent by the server to the client (SSH, FTP, mail protocols, for example). We just add other `match` lines after the `Probe`. Full documentation of this file format can be found at [https://nmap.org/book/vscan-fileformat.html](https://nmap.org/book/vscan-fileformat.html) ## How to generate and test probes So now, we need a way to know which packets need to be sent and what specific piece of information inside an answer can allow us to identify with a good assurance what protocol is being used and from that determine what is the service using this protocol. In order to illustrate the difference about service and protocol, you can look at the HTTP protocol and all the different services that will make use of it. SAP services implement many different binary protocols that does not ease our task. Let's have a look at a simple probe for a service using a binary protocol: SAP Router. ``` Probe TCP SAProuter q|\x00\x00\x00\x00| ports 3299 match saprouter m|SAProuter ([\d.]+) on '(\w+)'| p/SAProuter/ v/$1/ h/$2/ match saprouter m|SAProuter| p/SAProuter/ ``` Per official documentation SAP router service should be listening to the port tcp/3299. When sending the binary request `\x00\x00\x00\x00` to a SAP Router we can get several answers depending on the router version/configuration. Sometime the SAP Router can leak information like version + hostname, so we try to match this specific answer first and then we try to match the more generic answer without the information disclosure. The additional information we gather in the first `match` can be propagated and printed nicely by nmap using the version field and the hostname. That is what we accomplish with help of regular expression groups (using parenthesis inside the expression) and by referencing them via their position in the `v//` and `h//` statement ('v' standing for version, and 'h' for hostname). ## How to handle scan port range Usually with nmap, if we do not specify -p option it will scan the 1000 most used port (from Internet statistics). Unfortunately, many SAP ports will be missed by doing so. Therefore, we need to scan all 65535 ports at a big scan time cost or we look a bit closer at how to generate these SAP ports. For efficiency, we decide to choose the second option. If we look at SAP documentation, we see their rules to define potential ports for each services. So by using these rules, we can expand the full list of potential SAP ports. SAP services have the notion of instance number, this is a number that can vary from 00 to 99 and the port of the service will depend on it. SAP official documentation on all SAP TCP ports used by their services can be accessed at [https://cp.hana.ondemand.com/dps/d/preview/47673f06bd494db680ff6150c0b08108/2.0/en-US/frameset.htm](https://cp.hana.ondemand.com/dps/d/preview/47673f06bd494db680ff6150c0b08108/2.0/en-US/frameset.htm) For example the web ports for ICM HTTP service are noted 80NN, with NN being this instance number. It means they can cover the range 8000-8099. If we look at another example the SAP TREX nameserver service will listen on ports 3NN01. So our potential port range will be from 30001, 30101, 30201,...,39901. You can find port collision with two (and more) different services/protocols using theoretically the same port. Some examples: 32NN used on the Netweaver Java platform by the Enqueue service and on the Netweaver ABAP platform by the Dispatcher service. Another one is the previous example with port 3NN01 being used by SAP TREX nameserver and SAP HANA TREXNet internal nameserver port. Nmap handle all of that nicely with its service detection algorithm given a proper `nmap-service-probe` file: we can have the same port used in a `Probe` rule, and several `match` on a single port. ### Port generation tool The following python tool [sap_ports.py](sap_ports.py) takes care of port generation and prints out a comma-separated list of ports that can be used as the nmap `-p` parameter as following: ``` $ nmap -p $(sap_ports.py) $TARGETS ``` The main idea of `sap_ports.py` is to use a statically defined dictionary with information gathered from SAP on-line documentation to generate the list of ports with possibility to generate a subset of the ports depending on several criteria. ### What about port customization by the admin? During our security audit we saw rarely cases of port customization. One example case lead to wrong assumption on the instance number of a service by analyzing the port number. For instance: using 3617 for the message server service on the instance number 32... In this case it is necessary to inspect the protocol and use information disclosures to be able to disambiguate this situation. There is no generic answer to this problem if we do not want to scan the 64k TCP ports. We accept in this article the low risk that some port customization could be out of our static port range from our experience of seeing it very rarely. ## How a scan looks like with custom SAP probes ``` Nmap scan report for 172.16.30.29 Host is up (0.00018s latency). Not shown: 6563 closed ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 6.2 (protocol 2.0) 111/tcp open rpcbind 2-4 (RPC #100000) 1128/tcp open sapstartservice SAP Management Console (SID SAP, NR 99) 3201/tcp open sapjavaenq SAP Enqueue Server 3299/tcp open saprouter SAProuter 40.4 3301/tcp open sapgateway SAP Gateway 3901/tcp open sapms SAP Message Server 4901/tcp open sapase SAP ASE Database 4902/tcp open sybase-backup Sybase Backup Server 4903/tcp open unknown 8101/tcp open sapmshttp SAP Message Server httpd release 745 (SID J45) 30201/tcp open saptrex SAP TREX Name server 30202/tcp open saptrex SAP TREX Preprocessor 30203/tcp open saptrex SAP TREX Index server 30204/tcp open saptrex SAP TREX Queue server 30207/tcp open saptrex SAP TREX RFC server 30208/tcp open saptrex SAP TREX Cruise server 30211/tcp open saptrex SAP TREX AlertServer (BaseHTTP/0.3 Python/2.7.10) 30216/tcp open saptrex SAP TREX Index server 40080/tcp open sapigs SAP Internet Graphics Server 50000/tcp open sapjavaweb SAP NetWeaver Application Server (Kernel version 7.45, Java version 7.50) 50001/tcp open ssl/sapjavaweb SAP NetWeaver Application Server (Kernel version 7.45, Java version 7.50) 50004/tcp open sapjavap4 SAP JAVA P4 (Potential internal IP 172.16.30.29) 50007/tcp open sapp4iiop (Internel IP 172.16.30.29) 50013/tcp open sapstartservice SAP Management Console (SID J45, NR 00) 50014/tcp open ssl/sapstartservice SAP Management Console (SID J45, NR 00) 50020/tcp open sapjoin SAP Java Cluster Join Service 50113/tcp open sapstartservice SAP Management Console (SID J45, NR 01) 50114/tcp open ssl/sapstartservice SAP Management Console (SID J45, NR 01) 50213/tcp open sapstartservice SAP Management Console (SID TRX, NR 02) Service Info: Host: java745; ``` ## Issues encountered: SSL In theory there is the keyword `sslports` in the service-probe file that may indicate on which port a specific probe should be checked upon the SSL layer. In practice these specified ports were not properly validated as SSL ones without ripping the whole probes related to SSL in the original nmap-service-probe file (begins in our custom probe file at the `Probe TCP SSLSessionReq`). ## What can be improved Code exploits / port information disclosure in NSE Lua scripts tagged by categories: - version, discovery, exploit, auth, dos - safe, intrusive ## What to do next with that information? If you are a pentester, you probably have a bag full of exploits for specific SAP services, so you want to automatically link open ports to exploits attempts. That can be easily done by storing the nmap scan into an XML file (-oX option) and then writing a parser that will generate exploit command-line to be executed on the specific open ports. On the other hand, if you are a security analyst or doing operational security you probably want to store those results and be able afterwards to search them to detect change in the landscape or be able to pinpoint vulnerable services by their version. For this mean, we use the [IVRE framework](https://ivre.rocks/) that can import our XML nmap scans and provides a nice web interface to query scan results and allows doing basic statistics/reporting tasks. The attached screenshots shows a scan in IVRE with filtering OFFICE (internal lab) scan source and looking for P4 service (present on Java NetWeaver application servers) detected on the network. The right column shows the top ports histogram computed from those specific scan results. ![](ivre_nmap.png) ## Conclusion We hope that this will help you better understand what is hidden behind those cryptic SAP servers and show you that only with network level probes we can go deep in this knowledge of what is behind an SAP server. This blog post is a way to remind that SAP servers have a huge exposition surface and that enforcing a strict networking policy including them is part of a good security hygiene. This article and the associated Nmap files are available at [github.com](https://github.com/gelim/nmap-erpscan). A web-only version is available at https://erpscan.com/press-center/blog/sap-services-detection-via-nmap-probes/ ## Authors Name | Mail | Involvement ------|-------|------------ Mathieu Geli | | Main author/maintainer of those files Michael Medvedev | | Second author Martin Gallo | | Initial support on Diag/RFC/MS/Enqueue protocols Joris van de Vis | | Improvements over RFC probes