Juniper Host Checker (tncc.jar)

The Host Checker mechanism is a security scanner for the Juniper VPNs, in the same vein as Cisco's CSD and GlobalProtect's HIP. It is also used by the Pulse Secure protocol but support for running it with the Pulse protocol is not included in OpenConnect yet.

Background

Many sites require a Java applet to run certain tests as a precondition of authentication. This works by sending a DSPREAUTH cookie to the client which is attempting to authenticate, and the Java code in tncc.jar then runs and communicates with the server, handing back a new value for the DSPREAUTH cookie to be used when autnentication continues.

This Java applet is a black-box binary provided by a server outside of the client's control, and therefore has similar security concerns to Cisco's CSD trojan.

TNCC support in OpenConnect

OpenConnect supports running the Java binary, or emulating its behaviour, by passing the --csd-wrapper=SCRIPT argument with a shell script.

The OpenConnect distribution includes two alternative scripts to support the execution or emulation of Host Checker, in the trojans/ subdirectory:

  • tncc-wrapper.py: This Python 3.x wrapper script runs the actual tncc.jar binary, with a little assistance. Running this wrapper requires you to build tncc-preload.so from russdill/ncsvs-socks-wrapper on GitHub. Because of the security dangers of executing a server-provided trojan binary, this script should ideally be executed with the permissions of a low-privilege user (e.g. --csd-user=nobody).
  • tncc-emulate.py: This Python 3.x script does not actually run the tncc.jar binary. Instead, it emulates the behaviour of the tncc.jar binary, rather than actually executing it. Because this script does not actually execute a server-provided binary, security concerns are greatly alleviated.

    It may require configuration or customization to work with VPNs that have modified the behaviour of their Host Checker binaries in some way; consult its source code for details, starting with the list of environment variables that may be set to overridden some of the data that it sends to the server.

    This script is based entirely on tncc.py from russdill/juniper-vpn-py on GitHub.)

With either of these scripts, it may also be necessary to pass a Mozilla-compatible user agent string:

  ./openconnect --protocol=nc --useragent 'Mozilla/5.0 (Linux) Firefox' --csd-wrapper=trojans/tncc-wrapper.py vpn.example.com