jvpn – Perl script to connect to the Juniper VPN with Host Checker enabled

Overview

To access some company resources i need to use Network Connect  VPN from Juniper.  Network Connect is a software package that interfaces with its Secure Access hardware and provides a Virtual Private Network (VPN) solution. There are two software products that connect to Secure Access servers: Windows Secure Application Manager which, as you might guess, runs on Microsoft Windows; and Network Connect which runs on other platforms, in particular GNU/Linux. All  clients are closed source, without open source alternative.

I personally think that all closes source VPN clients should die one day – typically it is a perfect example of security by obscurity – internally they are using known algorithms and typically built with OpenSSL inside so there are no “secret” technologies. But closed source form will not allow to audit the code or to connect from non-supported OS (including non-x86 Linux, e.g. ARM). Also i`m  sure that code security level is very low – often such clients contains statically linked outdated libraries or input parameter validation is bad. In the worst case such clients including kernel modules (some s..t from Cisco) and then you forced to use only supported kernel. In Juniper case native Linux client requires Java + web browser installed. Also its built with JNI (Java Native Interface) so it will run only on 32-bit platforms. To run it on my Linux/x86_64 i installed 32 bit versions of the Firefox and Oracle  Java. It was very annoying to keep all this blobs in the RAM, so i decided to understand how it works and write some alternative.

How Network Connect works

After debugging with strace, java decompiler and tcpdump i got a clear view how Network Connect works:

  1. In the web browser client opening VPN page and entering Login/Password (in my case password generated from RSA Secure device)
  2. If authorization successful browser checks if VPN software is installed using Java applet. If it is not installed – ncLinux.jar file is downloaded and installation script is running. Client is installed to ~/.juniper_networks/network_connect. Also it will set SUID bit on ncsvc binary using su or sudo (password is prompted)
  3. Then optionally host checker (tncc.jar) client is running. This package validating if your system conforms policies configured on VPN host. In my case HC  is running but probably is not strict – i am able to logon to VPN from my home Linux.
  4. On next step Java Applet launcing NC.jar and passing some parameters to it. Most important one is DSID – dynamic session key, taken from the browser cookie.
  5. NC.jar will start Java (AWT based) GUI and console client (ncsvc) using JNI (code is inside libncui.so). I found that after ncsvc startup it listening on TCP port 4242 (127.0.0.1 address). Then Java GUI starts and connecting to the ncsvc (port 4242).
  6. After connecting Java GUI sending configuration to the ncsvc using non-documented protocol and ncsvc establishing remote connection. In configuration packet i found DSID, certificate md5 fingerprint, hostname and some other data.
  7. When connection is established Java GUI getting reply and communicating with ncsvc to get connection statistic (number of data transferred, VPN algorithm, etc.).
  8. On disconnect GUI sends special command to ncsvc process and it disconnecting from the remote host and doing some cleanup (e.g. reverting /etc/resolv.conf and /etc/hosts).

ncsvc client

Connection is established and maintained with ncsvc client. I found some information in the network (e.g. mad-scientist.us/juniper.html or www.joshhardman.net/juniper-network-connect-vpn-linux-64-bit/) on how to run it from command line, including some scripts. In my case all this scripts failed. If this scripts are working for you than you don`t need jvpn :)   Reason of fail was a Host Checker – related Juniper KB contains “Launch Network Connect only through the Internet browser on the supported Linux platforms” text. But i was not satisfied with this  and decided to emulate Java GUI to run client from command line, without web browser. Command line interface of ncsvc (see ncsvc -h) will not help in this case, because there is no possibility to pass DSID , and all other CLI options failing in my case. So i wrote a perl script – jvpn.pl, and hooray – i was able to establish connection.

jvpn.pl scrip – description

  • To use this script you need Perl (with some modules) and openssl binary. Also unzip is required if client is not installed.
  • jvpn.pl using configuration file jvpn.ini – before usage you will need to setup host name, login, password and realm. If you don`t know your realm – read HTML source for the login page – it will contain hidden “REALM” input element.
  • If ncsvc client is not installed – jvpn will download it to the current directory automatically from your VPN host
  • Then it logging in to the web site using your username/password and getting DSID. It handles some advanced scenarios like “active sessions found” and “additional code required” pages from VPN. It also getting md5 fingerprint of the SSL certificate using “openssl” binary.
  • After getting DSID it starts ncsvs and sending configuration commands to it using TCP protocol (port 4242). On this stage ncsvs establishing VPN connection. Then jvpn.pl entering statistic loop, like Java GUI.
  • On Ctrl+C jvpn.pl sending disconnect command to the ncsvs and also logging out from the VPN web site, to make sure that DSID is invalidated.

Screenshot

Download

Version 0.5.0 – samm.kiev.ua/jvpn/jvpn-0.5.0.tar.bz2. If you found some bugs or did some improvements – drop me a note.

About these ads
Tagged , , , , ,

42 thoughts on “jvpn – Perl script to connect to the Juniper VPN with Host Checker enabled

  1. Peter says:

    Hi,

    Love the post, I think ive gotten most of the way there with the needed perl modules for RHEL 6 Client x86_64. The only error that eludes me as to the solution is the following.

    # sudo ./jvpn.pl
    [sudo] password:
    Enter PIN+passsword: *********
    Can’t use an undefined value as filehandle reference at ./jvpn.pl line 74.

    I vi’ed the file and found this line “my $retcode = $curl->perform;” but stopped and figured i would ask before i went any further.

    Any help would be awesome.

    to help, here is a uname of the version I am running.
    Linux 2.6.32-279.1.1.el6.x86_64 #1

  2. Peter says:

    Ill have a go at it and let you know :-)

  3. Peter says:

    That got me a bit further, but thru a new massage. I think a operator or element isnt happy :-D

    Can’t use string (“43″) as an ARRAY ref while “strict refs” in use

  4. Peter says:

    Funny you just said that. I tried that and I got past the massage. perhaps I am missing a module for perl.

    • sammczk says:

      No, you have all the modules. Probably curl binding in Perl is buggy. Please, try also to add line

      no strict ‘refs’;

      before line “my $cookies;”

      P.S. May be i`ll rewrite HTTP code to LWP, it could work better.

      • Peter says:

        Like so?

        no strict ‘refs’; # apended line 114
        my $cookies = $curl->getinfo(CURLINFO_COOKIELIST);
        my $cookie = “”;
        foreach $cookie (@$cookies) {
        if ( $cookie =~ /DSID\s+([a-f\d]+)/){
        $dsid=$1;
        }
        if ( $cookie =~ /DSFirstAccess\s+(\d+)/){
        $dfirst=$1;
        }
        if ( $cookie =~ /DSLastAccess\s+(\d+)/){
        $dlast=$1;
        }

    • Peter says:

      I think this helped to identify the problem. I appear to be missing the restrict.pm file.

      Can’t locate restrict.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at ./jvpn.pl line 113.
      BEGIN failed–compilation aborted at ./jvpn.pl line 113.

      • sammczk says:

        Ok, i found problem. Perl binding to libcurl is very buggy in RHEL6. I decided to rewrite script using LWP – now it works much better. Please try 0.4.0 version and report if it work for you. Dependency list is:

        perl
        perl-Crypt-SSLeay
        perl-TermReadKey
        perl-libwww-perl

        I tested it on RHEL6 and it works for me

  5. Peter says:

    I tried that, downloaded the Dependency’s, downloaded the script and then edited the .ini.

    It seems to be working now :-)

    Transfer went ok
    Got DSID
    Certificate fingerprint: [11c3b544c4af316de1e5e450459eef64]
    TCP Connection to ncsvc process established.
    Sending handshake #1 packet… [done]
    Sending handshake #2 packet… [done]
    Sending configuration packet…

    Though I need to check the switch as its not responding to the config packet being sent.

    • sammczk says:

      Ok, now its much better – first stage is done. For some reason connection is not established.

      I am recommending to enable debug in the config and send me report to the samm [at] os2.kiev.ua. I`ll try to look on it.

      P.S. when you connecting from browser VPN starts fine?

    • Vitaliy says:

      Same problem in my configuration. Hanging on “Sending configuration packet…”

      • sammczk says:

        I can try to debug this – please contact me via jabber (samm at kaa.ru), skype (sammkyiv) or email (samm at os2.kiev.ua). I`ll send debug version.

      • I tried on Debian squeeze and had to do the following .Hope this helps someome
        cpan -i Term::ReadKey
        cpan -i IO::Socket::SSL
        aptitude install libcrypt-ssleay-perl libnet-ssleay-perl
        After installing everything and running the perl script , i’m having the same problem of hang @ “Sending configuration packet…”

      • sammczk says:

        I sent you debug details by email

  6. Figue says:

    Hi

    First of all, thank you for this script. I’m trying to use it to connect to my company VPN. It has a host checker and a simple user/password authentification, without any PIN (FYI I don’t have any control on the Juniper).
    The problem is the script can’t get any information in the cookie. I check the first POST submit with Tamper Data and it’s not the same in your script:

    my $res = $ua->post(“https://$dhost:$dport/dana-na/auth/url_default/login.cgi”,
    [ btnSubmit => 'Sign In',
    password => $password,
    realm => $realm,
    tz => '60',
    username => $username,
    ]);

    in my case, I see something different, I think this is what I need:
    my $res = $ua->post(“https://$dhost:$dport/dana-na/auth/url_default/login.cgi”,
    [ tz_offset => '60',
    username => $username,
    password => $password,
    realm => $realm,
    btnSubmit => 'Acceder',
    ]);

    (FYI btnSubmit it’s translated in spanish…)

    After the first POST the script can’t catch any information.

    [figue@M12658 jvpn-0.4.1]$ ./jvpn.pl
    Enter PIN+passsword: *******
    Transfer went ok
    Got DSID=, dfirst=, dlast=
    Unable to get data, exiting

    Tried many things, but I can’t find nothing. Can you help me? I’m on Archlinux x86_64 box with all Perl modules installed.

    Thank you

  7. Zach says:

    I to am getting to a “Sending configuration packet” and then it hangs. Help would be appreciated.

    • sammczk says:

      It could be number of reasons. I think i will do a blog post about jvpn debugging. If you will set debug level to 1 you should have some logs at directory with juniper binaries. E.g. ~/.juniper_networks/network_connect/. Also if you can create temporary vpn account i can try to debug it.

      BTW, does it works in Linux at all? It is also possible that host checker (tncc.jar) is mandatory on your system and this is the reason. In my case it is not.

      • lindenleAlex says:

        Hi, I have the same issue (I had to change a few of the inputs to match the web source) but when I run it just hangs at “Sending configuration packet”.

  8. Ihor says:

    As for section “Perl wrapper”:
    If in ubuntu you got message:

    root@localhost:~/Desktop/jvpn-0.4.1$ ./jvpn.pl
    Can’t locate Term/ReadKey.pm in @INC (@INC contains: /etc/perl /usr/local/lib/perl/5.14.2 /usr/local/share/perl/5.14.2 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.14 /usr/share/perl/5.14 /usr/local/lib/site_perl .) at ./jvpn.pl line 7.
    BEGIN failed–compilation aborted at ./jvpn.pl line 7.

    then please install following module

    sudo apt-get install libterm-readkey-perl

  9. jose says:

    Hi all,

    I tried install on ubuntu 10.04 (32 bits) and have the same problem, hangs at “Sending configuration packet”.

  10. [...] JVPN is a Perl script to connect to the Juniper VPN with Host Checker enabled. New version adds a lot of fixes + new experimental mode “ncui”. In this mode script trying to use libncui.so library instead of ncsvc directly. If you was able to get SSID but not able to connect in the previous version i am recommending to try ncui mode in version 0.5.0. [...]

  11. senthilkumar says:

    when i tried to connect it gave following error

    sudo ./jvpn.pl
    Enter PIN+password: ****
    An error happened: 500 Can’t connect to XXXXX (certificate verify failed)

  12. lm_ says:

    hi. this script worked on srx devices?

  13. Allan Joergensen says:

    I’m unable to get this to work:

    Enter PIN+password: **********
    Transfer went ok
    Got DSID=, dfirst=, dlast=
    Unable to get data, exiting

    It seems it doesn’t get any cookie data ($cookie is empty)

  14. Stefan Becker says:

    Now that Firefox 19 broke Juniper VPN, someone from our corporate IT send me a pointer to this post. Works like a charm on Fedora 18, 64-bit.

    Thanks!

  15. Eric says:

    Installed JVPN 0.5.0 on a Pinguyos 12.4 64bits:

    Loaded following:
    perl-Crypt-SSLeay
    perl-TermReadKey
    perl-libwww-perl
    cpan -i Term::ReadKey
    cpan -i IO::Socket::SSL

    Stuck at:

    Enter PIN+password: **************
    Transfer went ok
    Got DSID
    Certificate fingerprint: [dbdc10d4f53ced8dbf1081555c76ab32]
    TCP Connection to ncsvc process established.
    Sending handshake #1 packet… [done]
    Sending handshake #2 packet… [done]
    Sending configuration packet…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 212 other followers

%d bloggers like this: