Validating the security Blog Post

Unimus support forum
jstump
Posts: 11
Joined: Thu Jul 14, 2016 8:26 pm

Wed Aug 08, 2018 2:05 pm

Thanks for this! Very useful.

The only issue I'm having right now is that running this on 200 devices has created 23 different output groups, but they all have the same output? I have tripled checked to be sure. Running the latest version of Unimus and 6.42.6 and a few still (I know!) on 6.39.3. Ideas?
User avatar
Tomas
Posts: 561
Joined: Sat Jun 25, 2016 12:33 pm

Wed Aug 08, 2018 2:12 pm

Please re-run the installer to make sure you are running the latest build.
There were some hotfixes to output grouping.

Basically, MikroTik was adding a different number of spaces to output depending on how long the system identity was. That was causing creation of new output groups, since output was technically different.

We fixed it, but you will have to update to the newest build.
jstump
Posts: 11
Joined: Thu Jul 14, 2016 8:26 pm

Wed Aug 08, 2018 2:51 pm

Missed that. Thanks for the quick response. Updated and all good. Thanks again!
JAz
Posts: 34
Joined: Thu Apr 26, 2018 11:06 pm

Mon Aug 13, 2018 8:42 am

First, thanks for the blog post. Looks great, if only it worked for me. Not sure what I'm missing.

I get an

Code: Select all

"INTERACTION-ERROR-1". 
I've traced it down to the 3rd statement from your blog post:

Code: Select all

:if ([:len [/file find name~".*[Mm]ikrotik\\.php.*"]] >= 1) do={
  :put "\"mikrotik.php\" file found on the file system, high chance this device has been breached!"
} else { :put "Looks clean"}
Which runs successfully in a terminal in Winbox but causes the error if I run it in a push.

Unhelpfully, there is no log or anything I can find to see what failed. The "failed job" log on the Dashboard page shows nothing (the "job" did not fail after all) and the error text is terse and not explanatory.

So two things:

# 2 - suggestion/feature request for a push "job log" (tail or similar for example) of all interactions and replies to/from the router (yes, this could get lengthy/verbose but what is the alternative? How do we troubleshoot if we can't see where it breaks?)
The log (or more correctly a button going to it..) could be added directly to each push's screen. If you're concerned about verbosity and/or the extra bandwidth, a checkbox to turn this 'job logging' on and off could be added. I expect this serves not just debugging Unimus (if indeed Unimus is the issue here) but also debugging Push commands.

# 1 - What does my error mean and how do I fix it and run?

I'm on 1.8.2.
Thanks.
User avatar
Tomas
Posts: 561
Joined: Sat Jun 25, 2016 12:33 pm

Mon Aug 13, 2018 9:40 am

Not sure what I'm missing.
Else requires and = after it (before the curly bracket).

Code: Select all

...
} else={
...
Unhelpfully, there is no log or anything I can find to see what failed. The "failed job" log on the Dashboard page shows nothing (the "job" did not fail after all) and the error text is terse and not explanatory.
Indeed, we need to improve Mass Config Push to better let the user know what failed.

Thanks for the #2 suggestion, we will do some brainstorming here how to best handle / implement this.
Your suggestion will definitely not get lost in that discussion :)
JAz
Posts: 34
Joined: Thu Apr 26, 2018 11:06 pm

Mon Aug 13, 2018 4:38 pm

Tomas wrote:
Mon Aug 13, 2018 9:40 am
Not sure what I'm missing.
Else requires and = after it (before the curly bracket).

Code: Select all

...
} else={
...
Hmmm. I added that statement as a debug aid just to see if anything was happening in the local terminal. I had the same problem with the code as I copied /pasted it.
It also works without the '=' in the other four statements.

Unhelpfully, there is no log or anything I can find to see what failed. The "failed job" log on the Dashboard page shows nothing (the "job" did not fail after all) and the error text is terse and not explanatory.
Indeed, we need to improve Mass Config Push to better let the user know what failed.

Thanks for the #2 suggestion, we will do some brainstorming here how to best handle / implement this.
Your suggestion will definitely not get lost in that discussion :)
Good. Glad I can be of help. :)


EDIT-

Ok, just for the sake of trying, went and added the '=' in the else statement. No joy.
Also, I should clarify, I had added that else statement on all 5 directives and it works on the other 4. With and without the '=' following the 'else'.
JAz
Posts: 34
Joined: Thu Apr 26, 2018 11:06 pm

Mon Aug 13, 2018 7:29 pm

Follow up -


Had a few more minutes to play, still looking for a rhyme or reason -
I guessed maybe the line breaks were affecting so I concated each statement/directive to one line. No help. (I broke them apart again for readability)

I've reviewed the code and each line seems ok. Only the one line searching the scripts source causes a problem. I see no reason for it.

Here is teh full code I'm running for the snippet. I can comment out the one line and the push runs fine.

This runs (script source line commented) :

Code: Select all

:if ([/ip socks get enabled]) do={
  :put "Socks is enabled, if you didn't do this manually, this device has been breached!"
} else={ :put "Looks clean"}
:if ([:len [/file find name~".*[Mm]ikrotik\\.php.*"]] >= 1) do={
  :put "\"mikrotik.php\" file found on the file system, high chance this device has been breached!"
} else={ :put "Looks clean"}
#:if ([:len [/system script find source~".*[Mm]ikrotik\\.php.*"]] >= 1) do={
  :put "A script containing \"mikrotik.php\" found, high chance this device has been breached!"
} else={ :put "Looks clean"}
:if ([:len [/system scheduler find on-event~".*[Mm]ikrotik\\.php.*"]] >= 1) do={
  :put "A scheduled script containing \"mikrotik.php\" found, high chance this device has been breached!"
} else { :put "Looks clean"}
:if ([:len [/user find name~".*service.*"]] >= 1) do={
  :put "\"service\" user exists, if you didn't create this user manually, this device has been breached!"
} else={ :put "Looks clean"}
With this output:

