LostInSecurity

ANALIZANDO LA ACTUALIDAD
Cómo funciona la cuarentena en OSX (Gatekeeper)

Cuando Apple sacó la versión 10.7.5 de OSX Lion incluyó una característica adicional para proteger a los equipos frente a software malicioso debido quizás a la presión que había en los medios y por las casas antivirus publicando ciertas oleadas de nuevo malware para OSX. En las siguientes versiones y sobre todo depués de la aparición de la Mac App Store, ha ido incluyendo opciones como la de permitir ejecutar sólo aplicaciones descargadas desde ella, o firmadas digitalmente, por ejemplo. Estas opciones añaden cierta seguridad pero se quedan muy lejos de crear un entorno seguro, puesto que son muy limitadas; por ejemplo, Gatekeeper sólo comprueba un fichero la primera vez que lo ejecuta (!!).

Pero Gatekeeper es la evolución de unos tímidos intentos que empezó a realizar Apple para detectar aplicaciones maliciosas. Cuando apareción OSX Tiger (10.4) ya se empezó a implementar la cuarentena, que básicamente consiste en añadir ciertos atributos cuando se descarga desde alguna aplicación de Cocoa (no por ejemplo si se descarga con un curl o un wget desde la línea de comandos) un ejecutable de Internet para que cuando se intenté ejecutar aparezca una ventana diciendo que esa aplicación se ha descargado de Internet y nos pregunte si queremos de verdad ejecutarla. De hecho, para que cualquier aplicación de Cocoa aproveche esta funcionalidad, es tan sencillo como activar la clave LSFileQuarantineEnabled, que por defecto añadirá ciertos datos, pero es reponsabilidad de la aplicación añadir los que falten.

Posteriormente en la versión de Snow Leopard (10.6), Apple añadió una opción un poco chapucera de detectar ciertas familias de malware conocido que básicamente comprueba si existe cierto patrón dentro de los archivos descargados. También existe un binario que es /usr/libexec/XProtectUpdater que se encarga de actualizar las firmas de patrones. Si tenéis un OSX a mano, el fichero de firmas se guarda en /System/Library/CoreServices/ CoreTypes.bundle/Contents/Resources/, pero podéis acceder a él también donde se actualiza, que es en http://configuration.apple.com/configurations/macosx/xprotect/3/clientConfiguration.plist. A día de hoy, y con la versión 10.8.2 de OSX actual, detecta las siguientes familias (aunque no todas las variantes de las familias):

    • OSX.RSPlug.A
    • OSX.Iservice.A
    • OSX.Iservice.B
    • OSX.HellRTS
    • OSX.HellRTS
    • OSX.OpinionSpy
    • OSX.MacDefender.A
    • OSX.MacDefender.B
    • OSX.QHost.WB.A
    • OSX.Revir.A
    • OSX.FlashBack.A
    • OSX.DevilRobber.A
    • OSX.FlashBack.B
    • OSX.DevilRobber.B
    • OSX.FlashBack.C
    • OSX.FileSteal.i
    • OSX.Revir.ii
    • OSX.Mdropper.i
    • OSX.FkCodec.i
    • OSX.MaControl.i
    • OSX.Revir.iii
    • OSX.Revir.iv
    • OSX.SMSSend.i

Es interesante que al igual que ocurre en el mundo Microsoft, algunas de estas familias también desabilitán rápidamente esta protección de OSX (como OSX.FlashBack.C).

Pero volvamos al tema de la cuarentena; como he comentado anteriormente, OSX añade un cierto atributo extendido al fichero que es descargado con una aplicación de Cocoa. Podemos comprar si existe este atributo con un simple ls -l@ (la '@' es para que muestre los atributos extendidos):

ls -l@ Downloads/BoxCryptor_v1.0.5_Installer.dmg 
-rw-rw-rw-@ 1 dbarroso  staff  10659400 22 nov 16:33 Downloads/BoxCryptor_v1.0.5_Installer.dmg
com.apple.diskimages.fsck         20 
com.apple.diskimages.recentcksum          81 
com.apple.metadata:kMDItemDownloadedDate          53 
com.apple.metadata:kMDItemWhereFroms         162 
com.apple.quarantine          57

