Setup LibreNMS as Syslog Server

Using the LibreNMS documentation for setting up syslog-ng so LibreNMS can ingest logs from Cisco, Mikrotik, Ubiquiti etc. equipment.

https://docs.librenms.org/Extensions/Syslog/

Enable Syslog in LibreNMS settings

First thing we need to do is enable syslog for LibreNMS. Edit the /opt/librenms/config.php and add or enable

$config['enable_syslog'] = 1;

Install and Configure syslog-ng

Install syslog-ng with dnf or yum.

sudo dnf install -y syslog-ng

Create a config file for LibreNMS

vi /etc/syslog-ng/conf.d/librenms.conf

Put the following in the config file

source s_net {
        tcp(port(514) flags(syslog-protocol));
        udp(port(514) flags(syslog-protocol));
};

destination d_librenms {
        program("/opt/librenms/syslog.php" template ("$HOST||$FACILITY||$PRIORITY||$LEVEL||$TAG||$R_YEAR-$R_MONTH-$R_DAY $R_HOUR:$R_MIN:$R_SEC||$MSG||$PROGRAM\n") template-escape(yes));
};

log {
        source(s_net);
        source(s_sys);
        destination(d_librenms);
};

Restart and enable syslog-ng

sudo systemctl restart syslog-ng
sudo systemctl enable syslog-ng

SELinux

If we are running SELinux, we’ll need to make and apply a module to let the logs show up in the web interface.

vi librenms-rsyslog.te

Put the following in the file

module mycustom-librenms-rsyslog 1.0;

require {
        type syslogd_t;
        type httpd_sys_rw_content_t;
        type ping_exec_t;
        class process execmem;
        class dir { getattr search write };
        class file { append getattr execute open read };
}

#============= syslogd_t ==============
allow syslogd_t httpd_sys_rw_content_t:dir { getattr search write };
allow syslogd_t httpd_sys_rw_content_t:file { open read append getattr };
allow syslogd_t self:process execmem;
allow syslogd_t ping_exec_t:file execute;

Now run the following commands to make and apply our SELinux module.

checkmodule -M -m -o librenms-rsyslog.mod librenms-rsyslog.te
semodule_package -o librenms-rsyslog.pp -m librenms-rsyslog.mod
sudo semodule -i librenms-rsyslog.pp

Ubiquiti AirGateway Pro Firmware Download Link

Ubiquiti changed up their download pages and it appears that there is not a page to download the AirGateway Pro firmware.

The normal AirGateway and AirGateway LR use the same firmware. The Pro can use either 2.4 or 5Ghz frequencies and has a different firmware download.

When we search for AirGateway, we only find results for the regular and LR.

There is also no download link on either AirGateway page for the Pro.

https://ui.com/download/software/airgateway

Fortunately, we can copy the download link, and change the firmware name to download the Pro version. All we need to do is change “AirGW” to “AirGWP”

Here is the direct link.

https://dl.ubnt.com/firmwares/airgateway/v1.1.12/AirGWP.v1.1.12.1028.190918.0702.bin

AirGateway Random Users in Config!

Recently ran across some AirGateway configs that had an extra user account on them. Typically on most Ubiquiti AirMax and AirGateway equipment, there are two user accounts that show up in the config.

  • users.1.* which is the admin user.
  • users.2.* which is the read only user. Disabled by default

A cool trick we can do is add users in the config i.e. (users.3, users.4 etc.)

So what do you do when you see a third user showing up that you didn’t put there?!

The user account looked like the following.

users.3.name=112233AABBCC
users.3.password=Gczz8EBQEdAIg   
users.3.status=enabled

The username was the MAC address of the device and the password field is a DES(Unix) hash of what appears to be an 8 character randomly generated upper and lower case password.

Older AirOS versions only let a user select a password up to 8 characters long. You could create a longer one and log in via SSH, but you wouldn’t be able to log into the web interface.

Identifying Access

So how did these get on here in the first place?

I am guessing that the users were created at some point while trying to adopt them to UNMS/UISP before there was firmware that supported it. The user name is the actual MAC address of the device and the passwords do seem to be randomly generated. There do not appear to be any major differences between the support files from a normal AirGateway and a suspicious AirGateway.

Also appears to only affects AirGateways which were the only devices that had issues in the past connecting to UNMS/UISP. The rest of the AirMax equipment uses very similar firmware so if there was a security issue, it should have affected all the devices.

The hashing type “DES(Unix)” does not appear to be used anymore, being replaced with MD5 Crypt. So this does appear to have happened awhile ago.

Cracking the Hash

You’ll need hashcat installed and setup to crack the hash. Kali Linux has hashcat included (you will just want to have the NVIDIA drivers installed for optimal performance). You can also check out installing hashcat on Fedora, or check out the hashcat website for other systems. https://hashcat.net/hashcat/

Put the hashes of interest into a text file called hash.txt

Command to crack the passwords

 ./hashcat.bin -a 3 -m 1500 ./hash.txt -1?l?u ?1?1?1?1?1?1?1?1 -w 3 --session airgateway

the -1?l?u let’s us specify a custom character list made up of -l and -u. Lower and Upper case letters. –session airgateway will record a checkpoint ever so often. So if our run gets interrupted, we can restore the session with

./hashcat.bin --session airgateway --restore

