Ejercicio 1 - Universidad Rey Juan Carlos

Anuncio
Universidad Rey Juan Carlos
Seguridad Informática
Grado en Ingenierı́a Informática
Pruba de control 1
Control de acceso y seguridad software
Curso 2012–2013
Ejercicio 1 (1 punto)
Contesta verdadero o falso a las siguientes preguntas. Cada respuesta correcta suma
0.25 y cada respuesta incorrecta resta 0.25
1. Una lista de control de acceso (ACL) tiene la ventaja que es fácil revocar los
permisos de un determinado sujeto [V] [F]
2. Si el usuario alice:students ejecuta el programa -r-sr-xr-x grades.exe
bob:professors a lo largo de la ejecución del programa adoptará temporalmente el UID del usuario bob:professors [V] [F]
3. Un requisito necesario para que ocurra una condición de carrera entre dos procesos es que uno de los dos se ejecute con privilegios de administración [V] [F]
4. El principio del privilegio mı́nimo consiste en prohibir la ejecución de cualquier
programa con privilegios de administración [V] [F]
Ejercicio 2 (1 punto)
Explica brevemente en qué consiste un ataque por inyección SQL
Ejercicio 3 (3 puntos)
En un empresa de venta de material sanitario existen dos programas para la gestiı́on
de la facturacı́on y para la gestión de los clientes. Los dos programas en cuestión son
-rwxr-x--- /usr/bin/billing mgmt bill:billing
-rwxr-x--- /usr/bin/customers mgmt cust:customers
En el grupo billing está el usuario bill ası́ como todos los usuarios que trabajan
con el programa billing mgmt. En el grupo customers está el usuario cust ası́ como
todos los usuarios que trabajan con el programa customers mgmt
Cada dı́a 5 del mes, los usuarios del grupo customers que usan customers mgmt
necesitan algunos datos de facturación proporcionados por billing mgmt. Para ello,
los desarroladores de la empresa han definido un sistema basado en intercambio de
ficheros que utiliza el siguiente directorio
drwxrwxr-x /home/share bill:billing
En este directorio el programa billing mgmt escribe el siguiente fichero
-rw-rw-r-- /home/share/billing data bill:billing
Página 1 de 8
Hoja de Problemas 1
Control de acceso y seguridad software
(a) (1.5 puntos) Contesta verdadero o falso a las siguientes preguntas, explicando
brevemente el porqué de tu respuesta. Cada respuesta correcta suma 0.5 y cada respuesta incorrecta resta 0.5. Respuestas sin explicación no suman ni restan.
El sistema de intercambio de ficheros definido por los desarroladores podrı́a poner en peligro . . .
1) La integridad de la información [V] [F]
Sólo los usuarios del grupo billing pueden escribir el directorio /home/share
o el fichero /home/share/data
2) La confidencialidad de la información [V] [F]
Todos los usuario pueden leer el fichero /home/share/data
3) La disponibilidad de la información [V] [F]
Sólo los usuarios del grupo billing pueden por ejemplo borrar el directorio
/home/share o el fichero /home/share/data
(b) (1.5 puntos) Modifica oportunamente el sistema de intercambio de ficheros para
resolver los problemas identificados anteriormente. Para ellos es posible modificar
permisos, usuario propietario y grupo propietario del directorio /home/share,
del fichero /home/share/billing data y de los programas billing mgmt y
customers mgmt
Podemos hacer que todos los usuarios del departamento de facturación usen
el programa /usr/bin/billing mgmt bill:billing como si fueran el usuario
bill (usando el permiso SUID)
-rwsr-x--- /usr/bin/billing mgmt bill:billing
y modificar los permisos de la siguiente forma:
drwxr-x--- /home/share bill:customers
-rw-r----- /home/share/billing data bill:customers
Otra opción es hacer los usuarios del grupo billing miembros del grupo customers
y modificar los permisos de la siguiente forma:
drwxrwx--- /home/share bill:customers
-rw-rw---- /home/share/billing data bill:customers
Página 2 de 8
Hoja de Problemas 1
Control de acceso y seguridad software
Ejercicio 4 (5 puntos)
Considera el siguiente código fuente:
package system;
public class Permission {
private Resource resource;
// Los permisos pueden ser ’-’, ’r’ o ’w’
// ’-’ significa ningún permiso, ’r’ lectura, ’w’ lectura y escritura
// Los permisos están definidos para el propietario del recurso (permission[0])
// y para los otros usuarios (permission[1])
private char[] permission = new char[2];
protected void setResource(Resource resource){
this.resource = resource;
}
protected void setPermission(char[] permission){
for(int i = 0; i < permission.length; i++)
this.permission[i] = permission[i];
}
protected boolean denyReadPermission(int index){
if(index < 0 || index > 1)
throw new RuntimeException();
if(permission[index] == ’-’)
return true;
return false;
}
protected boolean denyWritePermission(int index){
if(index < 0 || index > 1)
throw new RuntimeException();
if(permission[index] == ’-’ || permission[index] == ’r’)
return true;
return false;
}
Página 3 de 8
Hoja de Problemas 1
Control de acceso y seguridad software
package system;
public class Monitor {
private static HashMap<Resource, Permission> policy = new HashMap<Resource, Permission>();
public static void setPermission(Resource resource, char[] permission, int ownerID){
Permission p = new Permission();
p.setResource(resource);
p.setPermission(permission);
policy.put(resource, p);
}
public static HashMap<Resource, Permission> getPolicy(){
return policy;
}
public static void write(Resource r, int userID){
if(userID == r.getOwnerID() && !policy.get(r).denyWritePermission(0))
r.write();
else if(userID != r.getOwnerID() && !policy.get(r).denyWritePermission(1))
r.write();
}
public static void read(Resource r, int userID){
if(userID == r.getOwnerID() && !policy.get(r).denyReadPermission(0))
r.read();
else if(userID != r.getOwnerID() && !policy.get(r).denyReadPermission(1))
r.read();
}
}
Página 4 de 8
Hoja de Problemas 1
Control de acceso y seguridad software
package system;
public class Resource {
private int ownerID;
private Object resource;
protected Resource(int ownerID, Object resource){
this.ownerID = ownerID;
this.resource = resource;
}
protected int getOwnerID(){
return ownerID;
}
protected Object getResource(){
return resource;
}
public void write(){
...
}
public void read(){
...
}
}
package client;
public class Session {
//La variable ‘‘myUserID’’ se inicializa al crear ls sesión
private final int myUserID;
public final void setPermission(Resource r, char[] p);
Monitor.setPermission(r, p, myUserID);
}
public final HashMap<Resource, Permission> getPolicy(){
return Monitor.getPolicy();
}
public final void write(Resource r){
Monitor.write(r, myUserID);
}
public final void read(Resource r){
Monitor.read(r, myUserID);
}
Página 5 de 8
Hoja de Problemas 1
Control de acceso y seguridad software
Existen dos paquetes, system y client. Las clases del paquete system modelan
los recursos del sistema (Resource), los permisos (Permission) y el monitor de referencia (Monitor) que implementa la polı́tica de control de acceso. La aplicación
prevé 3 tipos de permisos y dos tipos de usuarios. Los permisos están identificados
por un char, donde ’-’ significa ningún permiso, ’r’ significa permiso de lectura y
’w’ significa permiso de lectura y escritura. Los usuarios pueden ser el propietario
del recurso u otros usuarios. El tipo de permiso del propietario está almacenado en
Permission.permission[0], mientras que el tipo de permiso para todos los demás
está almacenado en Permission.permission[1]. El paquete system está “sellado”
(sealed ), lo cual significa que nadie puede definir una clase que pertenezca a este
paquete.
Los usuarios interactúan con los recursos usando la clase Session del paquete client.
Supongamos que la clase Session tenga funcionalidades para autenticar los usuarios
y asignar por lo tanto un valor a la variable myUserID. Un usuario podrı́a desarrollar
nuevas funcionalidades para la clase Session, pero no modificar los métodos ya definidos (que son declarados final) ası́ como el identificativo del usuario (myUserID).
La clase Session permite invocar los métodos ofrecidos por la clase Monitor para
fijar los permisos de un recurso (setPermission(Resource r, char[] p)), obtener
la lista de permisos sobre todos los recursos (getPolicy()), leer (read(Resource
r)) y escribir (write(Resource r)) recursos.
(a) (2 puntos) Contesta verdadero o falso a las siguientes preguntas. Cada respuesta correcta suma 0.5 y cada respuesta incorrecta resta 0.5
1) El control de acceso implementado por este código es control de acceso discrecional [V] [F]
2) Un desarrollador puede definir nuevos métodos en la clase Session para . . .
2.a) . . . invocar directamente el método setPermission(char[] permission)
de la clase Permission [V] [F]
2.b) . . . invocar directamente el método read() de la clase Resource [V] [F]
2.c) . . . crear recursos invocando el contructor Resource(int ownerID, Object
resource) [V] [F]
(b) (3 puntos) Identifica los fallos de este código fuente, tanto los que podrı́an causar
un mal funcionamiento del programa como los que representan un peligro para
la seguridad del programa. Para cada uno de ellos, describe a) en qué consiste el
fallo, b) qué problema puede causar al programa y c) cómo se podrı́a modificar
el código fuente para solucionar el fallo.
Página 6 de 8
Hoja de Problemas 1
Control de acceso y seguridad software
Solución
1. La clase Permission no comprueba si la longituda del array permission pasado
como parametro es 2, por lo tanto podrı́a causar una excepción. Para resolver el
fallo hay que manejar explicitamente este caso, por ejemplo ejecutando algo tipo
if(this.permission.length != permission.length)
return;
antes de copiar los permisos.
2. La clase Permission no comprueba que los char contenidos en el array permission
pasado como parametro sean los que el programa espera, es decir, ’-’, ’r’ o
’w’. Este fallo podrı́a causar un mal funcionamiento en la gestión de los permisos. Para resolver el fallo hay que comprobar los tipos de permisos que se
está intentando copiar, por ejemplo ejecutando algo tipo
for(char c in permission)
if(c != ’-’ || c != ’r’ || c != ’w’)
return;
antes de copiar los permisos.
3. Los métodos denyReadPermission() y denyWritePermission() ejecutan el
control de acceso en base a la denegación del acceso, no a la autorización. Si
un atacante se aprovecha del fallo definido anteriormente y pone como permiso
un char que no sea ’-’, ’r’ o ’w’, el método siempe devuelve false, lo cual
implica que el acceso es garantizado. Para resolver el fallo es necesario comprobar si un usuario tiene acceso. Por ejemplo el método denyReadPermission()
se deberı́a cambiar en grantReadPermission() de esta manera
protected boolean grantReadPermission(int index){
if(index < 0 || index > 2)
throw new RuntimeException();
if(permission[index] == ’r’ || permission[index] == ’w’)
return true;
return false;
}
4. El método setPermission(Resurce resource, char[] permission, int ownerID)
no comprueba que el ownerID del recurso resource coincida con el ownerID pasado como parametro. Aprovechando de este fallo un usuario podrı́a fijar los
permisos de un recurso que no le pertenece. Para resolver el fallo habrı́a que
ejecutar
if(resource.getOwnerID() != ownerID)
return;
Página 7 de 8
Hoja de Problemas 1
Control de acceso y seguridad software
antes de crear el objeto Permission que define la polı́tica de control de acceso
sobre el recurso.
5. El método getPolicy() de la clase Monitor devuelve un objeto mutable (la
HashMap con las parejas recursos-permisos). Un atacante podrı́a modificar la
politica de control de acceso, por ejemplo eliminando elementos de la HashMap.
Para resolver el fallo habrı́a que modificar el método getPolicy() de esta manera
public static HashMap<Resource, Permission> getPolicy(){
return Collections.unmodifiableMap(policy);
}
6. Los métodos read() y write() de la clase Resource son declarados public.
Cualquier usuario que acceda a la lista de recursos, invocando el método getPolicy(),
podrı́a leer y escribir los recursos saltándose la polı́tica de control de acceso ejecutada por la clase Monitor, que supuestamente deberı́a vigilar cualquier acceso
a los recursos. Para resolver el fallo habrı́a que declarar ambos métodos como
(por lo menos) protected.
7. Aun ası́, el modificador protected usado en la clase Permission no impide
que alguien cree en un paquete distinto de system una clase que extienda
Permission y pueda invocar todos los métodos declarados protected. Lo mismo vale para Resource. Habrı́a que declararlos package − private (es decir,
ningún modificador de visibilidad). De esta manera sólo las clases del paquete system pueden acceder a estos métodos, y dado que el paquete está sellado
ninguna clase más podrı́a acceder.
8. En general la clase Monitor, que es la interfaz entre los usuarios que usan la clase
Session y las clases del paquete system no ha sido programada de manera defensiva. Por ejemplo, en setPermission(), write() y read() no comprueba que el
recurso que se pasa es distinto de null. La istrucción policy.get(r).denyWritePermission()
en el método write() lanzarı́a una excepción si el resultado de policy.get(r)
fuera null (p.e., si el recurso r no existe).
Página 8 de 8
Descargar