Alarm mode

alarm ALARM_MODE ALARM_AND DNS pcre regex

Introduction

This tutorial details the use of the Alarm mode of the Anteater, which enables the user to produce plugin controlled flow release. Hence, any plugin can invoke an internal signal to release a specific flow, otherwise no flows are produced. An easy way to transform T2 into an elaborate NIDS. The following plugins implement currently the alarm mode:

dnsDecode if a DNS name is detected in a black list
regex_pcre if a regex triggers

Moreover, with the help of the pcapd plugin you can also extract all packets of a flow processed after the specific alarm.

Preparation

First, restore T2 into a pristine state by removing all unnecessary or older plugins from the plugin folder ~/.tranalyzer/plugins:

t2build -e -y

Are you sure you want to empty the plugin folder '/home/wurst/.tranalyzer/plugins' (y/N)? yes
Plugin folder emptied

Then compile the following plugins:

t2build tranalyzer2 basicFlow tcpStates dnsDecode txtSink

...
BUILD SUCCESSFUL

If you did not create a separate data and results directory yet, please do it now in another bash window, that facilitates your workflow:

mkdir ~/data ~/results

The anonymized sample PCAP used in this tutorial can be downloaded here: 2015-05-08-traffic-analysis-exercise.pcap. (Source: malware-traffic-analysis.net). Please extract it under your data folder.

Now you are all set for T2 alarm experiments.

Core alarm control

The alarm mode controls of the Anteater are residing in tranalyzer2/src/tranalyzer.h:

tranalyzer2

vi src/tranalyzer.h

...
// Tranalyzer User Operational modes

// Operation modes, Plugins which use these modes have to be recompiled

#define ALARM_MODE 0 // only flow output if an Alarm based plugin fires
#define ALARM_AND  0 // if (ALARM_MODE == 1) then 1: AND, 0: OR

#define FORCE_MODE 0 // netflow mode: parameter induced flow termination, implemented by plugins
#define BLOCK_BUF  0 // block unnecessary buffer output when non tranalyzer format event-based plugins are active: e.g. Syslog, ArcSight crap

#define USE_T2BUS  0 // XXX experimental (not implemented yet)
...

To enable the alarm mode switch ALARM_MODE to 1 as shown above. Several plugins can trigger an alarm concurrently, as we do not know what kind of plugin armada you might develop in the future. So the ALARM_AND switch denotes whether the flow release is triggered by a logical AND or OR. So either all alarm registered plugins must agree that this is worth a flow or either one can release a flow. The default value is OR, so any plugin can release a flow. Edit tranalyzer.h or use t2conf. Recompile t2 including all existing plugins:

t2conf tranalyzer2 -D ALARM_MODE=1 && t2build -R

Plugin alarm register and control

Let’s look at the dnsDecode plugin to illustrate the principle. It is capable to look for malware domains/IPs from a blacklist. This can be combined with the alarm mode, so that only the malware flows are released.

Move to the dnsDecode plugin folder and look into it:

dnsDecode

ls

autogen.sh  CMakeLists.txt  configure.ac  COPYING  default.config  doc  Makefile.am  maldomain.txt  meson.build  src  t2plconf  tests  utils

The file maldomain.txt contains a list of malware domains, not the newest, so feel free to compile your own. There are lots of lists available online. autogen.sh or t2build will convert that list into a T2 formatted list maldm.txt and copy it under your ~/.tranalyzer/plugins directory. More about that later when we edit the maldomain.txt list.

Now move to the src directory

ls src

dnsDecode.c  dnsDecode.h  dnsType.h  Makefile.am  malsite.c  malsite.h

malsite.c contains the search algorithm and malsite.h defines the type of search: domain or IP. Not important at the moment. Now open dsnDecode.h and enable the flow based malware test.

vi src/dnsDecode.h

...
/* ========================================================================== */
/* ------------------------ USER CONFIGURATION FLAGS ------------------------ */
/* ========================================================================== */

