Mostrar últimos comentarios de CuteNews

Filed in Lenguajes | PHP Leave a comment

CuteNews es un sistema de gestión de noticias muy fácil de usar y de implementar en la mayoría de los proyectos a nivel web. Sin embargo, a la hora de tratar de mostrar los últimos comentarios se dificulta un poco por lo que he creado un pequeño “hack” para facilitar ésta tarea; claro, como todo script tiene algunos contras:

  • Pro
    • Muestra los comentarios a base de un template sumamente editable.
  • Contra
    • Se deberan mudar los comentarios manualmente.

Lo primero que debemos hacer es dirigirnos a la línea 95 del archivo show.inc.php de la carpeta inc y sustituír:

$name = trim($name);
$mail = trim($mail);
$id = (int) $id;  // Yes it's stupid how I didn't thought about this :/

Por:

$name = trim($name);
$namec = trim($name); #Don't edit this (at: Xt3mP)
$mail = trim($mail);
$id = (int) $id;  // Yes it's stupid how I didn't thought about this :/
$commentc = $comments; #Don't edit this (at: Xt3mP)

Después en la línea 342 (contando que ya modificamos lo anterior) agregamos:

//============================
//   Last comments by Xt3mP
//============================
$newComments = @fopen('data/newComments.txt', 'a+');
@fwrite($newComments, $mail.'|'.$namec.'|'.$commentc.'|'.$id.'|'.$time."\r\n");
@fclose($newComments);

Con ésto sólo tendríamos el sistema que cada vez que se comente correctamente, abrirá el archivo newComments.txt en la carpeta data y agregará el comentario para posteriormente procesarlo y mostrarlo.

Ahora sólo queda crear el archivo show_comments.php en la raíz del sistema con el siguiente código PHP:

<?php
/*
 * Show comments from CuteNews 1.0
 * Author: Xt3mP
 * Author website: http://xt3mp.mx
 * Contact: xt3mp@null.net
 * Tested on: CuteNews 1.4.6
 */
//============================
//       Configuration
//============================
#Where do you've installed cutenews?
$basePath = 'http://localhost/projects/works/Habbostorm/noticias/';
#Where do you've the news show file?
$baseFile = 'show_news2.php';
#The show template
	#{url} = News' link
	#{comment} = The comment (oh really?)
	#{name} = The author
	#{date} = Time of the post
$template = '<a href="{url}">{name}</a>:
 {comment} - {date}
';
#How many comments wanna show?
$maxComments = 6;
#How length need to be any comment?
$maxLenght = 10;
#The "hack" comment file {don't edit this}
#============================
#  Process {don't edit this}
#============================
$dataContent = file_get_contents('data/newComments.txt');
$comments = explode("\r\n", $dataContent);
$from = count($comments) - ($maxComments + 1);
$to = count($comments);
$showComments = array();
for($i = $from; $i < $to;  $i++) { 	$newTemplate = $template; //Stupid fix? 	$comment = explode('|', $comments[$i]); 	if(!empty($comment[0])) 	{ 		$newTemplate = str_replace('{url}', 'show_news2.php?subaction=showcomments&template=&id='.$comment[3].'&archive=&start_from=&ucat=', $newTemplate); 		if(strlen($comment[2]) > $maxLenght)
			$newTemplate = str_replace('{comment}', htmlentities(substr($comment[2], 0, $maxLenght)).'...', $newTemplate);
		else
			$newTemplate = str_replace('{comment}', htmlentities($comment[2]), $newTemplate);
		$newTemplate = str_replace('{name}',  htmlentities($comment[1]), $newTemplate);
		$newTemplate = str_replace('{date}', date('d M Y h:i a', $comment[4]), $newTemplate);
		$showComments[] = $newTemplate;
	}
}
#Reverse array way
krsort($showComments);
#Print array
foreach($showComments as $comments)
	echo $comments;
?>

Con ésto sólo bastaría tener un iframe de la siguiente forma:

<iframe src="show_comments.php" width="200" height"100"></iframe>

La forma de editar el template se basa en la línea 21 del archivo show_comments.php el cual puede ser de varias formas:

$template = '<a href="{url}">{name}</a>:<br /> {comment} - {date}<br />';
$template = '<a href="{url}">{comment}</a>:<br /> {date}<br />';
$template = '<a href="{url}">{name}</a>:<br /> {comment}<br />';
$template = '<div id="comment"><div class="name"><a href="{url}">{name}</a>:</div><div class="comment">{comment}</div></div>';

Inclusive ustedes pueden agregar sus divs como en el último ejemplo. Para mudar los comentarios sólo deben seguir el formato:

correo|autor|comentario|id_noticia|timestamp(tiempo)

y guardarlos en el archivo newComments.txt.

