Why Does TowelRoot Require Internet / Network Access?


Question

I read a blog post somewhere that suggested TowelRoot does not need internet access, and I've also read that it does. The latest version I tried to run TowelRoot v3 will not work without it. Is it downloading or sending any information? If so, what?



Addendum: I suppose if they were trying to accomplish anything nefarious, they would just do it instead of asking for permission... right?


Answer

Since TowelRoot's code is not publicly available, I resorted to decompile the latest APK, downloaded from the TowelRoot website, in order to investigate the app's need for the INTERNET permission.






Relevant notes



Upon successful decompilation, it turned out that neither the activities nor the code itself be obfuscated. The developer certainly had anticipated that this app would've been investigated, yet he had left the code to be as much transparent as possible.
The most important file we have at this point is TowelRoot.smali, which describes all the workings of this app.



Note: depending on your particular version of ApkTool, the line numbers may vary.






Initial structure



In lines 13-22, the code initializes a field called fingerprint. The relevant code follows:



.field fingerprint:Ljava/util/List;
.annotation system Ldalvik/annotation/Signature;
value = {
"Ljava/util/List",
"<",
"Lorg/apache/http/NameValuePair;",
">;"
}
.end annotation
.end field


which is a Java list composed of key-value pairs, to be used when collecting the relevant info from the phone.






Data collected



In lines 56-215, the code describes a method called fillInFingerprint, which is responsible for retrieving the appropriate data to be sent to the TowelRoot website, in order to ascertain whether the device can be rooted via the homonymous exploit. This method makes an extensive use of the abovementioned fingerprint field. The collected data follows.



Device model



The visible device model. Lines 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


Device fingerprint



An unique identifier for the OS build. Lines 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


Device hardware



Likely the processor board. Lines 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


Device serial



Device's unique serial number. Lines 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


Device kernel version



Vital since the exploit is likely to have been patched in the recent kernels. Lines 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


TowelRoot version



Lines 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



The string modstring. Lines 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





The server request



In lines 227-329 the code describes the method queryServer, which queries the server's database in order to find a match with the collected data, and handles the possible exceptions in the code. Such data is transmitted to the URL https://towelroot.appspot.com/report/ via SSL and a POST request (lines 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





make it ra1n



The method buttonClicked (lines 333-426) contains the code that makes the app work when you push the button. Amongst others, it calls the methods fillInFingerprint to gather the required info, and queryServer to see if the device can be rooted.



It then proceeds by analyzing the server's response. If said response is empty, TowelRoot prompts you about the necessity of an Internet connection (lines 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


If the response is not empty, then TowelRoot proceeds by checking if the abovementioned equals the string nyet (lines 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


If the response equals nyet, then the phone isn't officially supported.



Finally, if the response is both non-empty and different from nyet, TowelRoot starts the rooting procedure by calling the native method rootTheShit, defined at line 448 and probably contained inside the library libexploit.so.






For the brave ones



TowelRoot includes a special mode for users with unsupported devices. This mode, whose code is defined inside the method titleClicked (lines 451-504), is accessible by tapping the red welcome to towelroot v3 title inside the app, and will allow the user to try different modstrings in order to try to root the device anyway.


Topics


2D Engines   3D Engines   9-Patch   Action Bars   Activities   ADB   Advertisements   Analytics   Animations   ANR   AOP   API   APK   APT   Architecture   Audio   Autocomplete   Background Processing   Backward Compatibility   Badges   Bar Codes   Benchmarking   Bitmaps   Bluetooth   Blur Effects   Bread Crumbs   BRMS   Browser Extensions   Build Systems   Bundles   Buttons   Caching   Camera   Canvas   Cards   Carousels   Changelog   Checkboxes   Cloud Storages   Color Analysis   Color Pickers   Colors   Comet/Push   Compass Sensors   Conferences   Content Providers   Continuous Integration   Crash Reports   Credit Cards   Credits   CSV   Curl/Flip   Data Binding   Data Generators   Data Structures   Database   Database Browsers   Date &   Debugging   Decompilers   Deep Links   Dependency Injections   Design   Design Patterns   Dex   Dialogs   Distributed Computing   Distribution Platforms   Download Managers   Drawables   Emoji   Emulators   EPUB   Equalizers &   Event Buses   Exception Handling   Face Recognition   Feedback &   File System   File/Directory   Fingerprint   Floating Action   Fonts   Forms   Fragments   FRP   FSM   Functional Programming   Gamepads   Games   Geocaching   Gestures   GIF   Glow Pad   Gradle Plugins   Graphics   Grid Views   Highlighting   HTML   HTTP Mocking   Icons   IDE   IDE Plugins   Image Croppers   Image Loaders   Image Pickers   Image Processing   Image Views   Instrumentation   Intents   Job Schedulers   JSON   Keyboard   Kotlin   Layouts   Library Demos   List View   List Views   Localization   Location   Lock Patterns   Logcat   Logging   Mails   Maps   Markdown   Mathematics   Maven Plugins   MBaaS   Media   Menus   Messaging   MIME   Mobile Web   Native Image   Navigation   NDK   Networking   NFC   NoSQL   Number Pickers   OAuth   Object Mocking   OCR Engines   OpenGL   ORM   Other Pickers   Parallax List   Parcelables   Particle Systems   Password Inputs   PDF   Permissions   Physics Engines   Platforms   Plugin Frameworks   Preferences   Progress Indicators   ProGuard   Properties   Protocol Buffer   Pull To   Purchases   Push/Pull   QR Codes   Quick Return   Radio Buttons   Range Bars   Ratings   Recycler Views   Resources   REST   Ripple Effects   RSS   Screenshots   Scripting   Scroll Views   SDK   Search Inputs   Security   Sensors   Services   Showcase Views   Signatures   Sliding Panels   Snackbars   SOAP   Social Networks   Spannable   Spinners   Splash Screens   SSH   Static Analysis   Status Bars   Styling   SVG   System   Tags   Task Managers   TDD &   Template Engines   Testing   Testing Tools   Text Formatting   Text Views   Text Watchers   Text-to   Toasts   Toolkits For   Tools   Tooltips   Trainings   TV   Twitter   Updaters   USB   User Stories   Utils   Validation   Video   View Adapters   View Pagers   Views   Watch Face   Wearable Data   Wearables   Weather   Web Tools   Web Views   WebRTC   WebSockets   Wheel Widgets   Wi-Fi   Widgets   Windows   Wizards   XML   XMPP   YAML   ZIP Codes