#define DNS_MODE         4 // 0: Only aggregated header info,
                           // 1: +Req Content Info,
                           // 2: +Answer Records,
                           // 3: +AUX records,
                           // 4: +Add records

#define DNS_HEXON        0 // 0: Hex output flags off, 1: Hex output flags on
#define DNS_HDRMD        0 // Header Flags_OpCode_RetCode: 0: Bitfield; 1: Integer; 2: String
#define DNS_TYPE         0 // Q/A Type: 0: Numeric; 1: String
#define DNS_AGGR         0 // 1: Record aggregation mode

#define DNS_QRECMAX     15 // Max # of query records / flow
#define DNS_ARECMAX     20 // Max # of answer records / flow

#define DNS_WHO          0 // 1: Country and organization of DNS reply address; 0: no

#define DNS_MAL_TEST     0 // 2: Mal test @ L4Callback, pcap ops; 1: Mal test @ flow terminated
#define DNS_MAL_TYPE     1 // 1: Type string; 0: Code

/* +++++++++++++++++++++ ENV / RUNTIME - conf Variables +++++++++++++++++++++ */

/*        No env / runtime configuration flags available for dnsDecode        */

/* ========================================================================== */
/* ------------------------- DO NOT EDIT BELOW HERE ------------------------- */
/* ========================================================================== */
...

MAL_TEST=1 produces the malware test on flow terminated, so it is more performant, than option 2 which does it at every packet.

MAL_TYPE is set to a human readable string output. A code number, the 2nd entry in the generated list maldm.txt under ~/.tranalyzer/plugins shown below, might be better for AI training purposes. So set MAL_TEST first.

t2conf dnsDecode -D MAL_TEST=1 && t2build dnsDecode

dnsDecode

lsx maldm.txt


...
uivabretof.com                          48                                      phishing
rujva.co.uk                             48                                      phishing
rukn-aljamal.com                        48                                      phishing
rumahhufazh.or.id                       48                                      phishing
rumahmakannusantara.biz.id              48                                      phishing
runawaydragons.com                      48                                      phishing
rundll.co.in                            57                                      scam
runngineszservices.co.uk                48                                      phishing
runvtkk.tel.lv                          48                                      phishing
runzemaoye.com                          42                                      malware
rupanic.webescuela.cl                   48                                      phishing
rupeewiz.com                            48                                      phishing
rupertsigns.com                         48                                      phishing
rushrepublic.co.uk                      48                                      phishing
rusiapromo2018.ml                       48                                      phishing
rusmondf.com                            48                                      phishing
russelakic.com                          60                                      suspicious
russianfossils.com                      48                                      phishing
...

If you want to add some more domains or download a new file store it under the name maldomain.txt in the dnsDecode directory. Because I do not have an appropriate pcap yet, add at the end of the maldomain.txt an entry indicated below:

vi maldomain.txt


...
bankhapoalim-online.com phishing
bestmLxer.in    phishing
rnyuthewallet.com       phishing
bankhapoailm.com        phishing
stevenmyersphotography.com      phishing
www.cambridge-solutions.online  phishing
bankhapoailm-login.com  phishing
btcbozdurma.ml  phishing
rnuelherwallet.com      phishing
techincpo.club  phishing
kbcbankieren.com        phishing
runlove.us      trojan      		<-- add this here at the end of the file, mind the tab between the parameters, but do not add this comment

Note columns are tab separated, so don’t just copy the last line without replacing all blanks. Invoke now the prepdl script in the dnsDecode/utils/ directory and copy the resulting file to ~/.tranalyzer/plugins/maldm.txt. If you invoke t2build -f, a new list will be downloaded and your changes will be overwritten.

Then invoke t2 on the pcap:

utils/prepdl -c

converting malware domains list 'maldomain.txt' to 'maldm.txt'

t2 -r ~/data/2015-05-08-traffic-analysis-exercise.pcap -w ~/results/

T2 indicates the alarm mode in the third line of the end report:


