How to live with WAF so that it is not excruciatingly painful

There will be no next article describing the capabilities of the application-level firewall. There are already plenty of them. Today we will explain the pitfalls when working with this solution so that you know about them even before the start of the project and correctly plot the course.

For the first time, they started talking about Web Application Firewall (WAF) in the domestic market in 2008, and it gained serious popularity in 2011. The solution is currently quite in demand, but no one really knows why it needs it (before the first incident). When communicating with information security divisions of various organizations, we often hear: “Yes, who needs us” and “We have not been hacked before and are not hacked now.” However, as practice shows, they attack everyone, automatically and sometimes targeted.

Hackers are a kind of community, which, like any other, consists of neophytes and professionals. Amateurs in this field have only one motive – to find vulnerability and boast of it, which for them is a reward in itself. Who is smarter, sells this information on the dark. There, she falls into the hands of very professional cyber groups organizing targeted attacks that are almost impossible to detect without preparation. Earlier in our articles, we already said that attackers are increasingly striving for a long-term and inconspicuous presence in vulnerable infrastructure in order to conduct a detailed study and get as full access to information and technological systems as possible.

The consequences of hacking can vary, from stealing money from current accounts to using the organization’s resources to conduct DDoS attacks (and the risks that you will be charged with this).

Customers who come to us for WAF Solar MSS services talk about the same problems that they themselves encountered during the implementation and which were not so obvious “ashore”.

Add extra budget

Fortunately, the purchase of web security solutions has recently become easier to justify in the budget. And now you are already the lucky owner of one of the WAFs that exist on the market, perhaps not even the worst … However, it’s enough to open the instructions to understand that without properly trained WAF specialists you can’t set up and do not protect yourself from intruders, and the IT unit is in no hurry to single out administrators for its operation.

Suppose you send an employee to learn how to use this device (by the way, many send the youngest and most inexperienced subordinates to such training – a big mistake). The specialist returns in a couple of days and begins, together with IT administrators, to configure the network connectivity of the web server and WAF (although in fact all this work usually comes down to changing default routes and redirecting traffic through WAF). And now all the keys and certificates are already on WAF, SSL traffic is thoroughly inspected, but at the same time half of the site’s functionality stops working. The excellent WAF protection modules decided that the JavaScript’s on the site work as malware or as bots, as it turns out, the CSRF token should not be requested everywhere, but where does it come from? you WAF had to know.

Then you see different numbers on the dashboards opposite the words “low”, “medium”, “high”, some trained 10 machine learning models are ready to get into work, just give them free rein and nobody knows what to do next. , and your trained specialist including. Because in two days it is impossible to train profiling for a specific WAF system, to give such a deep insight into all the varieties of typical and non-typical OWASP attacks so that a specialist can determine whether they are relevant for his company's web applications, and even more so to teach them how to adjust WAF settings for them .

But you still need to understand what events should be formed in the incident and how to adapt the correlation rules for a specific web application. If only the cost of the solution was included in the budget, there is often no money to attract an integrator who would help set it up, therefore, most often WAF put on a shelf they switch to span port operation mode, change network routes to default ones and postpone work until the next year when a new budget appears.

Along the way, many learn that WAF is not always stable 24×7 and often crashes, which can cause downtime in the availability of the web. You need a failover cluster, you need to constantly monitor its services and the availability of the web application. All this is best taken into account and budgeted “on the shore”.

Evaluate if you can write policies yourself and implement integration

After a while, you had a new budget, you attracted an integrator who set up correlation rules, machine learning models, black lists, and even the entire functionality of the site still works.

But when a new major release of your web application comes out, all these policies will turn into a pumpkin, since they were created for the previous version, and new functionality may simply not work through WAF.

In addition, for some tasks of protecting web applications, it is better to use separate classes of SZI, for example, Anti-DDoS or SIEM, and therefore, WAF will need to be integrated with them. This is also not a trivial task – you need to understand what data, how and in what format you need to send to these external systems, since SZI can not always independently send messages from WAF.

