Layered protection. Fortinet & Flowmon Networks

Recently, more and more companies are ripening to echeloned protection, when one solution protects the network perimeter, the other – end stations, the third constantly monitors the network, detecting anomalies, the fourth scans the network for unpatched vulnerabilities, and so on. At the same time, the need for various integrations is growing and it’s good when they are out of the box, that is, you don’t need to write complex scripts.
We recently wrote about the new TS Solution service – CheckFlow… This is a free audit of network traffic (both internal and external). Flowmon – a telemetry analysis and network monitoring solution that provides valuable information for both network administrators and security guards: anomalies, scans, illegitimate servers, loops, illegitimate interactions, network intrusions, zero-day attacks and much more.
I also recommend referring to article 9 common network problems that can be detected using analysis with Flowmon.

Integration Flowmon & FortiGate

Integration was mentioned in our blog… In general, it consists in the fact that the Next-Generation Firewall (such as FortiGate) protects the perimeter, and Flowmon monitors the network infrastructure, thereby giving the customer full network visibility. However, Flowmon can only detect, but not prevent attacks and anomalies, because it works on telemetry, which is obtained using Netflow / IPFIX. An NGFW or NAC (Network Access Control) solution can be used to quarantine a suspicious or infected host.
So, the vendor Flowmon released a shell script that, in response to security incidents, can perform the following actions on FortiGate:

  • Block the infected host by IP address (IP Ban);
  • Quarantine the host using FortiClient at MAC address (Quarantine with FortiClient);
  • Dynamic quarantine for all infected hosts by MAC addresses (Access Layer Quarantine);

Setting up

1. I will not go into the details of the script itself, I will only say that there are two versions: one for FortiGate above version 6.4.0, the other for earlier versions. The code is shown below.

Script code for FortiGate below version 6.4.0

#!/bin/bash
# Author: Jiri Knapek
# Description: This script is to quarantine IP on Fortigate Firewalls for FortiOS before 6.4.
# Version: 1.3
# Date: 8/3/2020
# Debug 1 = yes, 0 = no
DEBUG=0

[ $DEBUG -ne 0 ] && echo `date` "Starting mitigation script" >> /tmp/fg-mitigation.log

# Management IP/hostname of Firewall/ Core device
IP='10.10.30.210'
API_KEY='fp8114zdNpjp8Qf8zN4Hdp57dhgjjf'
# Default timeout for action is
# value in seconds or never
TIMEOUT='300'

# FortiGate API URL
BAN="https://$IP/api/v2/monitor/user/banned/add_users?access_token=$API_KEY"

function usage {
    cat << EOF >&2
usage: mitigation_script.sh 

Optional:
    --fw        IP / hostname of Fortigate firewall
	--timeout	Timeout in seconds
	--key		FortiGate API key
    
EOF
    exit
}      

params="$(getopt -o f:t:k:h -l fw:,timeout:,key:,help --name "mitigation_script.sh" -- "$@")"

[ $DEBUG -ne 0 ] && echo `date` "Params $params" >> /tmp/fg-mitigation.log

if [ $? -ne 0 ]
then
    usage
    [ $DEBUG -ne 0 ] && echo `date` "Got to usage." >> /tmp/fg-mitigation.log
fi

eval set -- "$params"
unset params

while true
do
    case $1 in
        -f|--fw)
            IP=("${2-}")
            shift 2
            ;;
        -k|--key)
            API_KEY=("${2-}")
            shift 2
            ;;
        -t|--timeout)
            TIMEOUT=("${2-}")
            shift 2
            ;;
        -h|--help)
            usage
            ;;
        --)
            shift
            break
            ;;
        *)
            usage
            ;;
    esac
done

# we dont support any other args
[ $# -gt 0 ] && {
    usage
    [ $DEBUG -ne 0 ] &&  echo `date`  "INFO: Too many arguments. Got to usage." >> /tmp/fg-mitigation.log 2>&1
}

cat << EOF >&2
-----  My params are ------------------
FW = $IP
API KEY = $API_KEY
TIMEOUT = $TIMEOUT
TOKEN = $TOKEN
---------------------------------------
EOF

[ $DEBUG -ne 0 ] && cat >> /tmp/fg-mitigation.log << EOF >&2
-----  My params are ------------------
FW = $IP
API KEY = $API_KEY
TIMEOUT = $TIMEOUT
TOKEN = $TOKEN
---------------------------------------
EOF

echo "Stdin read started..." >&2

LINE_NUM=1
array=()
while read line
do
    IFS=$'t'
    array=($line)
    echo "$LINE_NUM - ID ${array[0]} - type ${array[4]} - source ${array[10]}"
    [ $DEBUG -ne 0 ] &&  echo "$LINE_NUM - ID ${array[0]} - type ${array[4]} - source ${array[10]}" >> /tmp/fg-mitigation.log 2>&1
    
    LINE_NUM=$((LINE_NUM+1))

    # BAN the source IP of the event
    if [ $DEBUG -ne 0 ]; then
        /usr/bin/curl -k -X POST -H "Content-Type": "application/json" --data "{ "ip_addresses": ["${array[10]}"], "expiry": $TIMEOUT}" $BAN >> /tmp/fg-mitigation.log 2>&1
    else
        /usr/bin/curl -k -X POST -H "Content-Type": "application/json" --data "{ "ip_addresses": ["${array[10]}"], "expiry": $TIMEOUT}" $BAN
    fi

done < /dev/stdin

echo "---- Everything completed ----"
[ $DEBUG -ne 0 ] &&  echo `date` "---- Everything completed ----" >> /tmp/fg-mitigation.log

Script code for FortiGate version 6.4.0 and higher

#!/bin/bash
# Author: Jiri Knapek
# Description: This script is to quarantine IP or MAC on Fortigate Firewalls and Security Fabric
# Version: 2.0
# Date: 7/8/2020
# Debug 1 = yes, 0 = no
DEBUG=0

[ $DEBUG -ne 0 ] && echo `date` "Starting mitigation script" >> /tmp/fg-mitigation.log

# Flowmon API access
USER='admin'
PASS='admin'
# Management IP/hostname of Firewall/ Core device
IP='10.10.30.210'
WEBHOOK='FlowmonADS'
API_KEY='fp8114zdNpjp8Qf8zN4Hdp57dhgjjf'
MAC=0

URL="https://$IP/api/v2/monitor/system/automation-stitch/webhook/$WEBHOOK"

function usage {
    cat << EOF >&2
usage: mitigation_script.sh 

Optional:
    --fw        IP / hostname of Fortigate firewall
    --user      Username to be used for Flowmon API authentication
    --pass      Password for the user
	--key		FortiGate API key
	--mac	    Add this parameter to enable MAC mitigation

EOF
    exit
}



params="$(getopt -o f:u:p:k:h:m: -l fw:,key:,pass:,user:,help,mac: --name "mitigation_script.sh" -- "$@")"

[ $DEBUG -ne 0 ] && echo `date` "Params $params" >> /tmp/fg-mitigation.log

if [ $? -ne 0 ]
then
    usage
    [ $DEBUG -ne 0 ] && echo `date` "Got to usage." >> /tmp/fg-mitigation.log
fi

eval set -- "$params"
unset params

while true
do
    case $1 in
        -f|--fw)
            IP=("${2-}")
            shift 2
            ;;
        -k|--key)
            API_KEY=("${2-}")
            shift 2
            ;;
        -p|--pass)
            PASS=("${2-}")
            shift 2
            ;;
        -u|--user)
            USER=("${2-}")
            shift 2
            ;;
        -m|--mac)
            MAC=1
            shift 2
            ;;
        -h|--help)
            usage
            ;;
        --)
            shift
            break
            ;;
        *)
            usage
            ;;
    esac
done

# we dont support any other args
[ $# -gt 0 ] && {
    usage
    [ $DEBUG -ne 0 ] &&  echo `date`  "INFO: Got to usage." >> /tmp/fg-mitigation.log 2>&1
}

if [ $MAC -ne 0 ];
then
    # authenticate to localhost
    OUTPUT="$(/usr/bin/curl "https://localhost/resources/oauth/token" -k -d 'grant_type=password' -d 'client_id=invea-tech' -d "username=$USER" -d "password=$PASS")"
    TOKEN=""

    echo "${OUTPUT}" > /tmp/access_token.json

    if [[ $OUTPUT == *"access_token"* ]]; then
        [ $DEBUG -ne 0 ] && echo `date` "Successfully authenticated to Flowmon Collector!" >> /tmp/fg-mitigation.log
        TOKEN="$(cat /tmp/access_token.json | jq '.access_token')"
        TOKEN="${TOKEN//"}"
        TOKEN="Authorization: bearer "$TOKEN
    fi
fi

cat << EOF >&2
-----  My params are ------------------
FW = $IP
API KEE = $API_KEY
URL = $URL
MAC = $MAC
TOKEN = $TOKEN
---------------------------------------
EOF

[ $DEBUG -ne 0 ] && /tmp/fg-mitigation.log << EOF >&2
-----  My params are ------------------
FW = $IP
API KEE = $API_KEY
URL = $URL
MAC = $MAC
TOKEN = $TOKEN
---------------------------------------
EOF

echo "Stdin read started..." >&2