[INF] Creating flows for L2, IPv4, IPv6 [ALARM]

A warning at the end reports the total number of alarms and alarm flows. So two alarms in two flows total and all are coming from dnsDecode, because it is the only plugin loaded. The corresponding flows can be inspected in the flow file via a simple tawk statement. You see the detected runlove.us request and our type description in the two flows being written to the flow file out of 68 flows total.

tcol ~/results/2015-05-08-traffic-analysis-exercise_flows.txt

%dir  flowInd  flowStat            timeFirst          timeLast           duration  numHdrDesc  numHdrs  hdrDesc       srcMac             dstMac             ethType  vlanID  srcIP            srcIPCC  srcIPOrg           srcPort  dstIP            dstIPCC  dstIPOrg           dstPort  l4Proto  tcpStatesAFlags  dnsStat  dnsHdrOPField  dnsHFlg_OpC_RetC    dnsCntQu_Asw_Aux_Add  dnsAAAqF  dnsQname      dnsMalCnt  dnsMalType  dnsAname      dnsAPname  dns4Aaddress     dns6Aaddress  dnsQType  dnsQClass  dnsAType  dnsAClass  dnsATTL  dnsMXpref  dnsSRVprio  dnsSRVwgt  dnsSRVprt  dnsOptStat
A     17       0x0400000000004000  1431031903.052371  1431031903.052371  0.000000  1           3        eth:ipv4:udp  00:00:00:00:00:00  00:00:00:00:00:00  0x0800           192.168.138.158  07       "Private network"  61720    192.168.138.2    07       "Private network"  53       17       0x00             0x0001   0x0100         0x10_0x0001_0x0001  1_0_0_0               0         "runlove.us"  1          "trojan"                                                            1         1
B     17       0x0400000000004001  1431031903.089942  1431031903.089942  0.000000  1           3        eth:ipv4:udp  00:00:00:00:00:00  00:00:00:00:00:00  0x0800           192.168.138.2    07       "Private network"  53       192.168.138.158  07       "Private network"  61720    17       0x00             0x0001   0x8180         0x98_0x0001_0x0001  1_1_0_0               1.571429  "runlove.us"  1          "trojan"    "runlove.us"  ""         204.152.254.221                1         1          1         1          14069    0          0           0          0          0x00000000

Alarm controlled packet extraction

The pcapd plugin discussed in the pcap extraction tutorial is either controlled by t2 -e option, aka an external flow index file, or if omitted by an internal flag FL_ALARM in the flow and global status. If one or more plugins set that bit, pcapd will then extract all packets of that flow following the appearance of the FL_ALARM. Unfortunately, we cannot store all packets before that alarm, so they do not appear in the flow file. The packet mode has no alarm mode, so all packets will appear.

In order to inform pcapd to extract packets from flows, dnsDecode has to produce a signal at the packet level. So switch MAL_TEST to 2 in dnsDecode.h and add the pcapd plugin:

t2conf dnsDecode -D MAL_TEST=2 && t2build dnsDecode pcapd

t2 -r ~/data/2015-05-08-traffic-analysis-exercise.pcap -w ~/results/


================================================================================
Tranalyzer 0.9.1 (Anteater), Tarantula. PID: 37008
================================================================================
[INF] Creating flows for L2, IPv4, IPv6
Active plugins:
    01: basicFlow, 0.9.1
    02: tcpStates, 0.9.1
    03: dnsDecode, 0.9.1
    04: txtSink, 0.9.1
    05: pcapd, 0.9.1
