FRP signifie Factory Reset Protection. Il s’agit d’une fonction de protection de Google sur Android qui empêche d’utiliser un téléphone lié à un compte Google après une réinitialisation d’usine si vous ne connaissez pas le mot de passe du compte. Elle semble être l’équivalent du verrouillage d’activation iCloud des iPhones.
$ file SamFwFRPTool.exe SamFwFRPTool.exe: PE32 executable (GUI) Intel 80386 Mono/.Net assembly, for MS Windows
private void btn_EnableAdb_Click(object sender, EventArgs e) { int cur = this.comboPorts.SelectedIndex; bool flag = cur < 0; if (flag) { this.SendLog("No device selected", null, true, true); } else { Task.Run(delegate() { this.progressBarRunning(true); List<Form1.comInfo> list = this.listDevices; Form1.comInfo comInfo = list[cur]; this.SendLog("Using port " + comInfo.name, new Color?(Color.Green), true, true); using (SerialPort serialPort = new SerialPort("COM" + comInfo.comport)) { serialPort.RtsEnable = true; serialPort.DtrEnable = true; serialPort.WriteBufferSize = 921600; try { serialPort.Open(); } catch (UnauthorizedAccessException ex) { this.progressBarRunning(false); this.SendLog(ex.Message, new Color?(Color.Red), false, true); return; } this.SendLog("Initial...", null, true, true); bool flag2 = !this.ATSend(serialPort, "AT+KSTRINGB=0,3\r\n"); if (flag2) { MessageBox.Show("Go to emergency dialer enter *#0*#, click OK when done"); } this.SendLog("Enabling ADB...", null, true, true); this.SendLog("", null, true, true); this.SendLog("Method 1", null, true, true); this.SendLog("Step 1... ", null, true, false); bool flag3 = !this.ATSend(serialPort, "AT+DUMPCTRL=1,0\r\n"); if (flag3) { this.SendLog("FAIL", new Color?(Color.Red), false, true); } else { this.SendLog("OK", new Color?(Color.Green), false, true); } this.SendLog("Step 2... ", null, true, false); bool flag4 = !this.ATSend(serialPort, "AT+DEBUGLVC=0,5\r\n"); if (flag4) { this.SendLog("FAIL", new Color?(Color.Red), false, true); } else { this.SendLog("OK", new Color?(Color.Green), false, true); } this.SendLog("", null, true, true); this.SendLog("Method 2", null, true, true); this.SendLog("Step 1... ", null, true, false); bool flag5 = !this.ATSend(serialPort, "AT+SWATD=0\r\n"); if (flag5) { this.SendLog("FAIL", new Color?(Color.Red), false, true); } else { this.SendLog("OK", new Color?(Color.Green), false, true); } this.SendLog("Step 2... ", null, true, false); bool flag6 = !this.ATSend(serialPort, "AT+ACTIVATE=0,0,0\r\n"); if (flag6) { this.SendLog("FAIL", new Color?(Color.Red), false, true); } else { this.SendLog("OK", new Color?(Color.Green), false, true); } this.SendLog("Step 3... ", null, true, false); bool flag7 = !this.ATSend(serialPort, "AT+SWATD=1\r\n"); if (flag7) { this.SendLog("FAIL", new Color?(Color.Red), false, true); } else { this.SendLog("OK", new Color?(Color.Green), false, true); } this.SendLog("Step 4... ", null, true, false); bool flag8 = !this.ATSend(serialPort, "AT+DEBUGLVC=0,5\r\n"); if (flag8) { this.SendLog("FAIL", new Color?(Color.Red), false, true); } else { this.SendLog("OK", new Color?(Color.Green), false, true); } } this.SendLog("", null, true, true); this.SendLog("Enable ADB done", new Color?(Color.Green), true, true); this.SendLog("Running ADB command to remove FRP lock state...", null, true, true); string exe = Directory.GetCurrentDirectory() + "\\data\\adb.exe"; this.SendLog("Please click to the allow USB Debugging on the screen. If not apprear, unplug and replug the cable", new Color?(Color.BlueViolet), true, true); string text = this.execute(exe, "kill-server"); text = this.execute(exe, "wait-for-device"); text = this.execute(exe, "push frp.bin /data/local/tmp/temp"); text = this.execute(exe, "shell chmod 777 /data/local/tmp/temp"); text = this.execute(exe, "shell /data/local/tmp/temp"); this.SendLog(text, new Color?(Color.Brown), true, true); this.progressBarRunning(false); Process.Start("https://samfw.com"); }); } } private bool ATSend(SerialPort ATPort, string command) { bool flag = !ATPort.IsOpen; bool result; if (flag) { result = false; } else { ATPort.WriteLine(command); string text = ""; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); bool flag4; do { Thread.Sleep(50); bool flag2 = !ATPort.IsOpen; if (flag2) { break; } text = ATPort.ReadExisting(); bool flag3 = text.Contains("\r\nOK\r\n") || text.Contains("\r\nERROR\r\n"); if (flag3) { break; } flag4 = (stopwatch.ElapsedMilliseconds > 3000L); } while (!flag4); Console.WriteLine(text); bool flag5 = text.Contains("\r\nOK\r\n"); result = flag5; } return result; }
Les commandes AT permettent de communiquer avec le module GSM/MODEM du téléphone. Une ressource utile est atcommands.org et leur repo Github ici, car il contient des outils pour extraire toutes les commandes AT d’un firmware Samsung et même d’autres outils pour tester et interagir avec les commandes facilement. Ils fournissent également un outil nommé usbswitch qui peut être utilisé pour mettre un téléphone en mode modem USB sous Linux, qui est le mode nécessaire pour envoyer des commandes AT au téléphone.
D’autres ressources intéressantes concernant les commandes AT :
import usb.core dev = usb.core.find(idVendor=0x04e8, idProduct=0x6860) dev.reset() dev.set_configuration(0x2)
Cependant, pour une raison inconnue, ce code doit être exécuté deux fois pour fonctionner correctement. Les valeurs idVendor et idProduct sont spécifiques aux appareils Samsung et peuvent être trouvées à l’aide de la commande lsusb.
import serial import time ser = serial.Serial("/dev/ttyACM0", baudrate=115200) ser.write("MY_CMD".encode()) # To send a command time.sleep(0.5) r = ser.read_all() # To read the response
ser.write("AT+GMM\r\n".encode()) time.sleep(0.5) print(ser.read_all()) # AT+GMM # SM-G960F # OK
AT+KSTRINGB=0,3 AT+DUMPCTRL=1,0 AT+DEBUGLVC=0,5 AT+SWATD=0 AT+ACTIVATE=0,0,0 AT+SWATD=1 AT+DEBUGLVC=0,5
L’envoi de cet ensemble de commandes AT à l’intérieur du menu *#0*# de la fonctionnalité d’appel d’urgence active le débogage USB.
push frp.bin /data/local/tmp/temp chmod 777 /data/local/tmp/temp /data/local/tmp/temp
Le fichier frp.bin est poussé sur l’appareil, marqué comme executable, puis exécuté.
La commande strings produit le résultat suivant :
$Info: This file is packed with the UPX executable packer http://upx.sf.net $ $Id: UPX 3.94 Copyright (C) 1996-2017 the UPX Team. All Rights Reserved. $
Le binaire est packé avec UPX, donc nous pouvons facilement l’unpacker :
file frp.bin frp.bin: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (GNU/Linux), statically linked, no section header # sudo apt install upx-ucl upx -d frp.bin Ultimate Packer for eXecutables Copyright (C) 1996 - 2020 UPX 3.96 Markus Oberhumer, Laszlo Molnar & John Reiser Jan 23rd 2020 File size Ratio Format Name -------------------- ------ ----------- ----------- 17880 <- 10556 59.04% linux/arm frp.bin Unpacked 1 file. file frp.bin frp.bin: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /system/bin/linker, BuildID[sha1]=4617177c231c2ae12d2ed6bfcb5bf4a325cfd9df, stripped
Maintenant, nous avons la version décompressée, et une fois lancé, les logs de l’outil nous apprennent qu’il s’agit d’Android Service Tool v1.0.2 @Copyright 2013-2017 Justin Davis (amoamare). Après avoir analysé le binaire en utilisant Ghidra, il semble que pour les téléphones ayant la valeur ro.secure=1, il exécute uniquement les commandes suivantes dans un shell adb :
settings put global setup_wizard_has_run 1 settings put secure user_setup_complete 1 content insert --uri content://settings/secure --bind name:s:DEVICE_PROVISIONED --bind value:i:1 content insert --uri content://settings/secure --bind name:s:user_setup_complete --bind value:i:1 content insert --uri content://settings/secure --bind name:s:INSTALL_NON_MARKET_APPS --bind value:i:1 am start -c android.intent.category.HOME -a android.intent.action.MAIN # Wait 5 sec am start -n com.android.settings/com.android.settings.Settings # Wait 5 sec reboot
Au cours de cette analyse, nous avons appris que sur les appareils Samsung, nous pouvons accéder à une deuxième configuration USB qui ouvre une communication série, nous permettant d’envoyer des commandes AT. De plus, certaines combinaisons de commandes AT peuvent conduire à l’activation du débogage USB avant de configurer le téléphone et donc sans activer les options du développeur.
Enfin, en utilisant adb, il est possible de modifier certains paramètres afin de faire croire au téléphone que la configuration suite à une réinitialisation d’usine est terminé. Ceci permet de contourner le FRP puisque la vérification du FRP se fait à la fin de la configuration.