From 1024bf7f6ff1bacb771b63837a246f14afe75da3 Mon Sep 17 00:00:00 2001 From: Syuugo Date: Fri, 24 Nov 2023 00:35:34 +0900 Subject: [PATCH] Refactor --- .gitattributes | 1 + bypass.php | 760 +++++++++++++++--------------- README-zh.md => docs/README-zh.md | 214 ++++----- README.md => docs/README.md | 214 ++++----- 4 files changed, 595 insertions(+), 594 deletions(-) create mode 100644 .gitattributes rename README-zh.md => docs/README-zh.md (85%) rename README.md => docs/README.md (85%) diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..fcadb2c --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text eol=lf diff --git a/bypass.php b/bypass.php index 54e3870..2e32fa9 100644 --- a/bypass.php +++ b/bypass.php @@ -1,380 +1,380 @@ - refreshDeviceList(); - $t = array(); - foreach ($s as $d) { - if ($d["status"] === $a::CONNECT_TYPE_DEVICE) { - $t[] = array($d["serial"], $d["transport"]); - } - } - return $t; -} - -/** - * Formatted Log - * @param $m string optional Message - * @param $c string optional Color - * @param $p string optional Indicator - * @param $t string optional Type (Level) - * @author NekoYuzu (MlgmXyysd) - * @date 2022/03/24 14:50:01 - */ - -function logf(string $m = "", string $c = "", string $p = "-", string $t = "I"): void -{ - switch (strtoupper($c)) { - case "G": - $c = "\033[32m"; - break; - case "R": - $c = "\033[31m"; - break; - case "Y": - $c = "\033[33m"; - break; - default: - $c = ""; - } - switch (strtoupper($t)) { - case "W": - $t = "WARN"; - break; - case "E": - $t = "ERROR"; - break; - case "I": - default: - $t = "INFO"; - } - print(date("[Y-m-d] [H:i:s]") . " [" . $t . "] " . $p . " " . $c . $m . "\033[0m" . PHP_EOL); -} - -/** - * Curl HTTP wrapper function - * @param $url string required Target url - * @param $method string required Request method - * @param $fields array optional Request body - * @param $header array optional Request header - * @param $useForm bool optional Treat request body as urlencoded form - * @return array Curl response - * @author NekoYuzu (MlgmXyysd) - * @date 2023/11/20 23:50:39 - */ - -function http(string $url, string $method, array $fields = array(), array $header = array(), bool $useForm = false): array -{ - if ($useForm) { - $fields = http_build_query($fields); - } - $curl = curl_init(); - curl_setopt_array($curl, array( - CURLOPT_URL => $url, - CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", - CURLOPT_SSL_VERIFYPEER => false, - CURLOPT_SSL_VERIFYHOST => false, - CURLOPT_MAXREDIRS => 10, - CURLOPT_CONNECTTIMEOUT => 2, - CURLOPT_TIMEOUT => 6, - CURLOPT_CUSTOMREQUEST => $method, - CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_POST => $method == "POST", - CURLOPT_POSTFIELDS => $fields, - CURLOPT_HTTPHEADER => $header - )); - - $response = curl_exec($curl); - $info = curl_getinfo($curl); - $info["errno"] = curl_errno($curl); - $info["error"] = curl_error($curl); - $info["request"] = json_encode($fields); - $info["response"] = $response; - curl_close($curl); - return $info; -} - -/** - * HTTP POST wrapper - * @param $_api string required Target endpoint - * @param $data array optional Request body - * @param $header array optional Request header - * @param $useForm bool optional Treat request body as urlencoded form - * @return array Curl response - * @return false Response code is not HTTP 200 OK - * @author NekoYuzu (MlgmXyysd) - * @date 2023/11/20 23:55:41 - */ - -function postApi(string $_api, array $data = array(), array $header = array(), bool $useForm = false): array|false -{ - $response = http($GLOBALS["api"] . $_api, "POST", $data, $header, $useForm); - if ($response["http_code"] != 200) { - return false; - } - return json_decode($response["response"], true); -} - -/** - * Sign data using HMAC SHA-1 - * @param $data string required Data to sign - * @return string Signed hash - * @author NekoYuzu (MlgmXyysd) - * @date 2023/11/21 00:20:56 - */ - -function signData(string $data): string -{ - return strtolower(bin2hex(hash_hmac("sha1", "POST\n/v1/unlock/applyBind\ndata=" . $data . "&sid=miui_sec_android", $GLOBALS["sign_key"], true))); -} - -/** - * Decrypt data using AES/CBC/PKCS5Padding - * @param $data string required Data to decrypt - * @return string Decrypted data - * @return false Failed to decrypt - * @author NekoYuzu (MlgmXyysd) - * @date 2023/11/21 00:15:30 - */ - -function decryptData(string $data): string|false -{ - return openssl_decrypt(base64_decode($data), "AES-128-CBC", $GLOBALS["data_pass"], OPENSSL_RAW_DATA, $GLOBALS["data_iv"]); -} - -/*********************** - * Functions End * - ***********************/ - -/********************** - * Banner Start * - **********************/ - -logf("************************************", "g"); -logf("* Xiaomi HyperOS BootLoader Bypass *", "g"); -logf("* By NekoYuzu Version " . $version . " *", "g"); -logf("************************************", "g"); -logf("GitHub: https://github.com/MlgmXyysd"); -logf("XDA: https://xdaforums.com/m/mlgmxyysd.8430637"); -logf("X (Twitter): https://x.com/realMlgmXyysd"); -logf("PayPal: https://paypal.me/MlgmXyysd"); -logf("My Blog: https://www.neko.ink/"); -logf("************************************", "g"); - -/******************** - * Banner End * - ********************/ - -/******************** - * Main Logic * - ********************/ - -logf("Starting ADB server..."); - -$adb = new ADB(__DIR__ . DIRECTORY_SEPARATOR . "libraries"); - -$devices = parseDeviceList($adb); -$devices_count = count($devices); - -while ($devices_count != 1) { - if ($devices_count == 0) { - logf("Waiting for device connection..."); - } else { - logf("Only one device is allowed to connect, disconnect others to continue. Current number of devices: " . $devices_count); - } - sleep(1); - $devices = parseDeviceList($adb); - $devices_count = count($devices); -} - -$device = $devices[0]; -$id = $adb -> getDeviceId($device[1], true); -logf("Processing device " . $device[0] . "(" . $device[1] . ")..."); - -$adb -> clearLogcat($id); -$adb -> runAdb($id . "shell svc data enable"); - -logf("Finding BootLoader unlock bind request..."); - -$focus = $adb -> getCurrentActivity(); -if ($focus[0] != "com.android.settings") { - if ($focus[0] != "NotificationShade") { - $adb -> runAdb($id . "shell am start -a android.settings.APPLICATION_DEVELOPMENT_SETTINGS"); - } -} else { - if ($focus[1] != "com.android.settings.bootloader.BootloaderStatusActivity") { - $adb -> runAdb($id . "shell am start -a android.settings.APPLICATION_DEVELOPMENT_SETTINGS"); - } -} -logf("Now you can bind account in the developer options.", "y", "*"); - -$args = $headers = null; - -$process = proc_open($adb -> bin . " " . $id . "logcat *:S CloudDeviceStatus:V", array( - 1 => ["pipe", "w"] -), $pipes); - -if (is_resource($process)) { - while (!feof($pipes[1])) { - $output = fgets($pipes[1]); - - if (str_contains($output, "CloudDeviceStatus: args:")) { - if (preg_match("/args:(.*)/", $output, $matches)) { - $args = trim($matches[1]); - } - $adb -> runAdb($id . "shell svc data disable"); - } - - if (str_contains($output, "CloudDeviceStatus: headers:")) { - if (preg_match("/headers:(.*)/", $output, $matches)) { - $headers = trim($matches[1]); - } - logf("Account bind request found! Let's block it."); - break; - } - } - - fclose($pipes[1]); -} - -logf("Refactoring parameters..."); - -$data = json_decode(decryptData($args), true); - -// V816 is the special identity for HyperOS in MIUI version -$data["rom_version"] = str_replace("V816", "V14", $data["rom_version"]); - -$data = json_encode($data); -$sign = signData($data); - -$headers = decryptData($headers); -$cookies = null; -if (preg_match("/Cookie=\[(.*)\]/", $headers, $matches)) { - $cookies = trim($matches[1]); -} - -logf("Sending POST request..."); -$res = postApi("unlock/applyBind", array( - "data" => $data, - "sid" => "miui_sec_android", - "sign" => $sign -), array( - "Cookie: " . $cookies, - "Content-Type: application/x-www-form-urlencoded" -), true); - -$adb -> runAdb($id . "shell svc data enable"); - -if (!$res) { - logf("Fail to send request, check your internet connection.", "r", "!"); - exit(); -} - -switch ($res["code"]) { - case 0: - logf("Target account: " . $res["data"]["userId"], "g"); - logf("Account bound successfully, wait time can be viewed in the unlock tool.", "g"); - break; - case 401: - logf("Account credentials have expired, re-login to your account in your phone. (401)", "y"); - break; - case 20086: - logf("Device credentials expired. (20086)", "y"); - break; - case 30001: - logf("Binding failed, this device has been forced to verify the account qualification by Xiaomi. (30001)", "y"); - break; - case 86015: - logf("Fail to bind account, invalid device signature. (86015)", "y"); - break; - default: - logf($res["descEN"] . " (" . $res["code"] . ")", "y"); -} + refreshDeviceList(); + $t = array(); + foreach ($s as $d) { + if ($d["status"] === $a::CONNECT_TYPE_DEVICE) { + $t[] = array($d["serial"], $d["transport"]); + } + } + return $t; +} + +/** + * Formatted Log + * @param $m string optional Message + * @param $c string optional Color + * @param $p string optional Indicator + * @param $t string optional Type (Level) + * @author NekoYuzu (MlgmXyysd) + * @date 2022/03/24 14:50:01 + */ + +function logf(string $m = "", string $c = "", string $p = "-", string $t = "I"): void +{ + switch (strtoupper($c)) { + case "G": + $c = "\033[32m"; + break; + case "R": + $c = "\033[31m"; + break; + case "Y": + $c = "\033[33m"; + break; + default: + $c = ""; + } + switch (strtoupper($t)) { + case "W": + $t = "WARN"; + break; + case "E": + $t = "ERROR"; + break; + case "I": + default: + $t = "INFO"; + } + print(date("[Y-m-d] [H:i:s]") . " [" . $t . "] " . $p . " " . $c . $m . "\033[0m" . PHP_EOL); +} + +/** + * Curl HTTP wrapper function + * @param $url string required Target url + * @param $method string required Request method + * @param $fields array optional Request body + * @param $header array optional Request header + * @param $useForm bool optional Treat request body as urlencoded form + * @return array Curl response + * @author NekoYuzu (MlgmXyysd) + * @date 2023/11/20 23:50:39 + */ + +function http(string $url, string $method, array $fields = array(), array $header = array(), bool $useForm = false): array +{ + if ($useForm) { + $fields = http_build_query($fields); + } + $curl = curl_init(); + curl_setopt_array($curl, array( + CURLOPT_URL => $url, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_ENCODING => "", + CURLOPT_SSL_VERIFYPEER => false, + CURLOPT_SSL_VERIFYHOST => false, + CURLOPT_MAXREDIRS => 10, + CURLOPT_CONNECTTIMEOUT => 2, + CURLOPT_TIMEOUT => 6, + CURLOPT_CUSTOMREQUEST => $method, + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, + CURLOPT_POST => $method == "POST", + CURLOPT_POSTFIELDS => $fields, + CURLOPT_HTTPHEADER => $header + )); + + $response = curl_exec($curl); + $info = curl_getinfo($curl); + $info["errno"] = curl_errno($curl); + $info["error"] = curl_error($curl); + $info["request"] = json_encode($fields); + $info["response"] = $response; + curl_close($curl); + return $info; +} + +/** + * HTTP POST wrapper + * @param $_api string required Target endpoint + * @param $data array optional Request body + * @param $header array optional Request header + * @param $useForm bool optional Treat request body as urlencoded form + * @return array Curl response + * @return false Response code is not HTTP 200 OK + * @author NekoYuzu (MlgmXyysd) + * @date 2023/11/20 23:55:41 + */ + +function postApi(string $_api, array $data = array(), array $header = array(), bool $useForm = false): array|false +{ + $response = http($GLOBALS["api"] . $_api, "POST", $data, $header, $useForm); + if ($response["http_code"] != 200) { + return false; + } + return json_decode($response["response"], true); +} + +/** + * Sign data using HMAC SHA-1 + * @param $data string required Data to sign + * @return string Signed hash + * @author NekoYuzu (MlgmXyysd) + * @date 2023/11/21 00:20:56 + */ + +function signData(string $data): string +{ + return strtolower(bin2hex(hash_hmac("sha1", "POST\n/v1/unlock/applyBind\ndata=" . $data . "&sid=miui_sec_android", $GLOBALS["sign_key"], true))); +} + +/** + * Decrypt data using AES/CBC/PKCS5Padding + * @param $data string required Data to decrypt + * @return string Decrypted data + * @return false Failed to decrypt + * @author NekoYuzu (MlgmXyysd) + * @date 2023/11/21 00:15:30 + */ + +function decryptData(string $data): string|false +{ + return openssl_decrypt(base64_decode($data), "AES-128-CBC", $GLOBALS["data_pass"], OPENSSL_RAW_DATA, $GLOBALS["data_iv"]); +} + +/*********************** + * Functions End * + ***********************/ + +/********************** + * Banner Start * + **********************/ + +logf("************************************", "g"); +logf("* Xiaomi HyperOS BootLoader Bypass *", "g"); +logf("* By NekoYuzu Version " . $version . " *", "g"); +logf("************************************", "g"); +logf("GitHub: https://github.com/MlgmXyysd"); +logf("XDA: https://xdaforums.com/m/mlgmxyysd.8430637"); +logf("X (Twitter): https://x.com/realMlgmXyysd"); +logf("PayPal: https://paypal.me/MlgmXyysd"); +logf("My Blog: https://www.neko.ink/"); +logf("************************************", "g"); + +/******************** + * Banner End * + ********************/ + +/******************** + * Main Logic * + ********************/ + +logf("Starting ADB server..."); + +$adb = new ADB(__DIR__ . DIRECTORY_SEPARATOR . "libraries"); + +$devices = parseDeviceList($adb); +$devices_count = count($devices); + +while ($devices_count != 1) { + if ($devices_count == 0) { + logf("Waiting for device connection..."); + } else { + logf("Only one device is allowed to connect, disconnect others to continue. Current number of devices: " . $devices_count); + } + sleep(1); + $devices = parseDeviceList($adb); + $devices_count = count($devices); +} + +$device = $devices[0]; +$id = $adb -> getDeviceId($device[1], true); +logf("Processing device " . $device[0] . "(" . $device[1] . ")..."); + +$adb -> clearLogcat($id); +$adb -> runAdb($id . "shell svc data enable"); + +logf("Finding BootLoader unlock bind request..."); + +$focus = $adb -> getCurrentActivity(); +if ($focus[0] != "com.android.settings") { + if ($focus[0] != "NotificationShade") { + $adb -> runAdb($id . "shell am start -a android.settings.APPLICATION_DEVELOPMENT_SETTINGS"); + } +} else { + if ($focus[1] != "com.android.settings.bootloader.BootloaderStatusActivity") { + $adb -> runAdb($id . "shell am start -a android.settings.APPLICATION_DEVELOPMENT_SETTINGS"); + } +} +logf("Now you can bind account in the developer options.", "y", "*"); + +$args = $headers = null; + +$process = proc_open($adb -> bin . " " . $id . "logcat *:S CloudDeviceStatus:V", array( + 1 => ["pipe", "w"] +), $pipes); + +if (is_resource($process)) { + while (!feof($pipes[1])) { + $output = fgets($pipes[1]); + + if (str_contains($output, "CloudDeviceStatus: args:")) { + if (preg_match("/args:(.*)/", $output, $matches)) { + $args = trim($matches[1]); + } + $adb -> runAdb($id . "shell svc data disable"); + } + + if (str_contains($output, "CloudDeviceStatus: headers:")) { + if (preg_match("/headers:(.*)/", $output, $matches)) { + $headers = trim($matches[1]); + } + logf("Account bind request found! Let's block it."); + break; + } + } + + fclose($pipes[1]); +} + +logf("Refactoring parameters..."); + +$data = json_decode(decryptData($args), true); + +// V816 is the special identity for HyperOS in MIUI version +$data["rom_version"] = str_replace("V816", "V14", $data["rom_version"]); + +$data = json_encode($data); +$sign = signData($data); + +$headers = decryptData($headers); +$cookies = null; +if (preg_match("/Cookie=\[(.*)\]/", $headers, $matches)) { + $cookies = trim($matches[1]); +} + +logf("Sending POST request..."); +$res = postApi("unlock/applyBind", array( + "data" => $data, + "sid" => "miui_sec_android", + "sign" => $sign +), array( + "Cookie: " . $cookies, + "Content-Type: application/x-www-form-urlencoded" +), true); + +$adb -> runAdb($id . "shell svc data enable"); + +if (!$res) { + logf("Fail to send request, check your internet connection.", "r", "!"); + exit(); +} + +switch ($res["code"]) { + case 0: + logf("Target account: " . $res["data"]["userId"], "g"); + logf("Account bound successfully, wait time can be viewed in the unlock tool.", "g"); + break; + case 401: + logf("Account credentials have expired, re-login to your account in your phone. (401)", "y"); + break; + case 20086: + logf("Device credentials expired. (20086)", "y"); + break; + case 30001: + logf("Binding failed, this device has been forced to verify the account qualification by Xiaomi. (30001)", "y"); + break; + case 86015: + logf("Fail to bind account, invalid device signature. (86015)", "y"); + break; + default: + logf($res["descEN"] . " (" . $res["code"] . ")", "y"); +} diff --git a/README-zh.md b/docs/README-zh.md similarity index 85% rename from README-zh.md rename to docs/README-zh.md index 8c5f3f5..05f39b9 100644 --- a/README-zh.md +++ b/docs/README-zh.md @@ -1,107 +1,107 @@ -# Xiaomi HyperOS BootLoader Bypass - -![Version: 1.0](https://img.shields.io/badge/Version-1.0-brightgreen?style=for-the-badge) [![English](https://img.shields.io/badge/English-brightgreen?style=for-the-badge)](README.md) - -利用漏洞绕过小米 HyperOS 对 BootLoader 解锁账户绑定限制社区等级的 PoC。 - -您可随时向本项目提出改进方案 :) - -## 💘 php-adb - -本项目使用了 [php-adb](https://github.com/MlgmXyysd/php-adb) 运行库。 - -## ☕ 支持开发 - -✨ 如果您喜欢我的项目,可以请我喝咖啡: - - - [爱发电](https://afdian.net/@MlgmXyysd) - - [PayPal](https://paypal.me/MlgmXyysd) - - [Patreon](https://www.patreon.com/MlgmXyysd) - -## ⚠️ 警告 - -解锁 BootLoader 后,你可能会遇到以下情况: - -- 软件或硬件无法正常工作,甚至永久性损坏。 -- 设备中存储的数据丢失。 -- 信用卡被盗刷,或遭受其他经济损失。 - -如果您遇到上述任何情况,您应该自己承担所有责任,因为这是您在解锁 BootLoader 时可能遇到的风险。这显然不能涵盖所有风险。我们已经警告过您了。 - -- 保修丢失。根据小米提供的免责条款,这不仅是基础三包,您购买的一些额外延保(如 Mi Care 或碎屏险)也可能会丢失。 -- 像 Samsung Knox 那样的硬件级熔断。TEE 相关功能将永久损坏。除更换主板外,无法恢复。 -- 刷入第三方系统后出现功能异常,这可能是因为内核源代码闭源引起。 -- 设备或账号因为解锁 BootLoader 被小米封禁。 - -如果您遇到上述任何情况,请您自认倒霉。自从小米限制解锁 BootLoader 后,小米就一直在违背"极客"精神,甚至违背了 GPL。小米对 BootLoader 解锁的限制是无穷尽的,作为开发者,我们对此无能为力。 - -## 📲 前置要求 - -- 一个有效的设备: - - 一个未被封禁\*的小米、红米或 POCO 设备。 - - 设备正在运行官方版 HyperOS。 - - (2023/11/23 更新) 您的设备不会被小米强制验证账户资格。 -- 一个有效的 SIM 卡: - - \* 无法使用 SIM 卡的平板电脑除外。 - - SIM 卡不得处于停机或无服务状态。 - - SIM 卡需要能够连接到互联网。 - - 每张有效 SIM 卡在三个月内只能解锁 2 台设备。 -- 一个有效的小米账号: - - 一个未被封禁\*的小米账号。 - - 每个账号一个月只能解锁一部手机,一年只能解锁三部手机。 -- 您已阅读并理解上述 [警告](#%EF%B8%8F-警告)。 - -- \* 根据小米提供的解锁说明,某些账号和设备将被禁止使用解锁工具,这被称为"风控"。 - -## ⚙️ 使用教程 - -1. 从 [官方网站](https://www.php.net/downloads) 下载并安装适用于您操作系统的 PHP 8.0+。 -2. 在 `php.ini` 中启用 OpenSSL 和 Curl 扩展。 -3. 将 [php-adb](https://github.com/MlgmXyysd/php-adb) 中的 `adb.php` 放到目录中。 -4. 下载 [platform-tools](https://developer.android.com/studio/releases/platform-tools),并将其放入 `libraries`。*注意:Mac OS 需要将 `adb` 重命名为 `adb-darwin`。 -5. 打开终端,使用 PHP 解释器执行 [脚本](bypass.php)。 - -- p.s. Releases 已将所需文件和一键脚本打包。 - -6. 多次点击`设置 - 关于手机 - MIUI 版本`启用`开发者选项`。 -7. 在`设置 - 附加设置 - 开发者选项`中启用`OEM 解锁`、`USB 调试`和`USB 调试(安全设置)`。 -8. 登录一个_有效_\*的小米账号。 -9. 通过有线方式将设备连接到电脑。 -10. 选中`始终允许来自此计算机的调试`,然后单击`确定`。 - -- \* 请参阅上文的 "[前置要求](#-前置要求)"。 - -11. 等待并按脚本提示操作。 -12. 绑定成功后,您可以使用 [官方解锁工具](https://www.miui.com/unlock/index.html) 查看需要等待的时间。 -13. 在等待期间,请正常使用设备,保持 SIM 卡插入,不要登出小米账号或关闭"查找我的手机",不要重新绑定设备,直到成功解锁。设备将每隔一段时间自动向服务器发送 `HeartBeat` 数据包。 - -## 📖 漏洞分析 - -- 维修中... - -## 🔖 FAQ - -- Q: 为什么解锁工具仍然提醒我等待 168/360(或更长)小时? -- A: 根据原理,该 PoC 只绕过了小米为 HyperOS 额外添加的限制。您仍然需要遵循 MIUI 的限制。 - -- Q: 设备显示 "验证失败,请稍后再试"。 -- A: 这是正常现象,设备端的绑定请求已被脚本拦截。实际绑定结果以脚本提示为准。 - -- Q: 绑定失败,错误代码为 `401`。 -- A: 您的小米账号凭据已过期,您需要在设备中登出账号并重新登录。 - -- Q: 绑定失败,错误代码为 `20086`。 -- A: 您的设备凭据已过期,您可能需要重新启动设备。 - -- Q: 绑定失败,错误代码为 `20090` 或 `20091`。 -- A: 设备的 `Security Device Credential Manager` 功能已损坏,请联系售后服务寻求支持。 - -- Q: 绑定失败,错误代码为 `30001`。 -- A: 您的设备已被小米强制验证账户资格。小米早就抛弃了"极客"精神,我们对此无能为力。 - -- Q: 绑定失败,错误代码为 `86015`。 -- A: 服务器拒绝了本次绑定请求,请重试。 - -## ⚖️ 协议 - -无许可证,您只被允许使用本项目。未经许可,不得删除或更改本软件的所有版权(以及链接等)。本项目所有权利归 [MeowCat Studio](https://github.com/MeowCat-Studio)、[Meow Mobile](https://github.com/Meow-Mobile) 和 [NekoYuzu](https://github.com/MlgmXyysd) 所有。 +# Xiaomi HyperOS BootLoader Bypass + +![Version: 1.0](https://img.shields.io/badge/Version-1.0-brightgreen?style=for-the-badge) [![English](https://img.shields.io/badge/English-brightgreen?style=for-the-badge)](README.md) + +利用漏洞绕过小米 HyperOS 对 BootLoader 解锁账户绑定限制社区等级的 PoC。 + +您可随时向本项目提出改进方案 :) + +## 💘 php-adb + +本项目使用了 [php-adb](https://github.com/MlgmXyysd/php-adb) 运行库。 + +## ☕ 支持开发 + +✨ 如果您喜欢我的项目,可以请我喝咖啡: + + - [爱发电](https://afdian.net/@MlgmXyysd) + - [PayPal](https://paypal.me/MlgmXyysd) + - [Patreon](https://www.patreon.com/MlgmXyysd) + +## ⚠️ 警告 + +解锁 BootLoader 后,你可能会遇到以下情况: + +- 软件或硬件无法正常工作,甚至永久性损坏。 +- 设备中存储的数据丢失。 +- 信用卡被盗刷,或遭受其他经济损失。 + +如果您遇到上述任何情况,您应该自己承担所有责任,因为这是您在解锁 BootLoader 时可能遇到的风险。这显然不能涵盖所有风险。我们已经警告过您了。 + +- 保修丢失。根据小米提供的免责条款,这不仅是基础三包,您购买的一些额外延保(如 Mi Care 或碎屏险)也可能会丢失。 +- 像 Samsung Knox 那样的硬件级熔断。TEE 相关功能将永久损坏。除更换主板外,无法恢复。 +- 刷入第三方系统后出现功能异常,这可能是因为内核源代码闭源引起。 +- 设备或账号因为解锁 BootLoader 被小米封禁。 + +如果您遇到上述任何情况,请您自认倒霉。自从小米限制解锁 BootLoader 后,小米就一直在违背"极客"精神,甚至违背了 GPL。小米对 BootLoader 解锁的限制是无穷尽的,作为开发者,我们对此无能为力。 + +## 📲 前置要求 + +- 一个有效的设备: + - 一个未被封禁\*的小米、红米或 POCO 设备。 + - 设备正在运行官方版 HyperOS。 + - (2023/11/23 更新) 您的设备不会被小米强制验证账户资格。 +- 一个有效的 SIM 卡: + - \* 无法使用 SIM 卡的平板电脑除外。 + - SIM 卡不得处于停机或无服务状态。 + - SIM 卡需要能够连接到互联网。 + - 每张有效 SIM 卡在三个月内只能解锁 2 台设备。 +- 一个有效的小米账号: + - 一个未被封禁\*的小米账号。 + - 每个账号一个月只能解锁一部手机,一年只能解锁三部手机。 +- 您已阅读并理解上述 [警告](#%EF%B8%8F-警告)。 + +- \* 根据小米提供的解锁说明,某些账号和设备将被禁止使用解锁工具,这被称为"风控"。 + +## ⚙️ 使用教程 + +1. 从 [官方网站](https://www.php.net/downloads) 下载并安装适用于您操作系统的 PHP 8.0+。 +2. 在 `php.ini` 中启用 OpenSSL 和 Curl 扩展。 +3. 将 [php-adb](https://github.com/MlgmXyysd/php-adb) 中的 `adb.php` 放到目录中。 +4. 下载 [platform-tools](https://developer.android.com/studio/releases/platform-tools),并将其放入 `libraries`。*注意:Mac OS 需要将 `adb` 重命名为 `adb-darwin`。 +5. 打开终端,使用 PHP 解释器执行 [脚本](bypass.php)。 + +- p.s. Releases 已将所需文件和一键脚本打包。 + +6. 多次点击`设置 - 关于手机 - MIUI 版本`启用`开发者选项`。 +7. 在`设置 - 附加设置 - 开发者选项`中启用`OEM 解锁`、`USB 调试`和`USB 调试(安全设置)`。 +8. 登录一个_有效_\*的小米账号。 +9. 通过有线方式将设备连接到电脑。 +10. 选中`始终允许来自此计算机的调试`,然后单击`确定`。 + +- \* 请参阅上文的 "[前置要求](#-前置要求)"。 + +11. 等待并按脚本提示操作。 +12. 绑定成功后,您可以使用 [官方解锁工具](https://www.miui.com/unlock/index.html) 查看需要等待的时间。 +13. 在等待期间,请正常使用设备,保持 SIM 卡插入,不要登出小米账号或关闭"查找我的手机",不要重新绑定设备,直到成功解锁。设备将每隔一段时间自动向服务器发送 `HeartBeat` 数据包。 + +## 📖 漏洞分析 + +- 维修中... + +## 🔖 FAQ + +- Q: 为什么解锁工具仍然提醒我等待 168/360(或更长)小时? + - A: 根据原理,该 PoC 只绕过了小米为 HyperOS 额外添加的限制。您仍然需要遵循 MIUI 的限制。 + +- Q: 设备显示 "验证失败,请稍后再试"。 + - A: 这是正常现象,设备端的绑定请求已被脚本拦截。实际绑定结果以脚本提示为准。 + +- Q: 绑定失败,错误代码为 `401`。 + - A: 您的小米账号凭据已过期,您需要在设备中登出账号并重新登录。 + +- Q: 绑定失败,错误代码为 `20086`。 + - A: 您的设备凭据已过期,您可能需要重新启动设备。 + +- Q: 绑定失败,错误代码为 `20090` 或 `20091`。 + - A: 设备的 `Security Device Credential Manager` 功能已损坏,请联系售后服务寻求支持。 + +- Q: 绑定失败,错误代码为 `30001`。 + - A: 您的设备已被小米强制验证账户资格。小米早就抛弃了"极客"精神,我们对此无能为力。 + +- Q: 绑定失败,错误代码为 `86015`。 + - A: 服务器拒绝了本次绑定请求,请重试。 + +## ⚖️ 协议 + +无许可证,您只被允许使用本项目。未经许可,不得删除或更改本软件的所有版权(以及链接等)。本项目所有权利归 [MeowCat Studio](https://github.com/MeowCat-Studio)、[Meow Mobile](https://github.com/Meow-Mobile) 和 [NekoYuzu](https://github.com/MlgmXyysd) 所有。 diff --git a/README.md b/docs/README.md similarity index 85% rename from README.md rename to docs/README.md index cea9528..da005fd 100644 --- a/README.md +++ b/docs/README.md @@ -1,107 +1,107 @@ -# Xiaomi HyperOS BootLoader Bypass - -![Version: 1.0](https://img.shields.io/badge/Version-1.0-brightgreen?style=for-the-badge) [![中文文档](https://img.shields.io/badge/中文文档-brightgreen?style=for-the-badge)](README-zh.md) - -A PoC that exploits a vulnerability to bypass the Xiaomi HyperOS community restrictions of BootLoader unlocked account bindings. - -Feel free pull request if you want :) - -## 💘 php-adb - -The project proudly uses the [php-adb](https://github.com/MlgmXyysd/php-adb) library. - -## ☕ Buy me a Coffee - -✨ If you like my projects, you can buy me a coffee at: - - - [爱发电](https://afdian.net/@MlgmXyysd) - - [PayPal](https://paypal.me/MlgmXyysd) - - [Patreon](https://www.patreon.com/MlgmXyysd) - -## ⚠️ Warning - -After unlocking the BootLoader, you may encounter the following situations: - -- Software or hardware not working properly or even damaged. -- Loss of data stored in the device. -- Credit card theft, or other financial loss. - -If you're experiencing any of the above, you should take all the responsibility yourself as this is the risk you may encounter when unlocking BootLoader. This obviously does not cover all risks. You've been warned. - -- Warranty lost. Not only the base warranty, but some of the extra extended warranties (such as Mi Care or broken-screen warranty) that you have purchased may also be lost according to the exclusions provided by Xiaomi. -- Hardware level self-destruct like Samsung Knox. TEE-related features will be permanently damaged. There is no way to restore other than by replacing the motherboard. -- Functional anomalies after flashing a third-party system due to closed-source kernel source code. -- Device or account banned by unlocking BootLoader. - -If you're experiencing any of the above, consider yourself damned. Ever since Xiaomi restricted unlocking BootLoader, it has been against Xiaomi's 'geek' spirit and even the GPL. Xiaomi's restrictions on BootLoader unlocking are endless, and there's nothing we as developers can do about it. - -## 📲 Unlocking requirements - -- An valid device: - - A unbanned\* Xiaomi, Redmi or POCO device. - - Your device is running the official version of HyperOS. - - (Update 2023/11/23) Your device is not forced to verify account qualification by Xiaomi. -- An valid SIM card: - - \* Except for tablets that cannot use SIM cards. - - SIM card must not be out of service. - - SIM card needs to be able to access the internet. - - Only 2 devices per valid SIM card are allowed to be unlock to a valid SIM card within a three-month period. -- An valid Xiaomi account: - - A unbanned\* Xiaomi account. - - Each account can only unlock 1 phone in a month and 3 phones in a year period. -- You have read and understood the [Warning](#%EF%B8%8F-warning) above. - -- \* According to the unlocking instructions provided by Xiaomi, it will prohibit some accounts and devices from using the unlocking tool, which is called "risk control". - -## ⚙️ How to use - -1. Download and install PHP 8.0+ for your system from the [official website](https://www.php.net/downloads). -2. Enable OpenSSL and Curl extension in `php.ini`. -3. Place `adb.php` in [php-adb](https://github.com/MlgmXyysd/php-adb) to the directory. -4. Download [platform-tools](https://developer.android.com/studio/releases/platform-tools) and place them in `libraries`. *Note: Mac OS needs to rename `adb` to `adb-darwin`.* -5. Open a terminal and use PHP interpreter to execute the [script](bypass.php). - -- p.s. Releases has packaged the required files and click-to-run scripts. - -6. Tap repeatedly on the `Settings - About Phone - MIUI Version` to enable `Development Options`. -7. Enable `OEM Unlocking`, `USB Debugging` and `USB Debugging (Security Settings)` in `Settings - Additional Settings - Development Options`. -8. Log in an _valid_\* Xiaomi account. -9. Connect phone to PC via wired interface. -10. Check `Always allow from this computer` and click `OK`. - -- \* See "[Unlocking Requirements](#-Unlocking-requirements)" above. - -11. Wait and follow the prompts of script. -12. After successful binding, you can use the [official unlock tool](https://en.miui.com/unlock/index.html) to check the time you need to wait. -13. During the waiting period, please use the device normally, keep the SIM card inserted, do not log out of your account or turn off `Find My Phone`, and do not re-bind the device until it is successfully unlocked. The device will automatically send `HeartBeat` packets to the server every once in a while. - -## 📖 Workaround - -- Undergoing maintenance... - -## 🔖 FAQs - -- Q: Why does the unlock tool still remind me to wait 168/360 (or more) hours? -- A: By principle, this PoC only bypasses the restrictions added for HyperOS. You still need to comply with the restrictions for MIUI. - -- Q: The device shows `Couldn't verify, wait a minute or two and try again`. -- A: This is normal, the binding request on the device side has been blocked by our script. The actual binding result is subject to the script prompt. - -- Q: Binding failed with error code `401`. -- A: Your Xiaomi account credentials have expired, you need to log out and log in again in your device. - -- Q: Binding failed with error code `20086`. -- A: Your device credentials have expired, you need to reboot your device. - -- Q: Binding failed with error code `20090` or `20091`. -- A: Device's Security Device Credential Manager function failure, contact after-sales. - -- Q: Binding failed with error code `30001`. -- A: Your device has been forced to verify the account qualification by Xiaomi. Xiaomi lost its 'geek' spirit a long time ago, and there's nothing we can do about it. - -- Q: Binding failed with error code `86015`. -- A: The server has rejected this bind request, please try again. - -## ⚖️ License - -No license, you are only allowed to use this project. All copyright (and link, etc.) in this software is not allowed to be deleted or changed without permission. All rights are reserved by [MeowCat Studio](https://github.com/MeowCat-Studio), [Meow Mobile](https://github.com/Meow-Mobile) and [NekoYuzu](https://github.com/MlgmXyysd). +# Xiaomi HyperOS BootLoader Bypass + +![Version: 1.0](https://img.shields.io/badge/Version-1.0-brightgreen?style=for-the-badge) [![中文文档](https://img.shields.io/badge/中文文档-brightgreen?style=for-the-badge)](README-zh.md) + +A PoC that exploits a vulnerability to bypass the Xiaomi HyperOS community restrictions of BootLoader unlocked account bindings. + +Feel free pull request if you want :) + +## 💘 php-adb + +The project proudly uses the [php-adb](https://github.com/MlgmXyysd/php-adb) library. + +## ☕ Buy me a Coffee + +✨ If you like my projects, you can buy me a coffee at: + + - [爱发电](https://afdian.net/@MlgmXyysd) + - [PayPal](https://paypal.me/MlgmXyysd) + - [Patreon](https://www.patreon.com/MlgmXyysd) + +## ⚠️ Warning + +After unlocking the BootLoader, you may encounter the following situations: + +- Software or hardware not working properly or even damaged. +- Loss of data stored in the device. +- Credit card theft, or other financial loss. + +If you're experiencing any of the above, you should take all the responsibility yourself as this is the risk you may encounter when unlocking BootLoader. This obviously does not cover all risks. You've been warned. + +- Warranty lost. Not only the base warranty, but some of the extra extended warranties (such as Mi Care or broken-screen warranty) that you have purchased may also be lost according to the exclusions provided by Xiaomi. +- Hardware level self-destruct like Samsung Knox. TEE-related features will be permanently damaged. There is no way to restore other than by replacing the motherboard. +- Functional anomalies after flashing a third-party system due to closed-source kernel source code. +- Device or account banned by unlocking BootLoader. + +If you're experiencing any of the above, consider yourself damned. Ever since Xiaomi restricted unlocking BootLoader, it has been against Xiaomi's 'geek' spirit and even the GPL. Xiaomi's restrictions on BootLoader unlocking are endless, and there's nothing we as developers can do about it. + +## 📲 Unlocking requirements + +- An valid device: + - A unbanned\* Xiaomi, Redmi or POCO device. + - Your device is running the official version of HyperOS. + - (Update 2023/11/23) Your device is not forced to verify account qualification by Xiaomi. +- An valid SIM card: + - \* Except for tablets that cannot use SIM cards. + - SIM card must not be out of service. + - SIM card needs to be able to access the internet. + - Only 2 devices per valid SIM card are allowed to be unlock to a valid SIM card within a three-month period. +- An valid Xiaomi account: + - A unbanned\* Xiaomi account. + - Each account can only unlock 1 phone in a month and 3 phones in a year period. +- You have read and understood the [Warning](#%EF%B8%8F-warning) above. + +- \* According to the unlocking instructions provided by Xiaomi, it will prohibit some accounts and devices from using the unlocking tool, which is called "risk control". + +## ⚙️ How to use + +1. Download and install PHP 8.0+ for your system from the [official website](https://www.php.net/downloads). +2. Enable OpenSSL and Curl extension in `php.ini`. +3. Place `adb.php` in [php-adb](https://github.com/MlgmXyysd/php-adb) to the directory. +4. Download [platform-tools](https://developer.android.com/studio/releases/platform-tools) and place them in `libraries`. *Note: Mac OS needs to rename `adb` to `adb-darwin`.* +5. Open a terminal and use PHP interpreter to execute the [script](bypass.php). + +- p.s. Releases has packaged the required files and click-to-run scripts. + +6. Tap repeatedly on the `Settings - About Phone - MIUI Version` to enable `Development Options`. +7. Enable `OEM Unlocking`, `USB Debugging` and `USB Debugging (Security Settings)` in `Settings - Additional Settings - Development Options`. +8. Log in an _valid_\* Xiaomi account. +9. Connect phone to PC via wired interface. +10. Check `Always allow from this computer` and click `OK`. + +- \* See "[Unlocking Requirements](#-Unlocking-requirements)" above. + +11. Wait and follow the prompts of script. +12. After successful binding, you can use the [official unlock tool](https://en.miui.com/unlock/index.html) to check the time you need to wait. +13. During the waiting period, please use the device normally, keep the SIM card inserted, do not log out of your account or turn off `Find My Phone`, and do not re-bind the device until it is successfully unlocked. The device will automatically send `HeartBeat` packets to the server every once in a while. + +## 📖 Workaround + +- Undergoing maintenance... + +## 🔖 FAQs + +- Q: Why does the unlock tool still remind me to wait 168/360 (or more) hours? + - A: By principle, this PoC only bypasses the restrictions added for HyperOS. You still need to comply with the restrictions for MIUI. + +- Q: The device shows `Couldn't verify, wait a minute or two and try again`. + - A: This is normal, the binding request on the device side has been blocked by our script. The actual binding result is subject to the script prompt. + +- Q: Binding failed with error code `401`. + - A: Your Xiaomi account credentials have expired, you need to log out and log in again in your device. + +- Q: Binding failed with error code `20086`. + - A: Your device credentials have expired, you need to reboot your device. + +- Q: Binding failed with error code `20090` or `20091`. + - A: Device's Security Device Credential Manager function failure, contact after-sales. + +- Q: Binding failed with error code `30001`. + - A: Your device has been forced to verify the account qualification by Xiaomi. Xiaomi lost its 'geek' spirit a long time ago, and there's nothing we can do about it. + +- Q: Binding failed with error code `86015`. + - A: The server has rejected this bind request, please try again. + +## ⚖️ License + +No license, you are only allowed to use this project. All copyright (and link, etc.) in this software is not allowed to be deleted or changed without permission. All rights are reserved by [MeowCat Studio](https://github.com/MeowCat-Studio), [Meow Mobile](https://github.com/Meow-Mobile) and [NekoYuzu](https://github.com/MlgmXyysd).