- SAP Services detection via nmap probes
- How nmap can help us
- SAP existing support in nmap
- How to generate and test probes
- How to handle scan port range
- How a scan looks like with custom SAP probes
- Issues encountered: SSL
- What can be improved
- What to do next with that information?
- Conclusion
- 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 is a good starting point with its port scanner feature.
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.
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) 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.
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
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).
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
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.
The following python tool 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.
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.
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;
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
).
Code exploits / port information disclosure in NSE Lua scripts tagged by categories:
- version, discovery, exploit, auth, dos
- safe, intrusive
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 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.
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. A web-only version is available at https://erpscan.com/press-center/blog/sap-services-detection-via-nmap-probes/
Name | Involvement | |
---|---|---|
Mathieu Geli | mathieu.geli@gmail.com | Main author/maintainer of those files |
Michael Medvedev | m.medvedev@erpscan.com | Second author |
Martin Gallo | mgallo@coresecurity.com | Initial support on Diag/RFC/MS/Enqueue protocols |
Joris van de Vis | jvdvis@erp-sec.com | Improvements over RFC probes |