Conduct fuzz testing against WHOIS stream input
Domain Monitor's update
command involves interacting with a remote WHOIS server over a TCP connection on port 43. While the WHOIS servers in use are generally considered to be trustworthy, there is no native encryption, authentication or in-depth integrity checking on the connection and the transmitted content.
The primary threats are man-in-the-middle (MitM) attacks or compromised WHOIS servers, either of which may cause munged or invalid data to be received by and parsed by Domain Monitor. This data could contain non-ASCII characters or content designed to crash, hang or exploit PHP and/or Domain Monitor.
Usually, the risk of compromised WHOIS servers is low, and the risk of MitM against Domain Monitor/WHOIS depends on the specific user setup environment, but in most cases will be low.
The key areas of Domain Monitor's code that are exposed to the raw WHOIS stream/data are:
-
whois()
: Returns the raw WHOIS data for a domain by opening a connection to the required WHOIS server usingfsockopen()
. The domain name followed by a CRLF is written to the socket usingfwrite()
, then a maximum of 65535 bytes of the response is read usingfread()
, which is directly fed throughfilter_var()
using the flagsFILTER_DEFAULT
andFILTER_FLAG_STRIP_HIGH
. -
parseExpiry()
: Returns the expiry date from the passed raw WHOIS output inY-m-d
format. Apreg_match()
is used to identify and extract the relevant expiry date line, which is then cut down further usingsubstr()
to extract just the date string. ADateTime
object is then attempted to be created from the extracted date string usingnew DateTime
. A try/catch is used through the entire function to catch exceptions.
With the current mitigations in place, untrusted data is unlikely to result in a destructive attack (e.g. RCE) against domain monitor, however there may be future undiscovered vulnerabilities in the PHP functions used that could allow this to happen. The issues that are more likely to occur are crashes or hangs caused by invalid data.
Fuzzing the parseExpiry()
function should be pretty straightforward, however the whois()
function may be more of a challenge. To avoid having to implement a network-service based fuzzer, fsockopen()
can instead be used to open a local file. However, this may hit different code paths compared to accessing a remote network socket. I will assess whether this is the case and what impact it may have on the results.