[INF] IPv4 Ver: 5, Rev: 16122020, Range Mode: 0, subnet ranges loaded: 406105 (406.11 K)
[INF] IPv6 Ver: 5, Rev: 17122020, Range Mode: 0, subnet ranges loaded: 51345 (51.34 K)
[INF] dnsDecode: 26771 blacklisted domains
...
--------------------------------------------------------------------------------
tcpStates: Aggregated tcpStatesAFlags=0x42
dnsDecode: Aggregated dnsStat=0x0001
dnsDecode: Aggregated dnsHFlg=0x98, dnsOpC=0x0001, dnsRetC=0x0001
dnsDecode: Number of DNS packets: 16 [2.10%]
dnsDecode: Number of DNS Q packets: 8 [50.00%]
dnsDecode: Number of DNS R packets: 8 [50.00%]
dnsDecode: 2 alarms in 2 flows [0.00%]
pcapd: number of packets extracted: 2 [0.26%]
--------------------------------------------------------------------------------
...
Aggregated flowStat=0x0402000000004000
[WRN] 2 alarms in 2 flows [2.94%]
[INF] IPv4 flows
[INF] IPAlarm

So we see that pcapd extracted 2 packets and created a pcap file named 2015-05-08-traffic-analysis-exercise_pcapd.pcap.

ls ~/results

015-05-08-traffic-analysis-exercise_flows.txt  2015-05-08-traffic-analysis-exercise_headers.txt  2015-05-08-traffic-analysis-exercise_pcapd.pcap

Note that in the flowStat, you see now the notification from dnsDecode to pcapd. If you switched off ALARM_MODE, these flows could be isolated from the 68 flows by using this very bit:

tawk -V flowStat=0x0002000000000000


The flowStat column with value 0x0002000000000000 is to be interpreted as follows:

   bit | flowStat              | Description
   =============================================================================
    49 | 0x0002 0000 0000 0000 | Alarm mode & pcapd dumps packets from this flow to new pcap if not -e option

tcol ~/results/2015-05-08-traffic-analysis-exercise_flows.txt

%dir  flowInd  flowStat            timeFirst          timeLast           duration  numHdrDesc  numHdrs  hdrDesc       srcMac             dstMac             ethType  vlanID  srcIP            srcIPCC  srcIPOrg           srcPort  dstIP            dstIPCC  dstIPOrg           dstPort  l4Proto  tcpStatesAFlags  dnsStat  dnsHdrOPField  dnsHFlg_OpC_RetC    dnsCntQu_Asw_Aux_Add  dnsAAAqF  dnsQname      dnsMalCnt  dnsMalType  dnsAname      dnsAPname  dns4Aaddress     dns6Aaddress  dnsQType  dnsQClass  dnsAType  dnsAClass  dnsATTL  dnsMXpref  dnsSRVprio  dnsSRVwgt  dnsSRVprt  dnsOptStat
A     17       0x0402000000004000  1431031903.052371  1431031903.052371  0.000000  1           3        eth:ipv4:udp  00:00:00:00:00:00  00:00:00:00:00:00  0x0800           192.168.138.158  07       "Private network"  61720    192.168.138.2    07       "Private network"  53       17       0x00             0x0001   0x0100         0x10_0x0001_0x0001  1_0_0_0               0         "runlove.us"  1          "trojan"                                                            1         1
B     17       0x0402000000004001  1431031903.089942  1431031903.089942  0.000000  1           3        eth:ipv4:udp  00:00:00:00:00:00  00:00:00:00:00:00  0x0800           192.168.138.2    07       "Private network"  53       192.168.138.158  07       "Private network"  61720    17       0x00             0x0001   0x8180         0x98_0x0001_0x0001  1_1_0_0               1.571429  "runlove.us"  1          "trojan"    "runlove.us"  ""         204.152.254.221                1         1          1         1          14069    0          0           0          0          0x00000000

So unload pcapd and run t2 with the new pcap and store it in another file, otherwise the original flow file will be overwritten.

t2build -u pcapd

t2 -r ~/results/2015-05-08-traffic-analysis-exercise_pcapd.pcap -w ~/results/nudel


================================================================================
Tranalyzer 0.9.1 (Anteater), Tarantula. PID: 20263
================================================================================
[INF] Creating flows for L2, IPv4, IPv6 [ALARM]
Active plugins:
    01: basicFlow, 0.9.1
    02: tcpStates, 0.9.1
    03: dnsDecode, 0.9.1
    04: txtSink, 0.9.1
