Time Oracle for Hyperledger Fabric Blockchain
In the previous article, I described how the use of time servers (NTP and NTS) solves the problem of transaction time manipulation in the Hyperledger Fabric blockchain. The proof-of-concept code was written in Go. Therefore, it is not applicable to smart contracts Hyperledger Fabric written in other languages (Java, JavaScript, TypeScript). So, I decided to make Oracle time: a smart contract that will be a time source for other smart contracts. This will allow the time oracle to be used by smart contracts written in other languages. Time Oracle available in source code.
In this article, we will make sure that the oracle is resistant to a man-in-the-middle attack (using NTS). For the attack, we will use utilities netsed (to replace unencrypted data) and mitmproxy (to replace the TLS certificate). And also make sure that NTP protocol data can be replaced. Readers who are not familiar with the Hyperledger Fabric blockchain can imagine that the time oracle is some kind of API service that returns the current time (an intermediary between the client and the NTP/NTS server).
Description of the layout
The oracle is running in Docker (Docker network 172.18.0.0/24). On the Docker host (Host_1), netsed (port 4000/UDP) and mitmproxy (port 8080/TCP) are running. Traffic from the oracle to them will be sent via iptables (the rules are given below). From the second host (Host_2), the oracle functions GetTimeNtp and GetTimeNts are accessed (via a call peer chaincode querywhich creates a secure TLS connection). Calling these functions causes the oracle to contact the NTP server and NTS server, respectively.
Substitution of NTP protocol data
Let's start with the NTP protocol. I intercepted the data between the oracle and the NTP server (213.234.203.30) by running tcpdump on the oracle host. Looking at the protocol data in WiresharkI saw that the date is transmitted 3 times (fields “Reference Timestamp”, “Receive Timestamp”, “Transmit Timestamp”). The beginning of the data in this case began with %ea%33.
Without going into the principle of encoding the timestamp in the NTP protocol, I replaced %ea%33 with %eF%33. The iptables rule looked like this:
iptables -t nat -A PREROUTING -s 172.18.0.0/24 -d 213.234.203.30/32 -p udp -m udp --dport 123 -m udp -j REDIRECT --to-ports 4000
As can be seen from Figure 3, the replacement rule worked 3 times. That is, exactly as many times as there were previously timestamps with the required date in Wireshark. The result of the substitution: when calling the GetTimeNtp function, the time points to 2027.
As expected, the NTP protocol is susceptible to man-in-the-middle attacks.
Substitution of NTS protocol data
Repeating the same for the NTS server (ntp1.glypnod.com, address
104.131.155.175), this is what happened. netsed worked the same way (another port 8123 was used, because the server is 104.131.155.175, during the NTS connection, reported this port).
In Wireshark we see that the replacement was successful: the year is 2027 again.
But the result of the query to the oracle of this time did not return:
By looking at the container logs, the reason is also clear:
Now let's use mitmproxy. The NTS server runs on port 4460/TCP. So the iptables rule is:
iptables -t nat -A PREROUTING -p tcp -s 172.18.0.0/24 --dport 4460 -m tcp -d 104.131.155.175 -j REDIRECT --to 8080
In the mitmproxy console we see an error (Figure 9).
Let's look at the container logs. We see that the self-signed certificate did not work.
Features when interacting with NTS servers
Since a TLS connection is established during the connection to the NTS server, the client must have a relatively correct local time for it to be established successfully. Otherwise, an error will occur (see Figure 11). For example, for the ntp1.glypnod.com server, at the time of publication of this article, the certificate validity period is from 05/22/2024 to 08/20/2024. That is, the client must have a local time in this range.
If it is not possible to reliably achieve relatively correct time on the client, it is worth considering using NTP within a cryptographically protected channel that is not demanding of the client's local time.
Conclusion
As a result of the experiment, it was established that NTP server traffic is susceptible to a man-in-the-middle attack. A the NTS library implementation used in the oracle is not susceptible to this type of attack. In addition, logging in the oracle allows you to detect an attack attempt. Which may be useful for timely detection of an incident. The time oracle is suitable for use by other smart contracts of the Hyperledger Fabric blockchain and eliminates the need for developers to program the logic of interaction with NTP/NTS servers themselves.