{"id":828,"date":"2014-05-09T15:00:30","date_gmt":"2014-05-09T13:00:30","guid":{"rendered":"http:\/\/sseblog.ec-spride.de\/?p=828"},"modified":"2014-05-09T15:00:30","modified_gmt":"2014-05-09T13:00:30","slug":"easily-extracting-encrypted-messages-from-threema-textsecure-and-co","status":"publish","type":"post","link":"https:\/\/blogs.uni-paderborn.de\/sse\/2014\/05\/09\/easily-extracting-encrypted-messages-from-threema-textsecure-and-co\/","title":{"rendered":"Easily Extracting (&#8220;encrypted&#8221;) Messages from Threema, TextSecure, Chadder, WhatsApp, Hangouts and Co."},"content":{"rendered":"<div class=\"twoclick_social_bookmarks_post_828 social_share_privacy clearfix 1.6.4 locale-en_US sprite-en_US\"><\/div><div class=\"twoclick-js\"><script type=\"text\/javascript\">\/* <![CDATA[ *\/\njQuery(document).ready(function($){if($('.twoclick_social_bookmarks_post_828')){$('.twoclick_social_bookmarks_post_828').socialSharePrivacy({\"txt_help\":\"Wenn Sie diese Felder durch einen Klick aktivieren, werden Informationen an Facebook, Twitter, Flattr, Xing, t3n, LinkedIn, Pinterest oder Google eventuell ins Ausland \\u00fcbertragen und unter Umst\\u00e4nden auch dort gespeichert. N\\u00e4heres erfahren Sie durch einen Klick auf das <em>i<\\\/em>.\",\"settings_perma\":\"Dauerhaft aktivieren und Daten\\u00fcber-tragung zustimmen:\",\"info_link\":\"http:\\\/\\\/www.heise.de\\\/ct\\\/artikel\\\/2-Klicks-fuer-mehr-Datenschutz-1333879.html\",\"uri\":\"https:\\\/\\\/blogs.uni-paderborn.de\\\/sse\\\/2014\\\/05\\\/09\\\/easily-extracting-encrypted-messages-from-threema-textsecure-and-co\\\/\",\"post_id\":828,\"post_title_referrer_track\":\"Easily+Extracting+%28%26%238220%3Bencrypted%26%238221%3B%29+Messages+from+Threema%2C+TextSecure%2C+Chadder%2C+WhatsApp%2C+Hangouts+and+Co.\",\"display_infobox\":\"on\"});}});\n\/* ]]> *\/<\/script><\/div><p>Max Kolhagen (bachelor student) and <a href=\"http:\/\/www.ec-spride.tu-darmstadt.de\/en\/research-groups\/secure-software-engineering-group\/staff\/siegfried-rasthofer\/\">Siegfried Rasthofer<\/a>\u00a0demonstrate how a malicious application with no permission can be used to\u00a0read incoming messages from WhatsApps, Hangouts, etc. and even &#8220;<strong>encrypted<\/strong>&#8221; messages sent through Threema, TextSecure or Chadder with ease.<\/p>\n<p><!--more--><\/p>\n<p><a href=\"http:\/\/blogs.uni-paderborn.de\/sse\/files\/2014\/04\/Screenshot_2014-05-05-16-04-47-e1399394727730.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignright size-medium wp-image-894\" src=\"http:\/\/sseblog.ec-spride.de\/wp-content\/uploads\/2014\/04\/Screenshot_2014-05-05-16-04-47-180x300.png\" alt=\"Notifications\" width=\"180\" height=\"300\" \/><\/a><\/p>\n<p>Many messaging apps, such as WhatsApp or Hangouts have this nice feature of getting notifications when an SMS or message is received. The notification contains the full message including the name of the sender. Besides these &#8220;standard&#8221; messaging apps, there are also apps which support an end-to-end encryption for a secure communication between two users. The most common end-to-end encryption apps are: Threema, TextSecure and Cheddar. Also these apps support this nice feature. The image on the right shows an example of an incoming &#8220;encrypted&#8221; messages from Threema and TextSecure.<\/p>\n<p>But wait a second&#8230; Aren&#8217;t these message supposed to be encrypted? This was the point where it got interesting to\u00a0us and we tried to find out whether it is possible and how can we extract a\u00a0text from the notification bar.<\/p>\n<p><strong>How can one programmatically access the notification bar?<\/strong><\/p>\n<p>Well, there may be many different possibilities for extracting data from the notification bar. We will introduce two in the following, one method which works only on Android version greater than\u00a04.3 and one which works for 4.2 and below.<\/p>\n<p>Up until Android 4.3 every developer who wanted to get information from the notification bar, needed to use an <a href=\"http:\/\/developer.android.com\/reference\/android\/accessibilityservice\/AccessibilityService.html\" target=\"_blank\">AccessibilityService<\/a>. This particular service was originally intended to help developers build services that enable users with limited perception to <a href=\"http:\/\/developer.android.com\/guide\/topics\/ui\/accessibility\/services.html\" target=\"_blank\">engage with Android OS<\/a>.<\/p>\n<p>In order to being able to access notifications you need to tell the service what kind of events you want to subscribe to:<\/p>\n<pre>@Override\nprotected void onServiceConnected() {\n  super.onServiceConnected();\n\n  AccessibilityServiceInfo info = new AccessibilityServiceInfo();\n  info.flags = AccessibilityServiceInfo.DEFAULT;\n  info.eventTypes = AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED;\n  info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;\n\n  this.setServiceInfo(info);\n}\n<\/pre>\n<p>In our case we are subscribing to notification events only (TYPE_NOTIFICATION_STATE_CHANGED). Now every time a notification is posted, updated or removed the following method is called in which we can extract the desired data:<\/p>\n<pre>@Override\npublic void onAccessibilityEvent(AccessibilityEvent event) {\n  if (event.getEventType() != AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED)\n    return;\n\n  Notification notification = (Notification) event.getParcelableData();\n\n  Log.d(TAG, \"Incoming notification!\");\n  Log.d(TAG, \"App: \" + event.getPackageName());\n  Log.d(TAG, \"Ticker: \" + notification.tickerText);\n}\n<\/pre>\n<p>This was always considered a \u201chacky\u201d solution, so with Android Jelly Bean (4.3), accessing notification became a lot easier. In order to do that, a service called <a href=\"https:\/\/developer.android.com\/reference\/android\/service\/notification\/NotificationListenerService.html\" target=\"_blank\">NotificationListenerService<\/a> was introduced. This service&#8217;s only purpose is to provide access to all notifications with a much simpler interface.<\/p>\n<pre>@Override\npublic void onNotificationPosted(StatusBarNotification sbn) {\n  Log.d(TAG, \"Incoming notification!\");\n  Log.d(TAG, \"App: \" + sbn.getPackageName());\n  Log.d(TAG, \"Ticker: \" + sbn.getNotification().tickerText);\n}\n<\/pre>\n<p>This example does exactly the same as the AccessibilityService but without the event registration process and the usage of Parcelable objects.<\/p>\n<p><a href=\"http:\/\/blogs.uni-paderborn.de\/sse\/files\/2014\/05\/installation.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignright size-medium wp-image-914\" src=\"http:\/\/blogs.uni-paderborn.de\/sse\/files\/2014\/05\/installation-180x300.png\" alt=\"NotiReader: Installation\" width=\"180\" height=\"300\" srcset=\"https:\/\/blogs.uni-paderborn.de\/sse\/files\/2014\/05\/installation-180x300.png 180w, https:\/\/blogs.uni-paderborn.de\/sse\/files\/2014\/05\/installation.png 300w\" sizes=\"auto, (max-width: 180px) 100vw, 180px\" \/><\/a><\/p>\n<p>To sum it up, with either of these services we gain access to all notifications on the device. The alarming part about this is, that we do not need any permission to do so.<\/p>\n<p>As you can see in the image, the installation of an app that implements both of the previously mentioned services does not outline a single permission!<\/p>\n<p><strong>Extracting the notifications&#8217; content.<\/strong><\/p>\n<p>Up to this point we are able to access the notifications, but how do we access the messages of different messaging apps?<\/p>\n<p>You probably already noticed that one of the log statements included the package name of the app that posted the corresponding notification. We can use that information to differ if a certain notification belongs to a known messaging app or not.<\/p>\n<p>Extracting the actual content then depends on how the messaging app displays their messages in the notification bar. Some, like the Stock Android SMS\/MMS app, already display the whole message content inside the ticker text. Therefore, we are able to extract the message without further effort:<\/p>\n<pre>int indexDelimiter = ticker.indexOf(':');\n\nif (indexDelimiter == -1)\n  return null;\n\nString sender = ticker.substring(0, indexDelimiter);\nString message = ticker.substring(indexDelimiter + 2);\n<\/pre>\n<p>For others, though, this is a bit trickier since they only show the message in the real notification itself (see first image).<\/p>\n<p>In order to access their content you have to understand how notifications are displayed on the system level. They are built using a sequence of reflective actions that are performed on a blank notification view. Furtunately we are able to access these actions by also using reflections:<\/p>\n<pre>RemoteViews views = notification.contentView;\nClass&lt;?&gt; rvClass = views.getClass();\n\n\/\/ access private list mActions\nField field = rvClass.getDeclaredField(\"mActions\");\nfield.setAccessible(true);\n<\/pre>\n<p>Then we can browse that list of actions for the ones that are responsible for posting text. Since we know exactly how each messaging app displays their notifications, we are now able to precisely locate and extract the content that we are interested in.<\/p>\n<p><strong>Cool, so let&#8217;s try it on different messaging apps!<\/strong><\/p>\n<p>For that purpose we developed an app called NotiReader which, as mentioned, does not require <em>any permission<\/em>. It\u00a0is able to extract and store incoming messages, displayed in the notification bar.<\/p>\n<p>The following image shows an example of NotiReader:<\/p>\n<p><a href=\"http:\/\/blogs.uni-paderborn.de\/sse\/files\/2014\/04\/Screenshot_2014-05-05-15-48-38-e1399394617596.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-900\" src=\"http:\/\/sseblog.ec-spride.de\/wp-content\/uploads\/2014\/04\/Screenshot_2014-05-05-15-48-38-180x300.png\" alt=\"NotiReader App\" width=\"180\" height=\"300\" \/><\/a><\/p>\n<p>The fact that this application does not require any permission causes a\u00a0serious problem, because\u00a0an attacker is able to extract sensitive information from incoming SMS messages such as the TAN of a banking transaction without being detected. If one\u00a0would extend this app with a single permission, the Internet-permission, she\u00a0would be able actually steal all these sensitive data. Other research has already shown some approaches were data can be sent over the Internet without any permission. This shows, that it is even worse and this application could steal your personal data with\u00a0zero permissions.<\/p>\n<p><strong>Is it really as bad as it sounds?<\/strong><\/p>\n<p>Fortunately NO due to two reasons:<\/p>\n<p>1) SMS\/MMS (stock app), Hangouts, Facebook Messenger, Threema and TextSecure have the ability to disable information shown in the notification bar. Unfortunately,\u00a0in all of these apps, these settings are NOT activated by default! A user has to find this setting in the app and then disable it.<\/p>\n<p style=\"text-align: center\"><a href=\"http:\/\/blogs.uni-paderborn.de\/sse\/files\/2014\/05\/settings_threema.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-916\" src=\"http:\/\/blogs.uni-paderborn.de\/sse\/files\/2014\/05\/settings_threema-180x300.png\" alt=\"Settings: Threema\" width=\"180\" height=\"300\" srcset=\"https:\/\/blogs.uni-paderborn.de\/sse\/files\/2014\/05\/settings_threema-180x300.png 180w, https:\/\/blogs.uni-paderborn.de\/sse\/files\/2014\/05\/settings_threema.png 300w\" sizes=\"auto, (max-width: 180px) 100vw, 180px\" \/><\/a><a href=\"http:\/\/blogs.uni-paderborn.de\/sse\/files\/2014\/05\/settings_sms.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-913\" style=\"margin-left: 20px\" src=\"http:\/\/blogs.uni-paderborn.de\/sse\/files\/2014\/05\/settings_sms-180x300.png\" alt=\"Settings: SMS (Stock)\" width=\"180\" height=\"300\" srcset=\"https:\/\/blogs.uni-paderborn.de\/sse\/files\/2014\/05\/settings_sms-180x300.png 180w, https:\/\/blogs.uni-paderborn.de\/sse\/files\/2014\/05\/settings_sms.png 300w\" sizes=\"auto, (max-width: 180px) 100vw, 180px\" \/><\/a><\/p>\n<p>Other apps we examined, like WhatsApp and Cheddar, do currently not support such features. Threema and SMS\/MMS furthermore allow only showing a notification that does not reveal anything about the message&#8217;s content itself, which is a good trade-off.<\/p>\n<p>2) The extraction of information from the notification bar requires an additional manual activation of either the NotificationListenerService (which can be activated under Settings &#8211; Security &#8211; Notification access) or the AccessibilityService (Settings &#8211; Accessibility). In both cases the user gets a security alert from the Android OS:<\/p>\n<p style=\"text-align: center\"><a href=\"http:\/\/blogs.uni-paderborn.de\/sse\/files\/2014\/04\/Screenshot_2014-05-06-15-27-21-e1399394704979.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-896\" src=\"http:\/\/sseblog.ec-spride.de\/wp-content\/uploads\/2014\/04\/Screenshot_2014-05-06-15-27-21-180x300.png\" alt=\"Dialog: NotificationListenerService\" width=\"180\" height=\"300\" \/><\/a><a href=\"http:\/\/blogs.uni-paderborn.de\/sse\/files\/2014\/04\/Screenshot_2014-05-06-15-34-01-e1399394569933.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-897\" style=\"margin-left: 20px\" src=\"http:\/\/sseblog.ec-spride.de\/wp-content\/uploads\/2014\/04\/Screenshot_2014-05-06-15-34-01-180x300.png\" alt=\"Dialog: AccessibilityService\" width=\"180\" height=\"300\" \/><\/a><\/p>\n<p>These are good news, but one has to think about apps, which\u00a0have to activate these services for their internal functionality. Can we trust these apps that they do not steal our personal data?<\/p>\n<p>&nbsp;<\/p>\n<p>The full source code is available as a github project <a href=\"https:\/\/github.com\/mkolhagen\/NotiReader\">here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Max Kolhagen (bachelor student) and Siegfried Rasthofer\u00a0demonstrate how a malicious application with no permission can be used to\u00a0read incoming messages from WhatsApps, Hangouts, etc. and even &#8220;encrypted&#8221; messages sent through Threema, TextSecure or Chadder with ease.<\/p>\n","protected":false},"author":6581,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11,51],"tags":[],"class_list":["post-828","post","type-post","status-publish","format-standard","hentry","category-android","category-security-analysis"],"_links":{"self":[{"href":"https:\/\/blogs.uni-paderborn.de\/sse\/wp-json\/wp\/v2\/posts\/828","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.uni-paderborn.de\/sse\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.uni-paderborn.de\/sse\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.uni-paderborn.de\/sse\/wp-json\/wp\/v2\/users\/6581"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.uni-paderborn.de\/sse\/wp-json\/wp\/v2\/comments?post=828"}],"version-history":[{"count":0,"href":"https:\/\/blogs.uni-paderborn.de\/sse\/wp-json\/wp\/v2\/posts\/828\/revisions"}],"wp:attachment":[{"href":"https:\/\/blogs.uni-paderborn.de\/sse\/wp-json\/wp\/v2\/media?parent=828"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.uni-paderborn.de\/sse\/wp-json\/wp\/v2\/categories?post=828"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.uni-paderborn.de\/sse\/wp-json\/wp\/v2\/tags?post=828"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}