Você está na página 1de 33

THE ORIGINAL HACKER

SOFTWARE LIBRE, HACKING y PROGRAMA-


CIN, EN UN PROYECTO DE
EUGENIA BAHIT

@eugeniabahit
GLAMP HACKER Y
PROGRAMADORA EXTREMA
HACKER ESPECIALIZADA EN PROGRAMACIN
EXTREMA E INGENIERA INVERSA DE CDIGO
SOBRE GNU/LINUX, APACHE, MYSQL,
PYTHON Y PHP. EUGENIABAHIT.COM
DOCENTE E INSTRUCTORA DE TECNOLOGAS
GLAMP CURSOS.EUGENIABAHIT.COM
CURSOSDEPROGRAMACIONADISTANCIA.COM
MIEMBRO DE LA FREE SOFTWARE
FOUNDATION FSF.ORG, THE LINUX
FOUNDATION LINUXFOUNDATION.ORG E
INTEGRANTE DEL EQUIPO DE DEBIAN
HACKERS DEBIANHACKERS.NET.
CREADORA DE PYTHON-PRINTR, EUROPIO
ENGINE, JACKTHESTRIPPER. VIM CONTRI-
BUTOR. FUNDADORA DE HACKERS N'
DEVELOPERS MAGAZINE Y RESPONSABLE
EDITORIAL HASTA OCTUBRE '13.
Buenos Aires, 29 de Abril
de 2014
NDICE DE LA
EDICIN NRO5
INGENIERA DE SOFTWARE: MANIPULACIN DE WEB
FORMS Y CARGA DE ARCHIVOS CON PYTHON Y WSGI
SBRE APACHE..................................3
EUROPIO ENGINE LAB: DICT OBJECT, UN NUEVO
CONCEPTO EN OBJETOS PARA LAS VISTAS EN PHP.16
SEGURIDAD INFORMTICA: MODELOS DE SEGURIDAD
PERMISIVOS COMO MECANISMOS DE PREVENCIN DE
VULNERABILIDADES.............................20
BASH SCRIPTING AVANZADO: DIVERSAS FORMAS DE
IMPLEMENTACIN DE MENS DINMICOS............28
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
3
INGENIERA DE SOFTWARE:
MANIPULACIN DE WEB
FORMS Y CARGA DE
ARCHIVOS CON PYTHON Y
WSGI SBRE APACHE
TRABAJAR CON FORMULARIOS
HTML DESDE PYTHON Y
SOBRE TODO, MANEJAR LA
CARGA DE ARCHIVOS, ES
UNA DE LAS TAREAS MENOS
SENCILLAS A LA HORA DE
CREAR APLICACIONES WEB
SIN UTILIZAR FRAMEWORKS.
SIN EMBARGO, QUE NO SEA
LA MS SENCILLA NO
SIGNIFICA QUE SEA
IMPOSIBLE.
esde que Python comenz a implementarse en el diseo
de aplicaciones Web frameworks como Django o
e!2"# han parecido ser la !nica alternati"a posible
para desarrollar #o$tware accesible mediante un na"egador.
%
&l auge de estos frameworks y por sobre todo la gran publicidad
que los programadores menos e'perimentados en la (ngenier)a de
#o$tware basado en Web le han hecho a %jango lograron acercar a
miles de de usuarios que sin conocimientos de programacin en
Python pod)an desarrollar aplicaciones Web con tan solo aprender
a usar el framework.
#abemos que $a humani%a% se mueve a !ase %e a!usos de
todo tipo y la (ngenier)a de #o$tware no es ajena a ello. *anto es as)
que $os usuarios &ue %esarro$$an a'$i(a(iones e! uti$i)an%o
Django, %es(ono(en 'or (om'$eto e$ $enguaje y carecen de
nociones b+sicas de programacin a un punto tal que en mucho
casos se llega a creer imposible que puedan desarrollarse
aplicaciones Web en Python sin el uso de frameworks.
,ace un tiempo publiqu- un paper en De!ian *a(+ers
.
sobre cmo crear un sitio Web en Python bajo
/pache sin utilizar frameworks
2
. &ste art)culo pretende continuar esta idea otorgando al lector las
herramientas necesarias para manipular todo tipo de $ormularios Web incluyendo la carga de archi"os al
ser"idor. *oda esta in$ormacin puede complementarse con el material
0
del (urso %e Desarro$$o %e
A'$i(a(iones e! (on "#thon # ,#S-. que dict- durante 12.1 y 12.0 en cursos.eugeniabahit.com
. www.debianhac3ers.net
1 http455www.debianhac3ers.net5una6web6en6python6sobre6apache6sin6$ramewor3s6y6en6solo606pasos
0 http455www.cursosdeprogramacionadistancia.com5static5pd$5material6sin6personalizar6python.pd$
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
4
DECLARANDO EL ENCTYPE CORRECTO
&n los $ormularios ,*7L el atributo enctype se de$ine cuando el m-todo ha sido establecido como POST y su
$inalidad es la de indicar en qu- $orma ser+n codi$icados los datos al en"iarse el $ormulario.
<form id='something' method='post' action='/some/file' enctype='multipart/form-data'>
</form>
&l atributo enctype puede tener 0 va$ores di$erentes4
multipart/form-data
8odi$icacin4
ninguna 9los caracteres son en"iados tal cual est+n sin codi$icacin pre"ia:
;so4
recomendado para manipular la carga de archi"os
%elimitador de campos4
aleatorio 9se obtiene mediante la cla"e 8<=*&=*6*>P& del diccionario en"iron:
delimitador = environ['CONTNT!T"P'#$replace%'m&ltipart/form!data' (o&ndary=') ''*
# retornar algo como: -----------------------------17553758491697998425554867382
?ormato recepcin de datos4
&jemplo para un $ormulario con dos campos de te'tos 9nombre y edad:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!+,--.,-/01+21,11/03---0/2,./3
Content!4isposition5 form!data' name=6nom(re6
7&an P8re9
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!+,--.,-/01+21,11/03---0/2,./3
Content!4isposition5 form!data' name=6edad6
1:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!+,--.,-/01+21,11/03---0/2,./3!!
application/x-www-form-urlencoded
8odi$icacin4
/#8(( ,e'adecimal. Los espacios en blanco se reemplazan por el signo @
;so4
es el "alor por de$ecto de todo $ormulario. #e recomienda para todos los $ormularios que no requieran
manipular la carga de archi"os.
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
5
%elimitador de campos4
#igno A
?ormato recepcin de datos4
&jemplo para un $ormulario con dos campos de te'tos 9nombre y edad:
nom(re=7&an;P<C.<=1re9>edad=1:
=otar que la "ocal BeC acentuada ha sido codi$icada como D80D mientras que el espacio en blanco $ue sustituido por el signo @
text/plain
8odi$icacin4
ninguna 9los caracteres son en"iados tal cual est+n sin codi$icacin pre"ia:
;so4
desaconsejado
%elimitador de campos4
retorno de carro
?ormato recepcin de datos4
&jemplo para un $ormulario con dos campos de te'tos 9nombre y edad:
nom(re=7&anP8re9
edad=1:
&l uso del "alor te't5plain se desaconseja ya que al emplear el retorno de carro como delimitador di$iculta la
obtencin de datos en bloques de te'to que incluyan el salto de l)nea.
Para el comn de los formularios, no es necesario declarar el enctype.
Declararlo como multipart/form-data si se trabajar con la carga de archivos.
MANIPULANDO DATOS DESDE PYTHON Y WSGI
8uando se reciben datos mediante P<#* siempre se necesita tener acceso a dos $actores4 el nombre de los
campos y su correspondiente "alor. &n Python la $orma lgica de asociar un nombre de campo a un "alor es
utilizar un diccionario4
datos = dict%campo+='valor del campo +') campo3='valor del campo 3'*
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
6
Lo que se debe lograr entonces es crear un diccionario con dicha in$ormacin con"irtiendo los datos recibidos
en un diccionario.
La $orma de lograr esta con"ersin depende directamente del modelo de codi$icacin con el que la
in$ormacin haya sido en"iada es decir que depende del enctype que se haya declarado en el $ormulario.
8uando se trabaja con W#E( los datos en"iados por POST se almacenan en la cla"e ?sgi$inp&t del
diccionario environ 9que W#E( entrega a la $uncin application* y se obtienen leyendo dicho elemento
con el m-todo read%* tal como se muestra a cotinuacin4
datos = environ['?sgi$inp&t'#.read()
Retornatar algo como: campo1=valor1&campo2=valor2
APPLICATION/X-WWW-FORM-URLENCODED
Fecordemos que -ste es el "alor por de$ecto de todo $ormulario. #i no se ha asignado un enctype los datos
ser+n codi$icados siguiendo este $ormato.
8omo el delimitador de campos es el signo > podemos obtener una lista donde cada elemento sea un par
clave=valor
datos = environ['?sgi$inp&t'#$read%*.split('&')
Luego en cada elemento de la lista el signo = separa al nombre del campo de su "alor correspondiente con lo
que ya tenemos todos los elementos necesarios para armar el diccionario4
datos = environ['?sgi$inp&t'#$read%*$split%'>'*
POST = @A
for par in datos5
campo) valor = par$split%'='*
POST[campo# = valor
Fecordemos que los datos son codi$icados en $ormato /#8(( ,e'adecimal y los espacios en blanco sustituidos
por el signo @. Podemos "ol"er los "alores a su estado puro utilizando la $uncin &nB&ote del mdulo
&rlli(3 y reemplazando el signo @ por un espacio en blanco4
from urllib2 import unquote
datos = environ['?sgi$inp&t'#$read%*$split%'>'*
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
7
POST = @A
for par in datos5
campo) valor = par$split%'='*
POST[campo# = unquote(alor).replace('!'" ' ')
%e esta $orma habremos obtenido un diccionario como el siguiente4
@
'nom(re'5 '7&Cn P8re9')
'edad'5 '2-')
'nacionalidad'5 '&r&g&aya'
A
/l cual podremos acceder utilizando el nombre de los campos como nombre de cla"e4
nom(re = POST['nom(re'# if 'nom(re' in POST else ''
edad = POST['edad'# if 'edad' in POST else ''
nacionalidad = POST['nacionalidad'# if 'nacionalidad' in POST else ''
/EC01E/ 1/2"0S DE DA30S
&n cualquier $ormulario Web es $recuente tener grupos de opciones bajo un mismo nombre. &s el caso de los
campos de tipo chec3bo' y los de tipo select m!ltiple4
<inp&t type='checD(oE' name='gr&poFa' val&e='+' checDed>OpciGn +<(r>
<inp&t type='checD(oE' name='gr&poFa' val&e='3'>OpciGn 3<(r>
<inp&t type='checD(oE' name='gr&poFa' val&e='.' checDed>OpciGn .<(r>
<select name='com(o' si9e='.' m&ltiple>
<option val&e='+'>OpciGn +</option>
<option val&e='3'>OpciGn +</option>
<option val&e='.'>OpciGn +</option>
<option val&e='0'>OpciGn +</option>
<option val&e='-'>OpciGn +</option>
</select>
8uando -ste es el caso $os va$ores e$egi%os no son agru'a%os a$ momento %e enviarse. Por el
contrario el nombre del campo se repetir+ tantas "eces como opciones se hayan elegido.
Lo que se pretende entonces es capturar las opciones elegidas dentro de una lista asignada a la misma cla"e
del diccionario.
;n ejemplo de lo que se quiere obtener ser)a como el siguiente4
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
8
@
'gr&poFa'5 [+) .#)
'com(o'5 [3) 0) -#
A
Para lograrlo si simplemente asign+ramos el "alor a la cla"e el !ltimo "alor sobre escribir)a a los anteriores.
&ntonces antes de asignar un "alor a una cla"e debemos "eri$icar que la cla"e no e'ista.
POST = @A
for par in datos5
campo) valor = par$split%'='*
if not campo in #$%&'
POST[campo# = &nB&ote%valor*$replace%';') ' '*
#i la cla"e e'iste podemos encontrar dos posibilidades4
.. Gue su "alor sea un !nico dato 9el dato $ue almacenado cuando if not campo in POST $ue
"erdadero:
1. Gue su "alor sea una lista 9cuando if not campo in POST $uese $also:
&sto habr+ que "eri$icarlo y4
.. &n el primer caso habr+ que con"ertir al "alor de dicha cla"e en una lista y agregarle el "alor que ya
ten)a asignado m+s el nue"o "alorH
1. y en el segundo agregar directamente el nue"o "alor.
8ompletaremos el cdigo agrup+ndolo ya mismo en una $uncin y haremos que esta retorne el diccionario con
los datos para que pueda ser llamada desde cualquier $uncin que necesite obtener datos en"iados desde un
$ormulario4
from &rlli(3 import &nB&ote
def getFsimpleFformFdata%environ*5
datos = environ['?sgi$inp&t'#$read%*$split%'>'*
POST = @A
for par in datos5
campo) valor = par$split%'='*
valor = &nB&ote%valor*$replace%';') ' '*
if not campo in POST5
POST[campo# = valor
else5
if not isinstance%POST[campo#) list*5 # an no es na l!sta
POST[campo# = [POST[campo#) valor#
else5 # "a es na l!sta
POST[campo#$append%valor*
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
9
ret&rn POST
Luego podr)amos llamarla desde cualquier otra $uncin4
def enviarFform%environ*5
#$%& = (et)simple)form)data(eniron)
# ###
MULTIPART/FORM-DATA
7anipular datos en este caso es mucho m+s complejo ya que parte de esos datos es la carga de archi"os.
Para poder gestionar archi"os cargados desde un $ormulario se necesita recurrir a dos mdulos adicionales4
tempfile 9para trabajar con archi"os temporales: y c(i 9para $acilitar el acceso a todos los datos y obtener
toda la in$ormacin adicional sobre los mismos:. %e cada mdulo haremos uso de una sola clase4
TemporaryHile y HieldStorage respecti"amente.
from cgi import HieldStorage
from tempfile import TemporaryHile
La clase *ield%tora(e sir"e para almacenar una secuencia de campos leyendo justamente los datos
en"iados desde un $ormulario codi$icado como m&ltipart/form!data. &sta clase genera un diccionario
como el que creamos anteriormente de $orma manual pero con una di$erencia muy importante4 cada
elemento de este diccionario contiene in$ormacin rele"ante como el tipo 7(7& del dato e incluye el contenido
de archi"os incluso cuando -stos sean binarios.
Pero esta clase requiere inde$ectiblemente que se le indique un puntero y no puede utilizarse ?sgi$inp&t
para ser apuntado como archi"o. &s necesario entonces crear un archi"o temporal para poder trabajar con
HieldStorage la clase que nos permitir+ manejar la carga de archi"os.
Lo primero que debemos hacer entonces es grabar el contenido de ?sgi$inp&t en un archi"o temporal ya
que no nos ser+ posible trabajar directamente con ?sgi$inp&t ya que solo podr)amos acceder al nombre
del archi"o. Erab+ndolo en un archi"o temporal podremos utilizarlo como puntero desde HileStorage para
crear el archi"o en el ser"idor. Pero "amos de a poco. 8omencemos por grabar el contenido de ?sgi$inp&t
en un archi"o temporal4
# $rea n arc%!vo temporal " lo a&re 'por (e)ecto* en mo(o +,r
archivoFtemporal = TemporaryHile%*
# -scr!&!mos el conten!(o (e +sg!#!npt en el arc%!vo temporal
archivoFtemporal$?rite%environ['?sgi$inp&t'#$read%**
# .ovemos al crsor al !n!c!o "a /e neces!taremos leer este arc%!vo (es(e el com!en0o
archivoFtemporal$seeD%:*
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
10
;na "ez creado el archi"o temporal podemos inicializar un objeto HieldStorage indicando como puntero al
archi"o temporal que acabamos de crear4
datos = HieldStorage%fp=archivoFtemporal*
Por de$ecto HieldStorage obtiene el diccionario environ desde el mdulo os pero como estamos
trabajando con W#E( sabemos que el diccionario environ es modi$icado por W#E( as) que se lo pasaremos
para que pueda obtener la in$ormacin correcta4
datos = HieldStorage%fp=archivoFtemporal) environ=environ*
/hora la "ariable datos se ha con"ertido en un diccionario sobre el que podremos iterar para obtener los
pares de cla"e y sus "alores correspondientes.
&l nombre del campo 9o cla"e para nuestro diccionario: lo obtendremos iterando entonces sobre la "ariable
datos trat+ndola como si $uese un diccionario com!n y corriente4
for clave in datos5
# ###
/ntes de obtener el "alor de un campo necesitaremos saber si se trata o no de un archi"o porque de ser as)
no solo necesitar)amos el contenido del archi"o sino otros datos como el tipo 7(7& y el nombre del archi"o.
Para saber si se trata o no de un archi"o debemos "eri$icar si la propiedad filename es None4
for clave in datos5
if datos+clae,.filename is -one'
# 12 -3 n arc%!vo
#i no se tratase de un archi"o podr)amos obtener el "alor de este campo mediante la propiedad val&e4
for clave in datos5
if datos[clave#$filename is None5
alor = datos+clae,.alue
#i en cambio se tratara de un archi"o quisi-ramos que el "alor $uese otro diccionario con los siguientes datos4
nombre del archi"o tipo 7(7& y contenido 9para poder crearlo posteriormente en el ser"idor:. Para ello
necesitaremos acceder a las propiedades filename type y val&e respecti"amente4
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
11
for clave in datos5
if datos[clave#$filename is None5
valor = datos[clave#$val&e
else5
alor = dict(
filename=datos+clae,.filename"
filetype=datos+clae,.type"
content=datos+clae,.alue
)
?inalmente solo resta utilizar las cla"es y "alores para crear nuestro propio diccionario igual que hicimos
anteriormente4
POST = @A
for clave in datos5
if datos[clave#$filename is None5
valor = datos[clave#$val&e
else5
valor = dict%
filename=datos[clave#$filename)
filetype=datos[clave#$type)
content=datos[clave#$val&e
*
POST[clave# = valor
/EC01E/ 1/2"0S DE DA30S
=ue"amente nos podemos encontrar con que tenemos grupos de datos que pertenecen a un mismo nombre.
&n este caso el tratamiento di$iere del que hemos hecho antes ya que HieldStorage nos permite acceder a
los grupos de datos como una lista mediante el m-todo getlist%*. Lo que haremos entonces es "eri$icar si
se trata o no de un grupo de datos llamando a este m-todo y de ser as) el "alor ya no ser+ el obtenido
mediante la propiedad val&e) sino el obtenido mediante este m-todo. /l igual que en el caso anterior "amos
a apro"echar a colocar todo en una $uncin que retorne el diccionario P<#* para que pueda ser llamada
desde cualquier otra que la necesite4
from cgi import HieldStorage
from tempfile import TemporaryHile
def getFm&ltipartFformFdata%environ*5
archivoFtemporal = TemporaryHile%*
archivoFtemporal$?rite%environ['?sgi$inp&t'#$read%**
archivoFtemporal$seeD%:*
datos = HieldStorage%fp=archivoFtemporal) environ=environ*
POST = @A
for clave in datos5
if datos[clave#$filename is None5
lista = datos.(etlist(clae)
valor = datos+clae,.alue if len(lista) . 2 else lista
else5
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
12
valor = dict%
filename=datos[clave#$filename)
filetype=datos[clave#$type)
content=datos[clave#$val&e
*
POST[clave# = valor
ret&rn POST
8omo podemos "er "alor ser+ igual a lo obtenido mediante la propiedad val&e siempre y cuando la lista
tenga menos de dos elementos 9es decir uno o ninguno:. %e lo contrario el "alor ser+ la lista de datos.
/EC01E/ 1/2"0S DE A/C*450S
&n el ejemplo anterior se contempla que los grupos de datos 9campos con el mismo nombre y distintos
"alores: no ser+n de tipo file. #in embargo puede suceder que un mismo $ormulario tenga m+s de un campo
de tipo file con el mismo nombre y aqu) la metodolog)a de implementar getlist%* para reconocer Igrupos
de in$ormacinJ ya no ser+ "iable. Por consiguiente la primera condicin a e"aluar ya no ser)a preguntar si
datos[clave#$filename es nulo sino si datos[claves# es una lista.
Para que la $uncin no se haga repetiti"a y engorrosa crearemos una $uncin adicional encargada de retornar
los "alores como diccionario o string seg!n se trate de un campo de tipo $ile o no y luego la llamaremos
desde getFm&ltipartFformFdata%*.
from cgi import HieldStorage
from tempfile import TemporaryHile
def getFm&ltipartFformFdata%environ*5
archivoFtemporal = TemporaryHile%*
archivoFtemporal$?rite%environ['?sgi$inp&t'#$read%**
archivoFtemporal$seeD%:*
datos = HieldStorage%fp=archivoFtemporal) environ=environ*
POST = @A
for clave in datos5
if isinstance(datos+clae," list)'
POST[clave# = [#
for elemento in datos[clave#5
#$%&+clae,.append(traer)alor(elemento))
else5
#$%&+clae, = traer)alor(datos+clae,)
ret&rn POST
def traer)alor(dato)'
valor = dict%filetype=dato$type) filename=dato$filename) content=dato$val&e*
ret&rn dato$val&e if dato$filename is None else valor
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
13
UN DECORADOR QUE DECIDA SOLO
,emos logrado abarcar todas las posibilidades en cuanto a manipulacin de $ormularios respecta desde
Python con W#E(. 8reamos dos $unciones que contemplan todas las posibilidades que e'isten y podemos con
ellas crear un decorador para que mediante un simple llamado en"uel"a a cada $uncin que reciba datos
desde un $ormulario.
Si te perdiste la edicin anterior sobre wrappers y decoradores en Python, te
recomiendo descargues The Original Hacker N4 y leas el artculo de pgina 30.
Para descargar *he <riginal ,ac3er =KL ingresa en http455library.originalhac3er.org5biblioteca5re"ista5"er512
8rearemos un decorador gen-rico que identi$icando el enctype del $ormulario se encargue de llamar a una u
otra $uncin desde el ?rapper.
=o necesitamos modi$icar las $unciones que ya creamos aunque recomiendo hacerlas pri"adas y utilizar un
mdulo $py para las $unciones y el decorador.
from cgi import HieldStorage
from tempfile import TemporaryHile
from &rlli(3 import &nB&ote
def (et)post)data(funcion)'
def ?rapper%environ*5
FPOST = @A
try5
if not environ['CONTNTFT"P'#$starts?ith%'m&ltipart/form!data'*5
FPOST = FFgetFsimpleFformFdata%environ*
else5
FPOST = FFgetFm&ltipartFformFdata%environ*
eEcept5
pass
ret&rn f&ncion%FPOST*
ret&rn ?rapper
def ))(et)simple)form)data(eniron)'
datos = environ['?sgi$inp&t'#$read%*$split%'>'*
POST = @A
for par in datos5
campo) valor = par$split%'='*
valor = &nB&ote%valor*$replace%';') ' '*
if not campo in POST5
POST[campo# = valor
else5
if not isinstance%POST[campo#) list*5
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
14
POST[campo# = [POST[campo#) valor#
else5
POST[campo#$append%valor*
ret&rn POST
def ))(et)multipart)formdata(eniron)'
POST = @A
archivoFtemporal = TemporaryHile%*
archivoFtemporal$?rite%environ['?sgi$inp&t'#$read%**
archivoFtemporal$seeD%:*
datos = HieldStorage%fp=archivoFtemporal) environ=environ*
for clave in datos5
campo = datos[clave#
if isinstance%campo) list*5
POST[clave# = [#
for elemento in campo5
POST[clave#$append%FFgetFval&e%elemento**
else5
POST[clave# = FFgetFval&e%campo*
ret&rn POST
def ))(et)alue(campo)'
archivo = dict%filetype=campo$type) filename=campo$filename) content=campo$val&e*
ret&rn campo$val&e if campo$filename is None else archivo
Luego simplemente deber+s decorar a cualquier $uncin que reciba datos desde un $ormulario
independientemente del enctype que se le haya declarado4
/(et)post)data
def enviarFform%POST*5
pass
CARGA DE ARCHIVOS DESDE FORMULARIOS Y ALMACENAMIENTO EN
EL SERVIDOR
>a tenemos todo listo para poder manipular los archi"os. Lo !nico que nos resta es algo tan simple como
seguir unos cortos pasos.
8rear un directorio pri"ado con permisos de escritura4
mDdir privateFdir >> chmod ,,, !I privateFdir
Erabar el contenido del archi"o en uno nue"o dentro el directorio pri"ado4
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
15
JgetFpostFdata
def enviarFform%environ*5
carpeta = '/r&ta/a/directorio/privado/'
r&taFarchivo = carpeta ; POST['archivo'#['filename'#
?ith open%r&taFarchivo) '?'* as archivo5
archivo$?rite%POST['archivo'#['content'#*
Por supuesto que si se debe "alidar el tipo 7(7& del archi"o se lo har+ mediante POST['archivo'#
['filetype'# antes del bloque ?ith y solo se ejecutar+ -ste si el tipo 7(7& es el esperado4
JgetFpostFdata
def enviarFform%environ*5
carpeta = '/r&ta/a/directorio/privado/'
r&taFarchivo = carpeta ; POST['archivo'#['filename'#
mime = #$%&+'archio',+'filetype',
if mime == 'application/pdf''
?ith open%r&taFarchivo) '?'* as archivo5
archivo$?rite%POST['archivo'#['content'#*
ret&rn '=rchivo g&ardado'
else5
ret&rn 'Solo se permiten archivos P4H'
Contratan%o un 5"S (on e$ en$a(e %e esta 'u!$i(i%a%, me a#u%as a mantener 3he 0rigina$ *a(+er 67
Servi%ores a solo 2SD 8 9 mes4
20 1B de disco
%iscos SSD
. *B de trans$erencia
812 7B /A,
4nsta$a(i:n en menos %e 1;
&lige 2!untu Server 12<04 .3S y despreoc!pate de
la seguridad optimiz+ndolo con =a(+3heStri''er
Luego de instalarlo (on>ig?ra$o (on =a(+3heStri''er4 http455www.eugeniabahit.com5proyectos5jac3thestripper
Contratan%o (on este en$a(e, me a#u%as a mantener 3he 0rigina$ *a(+er6 http455bit.ly5promo6digitalocean
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
16
EUROPIO ENGINE LAB:
DICT OBJECT, UN NUEVO
CONCEPTO EN OBJETOS PARA
LAS VISTAS EN PHP
EUROPIO ENGINE EN LA
REVISIN 17 DE SU
VERSIN BETA 3.4,
INCORPORA UN NUEVO
CONCEPTO QUE REVOLUCIONA
EL TRATAMIENTO DE LAS
VISTAS EN PHP. SE TRATA
DE OBJETOS DE TIPO
DICCIONARIO QUE EN ESTAS
NOTAS, TE CUENTO LA
MOTIVACIN, SU
CONCEPCIN Y FORMA DE
IMPLEMENTARLOS.
n "arios papers y art)culos en general en los cuales hablo
de 7M8 no me canso de repetir que $as vistas en ,5C
son un arte. &
&n 7M8 todo el arte de las "istas se encuentra siempre en
(onvertir $o &ue se tiene en $o &ue se ne(esita. Lo que se
tiene siempre es distinto. #in embargo siempre es un objeto 9o
coleccin de objetos: mucho m+s all+ de su complejidad interna y
ni"eles de dependencia. > siempre lo que se necesita es con"ertir
todos esos objetos y sus propiedades en diccionarios que no son
m+s que arrays asociati"os para P,P.
7oti"ado por la necesidad de e"itar la redundancia de cdigo en las
"istas =imm# Danie$ Barran(o me propuso crear un helper a ni"el
del core que eliminara la redundancia. > as) entre ambos creamos
un nue"o concepto en P,P4 objetos de tipo diccionario. E$ o!jeto
Dict.
MOTIVACIN
8omo coment- al comienzo la moti"acin principal $ue la necesidad de suprimir la redundancia de cdigo en
las "istas. La misma se genera $recuentemente en las siguientes circunstancias4
0!jetos (om'uestos %e otros &ue (om'arten 'ro'ie%a%es (on $a misma %enomina(i:n6
$recuentemente sucede que se tiene un objeto / compuesto de un objeto B y ambos poseen una
propiedad denomina 8. &sto produce que en las E;( a $in de e"itar el solapamiento de identi$icadores
id-nticos se deban utilizar comodines compuestos que por lo general se constituyen del nombre de
las propiedades acompaadas por el nombre del objeto adquiriendo $ormatos similares a
@o(Keto$propiedadA. Por consiguiente es muy habitual en las "istas "er $racciones de cdigo
destinadas a crear nue"as propiedades 9o cla"es en un diccionario:.
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
17
Ne(esi%a% %e visua$i)ar %atos so!re o!jetos (on varios nive$es %e %e'en%en(ia6
la denominacin de las propiedades puede no ser igual pero sin embargo tener un objeto / que se
compone de uno B que a la "ez se compone de uno 8 etc. y necesitar mostrar en las E;( los datos del
objeto N es de lo m+s $recuente. > esta necesidad tambi-n genera en las "istas $racciones de cdigo
destinadas solo a crear nue"as propiedades o cla"es en un diccionario.
De>orma(i:n # ma$ uso %e o!jetos6
amparados por el hecho de saber que las "istas en 7M8 son m+s un arte que una ciencia para
satis$acer las dos necesidades anteriores lo $recuente se trans$ormaba en una de$ormacin absoluta
de los objetos lo cual tarde o temprano termina no IoliendoJ bien.
*odo lo anterior no hace m+s que generar grandes bloques de cdigo en la mayor)a de las "istas que no solo
podr)a e"itarse sino que adem+s deber)a e"itarse ya que $a sim'$i(i%a%, siem're %e!er@a ser $a ?ni(a
so$u(i:n (orre(ta.
UN OBJETIVO, UNA SOLUCIN...
*en)amos que lograr entonces crear un helper que no actuase de $orma IdesesperadaJ en pro de Ino repetir
cdigoJ. %eb)a solucionar el problema de una $orma correcta es decir solucionarlo empleando un argumento
lgico "+lido simpleza y prolijidad. ?ue entonces que al pensar en que si aquello que se necesita en las "istas
es un diccionario Opor qu- no crear el concepto de diccionario como objetoP > de hacerlo Oqu- caracter)sticas
deber)a tener -ste como objetoP La solucin hallada se e'plica a continuacin.
CARACTERSTICAS QUE DEBE POSEER UN OBJETO DICCIONARIO
8omo caracter)sticas del objeto hab)a que proponer algo simple que no $uese necesario e'plicar y que
pudiese deducirse por s) solo. 8omo !nicas caracter)sticas de este objeto se emplearon las siguientes4
"/0"4EDADES6 #us !nicas propiedades ser+n denominaciones $ormadas por pares
o(Keto$propiedad justi$icando -stas en que un diccionario debe ser un mapa de las propiedades
de uno o "arios de los objetos que se desea parsear en una "ista.
,A30D0S6 haciendo honor a los objetos hallados en los inicios cl+sicos de la programacin orientada
a objetos tradicional solo deber)a contar con un m-todo set. &l m-todo get no tendr)a razn de ser
ya que los diccionarios deber)an ser "ol+tiles y solo gestarse en base a objetos reales persistentes por
otras ")as.
RESULTADOS
(mplementando los objetos de tipo %iccionario en las "istas se obtienen resultados sumamente elegantes y de
esta $orma se pone $in a los complejos algoritmos y los largos bloques de cdigo que habitualmente solemos
tener.
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
18
&l objeto 4ict es un objeto instanciable que al in"ocar a su m-todo set%* se le pasa un objeto real como
par+metro. %e esta $orma tras in"ocar a set%* el objeto 4ict tendr+ disponible un mapa de propiedades
compuesto por los nombres de los objetos y las propiedades de -stos.
Para entenderlo mejor obser"ar el siguiente ejemplo. %ado un objeto compuesto con los siguientes ni"eles de
pro$undidad4
Hoo O(Kect
%
[a# => +
[(# => 3
[c# => .
[(ar# => Lar O(Kect
%
[a# => +
[(# => 3
*
[far# => Har O(Kect
%
[a# => +
[(# => 3
[c# => .
[d# => 0
*
*
<btendremos el siguiente diccionario4
4ict O(Kect
%
[foo$a# => +
[foo$(# => 3
[foo$c# => .
[(ar$a# => +
[(ar$(# => 3
[far$a# => +
[far$(# => 3
[far$c# => .
[far$d# => 0
*
&l cual nos permitir+ en las E;( utilizar identi$icadores como en el siguiente ejemplo4
<h+>0foo.a1</h+>
<h3>0foo.b1</h3>
<(locDB&ote>
<(>Lar5</(> 0bar.b1<(r>
<(>Har5</(> 0far.d1
</(locDB&ote>
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
19
USO E IMPLEMENTACIN
;tilizar el objeto 4ict es suma simple. #olo debe ser instanciado y luego se debe in"ocar al m-todo set%:
en"iando un objeto como par+metro y luego utilizar el objeto 4ict para e$ectuar la sustitucin de los ,*7L
los cu+les deber+n implementar el nombre de los objetos adem+s del de las propiedades.
(ndependientemente del ni"el de pro$undidad al que se llegue con la composicin de objetos $os
i%enti>i(a%ores B(omo%ines7 %e $os *3,. %e!erCn em'$ear e$ >ormato6
@o(Keto$propiedadA
Para generar e$ %i((ionario solo se requieren dos instrucciones4
Mdict = ne? 4ict%*'
Mdict!>set%Mo(Keto*'
printFr%Mdict*
#i se quieren o!tener %i((ionarios so!re una (o$e((i:n %e o!jetos se debe apelar al objeto
2ict3ollection$ &l mismo tambi-n cuenta con un m-todo set%* al que se le debe pasar una coleccin de
objetos 9propiedad colectora:. &l objeto 4ictCollection pro"eer+ de una propiedad colectora
4ictCollection!>collection compuesta de una coleccin de objetos 4ict5
MdictFcollection = ne? 4ictCollection%*'
MdictFcollection!>set%Mcoleccion*'
printFr%MdictFcollection!>collection*'
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
20
SEGURIDAD INFORMTICA:
MODELOS DE SEGURIDAD
PERMISIVOS COMO
MECANISMOS DE PREVENCIN
DE VULNERABILIDADES
LOS MODELOS DE SEGURIDAD
PERMISIVOS, A PESAR DE
LO COMPLEJO DE SU
ANLISIS, SON LOS NICOS
CAPACES DE GENERAR
APLICACIONES
INVULNERABLES, YA QUE AL
NO ESTAR BASADOS EN LA
PREVENCIN DE RIESGOS
CONOCIDOS NO DAN LUGAR A
DESCUBRIR NUEVOS
AGUJEROS , PUES LOS
PROPIOS MODELOS, NO SON
MS QUE ILUSIONES
PTICAS .
uando comenzamos a programar una de las primeras
cosas que aprendemos en materia de seguridad de
aplicaciones es a $iltrar entradas del usuario quit+ndoles
todo aquel caracter prohibido. ,oy me pregunto D%e ver%a% en
a$g?n momento nos hemos senti%o mCs $istos &ue e$ resto
%e$ mun%oE
8
"rohi!ir es una tarea te%iosa e in>initaH cuanto m+s se analizan
e in"estigan los posibles I$lancos de ataqueJ en una aplicacin la
tarea de prohibir puede llegar a hacerse interminable ya que en la
(ngenier)a de #o$tware aplica indirectamente el mismo principio
que en el derecho penal4 Ino e'iste prohibicin sin penaJ.
&n los sistemas in$orm+ticos al igual que un cdigo penal cada
prohibicin debe especi$icarse minuciosa y detalladamente. Pero la
peor parte 6para la in$orm+tica6 es que al prohibir necesariamente
se debe indicar Icu+l ser+ la penaJ solo que para el #o$tware esto
es meta$rico. > cuando hablamos de Iestablecer una penaJ nos
estamos re$iriendo a im'$ementar (om'$ejos a$goritmos &ue
res'on%an >rente a (a%a a(to 'rohi!i%o.
Prohibimos el ingreso de comillas simples entonces al igual que en el derecho no basta con decirle a un
indi"iduo que Iest+ prohibido matarJ porque en realidad no est+ prohibido est+ IpenadoJ. Con (o$o(ar un
(arte$ &ue %iga F'or >avor, no ingrese (omi$$as sim'$esG no a$(an)aH %e!emos (rear un a$goritmo
&ue se en(argue %e erra%i(ar$as< Pero esto no termina aqu) y debe repetirse el mismo esquema de
procedimientos con cada IcosaJ que deseemos prohibir en nuestro sistema.
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
21
Cuando implementamos modelos de seguridad por
prohibicin, no estamos teniendo en cuenta que no
somos omnipotentes
&n .QQQ la mayor)a de las aplicaciones Web que implementaban sistemas de registro de usuarios buscadores
basados en bases de datos y a$ines no e$ectuaban ning!n tipo de $iltro como los de hoy en d)a. ,asta que
alg!n d)a alguien habr+ "isto que un maldito < en un buscador pod)a romper el NOP de una sentencia #GL. >
eso mismo sucede todos los d)as.
Lamentablemente, cada vez ms gente invierte su
tiempo en mejorar tcnicas de pentesting y en crear
herramientas de exploiting, en vez de ampliar sus
capacidades cognitivas intentando hallar verdaderas
soluciones mediante investigacin cientfica
3o%os $os %@as se F%es(u!renG nuevas >ormas %e %estruir $os sistemas in>ormCti(os. #e les suele
llamar I"ulnerabilidadesJ pero desde mi punto de "ista todo sistema in$orm+tico aunque se encuentre libre
de toda "ulnerabilidad tendr+ al menos una !nica "ulnerabilidad si se implementa un modelo de seguridad
prohibiti"o4 $a >a$sa omni'oten(ia %e sus %esarro$$a%ores.
El modelo de seguridad prohibitivo es la primera
vulnerabilidad de un sistema informtico
La humanidad suele no tomarse la molestia de analizar y descubrir cone'iones lgicas entre dos o m+s hechos
que en apariencia no se encontrar)an relacionados. %icho de $orma m+s simple $a ma#or@a %e $as 'ersonas
no se mo$esta en Fatar (a!osG. Pues de hacerlo la seguridad in$orm+tica deber)a ser una ciencia e'acta ya
que en nuestra vi%a (oti%iana, tenemos so!ra%os ejem'$os %e (:mo Fe$ 'rohi!irG siem're se
&ue%a %etrCs %e $os a(onte(imientos ya que como marca un "iejo dicho popular hecha la Ley, hecha la
trampa. Pero a di$erencia del derecho en el caso de la (ngenier)a de #o$tware esto tiene solucin y consiste
en implementar Fmo%e$os %e seguri%a% 'ermisivosG.
QU SON Y EN QU CONSISTEN LOS MODELOS DE SEGURIDAD
PERMISIVOS?
=o es nada di$)cil deducir. #e trata de modelos de seguridad que para establecer sus pol)ticas se basan en
aquello que se permite en una aplicacin en "ez de in"ertir cientos y miles de bytes de$iniendo algoritmos
centrados en lo que se proh)be.
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
22
CARACTERSTICAS DE LOS MODELOS DE SEGURIDAD PERMISIVOS
&stos modelos suelen dar libertades al usuario que com!nmente se le niegan y hasta incluso podr)an
considerarse impensables como ser)a el caso de permitirle elegir un nombre de usuario con$ormado por
caracteres no al$anum-ricos como podr)an ser comillas simples. &s por ello que son (onsi%era%os mo%e$os
%e seguri%a% F$i!era$esG en los cuales la criptogra$)a 6tanto desde la codi$icacin hasta la encriptacin6
juegan un papel protagnico puesto que son el pilar del modelo.
La criptografa y la codificacin son el pilar de los
modelos de seguridad permisivos
&s entonces que como principales caracter)sticas podemos listar las siguientes4
.. %an amplia libertad de accin y mo"imiento al usuarioH
1. &mplean sistemas criptogr+$icos con mucha $recuenciaH
0. ;tilizan la 9re:codi$icacin como base del modelo liberal.
VENTAJAS Y DESVENTAJAS DE LOS MODELOS DE SEGURIDAD PERMISOS
Los modelos de seguridad permisi"os 9o liberales:
suelen traer aparejadas much)simas m+s "entajas y
por consiguiente bene$icios que des"entajas.
.as %esventajas sue$en ser mCs !ien %e @n%o$e
so(ia$ ya que las aplicaciones que implementan
modelos de seguridad permisi"os suelen ser blanco
$+cil de los Iaprendices de crackersJ o de conductas
delicti"as semejantes ya que inicialmente los
$uturos delincuentes suelen dejarse lle"ar por el
entusiasmo de creer que Iel e'ceso de libertadesJ
se debe a una conducta negligente de los
programadores.
#in embargo e$ (ese %e $os intentos %e ata&ue
sue$e 'ro%u(irse mu(ho mCs rC'i%o que en las
aplicaciones que implementan modelos de
seguridad restricti"os 9o prohibiti"os: ya que en su
mayor)a este ti'o %e %e$in(uentes !us(an
satis>a(er sus >antas@as %e >orma inme%iata #
a$ no (onseguir$o, a!an%onan 'ara !us(ar una
v@(tima mCs vu$nera!$e &ue $es >a(i$ite e$
'$a(er inme%iato.
=o obstante es "+lido recordar que si bien todo per$il
criminal busca la satis$accin inmediata de sus
$antas)as e'iste porcin m+s reducida de
delincuentes con una psiquis mucho m+s compleja
que podr)an permanecer aos tratando de "iolar la
seguridad de un sistema por el mero hecho de sentir
el placer que no logran alcanzar en otros aspectos
de sus "idas. Por consiguiente ser@a un error
asumir &ue $os mo%e$os %e seguri%a%
'ermisivos evitan 'or (om'$eto $os intentos %e
ata&ues a (orto '$a)o.
#i bien hasta aqu) toda des"entaja parece estar
compensada por una "entaja o bene$icio e'iste un
$actor que con"ierte a los modelos de seguridad
permisi"os en algo di$)cil de ser implementados pues
solo ser+n realmente seguros si la pol)tica de
permisos es delineada por pro$esionales que poseen
un conocimiento pro$undo del $uncionamiento
interno de un sistema in$orm+tico completo y de la
teor)a de ordenadores pues una 'o$@ti(a
'ermisiva ma$ 'ensa%a 'o%r@a generar una
a'$i(a(i:n mu(ho mCs vu$nera!$e que aquella
que implemente un modelo restricti"o.
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
23
EJEMPLOS PRCTICOS DE POLTICAS DE SEGURIDAD BASADAS EN
MODELOS PERMISIVOS
/unque todo parezca 6en principio6 demasiado no"edoso algunas pol)ticas resultar+n $amiliares ya que en
alg!n momento se habr+n puesto en pr+ctica y seguramente en m+s de una oportunidad. #in embargo
im'$ementar 'o$@ti(as 'ermisivas %e >orma ais$a%a en un mo%e$o restri(tivo, 'ue%e ser tan
riesgoso (omo no im'$ementar ninguna< Por lo tanto los siguientes ejemplos solo se e'ponen a $in de
alcanzar una mejor comprensin sobre los modelos de seguridad permisi"os y no deben ser interpretados
como una gu)a de seguridad !nica.
#in duda la pol)tica permisi"a m+s implementada en aplicaciones es el paso de nombres de archi"o por la
;F( $recuentemente utilizado para la muestra o descarga de contenido est+tico. #in embargo $a misma
'o$@ti(a 'o%r@a estar '$antea%a tanto en un mar(o 'ermisivo (omo en uno restri(tivo,
%e'en%ien%o %e $a :'ti(a %es%e $a (ua$ se $o ha#a e$a!ora%o.
Msolicit&d = isset%MFQT['page'#* 5 strtolo?er%MFQT['page'#* 5 'defa&lt''
Marchivo = SORFP=TS $ 6/html/@Msolicit&dA$html6'
McontenidoFinterno = fileFgetFcontents%Marchivo*'
print strFreplace%'@contenidoA') McontenidoFinterno) SORFTRPN=T*'
,asta aqu) "emos el concepto sin ninguna medida de seguridad de$inida. #uponiendo que en la carpeta
SORFP=TS $ 6/html/6 todos los archi"os con e'tensin html que se almacenan puedan ser accesibles
por el usuario a lo sumo se podr)a incluir una "alidacin de e'istencia del archi"o para e"itar un $allo en el
cdigo que re"elase in$ormacin del sistema4
Msolicit&d = isset%MFQT['page'#* 5 strtolo?er%MFQT['page'#* 5 'defa&lt''
Marchivo = SORFP=TS $ 6/html/@Msolicit&dA$html6'
if%file)exists(4archio)* @
McontenidoFinterno = fileFgetFcontents%Marchivo*'
A else @
McontenidoFinterno = '''
A
print strFreplace%'@contenidoA') McontenidoFinterno) SORFTRPN=T*'
& incluso el algoritmo anterior podr)a optimizarse a!n m+s de$iniendo un contenido interno por de$ecto y
haciendo el algoritmo mucho m+s seguro y legible4
Msolicit&d = isset%MFQT['page'#* 5 strtolo?er%MFQT['page'#* 5 'defa&lt''
Marchivo = SORFP=TS $ 6/html/@Msolicit&dA$html6'
4contenido)interno = ''5
if(file)exists(4archio)) 4contenido)interno = file)(et)contents(4archio)5
print strFreplace%'@contenidoA') McontenidoFinterno) SORFTRPN=T*'
8onceptualmente a pesar de estar IpermitiendoJ al usuario pasar el nombre de un archi"o por la ;F( le
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
24
estar)amos dando un en$oque Iprohibiti"oJ ya que si la carpeta SORFP=TS $ 6/html/6 almacenara un
archi"o que no se quisiese poder tratar como Icontenido internoJ habr)a que Iprohibir su accesoJ4
Msolicit&d = isset%MFQT['page'#* 5 strtolo?er%MFQT['page'#* 5 'defa&lt''
Marchivo = SORFP=TS $ 6/html/@Msolicit&dA$html6'
McontenidoFinterno = '''
4es)template = (4solicitud == 'template')5
4es)menu)admin = (4solicitud == 'menu)admin')5
if%fileFeEists%Marchivo* && 64es)template && 64es)menu)admin) 0
McontenidoFinterno = fileFgetFcontents%Marchivo*'
A
print strFreplace%'@contenidoA') McontenidoFinterno) SORFTRPN=T*'
> en el mejor de los casos el almacenamiento de archi"os que no se quisiesen tratar como contenido interno
dentro de esa carpeta se estar@an restringien%o Fso$o 'or 'o$@ti(as %e seguri%a% # no 'or (uestiones
ar&uite(t:ni(asG. &sto es una clara consecuencia de las pol)ticas restricti"as.
#in embargo no debe con$undirse Ipermisi"oJ con IdescuidadoJ. 2na 'o$@ti(a 'ermisiva, es a&ue$$a &ue
F%e>ine $o &ue se 'ue%e ha(er en ve) %e %e>inir a&ue$$o &ue estC 'rohi!i%oG. &ntonces de$inir cu+les
archi"os est+n permitidos ser+ mucho m+s limpio y seguro que crear algoritmos para custodiar Ilas
prohibicionesJ4
4archios)permitidos = array('default'" 'contacto'" 'newsletter'" 'noticias'" 'lo(in')5
Msolicit&d = isset%MFQT['page'#* 5 strtolo?er%MFQT['page'#* 5 'defa&lt''
if(6in)array(4solicitud" 4archios)permitidos)) 4solicitud = 'default'5
Marchivo = SORFP=TS $ 6/html/@Msolicit&dA$html6'
McontenidoFinterno = fileFgetFcontents%Marchivo*'
print strFreplace%'@contenidoA') McontenidoFinterno) SORFTRPN=T*'
8omo se puede "er en el !ltimo ejemplo estableciendo una pol)tica permisi"a obtenemos4
un (:%igo &ue no re&uiere %e mantenimientos >uturos ya que el algoritmo se mantiene intacto
incluso aunque se modi$ique el contenido de la carpeta en cuestin. %e hecho el array de Iarchi"os
permitidosJ deber)a ser con$igurable desde un settingsH
a$goritmos (on menos instru((iones ya que no ser+ necesario "eri$icar la e'istencia del archi"o en
nombre de la seguridad. #i se decidiese e$ectuar dicha "alidacin ser)a por cuestiones de usabilidad
pero no de seguridad.
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
25
/nteriormente tambi-n hab)a comentado que se pod)a llegar a e'tremos impensables como permitir todo tipo
de caracteres en el nombre de usuario de un sistema de registro y autenticacin. &se es otro ejemplo de
pol)tica permisi"a. &n este caso no solo nos ahorramos largas "alidaciones en el cdigo sino que adem+s
e"itamos tener que IlimpiarJ la entrada del usuario. 8on solo encriptar 9hashear: el nombre del usuario
guardarlo encriptado y luego al momento de autenticar compararlo mediante su hash al igual que se hace
con las contraseas ser)a su$iciente4
M&sername = md-%MFPOST['&sername'#*'
/qu) lo permisi"o a pesar de lo que se podr)a creer en un principio no es el ingreso de caracteres Ie'traosJ.
&n realidad de $orma indirecta estamos de$iniendo que solo se permiten caracteres al$anum-ricos puesto
que un hash 7%R ci$rar+ la cadena resultando en otra que solo es al$anum-rica.
UN BUEN PROGRAMADOR ES AQUEL QUE MEJOR ENGAA AL USUARIO
8on"ertirse en un timador suena tr+gicamente espantoso. #in embargo como todo lo I"irtualJ en nuestros
queridos resultantes Iceros y unosJ no necesariamente con"ertir+ un ItimoJ en algo malo sino que ser+
aquello que otorgue gran libertad de mo"imiento a los usuarios generando una signi$icati"a reduccin en la
cur"a de aprendizaje que un usuario transita hasta entender la aplicacin que lo haga sentir cmodo pero que
al mismo tiempo no ponga en riesgo la aplicacin. #e trata de Fo>re(er es'ejos %e (o$oresG 9pero sin el
cruel objeti"o de la colonizacin:.
7e sucede con $recuencia que al momento de analizar requerimientos con mis alumnos al igual que los
usuarios se dejan lle"ar solo y !nicamente por aspectos "isuales. *a(e %I(a%as atrCs, era 'rC(ti(amente
im'ensa!$e &ue un 'rograma%or ana$i)ase un re&uerimiento (on Fojos %e usuarioG< #in embargo
desde la llegada de Ilas "entanasJ en modo gr+$ico y dispositi"os como el mouse la in$orm+tica se hizo
accesible a todos nosotros mediante ordenadores personales y en de$initi"a $a visin amigable e
intuitiva &ue $os grC>i(os otorgan a$ (om?n %e $as 'ersonas, >a(i$itaron e$ a((eso a $a
'rograma(i:n, %e gran 'arte %e $a 'o!$a(i:n.
%esde entonces se ha con"ertido en Imoneda corrienteJ obser"ar a programadores con$undir el problema a
resol"er 9requerimiento "isual en el QQD de los casos: con la solucin del mismo. > esto es importante
entenderlo ya que justamente $os mo%e$os %e seguri%a% 'ermisivos se !asan en Fmostrar a$ usuario
$o &ue %esea verG pero aquello que el usuario desea "er debe o$rec-rsele como una ilusin ptica una
$antas)a. Para nosotros lo que el usuario "ea deber+ ser el resultado de con"ertir Iaquello que permitimosJ
en lo que el usuario Icrea estar "iendoJ.
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
26
Por ejemplo le hago creer al usuario que est+ "iendo esto4
Pero en realidad lo anterior es una ilusin ptica resultado de haber con"ertido esto otro4
f&nctionCO4Q+2:CO4CaddCO4Q1-CO4CconfirmCO4Q0:CO4CCO4Q0+CO4CCO4Q+2:CO4CCO4Q+3.CO4CCO4S
CO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4ClinDsCO4Q+2:CO4CCO4Q2+CO4CCO4Q+2:CO4Cdoc
&mentCO4Q02CO4CgetlementsLyTagNameCO4Q0:CO4CCO4Q.1CO4CaCO4Q.1CO4CCO4Q0+CO4CCO4Q-1CO4C
CO4SCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CforCO4Q0:CO4CiCO4Q2+CO4C:CO4Q-1CO4C
CO4Q+2:CO4CiCO4Q2:CO4ClinDsCO4Q02CO4ClengthCO4Q-1CO4CCO4Q+2:CO4CiCO4Q0.CO4CCO4Q0.CO4
CCO4Q0+CO4CCO4Q+2:CO4CCO4Q+3.CO4CCO4SCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CC
O4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CifCO4Q0:CO4ClinDsCO4Q1+CO4CiCO4Q1.CO4CCO4
Q02CO4CtitleCO4Q02CO4CindeEOfCO4Q0:CO4CCO4Q.1CO4CeliminarCO4Q.1CO4CCO4Q0+CO4CCO4Q+2:C
O4CCO4Q2+CO4CCO4Q2+CO4CCO4Q+2:CO4C:CO4Q0+CO4CCO4Q+2:CO4CCO4Q+3.CO4CCO4SCO4Q+2:CO4C
CO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:
CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4ClinDsCO4Q1+CO4CiCO4Q1.CO4CCO4Q02CO4ConclicDCO4Q
+2:CO4CCO4Q2+CO4CCO4Q+2:CO4Cf&nctionCO4Q0:CO4CCO4Q0+CO4CCO4Q+2:CO4CCO4Q+3.CO4CCO4SC
O4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:
CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO
4Q+2:CO4CpartesCO4Q+2:CO4CCO4Q2+CO4CCO4Q+2:CO4CthisCO4Q02CO4ChrefCO4Q02CO4CsplitCO4Q0:
CO4CCO4Q.1CO4CCO4Q0,CO4CCO4Q.1CO4CCO4Q0+CO4CCO4Q-1CO4CCO4SCO4Q+2:CO4CCO4Q+2:CO4CC
O4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:
CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CpregCO4Q+2:CO4
CCO4Q2+CO4CCO4Q+2:CO4CCO4Q.0CO4CCO4Q+1+CO4CConfirmaCO4Q+2:CO4CB&eCO4Q+2:CO4CdeseaCO4Q
+2:CO4CeliminarCO4Q+2:CO4CesteCO4Q+2:CO4CCO4Q.0CO4CCO4Q+2:CO4CCO4Q0.CO4CCO4Q+2:CO4Cpa
rtesCO4Q1+CO4C0CO4Q1.CO4CCO4Q+2:CO4CCO4Q0.CO4CCO4Q+2:CO4CCO4Q.0CO4CCO4Q2.CO4CCO4Q.0
CO4CCO4Q-1CO4CCO4SCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO
4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q
+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CifCO4Q0:CO4CconfirmCO4Q0:CO4CpregCO4Q0+CO4CCO4Q0+CO4CCO
4Q+2:CO4CCO4Q+3.CO4CCO4Q+2:CO4CCO4SCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q
+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4
CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+
2:CO4ClocationCO4Q02CO4ChrefCO4Q+2:CO4CCO4Q2+CO4CCO4Q+2:CO4CthisCO4Q02CO4ChrefCO4Q-1C
O4CCO4Q+2:CO4CCO4SCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4
CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+
2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+3-CO4CCO4Q+2:CO4CelseCO4Q+2:CO4CCO4Q+3.CO4CCO4SCO4
Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO
4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q
+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4Cret&rnCO4Q+2:CO4CfalseCO4Q-1CO4CC
O4SCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4
Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO
4CCO4Q+2:CO4CCO4Q+3-CO4CCO4SCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4C
CO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+3
-CO4CCO4Q-1CO4CCO4SCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:C
O4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+3-CO4CCO4SCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4CCO4Q+2:CO4
CCO4Q+3-CO4CCO4SCO4Q+3-CO4C
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
27
8omo puede "erse en el ejemplo anterior es un simple e inocuo conjunto de caracteres al$anum-ricos que
solo y !nicamente del lado del cliente Iadoptan $ormaJ la $orma que nosotros como programadores le
hacemos "er al usuario.
CONCLUSIN
4m'$ementar mo%e$os %e seguri%a% 'ermisivos no es a$go sen(i$$o. Por el contrario su estrategia
requiere de cierta complejidad de an+lisis a la que tal "ez la mayor)a de los programadores no est+
acostumbrado. #in embargo no es imposible. Las grandes "entajas y sobre todo la innumerable cantidad de
bene$icios que los modelos de seguridad permisi"os aportan a los sistemas in$orm+ticos justi$ican la in"ersin
de tiempo y es$uerzo que la de$inicin desarrollo e implementacin de estos modelos demandan al
programador.
=o e'isten $rmulas !nicas y por consiguiente mucho menos las hay m+gicas para de$inir estos modelos.
*oda pol)tica de seguridad toda medida a implementar deber+n ser el producto de un anC$isis o!jetivo,
a!stra(to # (ui%a%o de lo que realmente se necesita.
Es im'osi!$e im'$ementar ver%a%eros mo%e$os %e seguri%a% 'ermisivos si se ana$i)an $as
a'$i(a(iones (on $a misma :'ti(a %e$ usuario< &s importante entender que aquello que el usuario "e no
necesariamente ser+ real. %e la misma $orma en la que nosotros hallamos 12 objetos complejos en lo que el
usuario solo "e como un sencillo $ormulario con .2 campos en los cu+les escribir 9o elegir: datos debemos "er
toda la aplicacin. Basarnos en la premisa de que todo absolutamente todo lo que el usuario "ea ser+ una
gran $antas)a.
4nsisto a mis a$umnos %e >orma (onstante en que desarrollen sobre la misma plata$orma en la que
$inalmente se ejecutar+ la aplicacin y en que e"iten tanto como les sea posible el uso de herramientas
gr+$icas para trabajar. > no lo hago por IcaprichoJ sino por el contrario $o hago 'ara ir a(ostum!ran%o a$
(ere!ro a ra)onar (a%a ve) %e >orma $o mCs a!stra(ta, in%e'en%iente # ais$a%a %e F>antas@as
:'ti(asG 'osi!$e< Porque cuanto m+s IamigableJ sea el entorno de trabajo menos es$uerzo mental
requerir+ por parte del programador pues cuanto menos es$uerzo mental est- haciendo el programador en su
trabajo m+s estar+ siendo ")ctima -l mismo de las Iilusiones pticasJ producidas por un programador m+s
astuto y entonces la pregunta es4
cmo lograr un programador, hacer aplicaciones
seguras si l mismo es vctima de ilusiones
pticas que no es capaz de entender ni descifrar?
;n usuario que programa no es lo mismo que un programador. #i te animas a ser programador lograr+s darte
cuenta de que en rea$i%a%, $as a'$i(a(iones invu$nera!$es eJisten # son 'osi!$es.
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
28
BASH SCRIPTING: DIVERSAS
FORMAS DE IMPLEMENTACIN
DE MENS DINMICOS
DESDE SIMPLES LECTURAS
DE LA ENTRADA ESTNDAR
HASTA COMPLEJOS
ALGORITMOS; CON
GNU/BASH, CREAR MENS
DINMICOS PUEDE
CONVERTIRSE EN UN
ENTRETENIDO ARTE.
uando el scripting en E=;5Bash no es nuestra acti"idad
principal y solo lo utilizamos como herramienta
complementaria para nuestros programas es de lo m+s
$recuente que le demos poca importancia al men! de nuestro
script. Pero tarde o temprano nos encontraremos con la necesidad
de mejorarlo y emplear un men! que realmente cumpla una $uncin
protagnica para el script.
8
Por suerte E=;5Bash es un lenguaje muy completo que nos brinda
un amplio abanico de opciones para crear men!s que puedan
satis$acer cada una de nuestras necesidades cubriendo as) una
gran cantidad de alternati"as posibles.
&n este art)culo "eremos la $orma de implementar %es%e sen(i$$os
men?s que tan solo act!en leyendo la in$ormacin de entrada
est+ndar hasta hacks &ue me%iante e$ em'$eo %e m?$ti'$es
(onstru(tores %e$ $enguaje, generen men?s (on una
(om'$eji%a% a$gor@tmi(a &ue 'ue%a (ontem'$ar hasta e$ mCs
m@nimo %eta$$e.
La $orma m+s com!n y tradicional con la que la mayor)a de los programadores suele trabajar en un script es
con la lectura de una entrada est+ndar4
#45&!n5&as%
OPCOONS=6=(rir Cerrar ditar Lorrar Q&ardar Salir6
echo MOPCOONS
echo
echo !n 'liKa &na opciGn5 '' read opcion
echo 6Tsted eligiG Mopcion$6
B+sicamente todo consiste en imprimir en pantalla una cadena de te'to de la cual el usuario Icopiar+J una
palabra 9qu- hace las "eces de IopcinJ: la ingresar+ nuestro script la leer+ y en base a ella har+
determinada accin. #imple sencillo y resuel"e de $orma r+pida los requerimientos m+s primiti"os de la
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
29
interaccin con un usuario. / lo sumo como gran complejidad se le suele agregar una estructura de control
condicional4
#45&!n5&as%
OPCOONS=6=(rir Cerrar ditar Lorrar Q&ardar Salir6
echo MOPCOONS
echo
echo !n 'liKa &na opciGn5 '' read opcion
if + 74opcion7 = 78brir7 ,5 then
echo 6sto a(re &n archivo6
else
echo 6Tsted eligiG la opciGn Mopcion6
fi
#in embargo (uan%o $a (anti%a% %e o'(iones a considerar en las estructuras de control condicionales se
van in(rementan%o se comienza a o'tar 'or (onstru(tores %e se$e((i:n mCs 're(isos como es el
caso del (onstru(tor case4
#45&!n5&as%
OPCOONS=6=(rir Cerrar ditar Lorrar Q&ardar Salir6
echo MOPCOONS
echo
echo !n 'liKa &na opciGn5 '' read opcion
case 4opcion in
8brir)
echo 6sto a(re &n archivo6
55
3errar)
echo 6so cierra &n archivo6
55
%alir)
echo 6sto sale del programa6
eEit
55
9) # $al/!er opc!6n no contempla(a
echo 6No eligiG ning&na opciGn correcta6
55
esac
Pero en E=;5Bash el constructor case es tan solo uno de los tantos constructores pro"istos por el lenguaje.
*ambi-n podemos encontrarnos con el constructor select.
EL CONSTRUCTOR SELECT
&l constructor select adoptado por primera "ez por Sorn #hell nos da resuelto en un solo paso4
La enumeracin de opciones posiblesH
La impresin ordenada de opciones en pantallaH
La lectura est+ndar de la opcin elegida por el usuarioH
La repeticin constante del men! en pantalla.
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
30
La sinta'is de este constructor es la siguiente4
select 78R98:;-<18.- [in l!sta<(e<opc!ones#5 do
# !nstrcc!ones
[(reaD#
done
Los corchetes [# indican Isinta'is opcionalJ
&l constructor select reproduce el men! de $orma permanente incluso despu-s de haber $inalizado con las
instrucciones internas. La instruccin (reaD romper+ ese bucle.
#45&!n5&as%
OPCOONS=6=(rir Cerrar ditar Lorrar Q&ardar Salir6
PS.=6liKa &na opciGn5 6 # 3! no se !n(!ca mostrar =#>= por (e)ecto
select opcion in MOPCOONS' do
echo 6Tsted ligiG la opciGn Mopcion6
brea: # Rompe el &cle
done
# -?ecc!6n en &cle 'cont!na(a* @ no se !n(!ca el &reaA
select opcion in MOPCOONS' do
echo 6Tsted ligiG la opciGn Mopcion6
done
&l algoritmo anterior producir+ una salida similar a la siguiente4
&serJhost5UM $/men&s!dnamicos$sh
+* =(rir
3* Cerrar
.* ditar
0* Lorrar
-* Q&ardar
2* Salir
liKa &na opciGn5
8omo puede "erse nos ahorra much)simo es$uerzo al momento de presentar las opciones en pantallas.
El constructor select es el generador de mens de
opciones por excelencia de !"#$%ash
8ombinando el constructor con una estructura de control condicional simple es posible determinar si el
usuario ha ingresado 6o no6 una opcin "+lida4
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
31
VW/(in/(ash
OPCOONS=6=(rir Cerrar ditar Lorrar Q&ardar Salir6
PS.=6liKa &na opciGn5 6
select opcion in MOPCOONS' do
if + 4opcion ,5 then
echo 6Tsted ligiG la opciGn Mopcion6
(reaD
fi
done
&sto nos da una gran "entaja ya que de tratarse de una opcin "+lida switchear la eleccin del usuario no
requerir)a de "alidaciones adicionales4
VW/(in/(ash
OPCOONS=6=(rir Cerrar ditar Lorrar Q&ardar Salir6
PS.=6liKa &na opciGn5 6
select opcion in MOPCOONS' do
if + 4opcion ,5 then
case 4opcion in
=(rir*
echo 6sto a(re &n archivo6
''
Cerrar*
echo 6so cierra &n archivo6
''
Salir*
echo 6sto sale del programa6
eEit
''
esac
brea:
fi
done
SELECT HACK: CAPTURAR LA OPCIN INVLIDA
?recuentemente cuando en la bibliogra$)a se habla del constructor select 6o del tan conocido case6 solo se
hace re$erencia a un conjunto de opciones posibles. #in embargo much)simas "eces una opcin select
in"+lida podr)a requerir un tratamiento distinto al de otra opcin select in"+lida.
4maginemos este es(enario6 el usuario se encuentra con un men! de opciones delante y la imposibilidad
de elegir la indicada puesto desconoce la utilidad de cada una. &l script espera una entrada del usuario pero
el usuario necesita conocer el n!mero de "ersin del script antes de decidir qu- opcin elegir. O8mo se
entera del n!mero de "ersin sin salir del scriptP Podr)a o$recerse la misma como una opcin m+s del men!
pero sin embargo se estar)a des"irtuando la $inalidad del programa. &n cambio un argumento ingresado en la
entrada est+ndar podr)a solucionar el problema.
The Original Hacker www.originalhacker.org
2013, 2014 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA
32
&e puede capturar la respuesta del usuario accediendo
a la variable de contexto '(E)L*
VW/(in/(ash
OPCOONS=6=(rir Cerrar ditar Lorrar Q&ardar Salir6
PS.=6liKa &na opciGn5 6
select opcion in MOPCOONS' do
if [ Mopcion #' then
case Mopcion in
=(rir*
echo 6sto a(re &n archivo6
''
Cerrar*
echo 6so cierra &n archivo6
''
Salir*
echo 6sto sale del programa6
eEit
''
esac
(reaD
else
case 4;<#=> in
!hX!!help*
echo 6=y&da so(re el programa6
''
-?--ersion)
echo 6mi!programa versiGn +$:$+6
''
!BXYB*
eEit
''
Z*
echo 6OpciGn invClida6
esac
fi
done
ACE/34=0
OPor qu- un hombre nacido el .2 de agosto del ao .R /8 a
las .T422 ,# y $allecido el .2 de agosto del ao .R %8 a las
.U4RQ ,# no lleg a cumplir los 02 aosP
A#u%a6 La respuesta no est+ en la matem+tica. %ebes razonar de $orma lateral.
Fesponde AN3ES del 2890892014
a tra"-s de 3Kitter utilizando el hashtag LA(ertijo30*8
E$ nom!re %e $os gana%ores serC 'u!$i(a%o en $a siguiente e%i(i:n
La respuesta correcta ser+ publicada en *he <riginal ,ac3er =KU junto con los ganadores
1404240651975
1404240651975
5

Você também pode gostar