For example, one of our customers had the task of recording failed authentication attempts on WAF, in order to forward these events to SIEM in the future and monitor for bruteforce attacks. Such rules are usually implemented in all popular WAFs and work out without additional adjustments. However, the developers of the customer’s web application wrote the authentication logic in such a way that the authorization form looked like an array in an array when sending it – non-standard for the authorization form and for WAF’s. It was impossible to process such a request form for bruteforce attacks with WAF regular rules. We created a custom rule that kept track of the number of authentication attempts, the format in which the form was sent, the server code and the response body in which the value of successful or unsuccessful authentication was parsed. Among other things, the rule should contain protection against bots: if the number of authentications exceeded the specified threshold, then a script entered the response page that checked requests to the server for “humanity”. If the next request to the server did not pass this check, then the client redirected to the captcha page. Also, this rule should not interfere with the legitimate activity of bots (Yandex, Google, etc.).

Implementation example

when CLIENT_ACCEPTED {
  BOTDEFENSE :: disable
  set loginevent 0
  set srcip2 [IP::remote_addr]
  set coun222t 0
  set login_count 3
  set countloginintable 0
  set user_agent 0
  set var test
}

when HTTP_REQUEST {
set sms_count 3
set evil_client 0
    set evil_client_action 0
set b_challande_count 0
set user_agent [HTTP::header User-Agent]
    set var [IP::client_addr]$ user_agent
if {[virtual name] == "vs_ccc_pilot"} {
##### START LK #########
 if {([HTTP::path] starts_with "/ login") and [HTTP::method] eq "POST"} {
    HTTP :: collect [HTTP::header Content-Length]
    set loginevent 1
    


   #log local0. "Login event $ loginevent"
 }
  if {([HTTP::path] eq "/ NCbf5") &&[tablekeys-subtablecustomer_login:[tablekeys-subtablecustomer_login:[IP::client_addr] -count]> = $ login_count} {
   set evil_client 1
   BOTDEFENSE :: enable
 if { [table keys -subtable customer_login_un:$var -count] > = 3} {
set evil_client_action 1
}
   
 }
  if {([HTTP::path] eq "/ NCbf5") &&[tablekeys-subtablecustomer_login:[tablekeys-subtablecustomer_login:[IP::client_addr] -count] < $login_count } {
  HTTP::redirect "/login"
  }

#####END_LK########

#####START_SMS########
 if { ([HTTP::path] starts_with "/somebuilder/somepath/someVerification/sendsomesms.json.jsp") and [HTTP::method] eq "POST"} {
    HTTP::collect [HTTP::header Content-Length]
    set loginevent 2
    set SMS_count 3
	set b_challande_count_sms 0
   #log local0. "Login event loginevent "
 }
#####END_SMS########


}
}

when HTTP_REQUEST_DATA {
###разбор запроса###
  if { $loginevent == 1 } { 
                             foreach x [split [string tolower [HTTP::payload]] "&"] {
				if { $x starts_with "%2fcom%2fsomesite%2fsomeuserprofil%2floginhandler.loginsensitive=" } { 
                      set user_agent [HTTP::header User-Agent]
                     set var [IP::client_addr]$user_agent
				     set username [lindex [split $x "="] 1]
				     set countloginintable [table keys -subtable customer_login:[IP::client_addr] -count]
				     set countloginintable2 [table keys -subtable customer_login_un:$var -count]
				    
                     if { [table keys -subtable customer_login:[IP::client_addr] -count] >= $ login_count} {
                         set evil_client 1
set srcip [IP::remote_addr]
						 set msec [clock clicks -milliseconds] 
						
						 
						 if { [table keys -subtable customer_login_un:$var -count] > = 3} {

set evil_client_action 1
} else {
table set -subtable customer_login_un: $ var $ msec indefinite 600
}
                         BOTDEFENSE :: enable

                        }
}

}
### parsing request ###
   log local0. "USERNAME $ username count $ countloginintable count capt $ countloginintable2 var $ var"
    HTTP :: release
  } elseif {$ loginevent == 2} {
                             foreach x [split [string tolower [HTTP::payload]]"&"]{
if {$ x starts_with "phone ="} {
set phone [lindex [split $x "="] one]table set -subtable sms_some_phone:[IP::client_addr] $ phone indefinite 600
                     if {[tablekeys-subtablesms_some_phone:[tablekeys-subtablesms_some_phone:[IP::client_addr] -count]> = $ sms_count} {
                         set evil_client 2
set srcip [IP::remote_addr]
                         BOTDEFENSE :: enable

                        }
}

}

   log local0. "phone sms $ phone"
    HTTP :: release
  }
  
}

### authentication verification ###

when HTTP_RESPONSE {
        if {$ loginevent == 1} {
        HTTP :: collect 2048
        if { [HTTP::cookie exists "SOME_USER_ID"] } {
        log local0. "successsss login $ username $ success_login Evilclient $ evil_client"

            set success_login 1
        } else {
            set success_login 0
                    log local0. "asdasdassuccesssss login $ username $ success_login Evilclient $ evil_client"

table set -subtable customer_login:[IP::client_addr] $ username indefinite 600
        }
        set loginevent 0
log local0. "success login $ username $ success_login Evilclient $ evil_client"
        }

}

 when BOTDEFENSE_ACTION {
 
  log local0. "BOTDEFENSE_ACTION [BOTDEFENSE::action] client $ evil_client BR [BOTDEFENSE::reason]  BC [BOTDEFENSE::captcha_status] $ evil_client_action "
    set coun222t 0
set key "$ srcip2"
append key "_8"
if {[HTTP::path] eq "/ NCbf5" and $ evil_client == 1 and  [HTTP::method] eq "GET" and not ([BOTDEFENSE::action] eq "allow")} {

if {($ evil_client == 1 and $ evil_client_action == 0) and (not ([BOTDEFENSE::reason] starts_with "passed browser challenge")) and ([BOTDEFENSE::captcha_status] ne "correct")} {

log local0. "[IP::client_addr] has [BOTDEFENSE::action], reason: [BOTDEFENSE::reason]"
#Browser Chalange
set res [BOTDEFENSE::action browser_challenge]

			} elseif {($ evil_client == 1 and $ evil_client_action == 1) and (not ([BOTDEFENSE::reason] starts_with "passed browser challenge")) and ([BOTDEFENSE::captcha_status] ne "correct")} {
set res [BOTDEFENSE::action captcha_challenge]
			      log local0. "[IP::client_addr] has [BOTDEFENSE::action], reason: [BOTDEFENSE::reason]"

} else {set res [BOTDEFENSE::action allow] }

} elseif {[HTTP::path] eq "/ login" and $ evil_client == 1 and  [HTTP::method] eq "POST" and (not ([BOTDEFENSE::reason] starts_with "passed browser challenge")) and ([BOTDEFENSE::captcha_status] ne "correct") and not ([BOTDEFENSE::action] eq "allow")} {
BOTDEFENSE :: action custom_redirect "/ NCbf5" 302
log local0. "Send custum redirect [IP::client_addr]"

} elseif {[HTTP::path] eq "/ NCbf5" and [BOTDEFENSE::action] eq "allow"} {
BOTDEFENSE :: action custom_redirect "/ login" 302
log local0. "Send custum redirect [IP::client_addr]"

}

 
 }

Such a rule allowed the customer to track events related to the selection of logins / passwords, even taking into account the features of its authorization form.

Remember that securing web applications is an ongoing process.

And there are also situations when information about a new vulnerability appears, and the vendor has not yet sent an update for WAF to start detecting and closing it. Vulnerable software developers haven’t managed to update anything yet. Remember ShellShock: then millions of systems became vulnerable at once, and the attack was so simple that “scriptdidi” could have done it. And they began to attack from the first hours after the publication of news about the vulnerability found. And what in this case to do? It is useless to try to profile policies for this vulnerability, there is no signature base.

In such a situation, you need to write a specific rule to detect and block such an attack – even if this is a temporary stub, but it needs to be done. Therefore, you need to keep your finger on the pulse and constantly monitor the Internet for new vulnerabilities.

Working with WAF involves constant interaction with all structural units that are responsible for the operation of the web server and the web applications located on it. Working with WAF is the constant operation and adaptation of existing security policies, it is 24X7 operation to support accessibility and response to emerging incidents, it is the presence of a staff of experienced specialists and analysts who perfectly understand the difference between XSS and SQL injection, understand what is relevant for one web application and is not applicable for another, they understand the principle of operation of different frameworks and can carry out high-quality and quick adaptation of the profile and security policies on WAF for a specific web application. We wrote more about this in the articles "The Problem of Continuous Protection of Web Applications", where they gave a look at the problem from developers and customers.

Perhaps after reading the article, someone will not want to contact WAF at all, but in modern realities this approach is almost impossible. Just from the very start of the project, keep in mind all the features of operation and plan how you will bypass these pitfalls.

Egor Valov, Analyst, Expert Presale, Products and Services, Solar JSOC

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *