Aquí está la información técnica detallada: da.vidbuchanan.co.uk/blog/exploiting-acr…palypse.html
A modo de resumen simplificando e intentando que sea sencillo de entender:
El problema es un bug o un cambio la API de ficheros de Android. Este bug causa que al guardar la versión recortada de la imagen reabre el mismo fichero en modo escritura sin borrado del contenido original (lo que se llama truncado y lo normal en POSIX y como era en Android hasta 10 es que la apertura de escritura sea con truncado por defecto), con lo cual la nueva imagen es más pequeña y como no hubo truncado se mantuvo el resto de bytes del fichero.
Un ejemplo visual, supongamos que tenemos un fichero llamado img.png con contenido: X0 X1 X2 X3 X4 X5 X6 X7 X8 X9
Y ahora lo sobreescribimos para que contenga Y0 Y1 Y2
abriéndolo como escritura y escribiendo el nuevo contenido: open('img.png', 'w').write('Y0 Y1 Y2')
Ahora lo que esperarías es que img.png contenga Y0 Y1 Y2
sin embargo debido al bug en la API de Android lo que tiene img.png es Y0 Y1 Y2 X3 X4 X5 X6 X7 X8 X9
Las cabeceras de PNG y el ZLIB subyacente así como la primera parte de la imagen original están rotas ya que los primeros bytes están sobreescritos por la nueva imagen recortada (en el ejemplo X0 X1 X2
se han perdido), sin embargo extrayendo los bytes restantes del fichero original (en el ejemplo X3 X4 X5 X6 X7 X8 X9
) y con conocimiento del formato consiguen ir extrayendo los bloques PNG y arreglar las cabeceras para recuperar parcialmente el fichero original.
Las recuperaciones siempre se ve que la parte superior de la imagen está en negro o de colorines sin sentido y esto es los bytes que han sido sobreescritos por la versión recortada. Por lo tanto cuanto más cortes (cuanto más pequeña sea la imagen resultante de tu corte) más información de la original es recuperable.