On MikroTik OpenVPN Security

I use MikroTik Routerborads quite a lot on remote sites to establish a secure tunnel to connect to internal services remotely (for example for employee time clocks). I like using OpenVPN because it is simple to configure and supports both, L2 (tap) and L3 (tun) secure (encrypted) tunnels. MikroTik’s Routerboards on the other hand are quite cheap and are providing a neat “black box” appliance which can easily handed to people with no IT experience.

So a basic (simplified) scenario looks like this:

  1. The server is configured to authenticate and authorize clients based on a client certificate, which must be issued by a certain certification authority (CA). This CA is normally an internal one dedicated for this usage. Authorization is thereby granted by signing a certificate with the CA’s private key.
  2. The server verifys the client’s authenticity using a client certificate and the client should verify the authenticity of the server’s certificate by checking whether the certificate is issued by a known and trusted CA
  3. The client now established a secure connection to the server and we can now tunnel whatever we want.

So far so good. I first created an own PKI with a CA certificate (ca1.pem) and a server key pair (test-server.pem and test-server_key.pem) as well as own dh-parameters (dh4096.pem).
The simple server configuration file now looks like this:

port 1194
server 192.168.1.0 255.255.255.0
proto tcp
dev tun-mik
ca pki1/ca/ca1.pem
cert pki1/ca/slaves/test-server/test-server.pem
key pki1/ca/slaves/test-server/test-server_key.pem
dh dh4096.pem
keepalive 10 120
cipher AES-256-CBC
persist-key
persist-tun
verb 3

Now to our Routerboard. In this case, I am using a hEX PoE with the latest firmware (6.41.4). In my test scenario, the server has the ip 192.168.88.254.
After creating, signing and uploading the client certificate and key I configured the vpn client as follows:

/interface ovpn-client add certificate=test-mikrotik.pem_0 cipher=aes256 connect-to=192.168.88.254 name=ovpn-out1 profile=default-encryption user=dummy

For some reason it is not possible to configure an MikroTik OpenVPN client without a username, so I named it “dummy”.

[admin@MikroTik] > /interface ovpn-client print
Flags: X - disabled, R - running 
 0  R name="ovpn-out1" mac-address=FE:DA:0A:A8:44:4C max-mtu=1500 connect-to=192.168.88.254 port=1194 mode=ip user="dummy" password="" profile=default-encryption certificate=test-mikrotik.pem_0 
      auth=sha1 cipher=aes256 add-default-route=no

So yeah, great success, we heve established a secure OpenVPN connection to our Server!

… or did we? Well, the connection works, I can ping and ssh to my server through the tunnel using the internal tunnel IP. But at this point I noticed I forgot to import the CA certificate, so how can the client verify the server’s authenticity?

[admin@MikroTik] > /certificate print 
Flags: K - private-key, D - dsa, L - crl, C - smart-card-key, A - authority, I - issued, R - revoked, E - expired, T - trusted 
 #          NAME                            COMMON-NAME                            SUBJECT-ALT-NAME                                                         FINGERPRINT                           
 0 K      T test-mikrotik.pem_0             test-mikrotik                          DNS:test-mikrotik                                                        e01bca9e...

But maybe it is a crude default behavior if I don’t have any trusted CAs in the certificate store. So I imported the CA certificate:

[admin@MikroTik] > /certificate import 
passphrase: 
     certificates-imported: 1
     private-keys-imported: 0
            files-imported: 1
       decryption-failures: 0
  keys-with-no-certificate: 0

Check if it is trusted:

[admin@MikroTik] > /certificate print  
Flags: K - private-key, D - dsa, L - crl, C - smart-card-key, A - authority, I - issued, R - revoked, E - expired, T - trusted 
 #          NAME                            COMMON-NAME                            SUBJECT-ALT-NAME                                                         FINGERPRINT                           
 0 K      T test-mikrotik.pem_0             test-mikrotik                          DNS:test-mikrotik                                                        e01bca9e...
 1        T ca1.pem_0                       CA1                                                                                                             604d532f...

For testing an “evil” server with an other identity, I created a new CA and server certificate (evil-server.pem) issued by that CA and created the following OpenVPN server configuration:

port 1194
server 192.168.1.0 255.255.255.0
proto tcp
dev tun-mik
ca pki1/ca/ca1.pem
cert pki2/ca/slaves/evil-server/evil-server.pem
key pki2/ca/slaves/evil-server/evil-server_key.pem
dh dh4096.pem
keepalive 10 120
cipher AES-256-CBC
persist-key
persist-tun
verb 3

As ca I still use the “good” CA so that the server accepts the certificate of the client but as cert and key I’m using certificates (evil-server.pem) issued by a totally different (new) CA.
So I stopped the old server and started the “evil” one and… well:

[admin@MikroTik] /interface ovpn-client> print
Flags: X - disabled, R - running 
 0  R name="ovpn-out1" mac-address=FE:DA:0A:A8:44:4C max-mtu=1500 connect-to=192.168.88.254 port=1194 mode=ip user="dummy" password="" profile=default-encryption certificate=test-mikrotik.pem_0 
      auth=sha1 cipher=aes256 add-default-route=no 

The connection is “running”, whereas a correct client configuration (with the ca directive set) yields an error:

client
remote 127.0.0.1 
port 1194
dev tun
proto tcp
nobind
tls-version-min 1.2
ca pki1/ca/ca1.pem
key pki1/ca/slaves/test-mikrotik/test-mikrotik_key.pem
cert pki1/ca/slaves/test-mikrotik/test-mikrotik.pem
cipher AES-256-CBC
auth SHA384
verb 3
...
Wed Apr 11 14:48:54 2018 Attempting to establish TCP connection with [AF_INET]127.0.0.1:1194 [nonblock]
Wed Apr 11 14:48:54 2018 TCP connection established with [AF_INET]127.0.0.1:1194
Wed Apr 11 14:48:54 2018 TCP_CLIENT link local: (not bound)
Wed Apr 11 14:48:54 2018 TCP_CLIENT link remote: [AF_INET]127.0.0.1:1194
Wed Apr 11 14:48:54 2018 TLS: Initial packet from [AF_INET]127.0.0.1:1194, sid=c967bfff f7d9ae33
Wed Apr 11 14:48:54 2018 VERIFY ERROR: depth=0, error=unable to get local issuer certificate: CN=evil-server
...

It’s hereby proved, that an attacker, who is able to intercept the traffic, can create a malicious server which, for example, may allow access to the network on the client side. This attack does not compromise the client’s authentication key.

I would currently advise not using MikroTik’s OpenVPN client in an untrusted network.

User “lapsio” in the MikroTik forum also reported this issue back in October 2017. I also tried the “correct” process described in the Wiki:

  1. Import CA
  2. Import client certificate
  3. Create client configuration

This setup does behave exactly the same as in the scenario described above.

I will continue the investigation and report my findings to MikroTik.

Update 2018-04-12

  • This vulnerability was assigned the id CVE-2018-10066.
  • This blog post was sent to MikroTik.

Update 2018-04-13

  • MikroTik acknowledged problems with their OpenVPN client and announced “improvements for the future versions”.
  • MikroTik: “[We] cannot tell when we will implement this feature. But it is not a secret that RouterOS OVPN can verify only client certificate, not the servers.”

Leave a Reply

Your email address will not be published. Required fields are marked *