📜 ⬆️ ⬇️

The path to SQL injection in the Zend Framework

Perhaps a slightly loud title of the article, but this question is raised.

First moment


If you follow all the rules, i.e. use the internal mechanisms of Zend, prepare the parameters in the methods - then at the moment there is no information about the possibility of a sql injection. We are talking about similar structures:
$select->order($value); 

Which somehow meet in practice.

Second moment


What is the salt? The fact is that even with the input of parameters to such methods without any preparation, the internal mechanisms still prepare them. But not all (and some partially) - this is what they mean.

Although we have the source code of this library, we will consider this topic as a “black box”, it will be clearer and clearer. More specifically, the MySQL adapter, the Zend_Db_Select class (the same was tested on PgSQL)
')

Third moment


In order to conduct an injection in Zend, we need to close the previous back quote (for example, in the case of the syntax from = select * from `table` ), or the apostrophe - ( where id = '1' ), since Zend follows the rules when specifying the parameter opens the desired "frame". In the first case, when passing to the tab`ble input, we should have ta``ble at the output, in the second case : at the input 1'2 , at the output 1''2 .
Once again, we are talking about the "raw" sending data to the method.

We have three cases:
  1. FQ - all parameters are prepared (fully quoted)
  2. NQ - the data is not prepared, everything will “go away” to the database, as it was transmitted (no quoted)
  3. PQ - some parameters are being processed, some are not (partially quoted)


Let's go in order, in order in the syntax of SQL

1) -> from - FQ

Code:
 $table = "wp_use`rs"; $select->from($table); 

[queryString] => SELECT `wp_use``rs`.* FROM `wp_use``rs`

2) -> join - PQ

 $table1 = 'tab`le1'; $table2 = 'tab`le2'; $key = 'i`d'; $data = 'da`ta'; $select = $db->select()->from($table1)->join($table2, $table1.'.'.$key.' = '.$table2.'.'.$key, array($data)); 

[queryString] => SELECT `tab``le1`.*, `tab``le2`.`da``ta` FROM `tab``le1` INNER JOIN `tab``le2` ON tab`le1.i`d = tab`le2.i`d

3) -> joinUsing - PQ

 $table1 = 'tab`le1'; $table2 = 'tab`le2'; $key = 'i`d'; $column = 'c`ol\'u;m"n'; $select = $db->select()->from($table1)->joinUsing($table2, $column); 

[queryString] => SELECT `tab``le1`.*, `tab``le2`.* FROM `tab``le1` INNER JOIN `tab``le2` ON `tab``le2`.c`ol'u;m"n = `tab``le1`.c`ol'u;m"n

4) -> where - NQ

 $select->from($table); $value = "1)2'3 --"; $select->where($value); 

[queryString] => SELECT `wp_users`.* FROM `wp_users` WHERE (1)2'3 --)

5) -> group - FQ

 $table = "wp_users"; $value = 'i`d'; $select = $db->select()->from($table)->group($value); 

[queryString] => SELECT `wp_users`.* FROM `wp_users` GROUP BY `i``d`

6) -> having - NQ

 $table = "wp_users"; $value = 'some_count > 0); hello habr -- 10'; $select = $db->select()->from($table)->having($value); 

[queryString] => SELECT `wp_users`.* FROM `wp_users` HAVING (some_count > 0); hello habr -- 10)

7) -> order - FQ

 $table = "wp_users"; $value = i`d'; $select = $db->select()->from($table)->order($value); 

[queryString] => SELECT `wp_users`.* FROM `wp_users` ORDER BY `i``d` ASC

8) -> limit - FQ

There is not even FQ, but simply - type conversion (to int)
 $table = "wp_users"; $limit1 = '1; hello -- '; $limit2 = '2; hello -- '; $select = $db->select()->from($table)->limit($limit1, $limit2); 

[queryString] => SELECT `wp_users`.* FROM `wp_users` LIMIT 1 OFFSET 2
Here -> limitPage (), similar work

9) -> union - NQ

$ db-> select + string
 $table = "wp_users"; $select = $db->select()->from($table); $select2 = "select * from ta\"b'le`2"; $select3 = $db->select()->union(array($select, $select2)); $db->query($select3); 

[queryString] => SELECT `wp_users`.* FROM `wp_users` UNION select * from ta"b'le`2

Summary


FQ: -> from, -> group, -> order, -> limit, -> limitPage
PQ: -> join, -> joinUsing
NQ: -> where, -> having, -> union

In practice, non-filtered data can be found, for example, in ajax handlers.

PS Among other things, perhaps someone will take this data to himself in CTF.

UPD: Moment 4: An article more for pentesters who may encounter an application on Zend.

Source: https://habr.com/ru/post/140145/


All Articles