Code: Select all

<prompt> :if ([/ip socks get enabled]) do={
{...                                                 
  :put "Socks is enabled, if you didn't do this manually, this device has been breached!"
{...                                                                                          
} else={ :put "Looks clean"}
Looks clean
<prompt> :if ([:len [/file find name~".*[Mm]ikrotik\\.php.*"]] >= 1) do={
{...                                                                               
  :put "\"mikrotik.php\" file found on the file system, high chance this device has been breached!"
{...                                                                                                    
} else={ :put "Looks clean"}
Looks clean
<prompt> #:if ([:len [/system script find source~".*[Mm]ikrotik\\.php.*"]] >= 1) do={
<prompt>   :put "A script containing \"mikrotik.php\" found, high chance this device has been breached!"
A script containing "mikrotik.php" found, high chance this device has been breached!
<prompt> } else={ :put "Looks clean"}
<prompt> :if ([:len [/system scheduler find on-event~".*[Mm]ikrotik\\.php.*"]] >= 1) do={
{...                                                                                               
  :put "A scheduled script containing \"mikrotik.php\" found, high chance this device has been breached!"
{...                                                                                                          
} else { :put "Looks clean"}
Looks clean
<prompt> :if ([:len [/user find name~".*service.*"]] >= 1) do={
{...                                                                     
  :put "\"service\" user exists, if you didn't create this user manually, this device has been breached!"
{...                                                                                                          
} else={ :put "Looks clean"}
Looks clean
<prompt> 

*** But this fails: (only uncommented the script source line) ***

Code: Select all

<prompt> :if ([/ip socks get enabled]) do={
{...                                                 
  :put "Socks is enabled, if you didn't do this manually, this device has been breached!"
{...                                                                                          
} else={ :put "Looks clean"}
Looks clean
<prompt> :if ([:len [/file find name~".*[Mm]ikrotik\\.php.*"]] >= 1) do={
{...                                                                               
  :put "\"mikrotik.php\" file found on the file system, high chance this device has been breached!"
{...                                                                                                    
} else={ :put "Looks clean"}
Looks clean
<prompt> #:if ([:len [/system script find source~".*[Mm]ikrotik\\.php.*"]] >= 1) do={
<prompt>   :put "A script containing \"mikrotik.php\" found, high chance this device has been breached!"
A script containing "mikrotik.php" found, high chance this device has been breached!
<prompt> } else={ :put "Looks clean"}
<prompt> :if ([:len [/system scheduler find on-event~".*[Mm]ikrotik\\.php.*"]] >= 1) do={
{...                                                                                               
  :put "A scheduled script containing \"mikrotik.php\" found, high chance this device has been breached!"
{...                                                                                                          
} else { :put "Looks clean"}
Looks clean
<prompt> :if ([:len [/user find name~".*service.*"]] >= 1) do={
{...                                                                     
  :put "\"service\" user exists, if you didn't create this user manually, this device has been breached!"
{...                                                                                                          
} else={ :put "Looks clean"}
Looks clean
<prompt> 

With a "Group" result of INTERACTION_ERROR-1 ( <=== What exactly does this mean?) and no output.


Image
User avatar
Tomas
Posts: 561
Joined: Sat Jun 25, 2016 12:33 pm

Mon Aug 13, 2018 7:38 pm

"INTERACTION_ERROR" means that prompt was not received when expected.
(technically it means "something" Unimus was waiting for did not come within timeout - such as prompt, a "[y/n]" question, etc.)

Can you please run Unimus in debug mode and run the push on one device that is failing?
Please PM me the debug logs from that run.

How to run in debug:

On Linux:

Code: Select all

sudo su
service unimus stop
cd /opt/unimus
java -jar Unimus.jar \
--logging.level.net.unimus.core=TRACE \
--unimus.core.echo-ssh=TRUE \
--unimus.core.echo-telnet=TRUE
On Windows:

Code: Select all

1) Download .jar distribution:
   https://unimus.net/download.html
2) Stop Unimus service
   If you are running the Portable version, skip this
3) Open an admin command prompt
4) change to folder where Unimus.jar was downloaded
5) Run "java -jar Unimus.jar --logging.level.net.unimus.core=TRACE --unimus.core.echo-ssh=TRUE --unimus.core.echo-telnet=TRUE"
6) Logs should be in the command prompt window
JAz
Posts: 34
Joined: Thu Apr 26, 2018 11:06 pm

Tue Aug 14, 2018 9:03 am

Debug sent
User avatar
Tomas
Posts: 561
Joined: Sat Jun 25, 2016 12:33 pm

Wed Aug 15, 2018 11:46 am

Thanks for the log!

If you run this manually on the router:

Code: Select all

:if ([:len [/system script find source~".*[Mm]ikrotik\\.php.*"]] >= 1) do={
  :put "A script containing \"mikrotik.php\" found, high chance this device has been breached!"
} else={ :put "No scripts referencig mikrotik.php found"}
How long does it take to output "No scripts referencig mikrotik.php found" and the prompt?

Thanks!
Post Reply