[INF] IPv4 Ver: 5, Rev: 16122020, Range Mode: 0, subnet ranges loaded: 406105 (406.11 K)
[INF] IPv6 Ver: 5, Rev: 17122020, Range Mode: 0, subnet ranges loaded: 51345 (51.34 K)
[INF] dnsDecode: 26771 blacklisted domains
...
--------------------------------------------------------------------------------
dnsDecode: Aggregated dnsStat=0x0001
dnsDecode: Aggregated dnsHFlg=0x98, dnsOpC=0x0001, dnsRetC=0x0001
dnsDecode: Number of DNS packets: 2 [100.00%]
dnsDecode: Number of DNS Q packets: 1 [50.00%]
dnsDecode: Number of DNS R packets: 1 [50.00%]
dnsDecode: 2 alarms in 2 flows [100.00%]
--------------------------------------------------------------------------------
Headers count: min: 3, max: 3, average: 3.00
Number of UDP packets: 2 [100.00%]
Number of UDP bytes: 156 [100.00%]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Number of processed   flows: 2
Number of processed A flows: 1 [50.00%]
Number of processed B flows: 1 [50.00%]
Number of request     flows: 1 [50.00%]
Number of reply       flows: 1 [50.00%]
...
Aggregated flowStat=0x0402000000004000
[WRN] 2 alarms in 2 flows [100.00%]
[INF] IPv4 flows
[INF] IPAlarm

If you compare the nudel flow file with the original flow file above, they are the same. Note, that is due to fact that in the first packet the alarm was produced.

tcol ~/results/nudel_flows.txt

%dir  flowInd  flowStat            timeFirst          timeLast           duration  numHdrDesc  numHdrs  hdrDesc       srcMac             dstMac             ethType  vlanID  srcIP            srcIPCC  srcIPOrg           srcPort  dstIP            dstIPCC  dstIPOrg           dstPort  l4Proto  tcpStatesAFlags  dnsStat  dnsHdrOPField  dnsHFlg_OpC_RetC    dnsCntQu_Asw_Aux_Add  dnsAAAqF  dnsQname      dnsMalCnt  dnsMalType  dnsAname      dnsAPname  dns4Aaddress     dns6Aaddress  dnsQType  dnsQClass  dnsAType  dnsAClass  dnsATTL  dnsMXpref  dnsSRVprio  dnsSRVwgt  dnsSRVprt  dnsOptStat
A     1        0x0402000000004000  1431031903.052371  1431031903.052371  0.000000  1           3        eth:ipv4:udp  00:00:00:00:00:00  00:00:00:00:00:00  0x0800           192.168.138.158  07       "Private network"  61720    192.168.138.2    07       "Private network"  53       17       0x00             0x0001   0x0100         0x10_0x0001_0x0001  1_0_0_0               0         "runlove.us"  1          "trojan"                                                            1         1
B     1        0x0402000000004001  1431031903.089942  1431031903.089942  0.000000  1           3        eth:ipv4:udp  00:00:00:00:00:00  00:00:00:00:00:00  0x0800           192.168.138.2    07       "Private network"  53       192.168.138.158  07       "Private network"  61720    17       0x00             0x0001   0x8180         0x98_0x0001_0x0001  1_1_0_0               1.571429  "runlove.us"  1          "trojan"    "runlove.us"  ""         204.152.254.221                1         1          1         1          14069    0          0           0          0          0x00000000

Alarm your own plugin

If you intent to integrate the ALARM mode in your own plugin, refer to the Plugin alarm mode tutorial.

Conclusion

Do not forget to reset tranalyzer2 and dnsDecode for your next tutorial, so that your output always matches the one on the webpage:

t2conf tranalyzer2 -D ALARM_MODE=0

t2conf dnsDecode -D MAL_TEST=0

t2build -R

or use the new command

t2conf --reset -a && t2build -R

Have fun!