Thursday, April 23, 2020

Easy Cord Cutting Guide - Zero to Hero

By Tony Lee

In my house, we don't watch a lot of traditional cable TV, so we ditched cable years ago and instead increased our Internet bandwidth so we could stream more content such as Amazon Prime, Hulu, Netflix, and now Disney+. Additionally we purchased a couple of inexpensive and easy to install over the air (OTA) antennas for two TVs so we can get local news + Good Morning America, Wheel of Fortune and Jeopardy! This setup which provided around 18 channels total worked great until Covid-19 hit and the family started watching a little more TV. I figured now is a good time to level up our cord cutting game and reduce some house hold stress (everyone else's stress--not mine... ha!). This guide is intended to give you the quick basics to get you up and running fast using freely available over the air TV signal.

Topics covered:

  • Checking Channel Availability
  • OTA Tuners
  • Antenna Choice
  • Antenna Direction
  • Signal Distribution
  • OTA Digital Video Recorder (DVR)


Checking Channel Availability

Before you even spend one penny, you can check to see what sort of channels you can expect to easily receive by using one of a handful of free websites. Two are shown below:

https://www.antennasdirect.com/transmitter-locator.html
https://www.antennaweb.org/

After entering your address, the map shows the transmitters relative to your house and in which direction to expect the signal.  Figure out which channels you care about and target those transmitters first.

Figure 1:  Map showing transmitters relative to my house

The same site will also list the number of the channel, the affiliate (name you know), and the distance as shown in Figure 2 below.  Depending on the terrain, you typically have a very good chance of picking up channels within 20 - 25 miles. For transmitters that are 35 - 50 miles away, that can be a little difficult and the signal can cut in and out on smaller antennas that are not attic or roof mounted.  Anything above 50 miles can be very difficult to receive without proper conditions and the antenna as high as possible.

Figure 2:  Channel line up and the likelihood of receiving the channels

OTA Tuners

Once you have determined the stations you want and the estimated feasibility, now you need to make sure your TV has an OTA tuner. The good news is that most flat panel TVs come with built in TV tuners that can use to find channels when hooked up to an OTA antenna. Each TV will vary in how to accomplish this, but generally you want to go to TV input > Antenna > Scan for channels. If you have an older TV that does not have a built in tuner, you can purchase a tuner for very little money, but check your TV first since it is probably already built-in. Tuner quality can make a difference, but in most cases it will be minor. A sample tuner for $30 is shown below if your TV does not already have one:  https://www.amazon.com/Mediasonic-HOMEWORX-HW130STB-Converter-Recording/dp/B01EW098XS

Figure 3:  Sample TV Tuner

Antenna Choice

Now that we confirmed we have an OTA tuner, there are a ton of antennas to choose from and we could write a novel just covering antenna theory, design, and options, etc. But we want to give you the basics so we will cover three of the best options here:

1)  Flat antenna - We received a max of 18 channels with this antenna
Good for one TV tuner placed on an outer wall or window in the general direction of the towers--this is fairly discrete and the easiest and cheapest way to get started and test the waters with minor risk.  Sometimes you can even hide these antennas on the wall behind the TV with the double sided tape provided. We used this for years to get the local channels on a couple of TVs and it worked great. But when we started consuming a bit more TV content, we moved to the larger antennas mentioned below.

Note: This antenna comes with an inline amplifier. Try it first without the amplifier and then try it with it the amplifier. Each time you change direction or configuration of the antenna you need to rescan for channels. If you are already close to the towers, the amplifier can work against you by overpowering the signal. If you are farther from towers, this may be beneficial to use it.

Subnote:  This Antenna claims it has a 120 mile range, but that is quite the over exaggeration. The planets would probably need to align for that to happen.  Meh.

Figure 4:  Basic flat antenna that you can stick to the wall or window

Subsubnote:  We also tried a TV mounted bar antenna on an inner room without access to an outer wall and the experience was not as good, but might be worth trying. It just depends on your conditions and proximity to the transmitters.  An example is shown below:
https://www.amazon.com/GE-UltraPro-Compatible-Amplifier-37075/dp/B071S7GN8P