En este caso lo que nos interesa son los últimos atributos, com.apple.metadata:kMDItemDownloadedDate, com.apple.metadata:kMDItemWhereFroms, y com.apple.quarantine que en este caso tiene un tamaño de 57 bytes. Si analizamos el contenido de estos atributos, podemos ver lo siguiente:

xattr -l Downloads/BoxCryptor_v1.0.5_Installer.dmg

com.apple.diskimages.fsck: i.?3?h?U?]??Ѧ?
com.apple.diskimages.recentcksum: i:26172962 on E62A91BF-7C3C-3494-A435-B141815ABBA8 @ 1353598432 - CRC32:$3243FE6F
com.apple.metadata:kMDItemDownloadedDate:
00000000  62 70 6C 69 73 74 30 30 A1 01 33 41 B6 5E 7D 61  |bplist00..3A.^}a|
00000010  2D 0C 1C 08 0A 00 00 00 00 00 00 01 01 00 00 00  |-...............|
00000020  00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00  |................|
00000030  00 00 00 00 13                                   |.....|
00000035
com.apple.metadata:kMDItemWhereFroms:
00000000  62 70 6C 69 73 74 30 30 A2 01 02 5F 10 3C 68 74  |bplist00..._.<ht|
00000010  74 70 73 3A 2F 2F 77 77 77 2E 62 6F 78 63 72 79  |tps://www.boxcry|
00000020  70 74 6F 72 2E 63 6F 6D 2F 64 6F 77 6E 6C 6F 61  |ptor.com/downloa|
00000030  64 2F 42 6F 78 43 72 79 70 74 6F 72 5F 49 6E 73  |d/BoxCryptor_Ins|
00000040  74 61 6C 6C 65 72 2E 64 6D 67 5F 10 32 68 74 74  |taller.dmg_.2htt|
00000050  70 73 3A 2F 2F 77 77 77 2E 62 6F 78 63 72 79 70  |ps://www.boxcryp|
00000060  74 6F 72 2E 63 6F 6D 2F 64 6F 77 6E 6C 6F 61 64  |tor.com/download|
00000070  32 2F 3F 70 6C 61 74 66 6F 72 6D 3D 6D 61 63 08  |2/?platform=mac.|
00000080  0B 4A 00 00 00 00 00 00 01 01 00 00 00 00 00 00  |.J..............|
00000090  00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |................|
000000A0  00 7F                                            |..|
000000a2
com.apple.quarantine: 0002;50ae45e1;Safari;3D236707-81B9-4AF4-A347-2A1EAB881EB6

En un simple vistazo podemos ver que hay ciertos datos interesantes como la URL donde se ha descargado el binario, que se ha descargado desde Safari, e incluso que hay un campo que parece que puede ser la fecha de descarga. En la última línea, que es la propia de la cuarentena, si nos fijamos hay 4 campos, el primero desconocido, la fecha de descarga, el programa que lo ha descargado, y un identificador UTI (Uniform Type Identifier).