Es todo, cualquier duda, comentario o sugerencia comenten.

Xt3mP ~ xt3mp@null.net

, , , , , , , ,

Dorks links Grabber (Bing Version)

Filed in In/seguridad | PHP Leave a comment

Este es un script que ya tenía guardado, el cual tiene como fin obtener páginas del motor de Bing para comprobarlas y checar el archivo en cuestión (ingresado) existe. La idea la tenía ya hace un tiempo pero en realidad la idea príncipal le corresponde a ar3sw0rmed ya que el me lo comentó y me gustó la idea.

Nota: Es probable que pueda generar falsos positivos porque la manera de comprobar el archivo no es tan eficaz, por lo que algunos servidores al entrar a web.com/archivoinexistente.php lo regresa como 200 en éste caso ya que es encontrada y no quize comprobar la página por cURL.

La utilidad consta de lo siguiente:

  • Insert DORK: Dork de bing.
  • Search Engine: Por el momento Bing; Google se maneja diferente y está un poco más complicado.
  • Output file: Nombre de archivo donde se guardara el resultado.
  • Check file: Nombre de archivo a comprobar.
  • Raw links: Todos los enláces encontrados.
  • Correct links: Todos los enláces correctos.
  • Bad links: Todos los enláces incorrectos.
  • Output file: Ruta del archivo creado.
  • Estadísticas.

El script sólo llega hasta la página 20 apróximadamente y puede tardar dependiendo del servidor, en mi caso, en localhost tardó 7 minutos.


