Browsing posts in: WordPress

Cómo solucionar “Hacked by Gabby” en WordPress

Ninguna plataforma es 100% fiable ni segura, mucho menos cuando tienes un hosting compartido con cPanel, como es mi caso. Por ello, esta noche tuve una intromisión en este blog; afortunadamente todo estaba con copia de seguridad pertinente.

El problema fue el “Hacked by Gabby”, parecido al “hacked by hacker”, pero algo más enrevesado y complicado de solucionar, ya que Google no arroja ningún resultado de momento, además de no dejar acceder al wp-admin. En principio reinstalé todo WordPress, pero el error continuaba -aunque ya tenía acceso al wp-admin-, aunque por un momento lograba ver mi web anterior, antes de ser reemplazada por la molesta frase. Buscando en todos los archivos de PHP buscaba la frase, incluso cortada; también en los ficheros de JS del tema, pensando que era una redirección o sobrescritura en el onready. Pero era algo más fácil, una línea de código insertada desde un widget de texto en la barra lateral que reemplazaba el innerHtml del documentElement.

document.documentElement.innerHTML = unescape('%48%61%63%6b%65%64%20%42%79%20%47%61%62%62%79');

Nótese la malicia poniendo el texto.

Conclusión

  1. Para tener acceso al wp-admin reinstala WordPress por FTP. (Nota: no sé si habrá una forma más fácil de hacerlo).
  2. Ve a Apariencia->Widgets.
  3. Busca un Widget de texto con el trozo de código arriba mencionado.
  4. Elimina dicho widget.
  5. Ya tienes tu blog sin el “Hacked By Gabby” :).

Cómo enviar comentarios a WordPress desde Windows Phone [C#]

Por si alguna vez necesitáis enviar comentarios a un blog de WordPress desde vuestra aplicación de Windows Phone 7 (en realidad se puede adaptar el código a otras plataformas con dos pequeños tweaks), lo que necesitáis hacer es lo siguiente:

##El problema, identificando requerimientos##

Necesitamos enviar un comentario a un blog de WordPress, se nos puede ocurrir que tenemos que enviar una petición con unos datos al blog. ¿A qué dirección? ¿Qué datos? ¿En qué forma?

WordPress tiene una página para eso, es http://nombreblog.com/wp-comments-post.php. En este caso, por ejemplo, es http://danielrozo.es/wp-comments-post.php. Ya tenemos resuelta la primera duda.

Ahora necesitamos saber qué datos debemos enviar, para ello sólo basta con mirar el formulario que aparece debajo de cada entrada de WordPress, o bien, mirar el código fuente de wp-comments-post.php y ver las peticiones POST que acepta, que son:

  • comment_post_ID.
  • author.
  • email.
  • comment.
  • url.

Con esto hemos respondido las preguntas que nos quedaban: debemos enviar todos estos datos en una petición de tipo POST a /wp-comments-post.php.

El diseño de una página que haga esto es muy sencillo, os lo dejo a vosotros (son textboxes y fuera).

La única duda que queda por contestar es ¿Cómo identifica wp-comments-post.php el post al que quiero enviar el comentario? Pues con el comment_post_ID que le enviamos. Como consecuencia de ello, necesitamos el ID del post, en los WordPress que no tengan vanity URLs es el número que sale después de ?p= en la dirección. Para los que sí la tengan, es necesario cogerlo del RSS. Por ejemplo, si vemos el RSS de esta página vemos que dentro de cada <item> hay un <guid>, este es el elemento que necesitamos tratar para coger el ID del post. Vamos a ver cómo hacerlo usando LINQ, que es una maravilla. Supondré que tenéis una clase Post con los atributos creados, getters, setters y esas cositas que hacen falta. Este código debéis encapsularlo en un método al que le pasáis la string del XML del RSS que descargáis.


StringReader stringReader = new StringReader(feedXML);
 XmlReader xmlReader = XmlReader.Create(stringReader);
 XDocument loadedPosts = XDocument.Load(xmlReader);
 XNamespace dc = "http://purl.org/dc/elements/1.1/";
 XNamespace content = XNamespace.Get("http://purl.org/rss/1.0/modules/content/");
 var data = from query in loadedPosts.Descendants("item")
 select new Post
  {
   NombreBlog=(string)query.Parent.Element("title"),
   Titulo = (string)query.Element("title"),
   Autor = (string)query.Element(dc + "creator"),
   Contenido = (string)query.Element(content + "encoded"),
   Fecha = (string)query.Element("pubDate"),
   Link = (string)query.Element("link"),
   ID=getId((string)query.Element("guid")),
   Imagen = getImage((string)query.Element(content + "encoded"))
  };
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
  feedListBox.ItemsSource = data;
});

Dejando de lado los detalles del asunto, sólo os hace falta el método getId, que es el siguiente:

</pre>
private string getId(string s)
 {
string [] sa=s.Split('=');
return sa[1];
 }

Separa la string que le pasas, que será de tipo http://nombreblog.com/?p=xxxx, y devuelve solo el “xxxx” que es el ID.

Ahora sólo nos queda montar la petición POST que será enviada, que será algo parecido a esto:


WebClient webClient = new WebClient();
 webClient.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
 var uri = new Uri("http://" + url + "/wp-comments-post.php?", UriKind.Absolute);
 StringBuilder postData = new StringBuilder();
 postData.AppendFormat("{0}={1}", "comment_post_ID", HttpUtility.UrlEncode(_sItem.ID));
 postData.AppendFormat("&{0}={1}", "author", HttpUtility.UrlEncode(nombreTb.Text));
 postData.AppendFormat("&{0}={1}", "email", HttpUtility.UrlEncode(correoTb.Text));
 postData.AppendFormat("&{0}={1}", "comment", HttpUtility.UrlEncode(comentarioTb.Text));
 postData.AppendFormat("&{0}={1}", "url", HttpUtility.UrlEncode(urlTb.Text));
 MessageBox.Show("" + postData);

webClient.Headers[HttpRequestHeader.ContentLength] = postData.Length.ToString();
 webClient.UploadStringCompleted += new UploadStringCompletedEventHandler(webClient_UploadStringCompleted);
 webClient.UploadProgressChanged += webClient_UploadProgressChanged;
 webClient.UploadStringAsync(uri, "POST", postData.ToString());

Obviamente necesitáis tener los textboxes montados en vuestro XAML e implementar los métodos que se llaman por UploadStringCompleted (que será mostrar un mensaje de “Comentario posteado!” o algo y el UploadProgressChanged, que vendrá a actualizar una barra de progreso que tengáis con el ProgressPercentage del UploadProgressChangedEventArgs que le paséis al método.

¡Esto es todo, saludos!