Script attacks are the craziest attack methods on the Internet recently. Many servers are equipped with advanced hardware firewalls and multi-level security systems. Unfortunately, there is still no way to resist SQL injection and cross-site scripting attacks on port 80. You can only watch the data being changed beyond recognition by malicious intruders without any solution – arm your Snort and use it to detect such attacks!
We will use the open source intrusion detection system IDS as an example to write rule-based regular expressions to monitor such attacks. By the way, the default rule settings in Snort include keywords for detecting cross-site scripting. Will there be conflicts? Don’t worry, we still have a way to resolve this conflict. We can express them in hexadecimal form of ASCII code. For example, the keyword <script> that exists in both Snort and scripts can be replaced by %3C%73%63%72%69%70%74%3E.
If you want to detect every possible SQL injection, then you only need to check for the presence of any SQL metacharacters, such as single quotes (‘), semicolons (;), and double minus signs (–). Similarly, a very paranoid way to detect cross-site scripting attacks is to check the angle brackets (<, >) of HTML tags. However, the above method may cause a large number of false positives. In order to avoid false positives, we must set the filtering rules as accurate as possible. Even so, we still cannot guarantee that there will be no false positives, so we can only do our best.
In this article, we will use Snort to detect strings in Perl as an example to give a detailed introduction. Readers who are not familiar with Perl should go back and read the regular expressions in Perl carefully.
1. Regular expressions for SQL injection
When choosing regular expressions for SQL injection, you need to remember that in addition to attacking from the cookie field, attackers can also attack through the input box of the form. Therefore, when you perform logical validation on input, you should also consider every input information from the user, such as form fields and cookie information should be regarded as suspicious objects. Similarly, if you find many alerts for single quotes and semicolons, it may be because of the information in the cookies of the web application. Therefore, such special symbols must be evaluated for specific web applications.
As mentioned earlier, a weak regular expression for detecting SQL injection attacks is to check for the metacharacters mentioned above (‘;–). To detect such metacharacters, or their hexadecimal equivalents, we can use the following regular expression:
/(%27)|(‘)|(–)|(%23)|(#)/ix
Here, %27 is the hexadecimal value of single quotes, and %23 is the hexadecimal value of ‘#’. Single quotes and hyphens are special characters in MS SQL Server and Oracle. If we are using MySQL, we must also detect the occurrence of ‘#’. It is important to note that the hexadecimal value of “—” does not need to be checked because it is not an HTML metacharacter and will not be encoded by the browser. Similarly, if an attacker tries to manually modify “—” to its hexadecimal value %2D, the SQL injection operation will fail. For those who are not familiar with Perl, I will briefly explain the regular expression above: // is the code used in Perl to cause pattern matching, and its full form is m//. Usually, when we use double slashes to cause pattern matching code, we can omit m. The symbol “|” is the function of or, just like the usual meaning of or in other languages. The parentheses here are written to make it easier for readers to understand, and they can be completely omitted. The i after the second / means that the letters to be matched are not case-sensitive. The x after the second / means to ignore spaces in the pattern.
We can add the above expression to the Snort rule: alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:”SQL Injection – Paranoid”; flow:to_server,established;uricontent:”.pl”;pcre:”/(%27)|(‘)|(–)|(%23)|(#)/i”; classtype:Web-application-attack; sid:9099; rev:5;)
In this example, we used “.pl” in the uriconten keyword part because our CGI scripts are written in Perl in our test environment. The content of this part depends on your specific application, which may be “.php”, “.asp”, “.jsp”, etc. The content of the pcre keyword is the pattern that will be checked for .pl files. You can get inspiration from this regular expression to write more Snort rules.
It is also possible for a SQL query to contain pure numbers in the Where clause, like this:
select value1, value2, num_value3 from database where num_value3=some_user_supplied_numberIn
this example, the attacker could execute an additional SQL query like this:
3; insert values into some_other_tableThe
above Snort rule can be extended to filter for the presence of a semicolon (;). However, semicolons can also appear in normal HTTP interactions. To reduce false positives, the above rule can be modified to match the portion after the equal sign (=). When a user uses GET or POST to make a request, the input field generally appears like this:
username=some_user_supplied_value&password=some_user_supplied_value
Therefore, the detection of the user’s SQL injection attempt can start with the equal sign (=) or its hexadecimal value. The modified regular expression for SQL metacharacter detection is as follows:
/((%3D)|(=))[^n]*((%27)|(‘)|(–)|(%3B)|(;))/ix
This rule first checks the equal sign (=) or its hexadecimal %3D. Next, [^n]* means matching zero or more non-newline characters, where n is the newline character in Perl, ^ is the exclusion symbol, that is, non-newline character, and * means matching the character in front of it zero or more times. The following part is no different from the previous one.
A typical SQL injection attempt process usually creates a query around single quotes to see if the returned result is correct or not, so as to determine whether there is a SQL injection vulnerability. Most examples use the string 1’or’1’= ‘1. However, it is not easy to detect this type of string, because attackers can easily construct some equivalent strings, such as 1’or2>1–. In this way, the only unchanged parts are a constant and the following string ‘or’. For this type of attack, we can construct the following regular expression for detection, a typical regular expression for SQL injection attacks:
/w*((%27)|(‘))((%6F)|o|(%4F))((%72)|r|(%52))/ix
w (note that the w here is lowercase, the w and W used for pattern matching in Perl have completely different meanings) refers to uppercase and lowercase letters or numbers. After adding *, it means it is used to match one or more numbers or letters. (%27)|’ is used to match a single quote or its hexadecimal value. (%6F)|o|(%4F))((%72)|r|(%52), %6F and %4F are the uppercase and lowercase hexadecimal values of the letter o, and %72 and %52 are the uppercase and lowercase hexadecimal values of the letter r. Because of the use of the i option, there is no need to write out the uppercase and lowercase forms of the letters o and r. In this way, we have taken into account all forms of the word or.
Similarly, in SQL injection, we often use the union keyword. We can set the rule as follows, which is a regular expression for detecting SQL injection of the UNION keyword:
/((%27)|(‘))union/ix
With the above foundation, this rule does not need to be explained in detail. For select, insert, update, delete, drop and other statements that are also frequently encountered, we can draw inferences from one example and flexibly apply the rules to set them.
In SQL injection, in order to make the SQL server return an error and then obtain useful information through the error, we often encounter statements such as 1=(select name from student where sno=’200021′). The value returned by this subquery statement is of character type, while 1 is a number. At this time, an error will occur, thereby leaking the content of the name field. This leads to the fact that we must be able to monitor this common injection. For this type of attack, we cannot start the restriction from 1, because this may lead to a large number of false detections. Obviously, the solution is to monitor the select keyword, because the information submitted in the URL will not normally contain the select keyword.
2.5 Regular expression for monitoring queries similar to 1=(select name from student where sno=’200021′):
/((%27)|(‘))select/ix
In MS SQL Server, extended stored procedures such as xp_cmdshell, xp_regread, and xp_regwrite are also frequently used. When calling this type of stored procedure, the exec keyword must be used. In addition, the system’s stored procedures usually start with sp or xp, so we can configure regular expressions as follows for this type of SQL injection. Regular expression for detecting SQL injection in MS SQL Server:
/exec(s|+)+(s|x)pw+/ix
exec is the keyword for calling a stored procedure. (s|+) represents a space or its HTTP-encoded equivalent. + is used to make the preceding and following characters match at least once. Thus, (s|+)+(s|x) means to make the space and one of s and x match at least once. w+ has been explained before, so I won’t go into details here.
Above, we only monitor some of the most basic methods of SQL injection. However, people who are familiar with SQL injection know that there are many other methods used in SQL injection. We cannot write them all here, so please understand.
2. Regular expressions for cross-site scripting attacks
Before launching a cross-site scripting attack, in order to test the vulnerability of a website, the attacker usually has to do a simple HTML test, which may involve tags in HTML such as <b>, <i>, <u>, etc. Similarly, you can also use a simple script such as <script>alert(“OK”)< /script>. This may be because most of the discussion documents about CSS use such a simple script example to determine whether a site can be attacked by CSS. We can detect this type of attempt through Snort. Some advanced intruders may use transformation methods to test, such as replacing the corresponding hexadecimal value with an equivalent, such as <script> can be replaced with %3C%73%63%72%69%70%74%3E.
The following regular expression can detect this type of attack. It will capture attempts to use <b>, <u>, or <script>. This regular expression is also case-insensitive. We must match both the angle bracket symbol and its hexadecimal value. The hexadecimal value of the left angle bracket < is %3C, and the hexadecimal value of the right angle bracket > is %3E. The regular expression for a simple CSS attack:
/((%3C)|<)((%2F)|/)*[a-z0-9%]+((%3E)|>)/ix
((%3C)|<) detects the left angle bracket. ((%2F)|/)* matches the slash or hexadecimal value that indicates the end of the tag mark. [a-z0-9%]+ matches one or more lowercase letters or Arabic numerals. ((%3E)|>) matches the right angle bracket or its hexadecimal value. This becomes a Snort rule: alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:”NII Cross-site scripting attempt”; flow:to_server,established; pcre:”/((%3C)|<)((%2F)|/)*[a-z0-9%]+((%3E)|>)/i”;classtype:Web-application-attack; sid:9000; rev:5;)
Cross-site scripting can also be achieved by using the <img src=> technique. For this type of attack, we can configure it like this to make CSS attacks less likely to be achieved. Regular expression for CSS attack against <img src>:
/((%3C)|<)((%69)|i|(%49))((%6D)|m|(%4D))((%67)|g|(%47))[^n]+((%3E)|>)/iThe
left and right angle brackets are no longer interpreted. (%69)|i|(%49))((%6D)|m|(%4D))((%67)|g|(%47) is for the match of img. [^n]+ has been mentioned before. There is also a most paranoid regular expression for CSS attacks:
/((%3C)|<)[^n]+((%3E)|>)/i
This regular expression adopts the most “vicious” method, that is, all places where <> appears are considered as CSS attacks. It’s poisonous enough, haha! However, this method is most likely to cause false detection, but it can effectively prevent CSS attacks.
To some extent, cross-site scripting attacks seem to be easier to control, but in fact, readers who often pay attention to black defense have their own profound experience, so I won’t say more.
3. Write rules by yourself
When writing Snort rules, the first thing to consider is efficiency and speed. Good rules should include content options. 2. After version 0, Snort changed the way the detection engine works, doing a collection pattern match in the first stage. The longer a content option is, the more accurate the match will be. If a rule does not contain a content option, they will slow down the entire system.
When writing rules, try to target the attack (e.g., target offset 1025, etc.) rather than being more general (e.g., match script code here). Content rules are case-sensitive (unless you use the nocase option). Don’t forget that content is case-sensitive and that most programs have uppercase letters in their commands. FTP is a good example. Consider the following rules:
alert tcp any any -> 192.168.1.0/24 21 (content: “user root”; msg: “FTP root login”;)
alert tcp any any -> 192.168.1.0/24 21 (content: “USER root”; msg: “FTP root login”;)
The second rule above will detect most automated root login attempts, while the first rule will not. Internet daemons are very liberal in what they accept as input. When writing rules, a good understanding of the protocol specification will reduce the chances of missing an attack.
4. Conclusion
In this article, we have given a variety of regular expressions for SQL injection and cross-site scripting attacks. Although some of them are very paranoid and crude, because even if there is a little attempt to launch an attack, such regular expressions will cause Snort to alarm. Such paranoid regular expressions are most likely to cause false detections. In order to minimize such false detections, we must set regular expressions as accurately as possible. At the same time, the methods we introduced earlier are only for detection of the more common attacks now. In the hacker’s confrontation technology, there is always a rise and fall. “The higher the road, the higher the devil.” When we discover new intrusion methods, we must make appropriate adjustments to certain rules or even add new rules to adapt to new security requirements. I believe that everyone has already experienced this. This article is written based on my understanding. I hope to learn together with everyone.