Junos 10

Today I have been mostly installing Junos. Well actually I’ve wasted most of the day trying to get Junos 10.4 to work in Olive under VirtualBox. I understood that it required FreeBSD 7.1, so tried installing it under 7.1 and 7.4 to no avail.

In the end I cloned my Junos 9.0/FreeBSD 4.11 VM, allocated 512Mb instead of 256Mb and installed 10.4 as an upgrade, which also meant I didn’t have to bother removing checkpic.

I wasted a few rounds of installing due to using the export version, which doesn’t include SSH! Also part of the trick of getting it to work under VBox seemed to be to create a serial port as a named pipe – not sure why but that seemed to help get past the bootloader hanging, possibly as it had a TTY to allocate.

I also upgraded my 9.0 to 9.6 which has a bit of a more useful JWeb interface, and also requires 512Mb now.

All of this was to aide my development of a set of NASL scripts to do Junos security compliance auditing. It seems Tenable have worked around the UNIX-only limitation of Nessus’ ssh_cmd() function by putting in a special check for when uname -a fails – i.e. its either IOS or Junos (or unsupported). Of course in Junos shell mode, it will pass (as its FreeBSD) so you have to check that you’re in CLI mode to do the config checking.

Its only taken them four years of me asking for this, and I guess its come as a result of Nessus’s new IOS support for their own compliance plugin and local security checks for Junos patches etc.

Update: I’ve written 20 NASL plugins to do the Junos auditing now and I noticed I was hitting the SSH rate-limit setting in Junos, so my plugins were getting booted off. It was because for each plugin I was calling ssh_cmd() at least once and also a function that checks I could login with the correct level/privileges etc; so was making at least two SSH connection attempts per plugin, which soon hit the 10 connection attempts per minute limit that was configured.

So now I’ve moved all of my ssh_cmd() calls into one big include file which uses a single SSH connection to send 30 or so commands, and populates the knowledgebase with the results. The plugins then have that in their script_dependencies() and don’t use SSH at all, just a couple of calls to get_kb_item() which simplifies the code quite a lot and an entire scan can be done in 10secs!

JunOS config checking

Today I’ve been automating Juniper router configuration assessment. Basically issuing a “show configuration” from the CLI and then using a Nessus .nasl script to parse the results.

The main problem is that JunOS uses multiline config statements, so to check if HTTP is enabled, you end up having to go through this lot:

system {
    services {
        web-management {
            http {
                interface em0.0;
            }
        }
    }
}

So you have to use a combination of functions – ereg() which can look for a multiline regex and return true/false, egrep() which can return a single matching line from a multiline string and eregmatch() which returns just the matching portion of that single line!

I’m thinking of checking for a true return of ereg() and then looping through the whole string to return the matching bit, seems a bit naff, but may be better than three function calls….

I’m not sure if I’m going to stick with my new VPS host, they don’t seem to know their way around OpenVZ, Hell I’ve been playing with it for a few days and seem to be able to run rings around them. The support does seem to have been outsourced to Pakistan by the looks of the IP addresses showing up in the control panel logs.

Every time they reboot the host node or my VPS for whatever reason (without telling me!) they seem to lose the NTP permissions, or bugger up the iptables state/conntrack modules etc. As I’ve not migrated to them yet and I’ve got a month or so before I have to pay them again and my existing host shouldn’t go away that quickly, I might sign up for some other hosts in the meantime.

What do you Expect?

I’ve been programming Expect scripts today, to login to Juniper routers and parse their config using Nessus. Similar to what I attempted with Cisco switches a while back, but I never really got into it then. I’ve got a working implementation now that can login to my Olive VM using just the regular expect program and a NASL script, no custom TCL or Perl or even the policy compliance plugin required.

I could probably get it down to one expect script per vendor for logging in and fetching the config, then a NASL script per device type to parse the output, e.g. for Cisco you’d have an expect script, then a NASL for CatOS on a 6509 and another for IOS on a 2950.

Its funny, if Cisco could sort out their SSH implementation to accept a command as input – like “ssh admin@10.0.0.4 show running-config” and use SSH keys, then everyone and his dog wouldn’t be writing expect scripts to do automated logins!

Anyway, here’s the basic expect script (created by running autoexpect and tidying the output) to query the config for a particular interface on JunOS Olive 9:

#!/usr/bin/expect

spawn ssh root@10.0.0.2
expect -exact "root@10.0.0.2's password: "
send -- "l337hax0r\r"
expect -re "\r
--- JUNOS.*\r
.*root@% "
send -- "cli\r"
expect -exact "cli\r\r
root> "
send -- "show interfaces em0 media\r"
expect -re " \r
.*
\r
root> "
send -- "exit\r"
expect -exact " \r
\r
root@% "
send -- "exit\r"
expect eof

You run that using pread() from the NASL, passing in the username, password, IP etc; to argv[], and Bob’s your uncle!

Olive Branch

I got JunOS Olive 9.0 installed under VirtualBox today.

Basically followed the VMWare instructions here, which are essentially:

1. Do a minimal install of FreeBSD 4.11, with the majority of disk space allocated to /var (4Gb disk, 256Mb RAM)
2. Setup a serial pipe and connect via “socat unix-client:/tmp/vbox.pipe -”
3. Setup a network interface via the CLI, reboot:

cli
configure
set interfaces em0 unit 0 family inet address 192.168.0.115/24
commit and-quit

4. scp the files across and “pkg_add jinstall-7.3R3.6-domestic-signed.tgz”, reboot
5. repeat #3 to upgrade to 9.0R1.10
6. install jWeb: “pkg_add jweb-9.0R1.10-signed.tgz”, reboot
7. enable jWeb via the CLI, which requires changing the root password, reboot:

cli
configure
set system root-authentication plain-text-password
set system services web-management http interface em0.0
commit and-quit

8. enable SSH and other goodies via jWeb

Here is a screenshot of the web GUI and the console – with Olive9 the serial pipe is not needed as it displays on the VGA console.

I’ve also been doing a lot more Nessus plugin writing lately, so might work on something for auditing JunOS config later.

There’s two inches of snow outside.