LINE_NUM=1
array=()
while read line
do
    IFS=$'t'
    array=($line)
    echo "$LINE_NUM - ID ${array[0]} - type ${array[4]} - source ${array[10]}"
    [ $DEBUG -ne 0 ] &&  echo "$LINE_NUM - ID ${array[0]} - type ${array[4]} - source ${array[10]}" >> /tmp/fg-mitigation.log 2>&1

    # Call a webhook
    if [ $MAC -ne 0 ];
    then
        MAC_ADDR="$(/usr/bin/curl "https://localhost/rest/ads/event/${array[0]}" -G -k -H "$TOKEN"  | jq '.macAddress')"
        if [ $DEBUG -ne 0 ]; then
            /usr/bin/curl -k -X POST -H "Authorization: Bearer $API_KEY" --data "{ "srcip": "${array[10]}", "mac": $MAC_ADDR, "fctuid": "A8BA0B12DA694E47BA4ADF24F8358E2F"}" $URL >> /tmp/fg-mitigation.log 2>&1
        else
            /usr/bin/curl -k -X POST -H "Authorization: Bearer $API_KEY" --data "{ "srcip": "${array[10]}", "mac": $MAC_ADDR, "fctuid": "A8BA0B12DA694E47BA4ADF24F8358E2F"}" $URL
        fi
    else
        if [ $DEBUG -ne 0 ]; then
            /usr/bin/curl -k -X POST -H "Authorization: Bearer $API_KEY" --data "{ "srcip": "${array[10]}",  "fctuid": "A8BA0B12DA694E47BA4ADF24F8358E2F"}" $URL >> /tmp/fg-mitigation.log 2>&1
        else
            /usr/bin/curl -k -X POST -H "Authorization: Bearer $API_KEY" --data "{ "srcip": "${array[10]}",  "fctuid": "A8BA0B12DA694E47BA4ADF24F8358E2F"}" $URL
        fi
    fi

    LINE_NUM=$((LINE_NUM+1))

done < /dev/stdin

echo "---- Everything completed ----"
[ $DEBUG -ne 0 ] &&  echo `date` "---- Everything completed ----" >> /tmp/fg-mitigation.log

2. I am using ForiGate version 6.4.3. In the script itself, on lines 13 and 14, you should add your username and password for Flowmonand also add API key from clause 5, FortiGate IP Address and Webhook name (the name of the automation engine).

3. In the FortiGate web interface, add in the tab Security Fabric> Automation> New Automation Stitch… Name – FlowmonADS, Status – Enabled, Trigger – Incoming Webhook, Action – IP BAN, Access Layer Quarantine, Quarantine with FortiCLient (if using).

4. Then you will see a window as in the screenshot below with the FortiGate URL for this Webhook, a field for the admin token API (we will create it later) and an example request.

5. Next, you need to create an administrator profile, which will have rights. Tab System> Admin Profiles> Create New

6. Assign rights Security Fabric – Read, Firewall – Read / Write, System – Read / Write, Security Profile – Read / Write

7. After in the tab System> Administrators create a new administrator with a profile api_admin… Optional in the field Trusted Hosts you can specify trusted networks or the IP address of the Flowmon.
Note: parameter Trusted Hosts allows you to hardcode segments of IP addresses from which api_admin will be able to send API requests to FortiGate, thus this is the recommended setting.

8. After this step, a API key, which must be added to the original script along with the other data specified in point 1 and in the webhook in point 4.

9. Next, go to Flowmon in the ADS (Anomaly Detection System) module in the tab System> System Settings> Custom Scripts> New Custom Script> Select file with extension .sh… Next, you need to set the parameters –fw (FortiGate IP address), –key (API token), –mac (nothing), –pass (password from REST API Flowmon), –user (REST API user Flowmon). Then press the button Save
Note: –pass and –user by default admin / admin

10. The final step is to establish the events to which the given program code will be triggered. In the tab Settings> Processing> Custom Scripts> New Custom Script Action the parameter should be changed Perspective on the Security Issues, set the threshold (Minimal priority to be reported) and check the parameters from the previous step.

Check

In case of triggering an event from the category Security Issues on Flowmon, FortiGate will block the given host. Further, in the convenient Quarantine widget, you can view potentially infected hosts by falling inside. Or through a command in the CLI diagnose user quarantine list

After information security, the administrator can start investigating the incident using Flowmon ADS, identifying the initially infected host, through which ports the malware spreads and its behavior. With the help of solutions to protect workstations, for example, FortiEDR you can cure the car and conduct a security incident investigation.
In order to move a host out of quarantine, select it and click the button Remove

Conclusion

The ubiquitous approach to defense in depth is pushing many vendors to integrate with other solutions out of the box. This article covered how to integrate, configure and demonstrate how Flowmon and FortiGate work together.
In the near future, we are planning a webinar, where we will tell in more detail how Flowmon and Fortinet complement each other, their integration with each other, and also answer your questions. Registration is available by link
If you are interested in this topic, then stay tuned in our channels (Telegram, Facebook, VK, TS Solution Blog)!

Similar Posts

Leave a Reply