Remediation

Fortunately, remediation is fairly simple.

SSH into the affected device and open up the config file

vi /tmp/system.cfg

Find the lines that start with “users.3.”, delete them, and save the file

Run the following command to save the changes.

/usr/etc/rc.d/rc.softrestart save 

If you are not comfortable with the command line, then you can, through the web gui, download a backup, edit the backup file in a text editor, then upload/restore the backup.

Other notes

Something else you may run across is a mcuser that shows up in /etc/passwd. This is typically a user used for AirControl, so if you have used AirControl in the past that is most likely why it is there. Check out the following article to remove the user.

Mongo “illegal hardware instruction mongo” on Linux

While trying to install and run mongo on Kali Linux, I encountered the following error.

zsh: illegal hardware instruction mongo

Using a Bash shell it returns the following instead.

Illegal instruction

It appears that the issue is from running mongo in a virtual machine.

https://www.mongodb.com/community/forums/t/mongodb-community-5-0-12-illegal-instruction-core-dumped-ubuntu-20-04-5-lts/204332

https://askubuntu.com/questions/699077/how-to-enable-avx2-extensions-on-a-ubuntu-guest-in-virtualbox-5

Resolution? Run on bare metal or find a way to enable avx2 in the virtual machine.

How To do a simple Timer in JavaScript

https://www.freecodecamp.org/news/javascript-timers-everything-you-need-to-know-5f31eaa37162/

Here are a couple different ways to do timers in JavaScript

Every X seconds do

We can use the setInterval global function to run code (myFunc()) every second.

setInterval(() => {
  myfunc()
}, 1000)

Execute X after Y seconds

Replace console.log with the code you want to execute with a delay.

setTimeout(() => {   
  console.log("Hello World")
}, 1000)

JavaScript Functions

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions

What is a function? A function is a block of code that does a particular task.

JavaScript has 3 different types of functions

  1. Function Declaration
  2. Function Expression
  3. Arrow Function Expression

Functions can also be named, or anonymous. There are a couple helpful things anonymous functions can help with.

Function Declaration

Function declaration’s are your standard functions. Syntax is as follows

function add(num1, num2) {
  return num1 + num2
}


console.log(add(1, 2));

Function Expression

A function expression can be thought of as a variable that is a function. We define function expressions like so

const add = function myFunction (num1, num2) {
  return num1 + num2;
}

console.log(add(1, 2));

Function expressions can be anonymous. To make the above function anonymous, remove “myFunction”. It would then read “function (num1, num2)”

Typically it is a good idea to name your function expressions as debugging anonymous functions can be a bit more difficult.

A warning about function expressions. They are not hoisted like function declarations. Just be sure that you define the function expression before you call it.

Arrow Function Expressions

Arrow functions are a compact version of function expressions that are always anonymous. They can be a bit tricky to get the syntax correct. Refer to the link below to get a better list of syntax and use. Arrow functions also have some other limitations. They do not have bindings to this, arguments or super.

const add = (num1, num2) => num1 + num2;

console.log(add(1, 2);

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

Anonymous Functions

Anonymous functions are functions that don’t have a name. For instance

function () {
  do something
}

Does not have a name and is therefore an anonymous function. Arrow functions are always anonymous.

When would you need to use an anonymous function?

One good example is when you want to call a named function from a timer, or when a button is clicked. For instance

// Find object id myButton
let buttonObject = document.getElementById('myButton')  

// Add an event listener, and run Log function when clicked.
buttonObject.addEventListener('click', Log) 
// If we call Log(), it will immediately trigger the function

function Log () {
  console.log("Hello World!")
}

But what if we want to pass in a variable to the Log function? We can’t run Log('some text') as the function will run before we click the object.

We can however wrap the Log function inside of an anonymous function like so

let buttonObject = document.getElementById('myButton')

// Now Log() function will be run with the variable getting passed.
buttonObject.addEventListener('click', function () {
  Log('Hello World!')
})

function Log (textVariable) {
  console.log(textVariable)
}

And our Log function gets triggered when the object is clicked, and the variable is passed properly. You can swap out function () with an arrow function () =>

How to Add a User from Windows Command Prompt

Adding a user from a Windows command prompt is easy. We can use the net user command. Specify the username and password, append a /ADD and we are off to the races.

net user username password /ADD

Example Command.

net user incredigeek mysecurepassword /ADD

https://www.windows-commandline.com/add-user-from-command-line/

How to Create a Preshared Key for Wireguard

You may have encountered a Mikrotik error when trying to create preshared key

Couldn't change wireguard peer<> - invalid preshared key (6)

This is because a Wireguard preshared key needs to be 256bit (32 byte) base64 encoded key. We have a couple different ways we can generate the correct format.

1. Use Openssl to generate a random 32 byte password

openssl rand 32 | base64

2. Create a 31 character password and base64 encode it

echo Thisisthepassword31characterslo | base64
VGhpc2lzdGhlcGFzc3dvcmQzMWNoYXJhY3RlcnNsbwo=

Now we can take this and add it to our config. The config option is

PresharedKey = VGhpc2lzdGhlcGFzc3dvcmQzMWNoYXJhY3RlcnNsbwo=

https://www.wireguard.com/papers/wireguard.pdf

https://forum.mikrotik.com/viewtopic.php?t=184469