2)  Inexpensive Small-ish Yagi Antenna - We received a max of 29 channels with this antenna
Now we will move into an antenna category that is probably too large to sit in your living room, but it should produce more channels by receiving signals from farther away. At around $50 regular price, this RCA yagi (https://www.amazon.com/Antenna-Satellite-Broadcast-Epicenter-Reception/dp/B0024R4B5C) is worth the $20 upgrade over the flat antenna, but now you need to attic, ground pole, or roof mount it and figure out where to run the coax (we ran a new coax cable to a wiring panel). We placed this antenna in our attic right on top of the insulation since it was so light weight. It claims to be a 70 mile antenna and that could be the case given perfect conditions.  There is very little assembly required, but the instructions are absolutely terrible, so you may need to read the instructions a million times to get it right...

Figure 5:  RCA Yagi Antenna

Figure 6:  The RCA yagi is so light weight it just sat on top of the insulation

3)  More expensive larger Antenna - We received a max of 43 channels with this antenna!!
If the RCA yagi did not get you exactly what you are seeking you can try to spend a tad more money than the yagi and go for a more capable antenna such as Antennas Direct Clearstream 4 (https://www.amazon.com/Antennas-Direct-ClearStream-Multi-directional-Installation/dp/B008PBTPOI). This also claims a 70 mile range which is quite possible given excellent conditions. This antenna impressed us right away with the easy assembly, increased amount of channels, and very strong signal.  The signals that came in weak for the RCA yagi came in great with this one. If you have $100 to spend on an antenna, this is worth it. This antenna not only picked up CBS, NBC, ABC, and FOX from 20 miles away, it also picked up PBS which we were not even receiving with the RCA yagi!


Figure 7:  Antennas Direct Clearstream 4


Figure 8:  Pole mounted the Clearstream due to the weight and inability to sit upright with the insulation

Antenna Direction

Before you climb into the attic to mount the antenna, make sure you download an antenna app or two to tell you the rough direction in which to point the antenna. We used two apps to spot check each other.

RCA Signal Finder app:
https://play.google.com/store/apps/details?id=com.voxxaccessories.signalfinder&hl=en_US

Digital TV Antennas app:
https://play.google.com/store/apps/details?id=ar.com.lichtmaier.antenas&hl=en_US

Both of these apps use GPS and compass capabilities in your phone to point you in the direction of the transmitter towers. So, we suggest you use multiple apps to check each other and this will get you very close. You may need someone standing at a TV confirming the signal quality though. One of our TVs (TCL 49S325) actually has a signal meter which was handy for this part.

Figure 9:  Using a phone app in the attic to determine the direction that the antenna needs to point

Signal Distribution

If you are using an attic, pole, or roof mount antenna, you probably want to run this signal to multiple TVs which requires splitting the signal. You could use a 2 or 3-way splitter to send it to a couple of TVs or your house may have a distribution panel which allows you to send it to all coax wall jacks. Either way, make sure you select the proper hardware below.

Passive Splitters:
For around $10 or less, you could try a passive splitter to send the signal to multiple TVs, however these introduce loss which matter far more in receiving OTA signal than through conventional cable TV.  Each split in the line can reduce the number of channels you can find and the overall signal quality. These are not really recommended--especially when chained, however if you need to split signal, try to get higher quality splitters with decent reviews. Two examples can be found below:

2-way splitter:
https://www.amazon.com/gp/product/B00KO8W93E/

3-way splitter:
https://www.amazon.com/gp/product/B00KO8W9RA/


"Lossless" distribution amplifier:
Signal boosters that also split the signal are typically more expensive ($40+) than passive splitters, however they should perform better--especially when splitting the signal to a high number of TVs. There are a fair amount of options here, but the most popular seem to be Leviton, Channel Master, or Antronix.

Figure 10:  Channel Master distribution amplifier


Figure 11:  Picture of my wiring "closet" - Distribution box into some splitters - needs some clean up.  :-|

8 output Channel Master Distribution Amplifier:
https://www.amazon.com/Channel-Master-Distribution-Amplifier-Antenna/dp/B002M1EPL0

9 Port Antronix Bi-Directional Cable TV Splitter Signal Booster:
https://www.amazon.com/gp/product/B07YYM4KBL


OTA Digital Video Recorder (DVR)

The last step to complete the premium OTA experience is to be able to provide a TV guide (some, but not all, TVs can generate this for you) and the ability to record, pause, and fast forward your favorite shows. For this, you will need an OTA DVR which can be the most expensive component of cutting the cord, but it may also be the step that makes it most palatable. There are a number of options listed below, but we chose the Amazon Fire TV Recast since we are already a household driven by Amazon and Alexa. This enables us to record 2 channels at the same time and watch 2 channels at the same time through the Fire sticks and any echo show device. The UI can be a little clunky at first, but once you get used to it, the experience is quite nice. My only wish is that it could stream to more than 2 devices at a time. If we need to do so, we just use the TVs tuner to watch live TV, but we don't get to fast forward or pause when we use the TVs tuner directly.  #FirstWorldProblems - let's keep it in perspective... Some other options are below, but note that some of them do not come with a hard drive and that is an additional cost.

Figure 12:  Fire TV Recast


Fire TV Recast ($194 on sale and includes the hard drive):
https://www.amazon.com/Fire-TV-Recast-over-the-air-DVR-1TB-150-hours/dp/B074J1GPB8/


Tablo Quad OTA DVR ($199 and still needs a hard drive):
https://www.amazon.com/Tablo-Quad-OTA-Cord-Cutters/dp/B07PLVF8B7


TiVo Bolt ($199 and includes the hard drive):
https://www.amazon.com/TiVo-Bolt-Antenna-All-One/dp/B07GY54JPV


Conclusion

This article outlines the various levels of cord cutting OTA heroism which is summarized below. You can spend as little as $30 for a decent experience or you can spend several hundred dollars for an experience so good--most do not know it is OTA. Either way, you will recover your investment over the long run and regardless of the reason for cutting the cord, you have plenty of options to still receive useful content for a reasonable time and money investment. Please feel free to leave feedback in the comments section.  Enjoy!

Level 1: - ~$30 - $60 total
 - Confirming channels - Free
 - Confirming tuner availability - Free or $30 max
 - Adding a flat antenna for a single TV - $30

Level 2: - ~$160
 - First two in level 1
 - Antenna is mounted on roof, attic, or pole in the proper direction - $100
 - Signal is distributed to multiple TV sets or the whole house via a powered distributor - $55

Level 3: Cost of Level 1 or 2 + $200+
 - All or most of level 2
 - OTA Digital Video Recorder

Figure 13: Progression of OTA super hero status

Tuesday, April 7, 2020

Battle Covid-19 Using 3D Printing

By Tony Lee

This is a bit of a different topic than we usually cover on this blog, but it is difficult to ignore the current situation regarding the Coronavirus. That said, many of my friends and family are putting in a valiant effort sewing masks to give away to doctors, nurses, family, friends, and even strangers on Facebook--hopefully these masks are a last resort for some previously mentioned but we might as well be prepared for the worst. That had me thinking as a non-sewing individual, how can I contribute? That's when I saw folks 3D printing parts for face shields and these things called "Ear Savers" which help prevent skin irritation behind the ear caused by friction from elastic bands found on common protective masks.

Figure 1:  Ear saver shown from:  https://www.thingiverse.com/thing:4255405
Prior to printing anything of actual importance my 3D printer's main duty was to print Play-Doh molds and toys for my kids. It has now been reassigned to a greater purpose and we are using this article to share some tips and tricks with others that may also want to contribute to battling Covid-19 using 3D printing. You can get up and running with the basics for a couple hundred dollars or less--the rest is convenience and efficiency.

Materials

3D Printer
The 3D printer I purchased two years ago is a Comgrow Creality Ender 3 (https://www.amazon.com/Comgrow-Creality-Ender-Aluminum-220x220x250mm/dp/B07BR3F9N6). It is a very capable printer that can print larger items, but it is sort of a kit that you put together (a task not for the faint of heart). At the time it was regularly priced at $230, but I bought it on an Amazon lightning deal for $180 as a STEM project that I could enjoy with my kids. This is just an example of what I use--but the exact printer does not matter as much for this purpose. 3D printers vary widely in price and capability and some printers even arrive pre-built and ready to go.  ;-)

3D Printing Filament
This is the material that is melted by the heat from the print nozzle and then reformed into whatever you are printing. Polylactic Acid (commonly called PLA) seems to be most commonly used material and it is derived from renewable resources like corn starch or sugar cane instead of petroleum.  Two examples of PLA that I have purchased are shown below.

White PLA large spool - $21
https://www.amazon.com/gp/product/B06XR7621X

Multicolor PLA 4 smaller spools - $23
https://www.amazon.com/gp/product/B074W1XFRX


Figure 2:  The 3D printer doing its thing!

3D Print Designs and Modification

Getting Ideas
If you are new to 3D printing, you may want to start off by using someone else's initial design and then possibly modifying it (if necessary).  A great place to get started with freely shared designs is Thingiverse (https://www.thingiverse.com/).  This is where I download .STL files and then convert them to .gcode -- which is essentially the three dimensional coordinates in space that the printer uses to know where to place the print nozzle. If you are a multivariable calculus nerd, you should naturally love 3D printing--but it is not needed to enjoy this hobby.

Simple Modifications
If you need to make some modifications to the design or even create your own from scratch, you can use the included slicer software or there are some really great free resources on-line. My Ender 3 came with Ultimaker Cura slicer software, but I don't really use it other than to convert the .STL files to .gcode.  Instead, I use a free site called Tinkercad (https://www.tinkercad.com/) which is made freely available by Autodesk. This software is amazingly powerful for editing .STL files from Thingiverse or other sites, but it can also be used to create your own 3D designs. As a final step, I still slice the .STL to .gcode using the included Ultimaker Cura software, but you could also try using the freely available ideaMaker slider from https://www.raise3d.com/download/.

Figure 3:  Modifying the design and quantity using Tinkercad

Monitoring the Print Job

There are many fancy ways to monitor a print job--some of which include customized firmware and Raspberry Pis, but I took a different approach. I purchased a 1080p Wyze camera (https://www.amazon.com/gp/product/B076H3SRXG) on sale from Amazon for around $20. I then play the video through my echo show ("Alexa, show me the Ender Camera") and watch for the print job to complete. The added bonus of using the Wyze camera is that it has night vision so I can turn the lights off in the garage but still monitor the print with excellent clarity. I can also ask Alexa to set a timer for the print job ("Alexa set a timer for x minutes") so I know roughly when to peel off the completed work and start a new one. A process that only takes a minute--the printer is doing the real work, but it doesn't mind.

Figure 4:  Monitoring the 3D print job using the Wyze camera through the Amazon Echo Show


Design Evaluation

The best thing about being able to 3D print something is instant gratification AND the ability to quickly evaluate the efficacy of an idea without a significant spend (time and money). In the case of the ear savers, we evaluated four different designs found on Thingiverse and tried them with the masks that my family is producing. Then we were able to stack rank them based on comfort and then start mass producing the most comfortable design. Of course, we appreciate everyone's contributions to Thingiverse, but some designs are work better for certain projects or are easier to modify when needed.

For example, the graciously provided ear saver designs we evaluated were:
https://www.thingiverse.com/thing:4263730
https://www.thingiverse.com/thing:4255405
https://www.thingiverse.com/thing:4264697
https://www.thingiverse.com/thing:4255721


Figure 5:  Evaluating the ear savers and ranking them in terms of comfort from top to bottom (personal preference)
This quick evaluation allowed us select the best option and now we include ear savers with every mask we deliver. When ear saver production out paces the masks, we send those out where there is a need.

Conclusion

At some point, we may post follow up articles that cover more of the intricacies of 3D printing, but we wanted to share this information with others who might also be looking for ways to contribute to the battle against Covid-19. We hope you enjoyed the article and encourage respectful and helpful feedback in the comment section below. This is by no means the only way to 3D print, but it should help some get started 3D printing to combat Covid-19. It is quite an amazing experience to see or hear about a person's reaction when you freely give them something you created to protect their health--sometimes they cry. There may be no way to describe this feeling in words, but it certainly makes the time and effort worth every second and every penny. Please stay safe and happy 3D printing.


Tuesday, February 25, 2020

Advanced Ticketing Analytics Using Your SIEM

By Tony Lee

The Problem with Ticketing Systems

Regardless of the vendor, ticketing systems are a double-edged sword. At the extremes they have immense power and utility when used correctly, but they can also overwhelm users and mislead decision makers when used incorrectly. My personal observations indicate that many implementations seem to be stuck in an in between state of partially useful without providing much insight. However, it isn’t the product’s fault per say because anything out of the box cannot efficiently solve all problems. Ticketing systems are multipurpose tools so they need a bit of customization to achieve their full potential. But this customization requires a good (but difficult to find) ticketing system develop, right?  Maybe not!  Take a look at our example below using ServiceNow and Splunk and let us know if you are doing something similar with other platforms.

Figure 1:  Example Splunk dashboard processing and displaying ServiceNow tickets


Possible Solution

All is not lost if you don’t have a good ticketing system developer. If you are sending the ticket data to your SIEM, you can build those dashboards and gain awesome insight within your single pane of glass. Some ideas for useful insights are:

  • Total number of tickets
  • Opened and assigned
  • Unassigned
  • Waiting on third party
  • Ticket priority
  • State of tickets
  • Oldest tickets
  • Most affected user
  • Most affected group/department
  • Responder handling the most tickets
  • Top close code


Bonus Round

In addition to building the statistical visibility above, filters can be quite useful in narrowing down the information you are seeking. This also allows you to pivot to more complex outliers. The following filters have proven quite useful for us:

  • Time range
  • Wild card search
  • Ticket state
  • Ticket substate
  • Assignment group
  • Priority 


Extra Credit

After creating the filters above, we recommend adding the ability to pivot back to the ticketing system to check out ticket details or possibly take action on tickets. Such as the ability to change the status of a ticket with a single click. These work flow efficiencies prevent copy and paste errors and shave off serious time and effort from an already overloaded responder. Our example dashboard contains multiple places where a responder may pivot back.

Conclusion

If you are in need of greater insight into tickets and their status, creating that insight in a SIEM such as Splunk may not be a bad idea. Even if you have a ticketing system developer, sometimes they just need some ideas to get started on dashboard development and this may be just what they need. This article is meant to provide ideas and even a jumpstart if Splunk and ServiceNow are in use in your environment. We hope it saves you some time—feel free to leave feedback in the section below.

Note:  In our ServiceNow / Splunk example, we used the existing Cylance ServiceNow Technology Add-on.  That said, not all fields are always properly parsed – especially if they are longer fields and use characters that may break the parsing.  It will get you 95% of the way there though.

Dashboard Code

The following dashboard assumes that the appropriate logs are being collected and sent to Splunk. Additionally, the dashboard code assumes an index of snow. Feel free to adjust as necessary. Splunk dashboard code provided below:

<form>
  <label>ServiceNow Tickets</label>
  <description>Limited to INSERT_YOUR CI Type</description>
  <search id="Base_Search">
    <query>index=snow sourcetype="snow:incident" $wild$ u_ci_autofill=YOUR_AUTOFILL_ID | dedup number | eval DaysOpen=round((now()-strptime(dv_opened_at, "%m-%d-%Y"))/86400,2) | rex field=dv_priority "\d\s-\s(?&lt;dv_priority&gt;.*)" | rex field=dv_severity "\d\s-\s(?&lt;dv_severity&gt;.*)" | table dv_opened_at, DaysOpen, dv_opened_by, dv_closed_at, dv_closed_by, number, dv_incident, dv_state, dv_substate, dv_close_code, dv_priority, dv_severity, dv_u_affected_user, dv_cmdb_ci, dv_malware_url, dv_approval, dv_assigned_to, dv_assignment_group, dv_short_description, close_notes | search $dv_priority$ $assignment_group$ $substate$ $dv_state$</query>
    <earliest>$time.earliest$</earliest>
    <latest>$time.latest$</latest>
  </search>
  <fieldset submitButton="false" autoRun="true">
    <input type="time" token="time" searchWhenChanged="true">
      <label>Time Range</label>
      <default>
        <earliest>-24h@h</earliest>
        <latest>now</latest>
      </default>
    </input>
    <input type="text" token="wild" searchWhenChanged="true">
      <label>Wildcard Search</label>
      <default>*</default>
    </input>
    <input type="dropdown" token="dv_state">
      <label>Ticket State</label>
      <choice value="NOT dv_state=Canceled NOT dv_state=Closed NOT dv_state=Resolved">Not Canceled, Closed, Resolved</choice>
      <choice value="*">All</choice>
      <choice value="dv_state=New">New</choice>
      <choice value="dv_state=Analysis">Analysis</choice>
      <choice value="dv_state=Contain">Contain</choice>
      <choice value="dv_state=Cancelled">Cancelled</choice>
      <choice value="dv_state=Closed">Closed</choice>
      <choice value="dv_state=Review">Review</choice>
      <choice value="dv_state=Resolved">Resolved</choice>
      <default>NOT dv_state=Canceled NOT dv_state=Closed NOT dv_state=Resolved</default>
      <initialValue>NOT dv_state=Canceled NOT dv_state=Closed NOT dv_state=Resolved</initialValue>
    </input>
    <input type="multiselect" token="substate">
      <label>Ticket Substate</label>
      <choice value="*">All</choice>
      <choice value="&quot;Waiting on External&quot;">Waiting on External</choice>
      <choice value="SOC">SOC</choice>
      <default>*</default>
      <initialValue>*</initialValue>
    </input>
    <input type="multiselect" token="assignment_group">
      <label>Assignment Group</label>
      <choice value="*">All</choice>
      <choice value="&quot;SOC Level 1&quot;">SOC Level 1</choice>
      <choice value="&quot;SOC Level 2&quot;">SOC Level 2</choice>
      <choice value="&quot;SOC Level 3&quot;">SOC Level 3</choice>
      <valuePrefix>dv_assignment_group=</valuePrefix>
      <delimiter> OR </delimiter>
      <default>*</default>
      <initialValue>*</initialValue>
    </input>
    <input type="multiselect" token="dv_priority">
      <label>Priority</label>
      <choice value="*">All</choice>
      <choice value="Critical">Critical</choice>
      <choice value="High">High</choice>
      <choice value="Moderate">Moderate</choice>
      <choice value="Low">Low</choice>
      <default>*</default>
      <initialValue>*</initialValue>
      <delimiter> OR dv_priority=</delimiter>
      <prefix>dv_priority=</prefix>
      <valuePrefix>"</valuePrefix>
      <valueSuffix>"</valueSuffix>
    </input>
  </fieldset>
  <row>
    <panel>
      <single>
        <title>Total Tickets</title>
        <search base="Base_Search">
          <query>| stats count</query>
        </search>
        <option name="drilldown">all</option>
        <option name="refresh.display">progressbar</option>
      </single>
    </panel>
    <panel>
      <single>
        <title>Open and Assigned</title>
        <search base="Base_Search">
          <query>| search dv_state!=Cancelled dv_state!=Closed NOT dv_assigned_to=""  | stats count</query>
        </search>
        <option name="drilldown">all</option>
      </single>
    </panel>
    <panel>
      <single>
        <title>Open and Not Assigned</title>
        <search base="Base_Search">
          <query>| search dv_state!=Cancelled dv_state!=Closed dv_assigned_to="" | stats count</query>
        </search>
        <option name="drilldown">all</option>
      </single>
    </panel>
    <panel>
      <single>
        <title>Waiting on External</title>
        <search base="Base_Search">
          <query>| where dv_substate="Waiting on External" | stats count</query>
        </search>
        <option name="drilldown">all</option>
      </single>
    </panel>
  </row>
  <row>
    <panel>
      <chart>
        <title>Priority</title>
        <search base="Base_Search">
          <query>| top limit=0 dv_priority</query>
        </search>
        <option name="charting.chart">pie</option>
      </chart>
    </panel>
    <panel>
      <chart>
        <title>Top State</title>
        <search base="Base_Search">
          <query>| top limit=0 dv_state</query>
        </search>
        <option name="charting.chart">pie</option>
      </chart>
    </panel>
    <panel>
      <chart>
        <title>Top CI</title>
        <search base="Base_Search">
          <query>| top limit=0 dv_cmdb_ci</query>
        </search>
        <option name="charting.chart">pie</option>
      </chart>
    </panel>
  </row>
  <row>
    <panel>
      <chart>
        <title>Longest Open Tickets &gt; 7 days (Click to View Directly in Service Now)</title>
        <search base="Base_Search">
          <query>| stats values(DaysOpen) by number | rename values(DaysOpen) AS DaysOpen | where DaysOpen &gt; 7</query>
        </search>
        <option name="charting.axisTitleX.visibility">visible</option>
        <option name="charting.axisTitleY.visibility">collapsed</option>
        <option name="charting.axisY.scale">linear</option>
        <option name="charting.chart">bar</option>
        <option name="charting.chart.showDataLabels">all</option>
        <option name="charting.chart.stackMode">default</option>
        <option name="charting.drilldown">all</option>
        <option name="charting.layout.splitSeries">0</option>
        <option name="charting.legend.labelStyle.overflowMode">ellipsisEnd</option>
        <option name="charting.legend.placement">right</option>
        <drilldown>
          <link target="_blank">https://INSERT_YOUR.service-now.com/nav_to.do?uri=incident.do?sysparm_query=number%3D$row.number$</link>
        </drilldown>
      </chart>
    </panel>
    <panel>
      <chart>
        <title>Longest Open Tickets &gt; 7 days (Click to View in Splunk)</title>
        <search base="Base_Search">
          <query>| eval info=dv_assigned_to + " - " + number | stats values(DaysOpen) by info | rename values(DaysOpen) AS DaysOpen | sort - DaysOpen | where DaysOpen &gt; 7</query>
        </search>
        <option name="charting.axisTitleX.visibility">collapsed</option>
        <option name="charting.axisTitleY.visibility">collapsed</option>
        <option name="charting.axisY.scale">linear</option>
        <option name="charting.chart">bar</option>
        <option name="charting.chart.showDataLabels">all</option>
        <option name="charting.chart.stackMode">default</option>
        <option name="charting.drilldown">all</option>
        <option name="charting.layout.splitSeries">0</option>
        <option name="charting.legend.labelStyle.overflowMode">ellipsisEnd</option>
        <option name="charting.legend.placement">right</option>
      </chart>
    </panel>
  </row>
  <row>
    <panel>
      <table>
        <title>Top dv_u_affected_user</title>
        <search base="Base_Search">
          <query>| top limit=0 dv_u_affected_user</query>
        </search>
        <option name="drilldown">cell</option>
      </table>
    </panel>
    <panel>
      <table>
        <title>Top dv_assigned_to</title>
        <search base="Base_Search">
          <query>| top limit=0 dv_assigned_to</query>
        </search>
        <option name="drilldown">cell</option>
      </table>
    </panel>
    <panel>
      <table>
        <title>Top dv_assignment_group</title>
        <search base="Base_Search">
          <query>| top limit=0 dv_assignment_group</query>
        </search>
        <option name="drilldown">cell</option>
      </table>
    </panel>
    <panel>
      <table>
        <title>Top dv_close_code</title>
        <search base="Base_Search">
          <query>| top limit=0 dv_close_code</query>
        </search>
        <option name="drilldown">cell</option>
      </table>
    </panel>
  </row>
  <row>
    <panel>
      <table>
        <title>Details (Click the row to visit ServiceNow directly)</title>
        <search base="Base_Search">
          <query/>
        </search>
        <option name="dataOverlayMode">none</option>
        <option name="drilldown">cell</option>
        <option name="percentagesRow">false</option>
        <option name="rowNumbers">true</option>
        <option name="totalsRow">false</option>
        <option name="wrap">true</option>
        <format type="color" field="dv_incident">
          <colorPalette type="list">[#65A637,#6DB7C6,#F7BC38,#F58F39,#D93F3C]</colorPalette>
          <scale type="threshold">0,30,70,100</scale>
        </format>
        <format type="color" field="dv_substate">
          <colorPalette type="map">{"Waiting on External":#6A5C9E}</colorPalette>
        </format>
        <format type="color" field="dv_priority">
          <colorPalette type="map">{"High":#D93F3C,"Medium":#F7BC38,"Low":#6DB7C6}</colorPalette>
        </format>
        <drilldown>
          <link target="_blank">https://INSERT_YOUR.service-now.com/nav_to.do?uri=incident.do?sysparm_query=number%3D$row.number$</link>
        </drilldown>
      </table>
    </panel>
  </row>
</form>



Sunday, February 9, 2020

Detecting DNS Tunneling Using Subdomain Frequency Analysis

By Tony Lee

For those that may not be familiar, DNS tunneling is the process of embedding data inside DNS requests and responses. It is typically used by a threat actor as a last resort command and control (C2) channel due to the size limitations of DNS packets. One trade-off for the limited size and slow speed is that it is one of the stealthiest and most difficult C2 channels to detect--thus it is quite effective at  maintaining persistence even after other C2 is discovered and eliminated. Due to the prevalence of DNS and its generally trusted (not inspected) status in most networks, most organizations have little-to-no visibility, however this article will cover just one of the many methods of detecting this stealthy C2.  The first step is to collect the DNS logs and send them to a central log aggregation platform such as Splunk--which is what our example uses, but feel free to apply it to your platform of choosing.


Figure 1:  Visual explanation of DNS Tunneling


Query Length

After collecting the logs, we will next look for abnormally long DNS queries. Technically the longest allowable domain name per the RFC is 253 characters (including the dots)--thus we can encode enough data in each fully qualified domain name (FQDN) to constitute C2, but it does require creating longer DNS queries. The example search below assumes that we are storing the DNS logs in an index called dns and log format of Microsoft Windows AD DNS (hence the sourcetype), but this will also work for BIND and other DNS data.  Our example checks for a DNS query length greater than 50 characters--but it can be tuned to whatever works best in your environment. Keep in mind that if the number is too low, you will see too many false positives.  If it is too high, you may miss some tunneling or other strangeness that you want to investigate.  We recommend that you start at 50 and adjust as needed.

index=dns sourcetype="MSAD:NT6:DNS" NOT (query="_ldap*" OR query="*.in-addr.arpa." OR query="*.ip6.arpa") | where len(query)>50

Note:  Be sure to check that your DNS query is actually contained in the "query" field

Subdomain Frequency Analysis

If the above search worked and returned some results, we have met the prerequisites.  Taking the search above a step further we are going to parse out the domain portion and use statistical analysis to give us the following columns:
  • The domain controlled by the attacker
  • Potential number of victims querying this domain
  • Number of subdomains
  • Number of times the attacker-controlled domain was queried
  • List of potential victims
  • List of the subdomains that were queried

index=dns sourcetype="MSAD:NT6:DNS" NOT (query="_ldap*" OR query="*.in-addr.arpa." OR query="*.ip6.arpa") | where len(query)>50 | rex field=query ".*?\.(?<domain>.*)\.$" | stats dc(src_ip) AS NumSourceIPs, dc(query) AS NumSubDomains, count(query) AS DomainQueryCount, values(src_ip) AS SourceIPs, values(query) AS Subdomains by domain | sort - NumSubDomains | where NumSubDomains>1

Figure 1:  Fields provided by the search string above

Now look for anything that stands out as being suspicious.  Keep in mind some of this may be legitimate traffic, but you may also find some known bad domains as you research the results.


Defense Strategy

As mentioned in the introduction, DNS tunneling can be tough to defend against.  However, follow these tips and it will increase the difficulty of attacker success.
  • Keep a simple DNS infrastructure.  The more complicated and chained, the more difficult it is to detect this issue
  • Do not allow hosts to go directly to the Internet for DNS (block all but the DNS servers at the firewall and monitor for any deviation)
  • Send all DNS logs (Microsoft AD, BIND, etc.) to a centralized logging platform
  • Run searches (such as the one provided in this article) to continuously monitor and alert on anomalies
  • Use threat intelligence to augment your DNS tunneling searches to alert against known malicious domains

Conclusion

There are many ways of detecting potential DNS tunneling and this is just one of them. Even if you don't catch a threat actor in your network, you may end up discovering something else strange.  Content distribution networks (CDNs), threat actors, marketing software, spyware, and more may turn up in your search results.  Maybe some or all of those are a concern to your team.  You won't know until you take a look though.  Happy Searching!

References

Good explanation of DNS tunneling found at:  https://hackersterminal.com/dns-tunneling/ -- Kudos for their graphic as well--it is one of the clearest we found on-line.  Nice work.

Wednesday, November 27, 2019

Making Splunk Dashboards Available Outside of Splunk

By Tony Lee

Have you ever built a beautiful Splunk dashboard that was not only aesthetically pleasing, but also incredibly insightful? If so, maybe others learned of its value and now want that data shared--even to users who may not have Splunk accounts. We had such a case in which the Chief Information Officer (CIO) wanted to add a particular Splunk panel to his intranet site for all employees to see. In this article we will recreate the scenario and show you how this can be accomplished. The two screenshots below show two possibilities of embedding Splunk panels into external sites.

Figure 1:  Example of  a single panel embedded into a page outside of Splunk

Figure 2:  Example of two panels embedded into a page outside of Splunk

Problem

There are quite a few issues that we need to solve, such as:
  • Splunk does not make it easy to share panels and especially entire dashboards outside of their platform
  • Some data may be sensitive in nature, so just remember the potential audience
    • Fortunately, this sharing can be disabled if needed
  • This solution needs to be long-term low maintenance which means no manual updates
  • The new website must be able to reach the Splunk search head via HTTPS

Potential Solution

The potential solution we are going to show uses scheduled saved reports to share out a panel. Here are the steps below:

1) Generate your insightful panel using the proper search.  Click Save As > Report

Figure 3:  Creating a report

2)  Select the content and time range selector

Figure 4:  Saving the report

3) After saving the report, let's schedule it

Figure 5: Schedule the report

4) Specify the schedule - this example updates the report every hour with the last hour of data

Figure 6:  Schedule parameters

5) Generate the embedded link by clicking Edit > Embed

Figure 7: Generating the embedded link

6)  Copy the embedded iframe link into the external site in question (Example site shown in Demo Page Code section below)

