¿Qué falló en Playstation 3?Piratería, seguridad informática y el mercado de las videoconsolasMarco Antonio Gómezy Federico PeinadoMáster en Desarrollo de Videojuegos Universidad Complutense de Madridwww.videojuegos-ucm.eswww.gueim.org
El apagón de PlayStation NetworkSuspensión total del servicio en el mundo20 de abril de 2011 – ActualidadMás de 77 millones de usuariosAfectando incluso a algunos juegos offlinePérdidas de cientos de miles o incluso millones de dólares a empresas (Capcom) Suspensión relacionada de plataforma PC 2 de mayo de 2011 – Actualidad Sony Online Entertainment (MMOGs)Más de 24 millones de usuarios(aunque casi sin afectar a tarjetas de crédito)Motivo: Intrusiones externas Del 16 al 19 de abril de 2011 Datos comprometidos de identificación personal, contraseñas y tarjetas de créditoContinúa la investigación…
Copiar o no copiarContenidos digitales: ¡llega la copia sin pérdida!Sistemas anticopiaHardware (libros de claves, cartuchos, “mochilas”, etc.)Software (errores esperados, número de copias, SecuROM y otros DRMs, etc.)Internet y la WebDescargas masivas, difusión del homebrew, etc.Activación remota, rootkits, contenido en la nube, etc.
La caída de la PS3erk: C0 CE FE 84 C2 27 F7 5B D0 7A 7E B8 46 50 9F 93 B2 38 E7 70 DA CB 9F F4 A3 88 F8 12 48 2B E2 1Briv: 47 EE 74 54 E4 77 4C C9 B8 96 0C 7B 59 F4 C1 4Dpub: C2 D4 AA F3 19 35 50 19 AF 99 D4 4E 2B 58 CA 29 25 2C 89 12 3D 11 D6 21 8F 40 B1 38 CA B2 9B 71 01 F3 AE B7 2A 97 50 19R: 80 6E 07 8F A1 52 97 90 CE 1A AE 02 BA DD 6F AA A6 AF 74 17n: E1 3A 7E BC 3A CC EB 1C B5 6C C8 60 FC AB DB 6A 04 8C 55 E1K: BA 90 55 91 68 61 B9 77 ED CB ED 92 00 50 92 F6 6C 7A 3D 8DDa: C5 B2 BF A1 A4 13 DD 16 F2 6D 31 C0 F2 ED 47 20 DC FB 06 70Lanzamiento (Japón)11 de noviembre de 2006Modelo “slim” sin Linux1 de septiembre de 2009Exploit de GeoHot usando Linux26 de enero de 2010Firmware 3.21: Todos sin Linux28 de marzo de 2010PS JailBreak: 1er Cargador USB18 de agosto de 2010EpicFail: Anuncio de carga sin USB y firmado de ejecutables29 de diciembre de 2010GeoHot hace pública la clave raíz3 de enero de 2011Y la historia continúa…
La caída de la PS3erk: C0 CE FE 84 C2 27 F7 5B D0 7A 7E B8 46 50 9F 93 B2 38 E7 70 DA CB 9F F4 A3 88 F8 12 48 2B E2 1Briv: 47 EE 74 54 E4 77 4C C9 B8 96 0C 7B 59 F4 C1 4Dpub: C2 D4 AA F3 19 35 50 19 AF 99 D4 4E 2B 58 CA 29 25 2C 89 12 3D 11 D6 21 8F 40 B1 38 CA B2 9B 71 01 F3 AE B7 2A 97 50 19R: 80 6E 07 8F A1 52 97 90 CE 1A AE 02 BA DD 6F AA A6 AF 74 17n: E1 3A 7E BC 3A CC EB 1C B5 6C C8 60 FC AB DB 6A 04 8C 55 E1K: BA 90 55 91 68 61 B9 77 ED CB ED 92 00 50 92 F6 6C 7A 3D 8DDa: C5 B2 BF A1 A4 13 DD 16 F2 6D 31 C0 F2 ED 47 20 DC FB 06 70Lanzamiento (Japón)11 de noviembre de 2006Modelo “slim” sin Linux1 de septiembre de 2009Exploit de GeoHot usando Linux26 de enero de 2010Firmware 3.21: Todos sin Linux28 de marzo de 2010PS JailBreak: 1er Cargador USB18 de agosto de 2010EpicFail: Anuncio de carga sin USB y firmado de ejecutables29 de diciembre de 2010GeoHot hace pública la clave raíz3 de enero de 2011Y la historia continúa…La mayoría de las transparencias que siguen son directamente las de esta charla
La caída de la PS3erk: C0 CE FE 84 C2 27 F7 5B D0 7A 7E B8 46 50 9F 93 B2 38 E7 70 DA CB 9F F4 A3 88 F8 12 48 2B E2 1Briv: 47 EE 74 54 E4 77 4C C9 B8 96 0C 7B 59 F4 C1 4Dpub: C2 D4 AA F3 19 35 50 19 AF 99 D4 4E 2B 58 CA 29 25 2C 89 12 3D 11 D6 21 8F 40 B1 38 CA B2 9B 71 01 F3 AE B7 2A 97 50 19R: 80 6E 07 8F A1 52 97 90 CE 1A AE 02 BA DD 6F AA A6 AF 74 17n: E1 3A 7E BC 3A CC EB 1C B5 6C C8 60 FC AB DB 6A 04 8C 55 E1K: BA 90 55 91 68 61 B9 77 ED CB ED 92 00 50 92 F6 6C 7A 3D 8DDa: C5 B2 BF A1 A4 13 DD 16 F2 6D 31 C0 F2 ED 47 20 DC FB 06 70Lanzamiento (Japón)11 de noviembre de 2006Modelo “slim” sin Linux1 de septiembre de 2009Exploit de GeoHot usando Linux26 de enero de 2010Firmware 3.21: Todos sin Linux28 de marzo de 2010PS JailBreak: 1er Cargador USB18 de agosto de 2010EpicFail: Anuncio de carga sin USB y firmado de ejecutables29 de diciembre de 2010GeoHot hace pública la clave raíz3 de enero de 2011Y la historia continúa…
Arquitectura de la PS3
Conocimientos técnicos necesarios
Conocimientos previosBuffer overflowProtocolo USBArbitraje centralizado por el hostTamaño de paquetes variableMarcado por el hostSolicitado por el dispositivoConfiguraciones, interfaces y endpoints
PSJailbreak (y clones)Buffer overflow en lv2Consigue ejecutar código a nivel del kernelNo W^X en lv2HV da páginas ejecutables “con alegría”
PSJailbreak (y clones)Resultado:GameOS comprometidoLV1 no comprometidoSPE para seguridad no comprometidoPero tenemos pirateríaRompiendo el 20% del sistema de seguridad, tenemos el 100% de lo que Sony quería evitar
Fallo de seguridadLV1 no se encarga de asegurar a LV2 la integridad del juegoCon acceso a LV2 podemos quitar la protección
PSJailbreakAnálisis que sigue usando principalmente PSGrooveDos fasesConseguir acceso al SOCambiar su comportamiento
PSJailbreak: accediendo a lv2// Descriptor del dispositivo USB. Es el primero que// se envía.const uint8_t PROGMEM HUB_Device_Descriptor[] = {  0x12, // Longitud del paquete (18 bytes)  0x01, // Identificador cte: "device descriptor"  0x00, 0x02, // Versión de usb soportada: 02.00 (BCD)  0x09, // Deviceclass (usb.org) -> HUB        // http://www.usb.org/developers/defined_class/#BaseClass09h  0x00, // Devicesubclass (usb.org) \  0x01, // Codigo protocolo (usb.org)/\Hi-speedhubwith single TT  0x08, // Tam. máximo de paquete del zeroendpoint  0xAA, 0xAA, // Vendor id (supuestamente asignado por usb.org)  0xCC, 0xCC, // Product id (supuestamente asignado por usb.org)  0x00, 0x01, // Devicereleasenumber 01.00 (BCD)  0x00, // Index of ManufacturerString Descriptor  0x00, // Index of ProductString Descriptor  0x00, // Index of Serial NumberString Descriptor  0x01, // Number of PossibleConfigurations};
PSJailbreak: accediendo a lv2const uint8_t PROGMEM HUB_Config_Descriptor[] = {  // Config  0x09, // Long de la parte de configuración  0x02, // Constante indicando lo que somos  0x19, 0x00 // Tamaño total de toda la info, incluyendo interfaz y endpoint  0x01, // Numero de interfaces  0x01, // id de esta configuracion  0x00, // indice a la cadena que la describe (no hay)  0xe0, // Atributos: selfpowered y wakeup  0x32, // Consumo máximo 0x32*2mA = 100mA  // Interface  0x09, // long de la descr. del interfaz  0x04, // cte.  0x00, // número de interfaz  0x00, // valor para alternatesetting :?  0x01, // número de endpoints  0x09, 0x00, 0x00, // classcode, subclasscode, protocolcode                    // este es "Full speedHub"  0x00, // index of String Descriptor Describingthis interface  // Endpoint (interrupt in) ID 1 (el id 0 es siempre de control)  0x07, // long  0x05, // cte.   0x81, // mapa bits: dirección "IN", id 1  0x03, // mapa bits: tipo de transmisión por interrupción  0x01, 0x00, // tammaximo del paquete que manejamos  0x0c, // intervalo de tiempo para polling en frame-time (125micro secs.)        // => 1500microsecs.};
PSJailbreak: accediendo a lv2const uint8_t PROGMEM HUB_Hub_Descriptor[] = {  0x09, // Longitud  0x29, // Cte.  0x06, // Número de puertos del HUB: 6  0xa9, 0x00 // Flags. 10101001b:        //  D1,D0 (01) Indican el powerswitching de los dispostivos        //     que se conectan => Individual portpowerswitching.        //  D2 (0): Hubisnotpart of a compounddevice.        //  D4:D3 (01): Individual portover-currentprotection.        //     El hub controla problemas de corriente de cada puerto        //     de forma individual        //  D15:D5: reservados  0x05, //  Tiempo (en 2ms intervals) que tarda la secuencia power-on de        //  un dispositivo conectado desde que éste tiene corriente.        //  Básicamante indica el retardo que sufre la corriente en llegar        //  al puerto/dispositivo conectado.  0x64, // Corriente máxima necesitada por el controlador del HUB.  0x00, // Flags, un bit por puerto posible: todos los puertos son        // desenganchables (es decir, es un hub de verdad, no un hub en        // un dispositivo integrado que tiene varios dispositivos "en uno")  0xff, // En usb 2.0 mantener a 0xFF este valor.};
PSJailbreak: accediendo a lv2const uint8_t PROGMEM port1_device_descriptor[] = {  0x12, // Long del paquete (18)  0x01, // Constante (01 = device descriptor)  0x00, 0x02, // USB 2.0 compliant (BCD)  0x00, // Classcode. 0 indica que cada interfaz dará el suyo  0x00, 0x00, // Subclase y protocolo  0x08, // Max packetsize  0xAA, 0xAA, // Vendor ID  0x55, 0x55, // Product id  0x00, 0x00, // Devicereleasenumber  0x00, // Index of ManufacturerString Descriptor  0x00, // Index of ProductString Descriptor  0x00, // Index of Serial NumberString Descriptor  PORT1_NUM_CONFIGS, // 4};
PSJailbreak: accediendo a lv2// Primera contestación de la configuración del port1. La utilizaremos// cuando en la petición sólo podemos contestar con 8 bytes// y le diremos que necesitamos muchos más (las dos// constantes). El host contestará tras pedir esa memoria y// utilizaremos entonces port1_config_descriptor.const uint8_t PROGMEM port1_short_config_descriptor[] = {  // Config  0x09, // Longitud del paquete  0x02, // Constante 0x02: configurationdescription  PORT1_DESC_LEN_LO, PORT1_DESC_LEN_HI, // Bytes totales devueltos        // (o que necesitamos...) que incluyen el resto de información        // (interfaces y endpoints)  0x01, // Número de interfaces  0x00, // id de esta configuración (¿no habría que cambiarla?)  0x00, // id cadena explicativa  0x80, // bitmap: notselfpowered, notremotewakeup  0xfa, // max consumo energia (* 2mA = 500mA)  // Y aquí vendrían interface y endpoint};
PSJailbreak: accediendo a lv2// Versión "larga" de la configuración, distinta de la corta// para el exploitconst uint8_t PROGMEM port1_config_descriptor[] = {  // Config  0x09, // Longitud del paquete  0x02, // Constante  0x12, 0x00, // Tamaño total que enviamos. ¡EXPLOIT!   ...  // Interfaz  0x09, // Longitu del paquete  0x04, // Cte. de protocolo  0x00, // Número de interfaz  0x00, // Alternatesetting...  0x00, // Endpoints disponibles: 0. No hay más info después  0xfe, 0x01, 0x02, // Clase - subclase - protocolo. Tiene que ver con		    // firmware updates, pero el 0x02 no tiene		    // sentido.  0x00, // String explicativa  // TODO ESTO ES OVERFLOW QUE NOS GUARDARÁ LA PS3 PARA USAR LUEGO  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // padding	MAGIC_NUMBER,default_payload_macro,};
PSJailbreak: accediendo a lv2const uint8_t PROGMEM port2_device_descriptor[] = {  0x12, 0x01, // Longitud y constante  0x00, 0x02, // USB 2.0  0x00, 0x00, 0x00, // Class, subclass, protocol  0x08, // maxpacketsize  0xAA, 0xAA, 0xBB, 0xBB, // Vendor y product id  0x00, 0x00, // Releasenumber  0x00, 0x00, 0x00, // Indices a 3 stringdescriptors  0x01, // Número de configuraciones};
PSJailbreak: accediendo a lv2const uint8_t PROGMEM port2_config_descriptor[] = {  // config  0x09, // Longitud de la configuración.  0x02, // Cte.  0x16, 0x00 // Longitud total, incluyendo interfaz etc. Se dice que	     // son 22 bytes, aunque la info real según el protocolo	     // son 18. Le metemos 4 más que harán un trabajo importante...  0x01, // Número interfaces  0x01, // id de la configuración  0x00, // stringindex  0x80, // notselfpowered, notremotewakeup  0x01, // maxpower 2mA.  // interface  0x09, 0x04, // Long y cte.  0x00, // número de interfaz  0x00, // alternatesetting  0x00, // Número de endpoints  0xFE, 0x01, 0x02, // Classcode, subclass y protocolo.  0x00, // String descriptor.  // extra  0x04, 0x21, 0xb4, 0x2f,};
PSJailbreak: accediendo a lv2const uint8_t PROGMEM port3_device_descriptor[] = {  0x12, 0x01, // Longitud y constante  0x00, 0x02, // USB 2.0  0x00, 0x00, 0x00, // Class, subclass, protocol  0x08, // maxpacketsize  0xAA, 0xAA, 0x55, 0x55, // Vendor y product id  0x00, 0x00, // Releasenumber  0x00, 0x00, 0x00, // Indices a 3 stringdescriptors  0x02, // Número de configuraciones};
PSJailbreak: accediendo a lv2const uint8_t PROGMEM port3_config_descriptor[] = {  0x09, 0x02, 0x4d, 0x0a, 0x01, 0x01, 0x00, 0x80, 0x01,  0x09, 0x04, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x02, 0x00,  0x09, 0x04, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x02, 0x00,   … (más de 2Kb después…) 0x09, 0x04, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x02, 0x00,  0x09, 0x04, 0x00, 0x00, 0x00, 0xfe, 0x00, 0xfe, 0x01, 0x02, 0x00,  0x09, 0x04, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x02,};
PSJailbreak: accediendo a lv2Desconexióndeldispositivo 2…… y seguimos
PSJailbreak: accediendo a lv2const uint8_t PROGMEM port4_device_descriptor[] = {  0x12, 0x01, // Longitud y constante  0x00, 0x02, // USB 2.0  0x00, 0x00, 0x00, // Class, subclass, protocol  0x08, // max packet size  0xAA, 0xAA, 0x55, 0x55, // Vendor y product id  0x00, 0x00, // Release number  0x00, 0x00, 0x00, // Indices a 3 string descriptors  0x03, // Número de configuraciones};
PSJailbreak: accediendo a lv2const uint8_t PROGMEM port4_config_descriptor_1[] = {  // Config  0x09, // Longituddelpaquete  0x02, // Constante  0x12, 0x00, // Tamaño total que enviamos.  0x01, // Número de interfaces  0x01, // id de estaconfiguración  0x00, // id de cadenaexplicativa...  0x80, // bitmap: not self powered, not remotewakeup  0x01, // Consumomáximo, 2mA  // Interfaz  0x09, // Longitudelpaquete  0x04, // Cte. de protocolo  0x00, // Número de interfaz  0x00, // Alternate setting...  0x00, // Endpoints disponibles: 0. No haymás info después  0xfe, 0x01, 0x02, // Clase - subclase – protocolo  0x00, // String explicativa};
PSJailbreak: accediendo a lv2const uint8_t PROGMEM port4_short_config_descriptor_2[] = {	// config  0x09, // Long delpaquete  0x02, // Cte.  0x12, 0x00, // Tamaño total que enviamos; no entra, así que nos	      // pedirán la config otravezcuandotenganhueco.  0x01, // Número de interfaces  0x01, // id de esta config  0x00, // id la cadena  0x80, // not self powered, not remotewakeup  // y se acabó; deberían venir más, peroenviamos solo 8.};
PSJailbreak: accediendo a lv2const uint8_t PROGMEM port4_config_descriptor_2[] = {  // config  0x09,  // Long delpaquete  0x02, // Cte.  0x00, 0x00, // ¡EXPLOIT! ¡Ahora le decimos que no vamos a enviar	      // nada! (esto es el tamaño total que enviamos, según	      // debeinterpretarlo el protocolo USB.)  0x01, // Número de interfaces  0x01, // id de la configuracion  0x00, // id de la cadena  0x80, // Not self powered, not remotewakeup  0x01, // Consumomáximo, 2mA  // interface  0x09, // Longitudelpaquete  0x04, // Ctedelprotocolo  0x00, // número de interfaz  0x00, // alternate setting  0x00, // endpoints disponibles (0, no viene nada luego)  0xfe, 0x01, 0x02, // Clase - subclase - protocolo (DFU)  0x00, // String explicativo};
PSJailbreak: accediendo a lv2const uint8_t PROGMEM port4_config_descriptor_3[] = {  // config	0x09, 0x02, 0x30, 0x00, 0x01, 0x01, 0x00, 0x80, 0x01, 	// interface	0x09, 0x04, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x02, 0x00, 	// extra	0x3e, 0x21, 0x00, 0x00, 0x00, 0x00, // padding	MAGIC_NUMBER, /* magicnumber to look for in the start of the page */	SHELLCODE_PAGE, /* Initial data searchptr */	SHELLCODE_DESTINATION, /* destination ptr for heap structure (jigresponse) */};
PSJailbreak: accediendo a lv2const uint8_t PROGMEM port5_device_descriptor[] = {  0x12, 0x01, // Longitud y constante  0x00, 0x02, // USB 2.0  0x00, 0x00, 0x00, // Class, subclass, protocol  0x08, // max packet size  0x4c, 0x05, // Vendor id: Sony Corp  0xeb, 0x02, // Product id: JIG. No publicado  0x00, 0x00, // Release number  0x00, 0x00, 0x00, // Indices a 3 string descriptors  0x01, // Número de configuraciones};
PSJailbreak: accediendo a lv2const uint8_t PROGMEM port5_config_descriptor[] = {	// config	0x09, 0x02, 0x20, 0x00, 0x01, 0x00, 0x00, 0x80,	0x01,	// interface	0x09, 0x04, 0x00, 0x00, 0x02, 0xff, 0x00, 0x00,	0x00,	// endpoint	0x07, 0x05, 0x02, 0x02, 0x08, 0x00, 0x00,	// endpoint	0x07, 0x05, 0x81, 0x02, 0x08, 0x00, 0x00,}
PSJailbreak: accediendo a lv2const uint8_t PROGMEM jig_response[64] = {	SHELLCODE_PTR,	SHELLCODE_ADDRESS,	RTOC_TABLE,default_shellcode_macro,};
PSJailbreak: accediendo a lv2Y desenganchamos el dispositivo 3…; shellcode / egghunter ROM:00000018                 ld      %r4, -0x10(%r3) ROM:0000001C                 ld      %r3, -8(%r3) ROM:00000020 ROM:00000020 loc_20: ROM:00000020                 ld      %r5, 0x18(%r3) ROM:00000024                 addi    %r3, %r3, 0x1000 ROM:00000028                 cmpw    %r4, %r5 ROM:0000002C                 bne     loc_20 ROM:00000030                 addi    %r6, %r3, -0xFE0 ROM:00000034                 mtctr   %r6 ROM:00000038                 bctr
PSJailbreak: cambiando el SOPayloadTranslación a zona de memoria seguraCopia de parte del payload a zona residenteInstalación de un driver de USB: “prueba”, “inicialización”, “desconexión”.Syscall 36HooksHook_open
PSJailbreak: cambiando el SO“Guerra” de payloadsClones de PSJailbreakBackup managersAplicaciones homebrew…
ConclusionesCon la clave privada puedes firmar cosas…Homebrew sin payloadActualizaciones…
Wanna dance?Marco Antonio Gómez y Federico Peinadowww.gueim.org

¿Que falló en Playstation 3?

  • 1.
    ¿Qué falló enPlaystation 3?Piratería, seguridad informática y el mercado de las videoconsolasMarco Antonio Gómezy Federico PeinadoMáster en Desarrollo de Videojuegos Universidad Complutense de Madridwww.videojuegos-ucm.eswww.gueim.org
  • 3.
    El apagón dePlayStation NetworkSuspensión total del servicio en el mundo20 de abril de 2011 – ActualidadMás de 77 millones de usuariosAfectando incluso a algunos juegos offlinePérdidas de cientos de miles o incluso millones de dólares a empresas (Capcom) Suspensión relacionada de plataforma PC 2 de mayo de 2011 – Actualidad Sony Online Entertainment (MMOGs)Más de 24 millones de usuarios(aunque casi sin afectar a tarjetas de crédito)Motivo: Intrusiones externas Del 16 al 19 de abril de 2011 Datos comprometidos de identificación personal, contraseñas y tarjetas de créditoContinúa la investigación…
  • 4.
    Copiar o nocopiarContenidos digitales: ¡llega la copia sin pérdida!Sistemas anticopiaHardware (libros de claves, cartuchos, “mochilas”, etc.)Software (errores esperados, número de copias, SecuROM y otros DRMs, etc.)Internet y la WebDescargas masivas, difusión del homebrew, etc.Activación remota, rootkits, contenido en la nube, etc.
  • 5.
    La caída dela PS3erk: C0 CE FE 84 C2 27 F7 5B D0 7A 7E B8 46 50 9F 93 B2 38 E7 70 DA CB 9F F4 A3 88 F8 12 48 2B E2 1Briv: 47 EE 74 54 E4 77 4C C9 B8 96 0C 7B 59 F4 C1 4Dpub: C2 D4 AA F3 19 35 50 19 AF 99 D4 4E 2B 58 CA 29 25 2C 89 12 3D 11 D6 21 8F 40 B1 38 CA B2 9B 71 01 F3 AE B7 2A 97 50 19R: 80 6E 07 8F A1 52 97 90 CE 1A AE 02 BA DD 6F AA A6 AF 74 17n: E1 3A 7E BC 3A CC EB 1C B5 6C C8 60 FC AB DB 6A 04 8C 55 E1K: BA 90 55 91 68 61 B9 77 ED CB ED 92 00 50 92 F6 6C 7A 3D 8DDa: C5 B2 BF A1 A4 13 DD 16 F2 6D 31 C0 F2 ED 47 20 DC FB 06 70Lanzamiento (Japón)11 de noviembre de 2006Modelo “slim” sin Linux1 de septiembre de 2009Exploit de GeoHot usando Linux26 de enero de 2010Firmware 3.21: Todos sin Linux28 de marzo de 2010PS JailBreak: 1er Cargador USB18 de agosto de 2010EpicFail: Anuncio de carga sin USB y firmado de ejecutables29 de diciembre de 2010GeoHot hace pública la clave raíz3 de enero de 2011Y la historia continúa…
  • 6.
    La caída dela PS3erk: C0 CE FE 84 C2 27 F7 5B D0 7A 7E B8 46 50 9F 93 B2 38 E7 70 DA CB 9F F4 A3 88 F8 12 48 2B E2 1Briv: 47 EE 74 54 E4 77 4C C9 B8 96 0C 7B 59 F4 C1 4Dpub: C2 D4 AA F3 19 35 50 19 AF 99 D4 4E 2B 58 CA 29 25 2C 89 12 3D 11 D6 21 8F 40 B1 38 CA B2 9B 71 01 F3 AE B7 2A 97 50 19R: 80 6E 07 8F A1 52 97 90 CE 1A AE 02 BA DD 6F AA A6 AF 74 17n: E1 3A 7E BC 3A CC EB 1C B5 6C C8 60 FC AB DB 6A 04 8C 55 E1K: BA 90 55 91 68 61 B9 77 ED CB ED 92 00 50 92 F6 6C 7A 3D 8DDa: C5 B2 BF A1 A4 13 DD 16 F2 6D 31 C0 F2 ED 47 20 DC FB 06 70Lanzamiento (Japón)11 de noviembre de 2006Modelo “slim” sin Linux1 de septiembre de 2009Exploit de GeoHot usando Linux26 de enero de 2010Firmware 3.21: Todos sin Linux28 de marzo de 2010PS JailBreak: 1er Cargador USB18 de agosto de 2010EpicFail: Anuncio de carga sin USB y firmado de ejecutables29 de diciembre de 2010GeoHot hace pública la clave raíz3 de enero de 2011Y la historia continúa…La mayoría de las transparencias que siguen son directamente las de esta charla
  • 17.
    La caída dela PS3erk: C0 CE FE 84 C2 27 F7 5B D0 7A 7E B8 46 50 9F 93 B2 38 E7 70 DA CB 9F F4 A3 88 F8 12 48 2B E2 1Briv: 47 EE 74 54 E4 77 4C C9 B8 96 0C 7B 59 F4 C1 4Dpub: C2 D4 AA F3 19 35 50 19 AF 99 D4 4E 2B 58 CA 29 25 2C 89 12 3D 11 D6 21 8F 40 B1 38 CA B2 9B 71 01 F3 AE B7 2A 97 50 19R: 80 6E 07 8F A1 52 97 90 CE 1A AE 02 BA DD 6F AA A6 AF 74 17n: E1 3A 7E BC 3A CC EB 1C B5 6C C8 60 FC AB DB 6A 04 8C 55 E1K: BA 90 55 91 68 61 B9 77 ED CB ED 92 00 50 92 F6 6C 7A 3D 8DDa: C5 B2 BF A1 A4 13 DD 16 F2 6D 31 C0 F2 ED 47 20 DC FB 06 70Lanzamiento (Japón)11 de noviembre de 2006Modelo “slim” sin Linux1 de septiembre de 2009Exploit de GeoHot usando Linux26 de enero de 2010Firmware 3.21: Todos sin Linux28 de marzo de 2010PS JailBreak: 1er Cargador USB18 de agosto de 2010EpicFail: Anuncio de carga sin USB y firmado de ejecutables29 de diciembre de 2010GeoHot hace pública la clave raíz3 de enero de 2011Y la historia continúa…
  • 28.
  • 32.
  • 33.
    Conocimientos previosBuffer overflowProtocoloUSBArbitraje centralizado por el hostTamaño de paquetes variableMarcado por el hostSolicitado por el dispositivoConfiguraciones, interfaces y endpoints
  • 34.
    PSJailbreak (y clones)Bufferoverflow en lv2Consigue ejecutar código a nivel del kernelNo W^X en lv2HV da páginas ejecutables “con alegría”
  • 35.
    PSJailbreak (y clones)Resultado:GameOScomprometidoLV1 no comprometidoSPE para seguridad no comprometidoPero tenemos pirateríaRompiendo el 20% del sistema de seguridad, tenemos el 100% de lo que Sony quería evitar
  • 36.
    Fallo de seguridadLV1no se encarga de asegurar a LV2 la integridad del juegoCon acceso a LV2 podemos quitar la protección
  • 37.
    PSJailbreakAnálisis que sigueusando principalmente PSGrooveDos fasesConseguir acceso al SOCambiar su comportamiento
  • 38.
    PSJailbreak: accediendo alv2// Descriptor del dispositivo USB. Es el primero que// se envía.const uint8_t PROGMEM HUB_Device_Descriptor[] = { 0x12, // Longitud del paquete (18 bytes) 0x01, // Identificador cte: "device descriptor" 0x00, 0x02, // Versión de usb soportada: 02.00 (BCD) 0x09, // Deviceclass (usb.org) -> HUB // http://www.usb.org/developers/defined_class/#BaseClass09h 0x00, // Devicesubclass (usb.org) \ 0x01, // Codigo protocolo (usb.org)/\Hi-speedhubwith single TT 0x08, // Tam. máximo de paquete del zeroendpoint 0xAA, 0xAA, // Vendor id (supuestamente asignado por usb.org) 0xCC, 0xCC, // Product id (supuestamente asignado por usb.org) 0x00, 0x01, // Devicereleasenumber 01.00 (BCD) 0x00, // Index of ManufacturerString Descriptor 0x00, // Index of ProductString Descriptor 0x00, // Index of Serial NumberString Descriptor 0x01, // Number of PossibleConfigurations};
  • 39.
    PSJailbreak: accediendo alv2const uint8_t PROGMEM HUB_Config_Descriptor[] = { // Config 0x09, // Long de la parte de configuración 0x02, // Constante indicando lo que somos 0x19, 0x00 // Tamaño total de toda la info, incluyendo interfaz y endpoint 0x01, // Numero de interfaces 0x01, // id de esta configuracion 0x00, // indice a la cadena que la describe (no hay) 0xe0, // Atributos: selfpowered y wakeup 0x32, // Consumo máximo 0x32*2mA = 100mA // Interface 0x09, // long de la descr. del interfaz 0x04, // cte. 0x00, // número de interfaz 0x00, // valor para alternatesetting :? 0x01, // número de endpoints 0x09, 0x00, 0x00, // classcode, subclasscode, protocolcode // este es "Full speedHub" 0x00, // index of String Descriptor Describingthis interface // Endpoint (interrupt in) ID 1 (el id 0 es siempre de control) 0x07, // long 0x05, // cte. 0x81, // mapa bits: dirección "IN", id 1 0x03, // mapa bits: tipo de transmisión por interrupción 0x01, 0x00, // tammaximo del paquete que manejamos 0x0c, // intervalo de tiempo para polling en frame-time (125micro secs.) // => 1500microsecs.};
  • 40.
    PSJailbreak: accediendo alv2const uint8_t PROGMEM HUB_Hub_Descriptor[] = { 0x09, // Longitud 0x29, // Cte. 0x06, // Número de puertos del HUB: 6 0xa9, 0x00 // Flags. 10101001b: // D1,D0 (01) Indican el powerswitching de los dispostivos // que se conectan => Individual portpowerswitching. // D2 (0): Hubisnotpart of a compounddevice. // D4:D3 (01): Individual portover-currentprotection. // El hub controla problemas de corriente de cada puerto // de forma individual // D15:D5: reservados 0x05, // Tiempo (en 2ms intervals) que tarda la secuencia power-on de // un dispositivo conectado desde que éste tiene corriente. // Básicamante indica el retardo que sufre la corriente en llegar // al puerto/dispositivo conectado. 0x64, // Corriente máxima necesitada por el controlador del HUB. 0x00, // Flags, un bit por puerto posible: todos los puertos son // desenganchables (es decir, es un hub de verdad, no un hub en // un dispositivo integrado que tiene varios dispositivos "en uno") 0xff, // En usb 2.0 mantener a 0xFF este valor.};
  • 41.
    PSJailbreak: accediendo alv2const uint8_t PROGMEM port1_device_descriptor[] = { 0x12, // Long del paquete (18) 0x01, // Constante (01 = device descriptor) 0x00, 0x02, // USB 2.0 compliant (BCD) 0x00, // Classcode. 0 indica que cada interfaz dará el suyo 0x00, 0x00, // Subclase y protocolo 0x08, // Max packetsize 0xAA, 0xAA, // Vendor ID 0x55, 0x55, // Product id 0x00, 0x00, // Devicereleasenumber 0x00, // Index of ManufacturerString Descriptor 0x00, // Index of ProductString Descriptor 0x00, // Index of Serial NumberString Descriptor PORT1_NUM_CONFIGS, // 4};
  • 42.
    PSJailbreak: accediendo alv2// Primera contestación de la configuración del port1. La utilizaremos// cuando en la petición sólo podemos contestar con 8 bytes// y le diremos que necesitamos muchos más (las dos// constantes). El host contestará tras pedir esa memoria y// utilizaremos entonces port1_config_descriptor.const uint8_t PROGMEM port1_short_config_descriptor[] = { // Config 0x09, // Longitud del paquete 0x02, // Constante 0x02: configurationdescription PORT1_DESC_LEN_LO, PORT1_DESC_LEN_HI, // Bytes totales devueltos // (o que necesitamos...) que incluyen el resto de información // (interfaces y endpoints) 0x01, // Número de interfaces 0x00, // id de esta configuración (¿no habría que cambiarla?) 0x00, // id cadena explicativa 0x80, // bitmap: notselfpowered, notremotewakeup 0xfa, // max consumo energia (* 2mA = 500mA) // Y aquí vendrían interface y endpoint};
  • 43.
    PSJailbreak: accediendo alv2// Versión "larga" de la configuración, distinta de la corta// para el exploitconst uint8_t PROGMEM port1_config_descriptor[] = { // Config 0x09, // Longitud del paquete 0x02, // Constante 0x12, 0x00, // Tamaño total que enviamos. ¡EXPLOIT! ... // Interfaz 0x09, // Longitu del paquete 0x04, // Cte. de protocolo 0x00, // Número de interfaz 0x00, // Alternatesetting... 0x00, // Endpoints disponibles: 0. No hay más info después 0xfe, 0x01, 0x02, // Clase - subclase - protocolo. Tiene que ver con // firmware updates, pero el 0x02 no tiene // sentido. 0x00, // String explicativa // TODO ESTO ES OVERFLOW QUE NOS GUARDARÁ LA PS3 PARA USAR LUEGO 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // padding MAGIC_NUMBER,default_payload_macro,};
  • 44.
    PSJailbreak: accediendo alv2const uint8_t PROGMEM port2_device_descriptor[] = { 0x12, 0x01, // Longitud y constante 0x00, 0x02, // USB 2.0 0x00, 0x00, 0x00, // Class, subclass, protocol 0x08, // maxpacketsize 0xAA, 0xAA, 0xBB, 0xBB, // Vendor y product id 0x00, 0x00, // Releasenumber 0x00, 0x00, 0x00, // Indices a 3 stringdescriptors 0x01, // Número de configuraciones};
  • 45.
    PSJailbreak: accediendo alv2const uint8_t PROGMEM port2_config_descriptor[] = { // config 0x09, // Longitud de la configuración. 0x02, // Cte. 0x16, 0x00 // Longitud total, incluyendo interfaz etc. Se dice que // son 22 bytes, aunque la info real según el protocolo // son 18. Le metemos 4 más que harán un trabajo importante... 0x01, // Número interfaces 0x01, // id de la configuración 0x00, // stringindex 0x80, // notselfpowered, notremotewakeup 0x01, // maxpower 2mA. // interface 0x09, 0x04, // Long y cte. 0x00, // número de interfaz 0x00, // alternatesetting 0x00, // Número de endpoints 0xFE, 0x01, 0x02, // Classcode, subclass y protocolo. 0x00, // String descriptor. // extra 0x04, 0x21, 0xb4, 0x2f,};
  • 46.
    PSJailbreak: accediendo alv2const uint8_t PROGMEM port3_device_descriptor[] = { 0x12, 0x01, // Longitud y constante 0x00, 0x02, // USB 2.0 0x00, 0x00, 0x00, // Class, subclass, protocol 0x08, // maxpacketsize 0xAA, 0xAA, 0x55, 0x55, // Vendor y product id 0x00, 0x00, // Releasenumber 0x00, 0x00, 0x00, // Indices a 3 stringdescriptors 0x02, // Número de configuraciones};
  • 47.
    PSJailbreak: accediendo alv2const uint8_t PROGMEM port3_config_descriptor[] = { 0x09, 0x02, 0x4d, 0x0a, 0x01, 0x01, 0x00, 0x80, 0x01, 0x09, 0x04, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x02, 0x00, 0x09, 0x04, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x02, 0x00, … (más de 2Kb después…) 0x09, 0x04, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x02, 0x00, 0x09, 0x04, 0x00, 0x00, 0x00, 0xfe, 0x00, 0xfe, 0x01, 0x02, 0x00, 0x09, 0x04, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x02,};
  • 48.
    PSJailbreak: accediendo alv2Desconexióndeldispositivo 2…… y seguimos
  • 49.
    PSJailbreak: accediendo alv2const uint8_t PROGMEM port4_device_descriptor[] = { 0x12, 0x01, // Longitud y constante 0x00, 0x02, // USB 2.0 0x00, 0x00, 0x00, // Class, subclass, protocol 0x08, // max packet size 0xAA, 0xAA, 0x55, 0x55, // Vendor y product id 0x00, 0x00, // Release number 0x00, 0x00, 0x00, // Indices a 3 string descriptors 0x03, // Número de configuraciones};
  • 50.
    PSJailbreak: accediendo alv2const uint8_t PROGMEM port4_config_descriptor_1[] = { // Config 0x09, // Longituddelpaquete 0x02, // Constante 0x12, 0x00, // Tamaño total que enviamos. 0x01, // Número de interfaces 0x01, // id de estaconfiguración 0x00, // id de cadenaexplicativa... 0x80, // bitmap: not self powered, not remotewakeup 0x01, // Consumomáximo, 2mA // Interfaz 0x09, // Longitudelpaquete 0x04, // Cte. de protocolo 0x00, // Número de interfaz 0x00, // Alternate setting... 0x00, // Endpoints disponibles: 0. No haymás info después 0xfe, 0x01, 0x02, // Clase - subclase – protocolo 0x00, // String explicativa};
  • 51.
    PSJailbreak: accediendo alv2const uint8_t PROGMEM port4_short_config_descriptor_2[] = { // config 0x09, // Long delpaquete 0x02, // Cte. 0x12, 0x00, // Tamaño total que enviamos; no entra, así que nos // pedirán la config otravezcuandotenganhueco. 0x01, // Número de interfaces 0x01, // id de esta config 0x00, // id la cadena 0x80, // not self powered, not remotewakeup // y se acabó; deberían venir más, peroenviamos solo 8.};
  • 52.
    PSJailbreak: accediendo alv2const uint8_t PROGMEM port4_config_descriptor_2[] = { // config 0x09, // Long delpaquete 0x02, // Cte. 0x00, 0x00, // ¡EXPLOIT! ¡Ahora le decimos que no vamos a enviar // nada! (esto es el tamaño total que enviamos, según // debeinterpretarlo el protocolo USB.) 0x01, // Número de interfaces 0x01, // id de la configuracion 0x00, // id de la cadena 0x80, // Not self powered, not remotewakeup 0x01, // Consumomáximo, 2mA // interface 0x09, // Longitudelpaquete 0x04, // Ctedelprotocolo 0x00, // número de interfaz 0x00, // alternate setting 0x00, // endpoints disponibles (0, no viene nada luego) 0xfe, 0x01, 0x02, // Clase - subclase - protocolo (DFU) 0x00, // String explicativo};
  • 53.
    PSJailbreak: accediendo alv2const uint8_t PROGMEM port4_config_descriptor_3[] = { // config 0x09, 0x02, 0x30, 0x00, 0x01, 0x01, 0x00, 0x80, 0x01, // interface 0x09, 0x04, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x02, 0x00, // extra 0x3e, 0x21, 0x00, 0x00, 0x00, 0x00, // padding MAGIC_NUMBER, /* magicnumber to look for in the start of the page */ SHELLCODE_PAGE, /* Initial data searchptr */ SHELLCODE_DESTINATION, /* destination ptr for heap structure (jigresponse) */};
  • 54.
    PSJailbreak: accediendo alv2const uint8_t PROGMEM port5_device_descriptor[] = { 0x12, 0x01, // Longitud y constante 0x00, 0x02, // USB 2.0 0x00, 0x00, 0x00, // Class, subclass, protocol 0x08, // max packet size 0x4c, 0x05, // Vendor id: Sony Corp 0xeb, 0x02, // Product id: JIG. No publicado 0x00, 0x00, // Release number 0x00, 0x00, 0x00, // Indices a 3 string descriptors 0x01, // Número de configuraciones};
  • 55.
    PSJailbreak: accediendo alv2const uint8_t PROGMEM port5_config_descriptor[] = { // config 0x09, 0x02, 0x20, 0x00, 0x01, 0x00, 0x00, 0x80, 0x01, // interface 0x09, 0x04, 0x00, 0x00, 0x02, 0xff, 0x00, 0x00, 0x00, // endpoint 0x07, 0x05, 0x02, 0x02, 0x08, 0x00, 0x00, // endpoint 0x07, 0x05, 0x81, 0x02, 0x08, 0x00, 0x00,}
  • 56.
    PSJailbreak: accediendo alv2const uint8_t PROGMEM jig_response[64] = { SHELLCODE_PTR, SHELLCODE_ADDRESS, RTOC_TABLE,default_shellcode_macro,};
  • 57.
    PSJailbreak: accediendo alv2Y desenganchamos el dispositivo 3…; shellcode / egghunter ROM:00000018 ld %r4, -0x10(%r3) ROM:0000001C ld %r3, -8(%r3) ROM:00000020 ROM:00000020 loc_20: ROM:00000020 ld %r5, 0x18(%r3) ROM:00000024 addi %r3, %r3, 0x1000 ROM:00000028 cmpw %r4, %r5 ROM:0000002C bne loc_20 ROM:00000030 addi %r6, %r3, -0xFE0 ROM:00000034 mtctr %r6 ROM:00000038 bctr
  • 58.
    PSJailbreak: cambiando elSOPayloadTranslación a zona de memoria seguraCopia de parte del payload a zona residenteInstalación de un driver de USB: “prueba”, “inicialización”, “desconexión”.Syscall 36HooksHook_open
  • 59.
    PSJailbreak: cambiando elSO“Guerra” de payloadsClones de PSJailbreakBackup managersAplicaciones homebrew…
  • 69.
    ConclusionesCon la claveprivada puedes firmar cosas…Homebrew sin payloadActualizaciones…
  • 70.
    Wanna dance?Marco AntonioGómez y Federico Peinadowww.gueim.org