<?php
/*
 * Author: Xt3mP
 * Name: Dorks link grabber
 * Version: 1.0 Bing
 * Contact: xt3mp[at]null[dot]net
 * Website: http://xt3mp.mx | http://backroot.org
 */
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Dorks links Grabber (Bing version) | Xt3mP</title>
<style type="text/css">body{background-color:#2b2b2b;color:#777;font-family:Courier,"Courier New",monospace,sans-serif;font-size:12px}div#container{height:auto;margin:0 auto;width:600px}fieldset{background-color:#222;border:1px dashed #777;float:left;margin:5px;padding:5px;width:100%}legend{background-color:#555;border:1px dashed #777;color:#FFF;font-weight:700;margin:5px;padding:5px}label{float:left;margin-right:5px;padding-top:5px;text-align:right;width:100px}input,select{background-color:#E7E7E7;border:1px dashed #777;float:left;font-family:Courier,"Courier New",monospace,sans-serif;font-size:12px;margin-bottom:5px;padding:3px;width:490px}input[type=submit]{width:600px}h1{margin:0;padding:0}a{color:#CCC;font-weight:700}a:hover{color:#FFF;text-decoration:underline}</style>
</head>
<body>
<?php
set_time_limit(0);
class dorkGrabber
{
	private $bing;
	private $checkfile;

	public function __construct()
	{
		$this->bing = 'http://www.bing.com/search?q=';
	}

	private function getSource($target)
	{
		$target = @file_get_contents($target);
		return $target;
	}

	private function remakeUrl($url)
	{
		$url = explode("/", $url);
		for($z = 0; $z < count($url) - 1; $z++)
		{
			$new .= $url[$z].'/';
		}
		return $new;
	}

	private function checkUrl($url)
	{
		if(@fopen($this->remakeUrl($url).$this->checkfile, 'r'))
			return true;
		else
			return false;
	}

	private function parseLinks($target)
	{
		$data['rawlinks'] = array();
		$data['correctlinks'] = array();
		$data['badlinks'] = array();
		for($i = 0; $i < 21; $i++)
		{
			$first = ($i == 0) ? 0 : ($i * 10) + 1;
			$source = $this->getSource($target.'&first='.$first);
			$pattern = "/<h3><a href=\"(.*?)\" onmousedown=/";
			$preg = preg_match_all($pattern, $source, $output, PREG_PATTERN_ORDER);

			if(count($output[1]) != 0)
			{
				for($x = 0; $x<count($output[1]); $x++)
				{
					if(!in_array($this->remakeUrl($output[1][$x]), $data['correctlinks']))
					{
						if($this->checkUrl($output[1][$x]))
						{
							$data['rawlinks'][] = $output[1][$x];
							$data['correctlinks'][] = $this->remakeUrl($output[1][$x]);
						}else{
							$data['rawlinks'][] = $output[1][$x];
							$data['badlinks'][] = $output[1][$x];
						}
					}
				}
			}else{
				break;
			}
		}
		return $data;
	}

	private function getLinks($target)
	{
		$newTarget = $this->getSource($target);
		$check = "/<h1>No se han encontrado resultados para <strong>/";
		if(@preg_match($check, $newTarget))
			return false;
		else
			return $this->parseLinks($target);
	}

	private function makeData($type, $links, $output = null)
	{
		switch($type)
		{
			case 'raw':
				$title = '<h1>Raw links</h1>';
				foreach($links['rawlinks'] as $link)
				{
					$linkdir .= $link."\r\n";
				}
				$data = $title.'<textarea rows="5" style="width: 600px; font-size: 11px;">'.$linkdir.'</textarea>';
			break;
			case 'correct':
				$title = '<h1>Correct links</h1>';
				foreach($links['correctlinks'] as $link)
				{
					$linkdir .= $link."$this->checkfile\r\n";
				}
				$data = $title.'<textarea rows="5" style="width: 600px; font-size: 11px;">'.$linkdir.'</textarea>';
			break;
			case 'bad':
				$title = '<h1>Bad links</h1>';
				if(empty($links['badlinks']))
				{
					$data = $title.'<textarea rows="5" style="width: 600px; font-size: 11px;">None</textarea>';
				}else{
					foreach($links['badlinks'] as $link)
					{
						$linkdir .= $link."\r\n";
					}
					$data = $title.'<textarea rows="5" style="width: 600px; font-size: 11px;">'.$linkdir.'</textarea>';
				}
			break;
			case 'txt':
				$title = '<h1>Output file</h1>';
				foreach($links['correctlinks'] as $link)
				{
					$linkdir .= $link.$this->checkfile;
				}
				$tot = count($links['correctlinks']) + count($links['badlinks']);
				$statistics = '
							[Total links: <b>'.$tot.'</b>]
							[Correct links: <b>'.count($links['correctlinks']).'</b>]
							[Bad links: <b>'.count($links['badlinks']).'</b>]';
				$file = fopen($output, 'w+');
				if($file)
				{
					fwrite($file, $linkdir);
					fclose($file);
					$filedir = $output.' > http:/'.dirname($_SERVER["PHP_SELF"]).'/'.$output;
					$data = $title.'<textarea rows="5" style="width:600px;font-size:11px;margin-bottom:5px;">'.$filedir.'</textarea>';
					$data .= $statistics.' <a href="./'.$output.'" target="_blank">[View output file]</a>';
				}else{
					$data = $title.$statistics.' [Can\'t make output file]';
				}
			break;
		}
		return $data;
	}

	public function makeDirective($dork, $output, $checkfile = null)
	{
		$dork = urlencode($dork);
		$target = $this->bing.$dork;
		$this->checkfile = $checkfile;
		$grabber = $this->getLinks($target);
		$result = '<fieldset style="text-align: justify"><legend>Result</legend>';
		if($grabber === false)
		{
			$result .= 'The DORK (<b>'.urldecode($dork).'</b>) doesn\'t return any results.';
		}else{
			$result .= $this->makeData('raw', $grabber);
			$result .= $this->makeData('correct', $grabber);
			$result .= $this->makeData('bad', $grabber);
			$result .= $this->makeData('txt', $grabber, $output);
		}
		$result .= '</fieldset>';
		return $result;
	}
}
?>
<div id="container">
	<fieldset>
		<legend>Dorks links Grabber (Bing version) | <a href="http://xt3mp.mx" target="_blank">Xt3mP</a></legend>
		<form action="" method="POST">
			<label>Insert DORK:</label><input type="text" name="dork"/><br />
			<label>Search eng.:</label><input type="text" name="engine" value="Bing" disabled="disabled"><br />
			<label>Output file:</label><input type="text" name="output" /><br />
			<label>Check file:</label><input type="text" name="check"/><br />
			<input type="submit" name="get" value="Get Links!" />
		</form>
	</fieldset>
	<?php
	if(isset($_POST['get']))
	{
		if(empty($_POST['dork']) or empty($_POST['output']))
		{
			echo '<script>alert("Some fields are empty!.");</script>';
		}else{
			$mtime = microtime();
			$mtime = explode(' ',$mtime);
			$mtime = $mtime[1] + $mtime[0];
			$starttime = $mtime;
			$dorkGrabber = new dorkGrabber();
			echo $dorkGrabber->makeDirective($_POST['dork'], $_POST['output'], $_POST['check']);
			$mtime = microtime();
			$mtime = explode(' ',$mtime);
			$mtime = $mtime[1] + $mtime[0];
			$endtime = $mtime;
			$totaltime = ($endtime - $starttime);
			echo 'This page took '.round($totaltime).' seconds to load.';
		}
	}
	?>
</div>
</body>
</html>

Cualquier cosa comenten, porque como he dicho, puede que tenga errores.

Xt3mP ~ xt3mp@null.net

, , , , , ,

¿Comprimido?, no gracias.

Filed in In/seguridad Leave a comment

Hola, ¿qué tal?, me paso algo extraño en estos días que me llamo demasiado la atención. Estaba navegando como lo hago constantemente buscando bugs que reportar y me encontre con uno en peculiar, pero ¿qué tenía de peculiar?…
Se trataba de un uploader que todo archivo que se subía se comprimía y de esta manera en caso de que subieramos un .php no dejaría ejecutarlo.

Y aquí entran las posibilidades y preguntas como:

  • ¿Cómo se comprimirá el archivo? - Primero se debe subir para luego comprimir el mismo.
  • ¿Dónde se subirá el archivo? - En el mismo path [eso parece].
  • ¿Sube el archivo a un tmp o a un path? - En el mismo path [eso parece].

Hice un par de pruebas y me encontre que efectivamente, los subía a un path y no a un temporal:

Analizando y pensando como si yo hubiera programado el script llegué a la conclusión que si subo el archivo a un mismo path, para comprimirlo debería tener primero el archivo y decidí subir un “file.php” al servidor, pero no comúnmente si no que a mitad de la carga pare la página para que de esta manera solo se subiera el script y no se cumpliera la petición de comprimir.

Aún no sabía si lo había logrado… pero al entrar al path; BINGO!, logré conseguir la shell:

¿Qué quiero decir con esto? 
Que cuando ustedes programen no solo lo miren del método seguro, si no analizen todas las opciones para evitar que tengan posibles fallos como estos, una experiencia nada más que se me hizo peculiar.

P.D. Lo peor es que es una página del gobierno peruano la cual no fue tocada, ya les reporte el bug.

Xt3mP ~ xt3mp@null.net

, , , ,

Permitir sólo números en jQuery

Filed in jQuery | Lenguajes Leave a comment

A veces por cuestiones de la vida nos vemos en la situación de validar que caracter es ingresado permitiendo sólo así el ingreso de caracteres numéricos. Existen muchas maneras de lograrlo pero en mi caso, lo necesario era que en cuanto el visitante presione una tecla, validarla en tiempo real para solo permitir los caracteres que queremos; en éste caso, numéricos.

Haremos uso del evento keydown tomando como evento el caracter presionado pero antes, por cuestiones de eficacia y porque seguramente necesitamos usarlo en varios input/textarea, le asignaremos una clase de esta manera:

<input class="validar" type="text" name="casilla_1" />
<input class="validar" type="text" name="casilla_2" />

Ahora agregaremos el evento de la siguiente manera:

$(function(){
    $(".validar").keydown(function(event){
        if(event.keyCode < 48 || event.keyCode > 57){
            return false;
        }
    });
});

Con esto nos bastaría para solo permitir números aunque con IE8 tuve problemas. Y respecto a qué hacemos, pues fácil. Mandamos mediante “event” la tecla pulsada y la comparamos con su “char key code“. Los podemos encontrar en http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes.

Hay otras formas de hacer lo mismo, por ejemplo, utilizando isNaN (is not a number). Todo varia dependiendo la experiencia de cada programador aunque sinceramente a esto no le veo mucha ciencia así que espero que haya sido de utilidad aunque sea un poco, ya que estoy seguro que al menos una vez en la vida necesitaremos validar caracteres numéricos dejando de lado PHP, ASP, etc.

Xt3mP ~ xt3mp@null.net

, , , , , ,

Hola mundo en Delphi XE2

Filed in Delphi | Lenguajes 3 Comments

Como en todo buen lenguaje comenzaremos con el ya viral Hola mundo, y porqué no comenzar con éste para no perder la costumbre. (Cabe mencionar que a lo largo de estos días iré agregando contenido respecto a Delphi ya que yo también comenzaré a tocarlo por lo que cualquier cosa que haga la iré agregando).

Abriremos el embarcadero y nos vamos a File > New > VCL  Forms Applications – Delphi para comenzar un nuevo proyecto.

Existen varias formas de hacer nuestro cometido en Delphi, pero en esta ocasión solo miraremos dos:

  • Application.MessageBox(text, caption)
  • ShowMessage(String)

Primero añadiremos un TButton que será el encargado de manejar elevento navegando por la ‘Tool Palette/Paleta de herramientas‘; basta con arrastrarlo al formulario. Seguido de esto daremos doble click sobre el botón para comenzar a escribir nuestro código.

Opción: Application.MessageBox.
Procedure TForm1.Button1Click(Sender: TObject);
Begin
Application.MessageBox('Hola mundo!', ':)');
End;
Opción: ShowMessage.
Procedure TForm1.Button1Click(Sender: TObject);
Begin
ShowMessage('Hola mundo!');
End;

Así de simple tendríamos nuestra primer aplicación en Delphi con el famoso Hola mundo.
Para mayor información pueden visitar: http://delphiallimite.blogspot.com/2008/03/el-objeto-application.html

Xt3mP ~ xt3mp@null.net

, ,

TOP