Aparte de estos atributos, en OSX hay una base de datos sqlite donde de igual manera se guarda esta información. Esta base de datos está en el directorio $HOME/Library/Preferences/ y puede tener el nombre com.apple.LaunchServices.QuarantineEvents en Snow Leopard o com.apple.LaunchServices.QuarantineEventsV2 en Lion y Mountain Lion;estos ficheros contienen la tabla LSQuarantineEvent que tiene las siguientes columnas:

    • LSQuarantineEventIdentifier: identificador UTI que se usa como clave primaria, que es el mismo que hemos visto en los atributos.
    • LSQuarantineTimeStamp: fecha de descarga, representada en segundos desde el 1 de enero de 2001 12:00 AM (es decir, que hay que sumar 978307200 segundos para poder tener un UNIX timestamp normal).
    • LSQuarantineAgentBundleIdentifier: el nombre del bundle del programa que ha descargado el archivo (por ejemplo com.google.Chrome).
    • LSQuarantineAgentName: el nombre del programa que ha descargado del archivo (por ejemplo Google Chrome).
    • LSQuarantineDataURLString: la URL desde donde se ha descargado el archivo.
    • LSQuarantineSenderName: el nombre de la persona que envió un attachment de correo (es decir, sólo se pone si LSQuarantineTypeNumber es igual a '2')
    • LSQuarantineSenderAddress: la dirección de la persona que envió un attachment de correo, igual que en el caso anterior
    • LSQuarantineTypeNumber: el tipo de método de descarga:
      • 0 si es web (kLSQuarantineTypeWebDownload)
      • 1 si son otros programas (kLSQuarantineTypeOtherDownload) - como por ejemplo Transmission, o el mismo XCode
      • 2 si son attachments de correo (kLSQuarantineTypeEmailAttachment)
      • 3 si son attachments de programas de mensajería instantánea (kLSQuarantineTypeInstantMessageAttachment); por lo que he visto, sólo iChat
      • 4 si es calendario (kLSQuarantineTypeCalendarEventAttachment)
      • 5 si son otros attachments (kLSQuarantineTypeOtherAttachment)
    • LSQuarantineOriginTitle: en el caso de los eventos de calendario, el título de la cita/reunión.
    • LSQuarantineOriginURLString: la URL anterior (el referer) visitada antes de ir a la URL de descarga del archivo.
    • LSQuarantineOriginAlias: este campo está definido como un BLOB pero nunca lo he visto relleno

Es decir, que si por ejemplo queremos listar todos los archivos que nos hemos descargado, es tan simple como ejecutar:

sqlite3 com.apple.LaunchServices.QuarantineEventsV2 
"select LSQuarantineDataURLString from LSQuarantineEvent 
where LSQuarantineTypeNumber = 0;"

Como curiosidad, podemos ver como aplicaciones como Google Chrome añade estos atributos, aunque al ser navegador web, sólo añade los que cree que son relevantes. Por ejemplo, en el fichero quarantine_mac.mm podemos ver como se asignan los campos siguientes:

    • kLSQuarantineTypeKey que asigna como kLSQuarantineTypeWebDownload si es un recurso 'http' o 'https', o como kLSQuarantineTypeOtherDownload si es otro tipo de recurso (por ejemplo 'ftp')
    • kLSQuarantineOriginURLKey con el valor de la página anterior (referrer_url)
    • kLSQuarantineDataURLKey con el valor de la página actual (origin_url)
// kLSQuarantineAgentNameKey, kLSQuarantineAgentBundleIdentifierKey, and
// kLSQuarantineTimeStampKey are set for us (see LSQuarantine.h), so we only
// need to set the values that the OS can't infer.

if (![quarantine_properties valueForKey:(NSString*)kLSQuarantineTypeKey]) {
    CFStringRef type = (source.SchemeIs("http") || source.SchemeIs("https"))
                       ? kLSQuarantineTypeWebDownload
                       : kLSQuarantineTypeOtherDownload;
                       [quarantine_properties setValue:(NSString*)type
                           forKey:(NSString*)kLSQuarantineTypeKey];
}

if (![quarantine_properties
      valueForKey:(NSString*)kLSQuarantineOriginURLKey] &&
  referrer.is_valid()) {
NSString* referrer_url =
    [NSString stringWithUTF8String:referrer.spec().c_str()];
[quarantine_properties setValue:referrer_url
                         forKey:(NSString*)kLSQuarantineOriginURLKey];
}

if (![quarantine_properties valueForKey:(NSString*)kLSQuarantineDataURLKey] &&
  source.is_valid()) {
NSString* origin_url =
    [NSString stringWithUTF8String:source.spec().c_str()];
[quarantine_properties setValue:origin_url
                         forKey:(NSString*)kLSQuarantineDataURLKey];
}

En este caso Chrome no tiene que añadir ninguno más porque ya el sistema operativo por defecto añadirá los campos kLSQuarantineAgentNameKey, kLSQuarantineAgentBundleIdentifierKey y kLSQuarantineTimeStampKey. Recordad que sólo los añadirá si la clave LSFileQuarantineEnabled está activada en la aplicación.

Si eres un usuario paranoico y no quieres que OSX tenga esta funcionalidad, puedes desactivarla completamente:

defaults write com.apple.LaunchServices LSQuarantine -bool NO

comments powered by Disqus