Forum Discussion

danielpenna's avatar
Sep 01, 2021

Automate ASM "Ready to Be Enforced" Attack Signatures

Hi All,

Problem scenario is this: Multiple F5 ASM deplyoments which use BigIQ to push out updated attack signatures ( works well ) and a 14 day Enforcement Readiness Period. This all works well up to this point, where someone manually has to go and click the "Enforce Ready Entities" button.

 

That sounds like a minor thing to do, but in an Enterprise it includes change control/PVT etc to do...

 

...but automating this out as a fortnightly thing should reduce risk and I can do other things.

 

So I am comfortable with the API, but looking at v13/v14 API I dont see a functionality that can do this for me. Has anyone done this last step to fully utomate attack signature updates ?

 

  • In case anyone is still looking for a way to do this, I created a Big-IQ script that can be pushed to your ASM devices. Here's what it does:

    1. It checks the HA status, and exits the script if the HA status is Standby
    2. It uses iControl REST to create a file that lists the policy hashes for each of your ASM policies
    3. It uses a bash for loop to loop through each of your ASM policy hashes, and Enforces Ready Signatures for each policy, and apply each policy

    This is a plug-n-play script, so you shouldn't need to modify it at all. I've used it on v15.1.5 and v15.1.8.

    ------------------------------------------------------------------------------------------------------------------------

    # Determines HA Status, creates variable, then loops through it on Active devices

    bash
    cd /var/tmp/

    # Static Variables
    CREDS=admin

    # Writes HA Status to a file
    tmsh show /cm failover-status | grep Status > /var/tmp/ha-status.txt
    chmod 755 /var/tmp/ha-status.txt

    # Exits script if the HA Status file contains the string STANDBY
    if grep -q STANDBY /var/tmp/ha-status.txt; then
    exit
    fi

    # Creates variable with list of policy hashes, then prints variable contents to txt file (excluding parent and default policies)
    FILENAME=$(curl -kvu $CREDS http://localhost/mgmt/tm/asm/policies | jq -r '.items[] 
    printf "$FILENAME\n" > /var/tmp/policy-hashes.txt

    FILENAME="policy-hashes.txt"
    LINES=$(cat $FILENAME)

    # ASM - Enforces Ready Entities and Applies Policies - All Policies
    for LINE in $LINES
    do
      curl -kvu $CREDS -X PATCH "https://localhost/mgmt/tm/asm/policies/$LINE/signatures?\$select=&\$filter=hasSuggestions+eq+false+AND+wasUpdatedWithinEnforcementReadinessPeriod+eq+false+and+performStaging+eq+true" -u $CREDS -k -v -H "Content-Type: application/json" -d '{"performStaging":false}' | jq .
      LINK=\"https://localhost/mgmt/tm/asm/policies/$LINE\"
      curl -kvu $CREDS POST https://localhost/mgmt/tm/asm/tasks/apply-policy -k -v -H "Content-Type: application/json" -d "{\"policyReference\": {\"link\": $LINK }}" | jq .
    sleep 10s
    done

    ------------------------------------------------------------------------------------------------------------------------

    If you want to exclude specific policies, such as a Parent or Template policy, you can change the line where the FILENAME variable is created to exclude those policies like this:

    FILENAME=$(curl -kvu $CREDS http://localhost/mgmt/tm/asm/policies | jq -r '.items[] | select(.name!="asm_parent") | select(.name!="asm_template") | .id')

  • 2Bs's avatar
    2Bs
    Icon for Nimbostratus rankNimbostratus

    Thanks guys, I have managed to run it succesfuly using this script however it seems as it sends the Apply Policy command to all the policies and not only the ones who changed, is it possible to make it apply only at the policies that were changed?

     

    #!/bin/bash

    # Determines HA Status, creates variable, then loops through it on Active devices

     

    cd /var/tmp

     

    # Static Variables

    CREDS=admin:password

     

    # Writes HA Status to a file

    tmsh show /cm failover-status | grep Status > /var/tmp/ha-status.txt

    chmod 755 /var/tmp/ha-status.txt

     

    # Exits script if the HA Status file contains the string STANDBY

    if grep -q STANDBY /var/tmp/ha-status.txt; then

      exit

    fi

     

    # Creates variable with list of policy hashes, then prints variable contents to txt file (excluding parent and default policies)

    FILENAME=$(curl -kvu $CREDS http://localhost/mgmt/tm/asm/policies | jq -r '.items[] | .id')

    printf "$FILENAME\n" > /var/tmp/policy-hashes.txt

     

    FILENAME="policy-hashes.txt"

    LINES=$(cat $FILENAME)

     

    # ASM - Enforces Ready Entities and Applies Policies - All Policies

    for LINE in $LINES

    do

      curl -kvu $CREDS -X PATCH "https://localhost/mgmt/tm/asm/policies/$LINE/signatures?\$select=&\$filter=hasSuggestions+eq+false+AND+wasUpdatedWithinEnforcementReadinessPeriod+eq+false+and+performStaging+eq+true" -u $CREDS -k -v -H "Content-Type: application/json" -d '{"performStaging":false}' | jq .

      LINK=\"https://localhost/mgmt/tm/asm/policies/$LINE\"

      curl -kvu $CREDS POST https://localhost/mgmt/tm/asm/tasks/apply-policy -k -v -H "Content-Type: application/json" -d "{\"policyReference\": {\"link\": $LINK }}" | jq .

      sleep 10s

    done

  • 2Bs's avatar
    2Bs
    Icon for Nimbostratus rankNimbostratus

    Hello guys,

    Thanks for your hard work!

    Did you get it to work on v16? 

    I've been trying to use the scripts but unfortunately none of the works.

     

    • Holy64's avatar
      Holy64
      Icon for Nimbostratus rankNimbostratus

      Hi, I run my script in an ssh session on a 16.1.4.1 Big-IP.  I have an admin profile.

    • DanSkow's avatar
      DanSkow
      Icon for Cirrus rankCirrus

      Good morning,

      I was able to run the Big-IQ script just now against my lab running v16.1.4.3 without any issues. 

      Are you running the script from the Big-IQ, or trying to run it locally on the Big-IP? If you're trying to run it locally on the Big-IP, you'll need to update the "CREDS=admin" line to include your admin password. For example, "CREDS=admin:password" 

      If your password has certain special characters, you'll have to escape them with a backslash. For example, "CREDS=admin:password\!"

      If you're pushing it from the Big-IQ, you might be able to figure out the issue by looking at the Big-IQ script log. One common issue is not having Advanced Shell access for the admin user. 

      Let me know if you're able to find any logs related to the failure or any additional information on how you're running the script. 

      Thank you,

      Dan

      • 2Bs's avatar
        2Bs
        Icon for Nimbostratus rankNimbostratus

        Hi Dan!

        Thanks for your response.

        When I try to run the script it does not show any output.

        I run it directly from the BIGIP itself and do have special characters in the password so I added the backslash before each special character but I got the same result.

        I am running BIGIP v16.1.4.1

  • Holy64's avatar
    Holy64
    Icon for Nimbostratus rankNimbostratus

    I would to share my script.  We use partitions on our infrastructure.  I don't use the standby check status yet but that's good to add that function to my script. 
    I use has input parameter, all or the the list of partition where you would to enforce signatures ready to be enforced separate by a space.  That's because in our case, partitions could be active on node 1 or on node 2.
    I put a sleep 20 after requesting the signature enforcement and I checked during maximum 60 seconds for the ASM policy applying success status.  The script give detailled information in console.
    Tested on BigIP versions 15.1.8 and 14.1.5.
    ---------------------------------------------------------------------------------------------------

    # YHO 20220207 ASM staging signature enforcement
    # ASM-SignEnforcement.ksh
    # v01 yho 20220207
    export runUser=${USER}
    export logfolder=${HOME}/
    export policyList=${logfolder}/PolList.txt

    if [ "$1" == "" ];
    then
    echo ------------------------------------------------
    echo Partitions list :
    tmsh list auth partition one-line | awk '{print $3}' | sed ':a;N;$!ba;s/\n/ /g'
    echo ------------------------------------------------
    echo Give the option as first parameter
    echo Options are :
    echo " all : all partition in the above list"
    echo " or the partitions list between quotes \"partion list\""
    exit 1
    else
    if [ "$1" == "all" ]
    then
    export Partis=`tmsh list auth partition one-line | awk '{print $3}' | sed ':a;N;$!ba;s/\n/ /g'`
    else
    export Partis=$1
    fi
    fi
    echo ------------------------------------------------
    echo Signature enforcement for partitions
    echo ------------------------------------------------
    echo $Partis
    echo ------------------------------------------------
    echo "sleep 10 seconds - CTRL C to stop"
    sleep 10

    # List policies/policies ID
    mysql -uasm -p`perl -MF5::Cfg -e 'print F5::Cfg::get_mysql_password()'` -e "select name, rest_uuid from PLC.PL_POLICIES" > $policyList
    sed -i 's/\x09/,/' $policyList
    for parti in ${Partis}
    do
    for pol in `cat $policyList | grep "^\/"`
    do
    name=`echo $pol | awk -F ',' '{print $1}'`
    id=`echo $pol | awk -F ',' '{print $2}'`
    echo ${name} | grep "/${parti}/"
    if [ $? -eq 0 ]
    then
    echo ------------------------------------------------
    echo Check manual learning $name $id
    #restcurl -s -u ${runUser}: /tm/asm/policies/$id/policy-builder?$select=learningMode
    restcurl -s -u ${runUser}: /tm/asm/policies/$id/policy-builder?$select=learningMode | grep manual
    if [ $? -eq 0 ]
    then
    # enforce ready to enforce signatures
    echo Chek ready to enforce signatures number $name
    #restcurl -u ${runUser}: "/tm/asm/policies/$id/signatures?\$select=&\$filter=hasSuggestions+eq+false+AND+wasUpdatedWithinEnforcementReadinessPeriod+eq+false+and+performStaging+eq+true&\$top=1"
    restcurl -u ${runUser}: "/tm/asm/policies/$id/signatures?\$select=&\$filter=hasSuggestions+eq+false+AND+wasUpdatedWithinEnforcementReadinessPeriod+eq+false+and+performStaging+eq+true&\$top=1" | grep totalItems
    restcurl -u ${runUser}: "/tm/asm/policies/$id/signatures?\$select=&\$filter=hasSuggestions+eq+false+AND+wasUpdatedWithinEnforcementReadinessPeriod+eq+false+and+performStaging+eq+true&\$top=1" | grep 'totalItems.: [1-9]'
    if [ $? -eq 0 ]
    then
    echo Enforce ready to enforce signatures $name
    restcurl -X PATCH -u ${runUser}: "/tm/asm/policies/$id/signatures?\$select=&\$filter=hasSuggestions+eq+false+AND+wasUpdatedWithinEnforcementReadinessPeriod+eq+false+and+performStaging+eq+true" -d '{"performStaging":false}' | grep 'totalItems.: [1-9]'
    echo sleep 20 - signature update ongoing
    sleep 20
    # Apply policy
    echo Apply policy $name
    TaskId=`restcurl -s -u ${runUser}: -X POST /tm/asm/tasks/apply-policy -d "{\"policyReference\": {\"link\": \"https://localhost/mgmt/tm/asm/policies/$id\"}}" | grep -e "id.:" | sed 's/.*\"id\": \"//' | sed 's/\",.*//'`
    echo Apply policy TaskId : $TaskId - $name
    # Check policy applied
    app=60
    echo Check policy applied for max $app seconds for $name
    #exit 0
    while [ $app -ge 2 ]
    do
    app=$(($app-1))
    restcurl -s -u ${runUser}: "/tm/asm/tasks/apply-policy/$TaskId" | grep COMPLETED
    if [ $? -eq 0 ] ; then app=0; fi
    sleep 1
    done
    echo Policy applied COMPLETE if $app = 0 - $name
    else
    echo No signature to enforce for $name
    fi
    else
    echo Policy not in manual mode $name
    fi
    echo ==============================================
    fi
    done
    done
    # End

    ---------------------------------------------------------------------------------------------------

  • In case anyone is still looking for a way to do this, I created a Big-IQ script that can be pushed to your ASM devices. Here's what it does:

    1. It checks the HA status, and exits the script if the HA status is Standby
    2. It uses iControl REST to create a file that lists the policy hashes for each of your ASM policies
    3. It uses a bash for loop to loop through each of your ASM policy hashes, and Enforces Ready Signatures for each policy, and apply each policy

    This is a plug-n-play script, so you shouldn't need to modify it at all. I've used it on v15.1.5 and v15.1.8.

    ------------------------------------------------------------------------------------------------------------------------

    # Determines HA Status, creates variable, then loops through it on Active devices

    bash
    cd /var/tmp/

    # Static Variables
    CREDS=admin

    # Writes HA Status to a file
    tmsh show /cm failover-status | grep Status > /var/tmp/ha-status.txt
    chmod 755 /var/tmp/ha-status.txt

    # Exits script if the HA Status file contains the string STANDBY
    if grep -q STANDBY /var/tmp/ha-status.txt; then
    exit
    fi

    # Creates variable with list of policy hashes, then prints variable contents to txt file (excluding parent and default policies)
    FILENAME=$(curl -kvu $CREDS http://localhost/mgmt/tm/asm/policies | jq -r '.items[] 
    printf "$FILENAME\n" > /var/tmp/policy-hashes.txt

    FILENAME="policy-hashes.txt"
    LINES=$(cat $FILENAME)

    # ASM - Enforces Ready Entities and Applies Policies - All Policies
    for LINE in $LINES
    do
      curl -kvu $CREDS -X PATCH "https://localhost/mgmt/tm/asm/policies/$LINE/signatures?\$select=&\$filter=hasSuggestions+eq+false+AND+wasUpdatedWithinEnforcementReadinessPeriod+eq+false+and+performStaging+eq+true" -u $CREDS -k -v -H "Content-Type: application/json" -d '{"performStaging":false}' | jq .
      LINK=\"https://localhost/mgmt/tm/asm/policies/$LINE\"
      curl -kvu $CREDS POST https://localhost/mgmt/tm/asm/tasks/apply-policy -k -v -H "Content-Type: application/json" -d "{\"policyReference\": {\"link\": $LINK }}" | jq .
    sleep 10s
    done

    ------------------------------------------------------------------------------------------------------------------------

    If you want to exclude specific policies, such as a Parent or Template policy, you can change the line where the FILENAME variable is created to exclude those policies like this:

    FILENAME=$(curl -kvu $CREDS http://localhost/mgmt/tm/asm/policies | jq -r '.items[] | select(.name!="asm_parent") | select(.name!="asm_template") | .id')

    • Jan_Loukota's avatar
      Jan_Loukota
      Icon for Nimbostratus rankNimbostratus

      Hello,

      its awesome :). Could it be please extended a little bit? Because you need to also know which signatures were not ready for enforcement and review those. Those are possible attacks and you do not consider such situation.

      Thank you

      Best regards

      • DanSkow's avatar
        DanSkow
        Icon for Cirrus rankCirrus

        I'm glad the script works for you 🙂

        When a new batch of signatures is released, they should be reviewed to determine if there's a reason to enforce them before they complete their staging period. For example, when the Log4j and most other critical signatures are released, I've followed a different process. 

        First of all, my environment has a separate Signature Set named "Immediate Enforcement Signatures (Critical Sigs)". This Signature Set is attached to all policies. 

        Then when I want to enforce a new signature that hasn't completed it's staging period, I manually add that signature to the Signature Set using the GUI, then run this script from the Big-IQ:

        ---------------------------------------------------------------------------------------------------

        # This script skips Standby devices, then creates a list of all ASM policy hashes, then finds the ID of the Immediate Enforcement Signatures (Critical Sigs) signature set, and enforces the signatures in that signature set for all ASM policies that have the signature set attached.
        # In ASM GUI, add new signature(s) to the Immediate Enforcement Signatures (Critical Sigs) signature set, then run this script to enforce the set on all policies

        bash
        cd /var/tmp

        CREDS=admin

        # Writes HA Status to a file
        tmsh show /cm failover-status | grep Status > /var/tmp/ha-status.txt
        chmod 755 /var/tmp/ha-status.txt

        # Exits script if the HA Status file contains the string STANDBY
        if grep -q STANDBY /var/tmp/ha-status.txt; then
        exit
        fi

        # Creates variable with list of policy hashes, then prints variable contents to txt file (excluding parent and default policies)
        FILENAME=$(curl -kvu $CREDS http://localhost/mgmt/tm/asm/policies | jq -r '.items[] | .id')
        printf "$FILENAME\n" > /var/tmp/policy-hashes.txt

        FILENAME="policy-hashes.txt"
        LINES=$(cat $FILENAME)

        # ASM - Enable and Enforce Signatures in Signature Set on all policies, and Applies Policies - All Policies
        for LINE in $LINES
        do
        SETID=$(curl -kvu $CREDS -X GET "https://localhost/mgmt/tm/asm/policies/$LINE/signature-sets" -u $CREDS -k -v -H "Content-Type: application/json" | jq -r '.items[] | select(.signatureSetReference.name=="Immediate Enforcement Signatures (Critical Sigs)") | .id')
        DATA='{"commands":[{"method":"PATCH","uri":"/mgmt/tm/asm/policies/'$LINE'/signatures?$filter=signatureSets/id+eq+'\'$SETID\''","body":{"performStaging":false,"enabled":true}}]}'
        curl -kvu $CREDS -X POST "https://localhost/mgmt/tm/asm/tasks/bulk" -u $CREDS -k -v -H "Content-Type: application/json" -d $DATA | jq .
        LINK=\"https://localhost/mgmt/tm/asm/policies/$LINE\"
        curl -kvu $CREDS POST https://localhost/mgmt/tm/asm/tasks/apply-policy -k -v -H "Content-Type: application/json" -d "{\"policyReference\": {\"link\": $LINK }}" | jq .
        sleep 10s
        done

        ---------------------------------------------------------------------------------------------------

        This script does the equivilent of going to Security > Application Security > Policy Building > Learning and Blocking Settings, then under the Attack Signatures section, clicking "Enforce and Enable all Attack Signatures in the Signature Set" for Signature Set "Immediate Enforcement Signatures (Critical Sigs)", then it applies the policy. 

        The script automatically loops through all of your policies to enforce the Signature Set and apply the policy on all of them one-at-a-time. If you already have a Signature Set for this purpose, you can change the name in the script to match your Signature Set.

        If you want to exclude specific policies, such as a Parent or Template policy, you can change the line where the FILENAME variable is created to exclude those policies like this:

        FILENAME=$(curl -kvu $CREDS http://localhost/mgmt/tm/asm/policies | jq -r '.items[] | select(.name!="asm_parent") | select(.name!="asm_template") | .id')

    • Leslie_Hubertus's avatar
      Leslie_Hubertus
      Ret. Employee

      Thanks for this, DanSkow! I'm sure it'll come in handy for future users. Apologies to danielpenna for not having spotted that his question was hanging for so long! The team is working to correct that going forward.