WordPres in stabil eklentisi Akismet; spam yorumlari engellemenizi saglayan 1 milyondan fazla kullanicisi olan bi eklenti..
Bu konuda Akismet te bulunan stored xss ve detaylarini fix ve bug sürecini kapsamli olarak anlatacagim.
3.1.4 ve alt sürümlerde ki bu açik ile kritik düzeyde bilgilere erisebiliyorsunuz.
Ilk olarak açigin kaynak kodlarini inceleyecegiz.
class.akismet-admin.php açalim ve 44. satir ve 595-605. satirlari inceleyelim.
#44 add_filter( ’comment_text’, array( ’Akismet_Admin’, ’text_add_link_class’ ) );
ve...
# public static function text_add_link_callback( $m ) {
596 // bare link?
597 if ( $m[4] == $m[2] )
598 return ’<a ’.$m[1].’ href= "’.$m[2].’" ’.$m[3].’ class="comment-link">’.$m[4].’</a>’;
599 else
600 return ’<span title="’.$m[2].’" class="comment-link"><a ’.$m[1].’ href= "’.$m[2].’" ’.$m[3].’ class="comment-link">’.$m[4].’</a></span>’;
601 }
602
603 public static function text_add_link_class( $comment_text ) {
604 return preg_replace_callback( ’#<a ([^>]*)href= "([^"]+)"([^>]*)>(.*?)</a>#i’, array( ’Akismet_Admin’, ’text_add_link_callback’ ), $comment_text );
605 }
buradaki dikkat çeken noktalar text_add_link_class ve comment_text kisimlari... text add class ile comment_text yönetim panelinin içerinde ki kisimlari ilgilendiren fonksiyonlar..
yani burada yönetim paneli içersinde etki edecek "comment" post içerigi üzerinde xss deneyecek olursak belirli tirnak isaretleri ve payloadlar ile bu fonksiyonlar uzerinden etkilesim kurabiliyoruz..
konuyu biraz daha detayli olarak ele alayim yorum kismina ‘>Test<abbr title=""’ yazildigi vakit panelde su sekilde etkilesim kurulacaktir

istemciye gönderdigimiz bu payload a yanit veren fonksiyon u wordpress dosyalarindan rel=” nofollow” ile tespit edecegiz. Once wp-includes/formatting.php yi açalim ve rel=” nofollow” olarak aratalim.. Asagida ki kodlar dikkatimizi çekecek
2238 function wp_rel_nofollow( $text ) {
2239 // This is a pre save filter, so text is already escaped.
2240 $text = stripslashes($text);
2241 $text = preg_replace_callback(’|<a (.+?)>|i’, ’wp_rel_nofollow_callback’, $text);
2242 return wp_slash( $text );
2243 }
2244
2245 /**
2246 * Callback to add rel=nofollow string to HTML A element.
2247 *
2248 * Will remove already existing rel="nofollow" and rel=’nofollow’ from the
2249 * string to prevent from invalidating (X)HTML.
2250 *
2251 * @since 2.3.0
2252 *
2253 * @param array $matches Single Match
2254 * @return string HTML A Element with rel nofollow.
2255 */
2256 function wp_rel_nofollow_callback( $matches ) {
2257 $text = $matches[1];
2258 $text = str_replace(array(’ rel="nofollow"’, " rel=’nofollow’"), ’’, $text);
2259 return "<a $text rel=\\\\\\\\\\\\\\\\\\"nofollow\\\\\\\\\\\\\\\\\\">";
2260 }
Son kisima dikkat.. ve wp_rel_nofollow fonksiyonunun ilk girdigimiz degerler sonucu istemciye giden etkilesim ile Html destekli ögeleri çalistirdigini tespit ediyoruz. Ve farkli bir yöntem ile asagida ki sekilde tekrar comment kismina payload girelim.

Ve panel üzerinde alacagimiz sonuç asagida...

Buraya kadar kullandigimiz fonksiyon ve payloadlarin bir biri ile iletisim içinde oldugunu rahatlikla anladik.. Simdi bundan sonra bir baska fonksiyon ile pekistirip bulacagimiz kalici XSS için senaryo uretmeye devam edecegiz..
WordPress in filtre sisteminde bazi fonksiyonlar yer alir.. Bunlarin biri de wp_kses fonksiyonu. Bu özellik ile HTML karakterleri izin verildigi sürece özgürce istemcide calistirabiliyorsunuz.. Simdi bu fonksiyonu biraz önce gelistirdigimi payload da ki belirli tirnak isaretleri ile istismar edebiliyoruz.
wp-includes/default-filter.php dosyasinda ki kodlari inceleyelim
add_filter( ’comment_text’, ’wptexturize’ );
147 add_filter( ’comment_text’, ’convert_chars’ );
148 add_filter( ’comment_text’, ’make_clickable’, 9 );
149 add_filter( ’comment_text’, ’force_balance_tags’, 25 );
150 add_filter( ’comment_text’, ’convert_smilies’, 20 );
151 add_filter( ’comment_text’, ’wpautop’, 30 );
ve bahsettigimiz kses fonksiyonunun bi kismi..
foreach ( array( ’pre_term_name’, ’pre_comment_author_name’, ’pre_link_name’, ’pre_link_target’, ’pre_link_rel’, ’pre_user_display_name’, ’pre_user_first_name’, ’pre_user_last_name’, ’pre_user_nickname’ ) as $filter ) {
17 add_filter( $filter, ’sanitize_text_field’ );
18 add_filter( $filter, ’wp_filter_kses’ );
19 add_filter( $filter, ’_wp_specialchars’, 30 );
20 }
21
22 // Strip, kses, special chars for string display
23 foreach ( array( ’term_name’, ’comment_author_name’, ’link_name’, ’link_target’, ’link_rel’, ’user_display_name’, ’user_first_name’, ’user_last_name’, ’user_nickname’ ) as $filter ) {
24 if ( is_admin() ) {
25 // These are expensive. Run only on admin pages for defense in depth.
26 add_filter( $filter, ’sanitize_text_field’ );
27 add_filter( $filter, ’wp_kses_data’ );
28 }
29 add_filter( $filter, ’_wp_specialchars’, 30 );
Burada ki force_balance_tags, convert_smilies, wpautop ve convert_smilies kisimlari en basta belirttigimiz Akismet üzerinde baglantili olantext_add_link_class ile iliskili olup tamamen istemciye gönderilecek payloadlar ile iliskilidir..
Yukarida verdigimiz payloadi gelistirerek yeni bir tirnak isareti ile asagida ki sonucu alacagiz.
<span title="’> <img src= "http://cw.com/wp-includes/images/smilies/simple-smile.png">
ve <abbr title = ile DOM XSS enjekte edip istemciye gönderildiginde alinacak sonuc
##### DOM XSS : <abbr title=’" class="comment-link"><a href=’
href= "’> :-) <abbr title=’" ’ class="comment-link">x</abbr></a> ######

Ne yaptik? basit bir payload ile akismette bulunan kritik açik sayesinde wp dosyalari ile etkilesim kurarak Xss zafiyeti tespit ettik.
# Peki tüm bunlari nasil önleyecegiz?
En iyi ihtimalle 3.1.5 sürümünü download edin :) Manuel olarak isee.. class.akismet-admin.php de ki 27,45 ve 595-605. satirlari asagida ki kodlar ile degistirelim..
self::$initiated = true;
add_action( ’admin_init’, array( ’Akismet_Admin’, ’admin_init’ ) );
add_action( ’admin_menu’, array( ’Akismet_Admin’, ’admin_menu’ ), 5 ); # Priority 5, so it’s called before Jetpack’s admin_menu.
add_action( ’admin_notices’, array( ’Akismet_Admin’, ’display_notice’ ) );
add_action( ’admin_enqueue_scripts’, array( ’Akismet_Admin’, ’load_resources’ ) );
add_action( ’activity_box_end’, array( ’Akismet_Admin’, ’dashboard_stats’ ) );
add_action( ’rightnow_end’, array( ’Akismet_Admin’, ’rightnow_stats’ ) );
add_action( ’manage_comments_nav’, array( ’Akismet_Admin’, ’check_for_spam_button’ ) );
add_action( ’admin_action_akismet_recheck_queue’, array( ’Akismet_Admin’, ’recheck_queue’ ) );
add_action( ’wp_ajax_akismet_recheck_queue’, array( ’Akismet_Admin’, ’recheck_queue’ ) );
add_action( ’wp_ajax_comment_author_deurl’, array( ’Akismet_Admin’, ’remove_comment_author_url’ ) );
add_action( ’wp_ajax_comment_author_reurl’, array( ’Akismet_Admin’, ’add_comment_author_url’ ) );
add_action( ’jetpack_auto_activate_akismet’, array( ’Akismet_Admin’, ’connect_jetpack_user’ ) );
add_filter( ’plugin_action_links’, array( ’Akismet_Admin’, ’plugin_action_links’ ), 10, 2 );
add_filter( ’comment_row_actions’, array( ’Akismet_Admin’, ’comment_row_action’ ), 10, 2 );
add_filter( ’plugin_action_links_’.plugin_basename( plugin_dir_path( __FILE__ ) . ’akismet.php’), array( ’Akismet_Admin’, ’admin_plugin_settings_link’ ) );
Dip Not : Test etmeden sunucuya dosyalari atmayin.. Manuel olarak takip edip report dosyalarini mutlaka okuyun
Bug Researchers