Figure 8:  Embedded iframe link

Conclusion

This is one possible solution that creates a low maintenance panel shared outside of Splunk. If you want to share an entire dashboard, this can be repeated for every panel in the dashboard. Just be cautious of the sensitivity of the data. If it is later determined that this data is no longer needed or should not be shared, it can be disabled. If you have a different method of sharing panels and especially entire dashboards, we would love to hear it.  Feel free to post it in the comment section below and as always happy Splunking.

Demo Page Code

This is just a demo page that contains two embedded saved reports.  The panel on the left is a single value number and the one on the right is a timechart.  Just remember to replace the two locations of:  "YOUR_EMBEDDED_LINK_HERE"


<HTML>
<HEAD>
<TITLE>This is an embedded demo</TITLE>
<style type="text/css">
<!--
td {
  height: 300px;
  vertical-align: center;
  text-align: center;
}
iframe {
  vertical-align: center;
  text-align: center;
}
-->
</style>
</HEAD>
<BODY>

<center><h2>CIO's Corner</h2></center>

<table style="width:100%" border=1>
  <tr>
    <th>Total Count</th>
    <th>Count over Time</th> 
  </tr>
  <tr>
    <td width="25%" height=300><iframe frameborder="0" scrolling="no" src="YOUR_EMBEDDED_LINK_HERE"></iframe></td>
    <td width="75%" height=300><iframe height="100%" width="100%" frameborder="0" scrolling="no" src="YOUR_EMBEDDED_LINK_HERE"></iframe></td>
  </tr>
</table>

</BODY>
</HTML>