Leí una publicación de blog en algún lugar que sugería que TowelRoot no necesita acceso a Internet, y también leí que sí. La última versión que intenté ejecutar TowelRoot v3 no funcionará sin ella. ¿Está descargando o enviando alguna información? ¿Entonces qué?
Anexo: Supongo que si estuvieran tratando de lograr algo nefasto, simplemente lo harían en lugar de pedir permiso... ¿verdad?
Dado que el código de TowelRoot no está disponible públicamente, recurrí a descompilar el último APK, descargado del sitio web de TowelRoot , para investigar la necesidad de la aplicación del permiso INTERNET.
Tras una descompilación exitosa, resultó que ni las actividades ni el código en sí estaban ofuscados. El desarrollador ciertamente había anticipado que esta aplicación habría sido investigada, pero dejó que el código fuera lo más transparente posible. El archivo más importante que tenemos en este punto es TowelRoot.smali
, que describe todo el funcionamiento de esta aplicación.
Nota: dependiendo de su versión particular de ApkTool, los números de línea pueden variar.
En líneas 13-22
, el código inicializa un campo llamado fingerprint
. El código relevante sigue:
.field fingerprint:Ljava/util/List;
.annotation system Ldalvik/annotation/Signature;
value = {
"Ljava/util/List",
"<",
"Lorg/apache/http/NameValuePair;",
">;"
}
.end annotation
.end field
que es una lista de Java compuesta por pares clave-valor, que se utilizará al recopilar la información relevante del teléfono.
En las líneas 56-215
, el código describe un método llamado fillInFingerprint
, que es responsable de recuperar los datos apropiados para enviarlos al sitio web de TowelRoot, con el fin de determinar si el dispositivo puede ser rooteado a través del exploit homónimo. Este método hace un uso extensivo del fingerprint
campo mencionado anteriormente. Los datos recogidos a continuación.
El modelo de dispositivo visible. Líneas 70-80
:
iget-object v4, p0, Lcom/geohot/towelroot/TowelRoot;->fingerprint:Ljava/util/List;
new-instance v5, Lorg/apache/http/message/BasicNameValuePair;
const-string v6, "model"
sget-object v7, Landroid/os/Build;->MODEL:Ljava/lang/String;
invoke-direct {v5, v6, v7}, Lorg/apache/http/message/BasicNameValuePair;-><init>(Ljava/lang/String;Ljava/lang/String;)V
invoke-interface {v4, v5}, Ljava/util/List;->add(Ljava/lang/Object;)Z
Un identificador único para la compilación del sistema operativo. Líneas 83-93
:
iget-object v4, p0, Lcom/geohot/towelroot/TowelRoot;->fingerprint:Ljava/util/List;
new-instance v5, Lorg/apache/http/message/BasicNameValuePair;
const-string v6, "fingerprint"
sget-object v7, Landroid/os/Build;->FINGERPRINT:Ljava/lang/String;
invoke-direct {v5, v6, v7}, Lorg/apache/http/message/BasicNameValuePair;-><init>(Ljava/lang/String;Ljava/lang/String;)V
invoke-interface {v4, v5}, Ljava/util/List;->add(Ljava/lang/Object;)Z
Probablemente la placa del procesador. Líneas 96-106
:
iget-object v4, p0, Lcom/geohot/towelroot/TowelRoot;->fingerprint:Ljava/util/List;
new-instance v5, Lorg/apache/http/message/BasicNameValuePair;
const-string v6, "hardware"
sget-object v7, Landroid/os/Build;->HARDWARE:Ljava/lang/String;
invoke-direct {v5, v6, v7}, Lorg/apache/http/message/BasicNameValuePair;-><init>(Ljava/lang/String;Ljava/lang/String;)V
invoke-interface {v4, v5}, Ljava/util/List;->add(Ljava/lang/Object;)Z
Número de serie único del dispositivo. Líneas 109-119
:
iget-object v4, p0, Lcom/geohot/towelroot/TowelRoot;->fingerprint:Ljava/util/List;
new-instance v5, Lorg/apache/http/message/BasicNameValuePair;
const-string v6, "serial"
sget-object v7, Landroid/os/Build;->SERIAL:Ljava/lang/String;
invoke-direct {v5, v6, v7}, Lorg/apache/http/message/BasicNameValuePair;-><init>(Ljava/lang/String;Ljava/lang/String;)V
invoke-interface {v4, v5}, Ljava/util/List;->add(Ljava/lang/Object;)Z
Vital ya que es probable que el exploit haya sido parcheado en los kernels recientes. Líneas 122-134
:
iget-object v4, p0, Lcom/geohot/towelroot/TowelRoot;->fingerprint:Ljava/util/List;
new-instance v5, Lorg/apache/http/message/BasicNameValuePair;
const-string v6, "kernel"
invoke-virtual {p0}, Lcom/geohot/towelroot/TowelRoot;->javaSucksAssReadTheKernelVersion()Ljava/lang/String;
move-result-object v7
invoke-direct {v5, v6, v7}, Lorg/apache/http/message/BasicNameValuePair;-><init>(Ljava/lang/String;Ljava/lang/String;)V
invoke-interface {v4, v5}, Ljava/util/List;->add(Ljava/lang/Object;)Z
Líneas 168-180
:
iget-object v4, p0, Lcom/geohot/towelroot/TowelRoot;->fingerprint:Ljava/util/List;
new-instance v5, Lorg/apache/http/message/BasicNameValuePair;
const-string v6, "appversion"
invoke-direct {p0}, Lcom/geohot/towelroot/TowelRoot;->getSoftwareVersion()Ljava/lang/String;
move-result-object v7
invoke-direct {v5, v6, v7}, Lorg/apache/http/message/BasicNameValuePair;-><init>(Ljava/lang/String;Ljava/lang/String;)V
invoke-interface {v4, v5}, Ljava/util/List;->add(Ljava/lang/Object;)Z
modstring
la cuerda Líneas 202-211
:
.local v1, "modstring":Ljava/lang/String;
iget-object v4, p0, Lcom/geohot/towelroot/TowelRoot;->fingerprint:Ljava/util/List;
new-instance v5, Lorg/apache/http/message/BasicNameValuePair;
const-string v6, "modstring"
invoke-direct {v5, v6, v1}, Lorg/apache/http/message/BasicNameValuePair;-><init>(Ljava/lang/String;Ljava/lang/String;)V
invoke-interface {v4, v5}, Ljava/util/List;->add(Ljava/lang/Object;)Z
En líneas, 227-329
el código describe el método queryServer
, que consulta la base de datos del servidor para encontrar una coincidencia con los datos recopilados y maneja las posibles excepciones en el código. Dichos datos se transmiten a la URL https://towelroot.appspot.com/report/
a través de SSL y una solicitud POST (líneas 263-275
):
.local v2, "httppost":Lorg/apache/http/client/methods/HttpPost;
new-instance v5, Lorg/apache/http/client/entity/UrlEncodedFormEntity;
iget-object v6, p0, Lcom/geohot/towelroot/TowelRoot;->fingerprint:Ljava/util/List;
invoke-direct {v5, v6}, Lorg/apache/http/client/entity/UrlEncodedFormEntity;-><init>(Ljava/util/List;)V
invoke-virtual {v2, v5}, Lorg/apache/http/client/methods/HttpPost;->setEntity(Lorg/apache/http/HttpEntity;)V
.line 88
invoke-interface {v1, v2}, Lorg/apache/http/client/HttpClient;->execute(Lorg/apache/http/client/methods/HttpUriRequest;)Lorg/apache/http/HttpResponse;
move-result-object v3
El método buttonClicked
(líneas 333-426
) contiene el código que hace que la aplicación funcione cuando presiona el botón. Entre otros, llama a los métodos fillInFingerprint
para recopilar la información requerida y queryServer
para ver si el dispositivo se puede rootear.
Luego procede analizando la respuesta del servidor. Si dicha respuesta está vacía, TowelRoot le pregunta sobre la necesidad de una conexión a Internet (líneas 369-378
):
invoke-virtual {v0, v2}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v2
if-eqz v2, :cond_1
.line 115
const-string v2, "Please ensure you are connected to the internet"
invoke-virtual {v1, v2}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
Si la respuesta no está vacía, TowelRoot continúa verificando si lo mencionado anteriormente es igual a la cadena nyet
(líneas 391-402
):
const-string v2, "nyet"
invoke-virtual {v0, v2}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v2
if-eqz v2, :cond_2
.line 117
const-string v2, "This phone isn\'t currently supported"
invoke-virtual {v1, v2}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
Si la respuesta es igual a nyet
, entonces el teléfono no es oficialmente compatible.
Finalmente, si la respuesta no está vacía y es diferente de nyet
, TowelRoot inicia el procedimiento de enraizamiento llamando al método nativo rootTheShit
, definido en la línea 448
y probablemente contenido dentro de la biblioteca libexploit.so
.
TowelRoot incluye un modo especial para usuarios con dispositivos no compatibles. Se puede acceder a este modo, cuyo código se define dentro del método titleClicked
(líneas 451-504
), tocando el título rojo welcome to towelroot v3
dentro de la aplicación, y le permitirá al usuario probar diferentes modstrings para tratar de rootear el dispositivo de todos modos.