-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 NEFARIOUSPLAN-CANONICAL-V1 {"body_md":"## The CVE describes a broker that does not exist\n\nThe candidate is for a single bug class: MQTT without authentication. Reading the NVD text alone, a defender would conclude that some component in Yarbo's firmware runs a Mosquitto-style local broker open to LAN traffic. \"Any host on the same network\" in the NVD text reinforces that reading: a host on the same subnet as the robot, reachable across the residential router.\n\nThat broker does not exist. Andreas Makris' [writeup](https://github.com/Bin4ry/yarbo-nat-in-my-back-yard) dumps the broker configuration from the device filesystem. Yarbo robots speak MQTT to three remote brokers:\n\n| Broker | Region | Use |\n|---|---|---|\n| `t9db1d91.us-east-1.emqx.cloud:15736` | EMQX Cloud, US East | Production app and robot traffic |\n| `ke5bbebb.cn-shenzhen.emqx.cloud:8883` | EMQX Cloud, Shenzhen | CN users |\n| `mqtt-b8rkj5da-usw-public.mqtt.tencenttdmq.com` | Tencent Cloud | Server-flagged migration target |\n\nAll three are public-internet cloud services. None are embedded in the firmware. None are anonymous. From `userdata/greengrass/v2/.../device_ops_node.py` lines 44 and 45, replicated in `debug_control.py` line 72 and `debug_display.py` line 39:\n\n```python\nbroker = \"t9db1d91.us-east-1.emqx.cloud\"\nport = 15736\nusername = \"hytech\"\npassword = \"hy18129XXXXXX\"\n```\n\nThe CVE's \"any host on the same network\" describes a LAN-level attack surface. The actual surface is global: the broker is reachable from anywhere with internet access, authentication is required, and the credentials are fleet-wide. The bug is bigger than the CVE says. It also lives somewhere the CVE does not point.\n\n## One credential, six systems\n\n`hy18129XXXXXX` is not the broker's password. It is Yarbo's password, used by their engineers as a single authority token across every system the robots talk to. Makris' filesystem dump catalogs the same string in six separate roles on a single device:\n\n| System | File on robot | Role of the string |\n|---|---|---|\n| FRP SSH tunnel | `com.yarbo.frpc/1.0.17/Archive/frpc.toml` | `auth.token` (frpc to frps registration) |\n| EMQX MQTT (device ops) | `yarbo/3.10.0.3/.../device_ops_node.py` | MQTT password, username `hytech` |\n| EMQX MQTT (debug control) | `yarbo/3.10.0.3/.../launch/debug_control.py` | MQTT password |\n| EMQX MQTT (debug display) | `yarbo/3.10.0.3/.../launch/debug_display.py` | MQTT password |\n| Tencent TDMQ (migration) | `installer/.../MqttClient_v1.0.10_251014/mqtt_client.py` | MQTT password |\n| OTA progress reporting | `ota_progress/1.2.12/ota_progress/progress.py` | MQTT password |\n| Installer deploy script | `userdata/env_init/.env_init/deployDir/deploy.sh` | `usrKey` |\n\nThe `hy` prefix is Hanyangtech's internal naming convention. Hanyangtech (深圳汉阳科技有限公司) is Yarbo's Chinese parent company; the `@Author` headers in these files name `Darwin duanbin@hanyangtech.cn`. The same prefix appears in the root SSH password set by the `credential_updater` Greengrass component, `hy@0886!#`, applied identically on every robot in the fleet.\n\nSix systems, one token, fleet-wide. CVE-2026-7415 covers the MQTT instances. [CVE-2026-7413](https://takeonme.org/cves/cve-2026-7413/) covers the FRP/SSH instance. [CVE-2026-7414](https://takeonme.org/cves/cve-2026-7414/) covers developer credentials in the APK. The three CVEs describe three appearances of one design choice.\n\n## The credential is not leaked. It is shipped.\n\nA leaked credential is one that was supposed to be a secret. The compromised git commit, the misconfigured S3 bucket, the screenshot of a developer's terminal. The vendor's response in those cases is to rotate, revoke, and audit.\n\n`hy18129XXXXXX` is not in that category. There are two retrieval paths:\n\n1. The robot. Pull `device_ops_node.py` off the device filesystem; the password is on line 45.\n2. The phone. The Yarbo Android app, `com.hanyang.yarbo`, is on the Play Store. Extract the APK with any APK puller. The credential is in the asset bundle.\n\nCustomers receive `hy18129XXXXXX` as part of the purchase. The token is the API key the application uses to reach its own backend. There is no version of \"rotation\" that does not break every shipped robot and every installed phone.\n\nThis is what makes \"MQTT broker without ACLs\" the wrong framing. ACLs assume the credentials enforcing them are scoped per-caller. Yarbo issues one credential to every caller. There is no scoping to enforce. The MQTT broker is not the unit of trust; the Yarbo organization is.\n\n## `credential_updater` is the patch the firmware runs\n\nIf Yarbo wanted to fix this, they would push new credentials via OTA. The mechanism is already on every robot. It is named `credential_updater` (v1.0.3), and Makris recovered it from `userdata/greengrass/v2/packages/artifacts/credential_updater/1.0.3/x.update.credentials.sh`:\n\n```bash\nfunction update_password() {\n local user=\"$1\"\n local password=\"$2\"\n echo -e \"$password\\n$password\" | sudo passwd root\n}\n\nfunction main() {\n update_credentials \"$1\" \"$2\" \"firefly\" \"/home/firefly/.aws\"\n update_credentials \"$1\" \"$2\" \"root\" \"/root/.aws\"\n update_password \"root\" \"hy@0886!#\"\n}\n```\n\nThe component is not pushing per-device credentials. It is hardcoding `hy@0886!#` as the root SSH password and applying it identically on every robot in the fleet. The component runs on the device, with the credential baked into its own source.\n\nThe persistence layer beneath it is stacked. The FRP client installs itself into root's crontab on first boot, from `com.yarbo.frpc/1.0.17/Archive/start.sh`:\n\n```bash\n(crontab -l ; echo \"* * * * * bash $SCRIPT_PATH\") | crontab -\n```\n\nCron checks the process every minute. If `frpc` is not running, cron restarts it. A second Greengrass component, `monitor_files` (v1.0.28), uses Linux `auditd` to monitor critical filesystem paths and automatically restore deleted files from a backup directory. If an owner removes `credential_updater` or `com.yarbo.frpc`, `monitor_files` reinstates them. If an owner removes `monitor_files`, Greengrass redeploys it from the AWS IoT Greengrass v2 control plane.\n\nThe persistence is not a coincidence of layered safeguards. The persistence is Yarbo's design statement that the credential is not the customer's to change.\n\n## \"Remote access is not a 'permanently open' feature\"\n\nMakris emailed Yarbo support before publishing. The full transcript is in the writeup. The relevant claim, quoted from Yarbo's reply:\n\n> Remote access is not a \"permanently open\" feature. It is a strictly controlled protocol that is only initiated in the event of a specific repair or a backend diagnostic requirement. Apart from these authorized service instances, your Yarbo remains completely secure and under your exclusive control, no third party has the ability to access or view your details.\n\nThe technical reality is on the device filesystem in `frpc.toml`:\n\n```toml\nserverAddr = \"98.82.87.76\"\nserverPort = 7000\nauth.method = \"token\"\nauth.token = \"hy18129XXXXXX\"\ntransport.tls.enable = false\ntransport.poolCount = 5\ntransport.heartbeatInterval = 30\n\nstart = [\"tcpmuxhttpconnect\"]\n\n[[proxies]]\nname = \"tcpmuxhttpconnect\"\ntype = \"tcpmux\"\nmultiplexer = \"httpconnect\"\nlocalIP = \"127.0.0.1\"\nlocalPort = 22\ncustomDomains = [\"{{ .Envs.SN}}.yb.com\"]\n```\n\n`transport.poolCount = 5` keeps five pre-established TCP connections to Yarbo's frps server at `98.82.87.76:7000` at all times. `transport.heartbeatInterval = 30` is twice a minute. The cron line restarts the daemon if it dies. None of this is \"initiated in the event of a specific repair.\" The tunnel is the operating state of the device.\n\n\"No third party has the ability to access or view your details\" trades on the word `third party`. The frps server is run by Yarbo and routes traffic by serial number. Anyone who can reach `98.82.87.76:6000` and send an HTTP CONNECT request for `.yb.com` is forwarded to that robot's local port 22. Per `frpc.toml`, FRP's `routeByHTTPUser` directive (which would require HTTP Basic auth on the proxy port) is in the config file as a comment, not enabled. The HTTP CONNECT proxy accepts no credential from the caller. The third party in Yarbo's sentence is doing all the work: Yarbo is not a third party to itself, and the unauthenticated public is not a third party until they connect.\n\n## The \"third party\" framing fails further\n\nHanyangtech is not a vendor of Yarbo's. Hanyangtech is Yarbo. The Android package identifier `com.hanyang.yarbo` is the unhidden name; Yarbo Inc. is the US commercial subsidiary of 深圳汉阳科技有限公司, founded in Shenzhen in 2015. The engineers whose names appear in `device_ops_node.py` and `larkbot.py` are not contractors or third-party integrators. They are the company.\n\n`larkbot.py`, present in three locations on the device filesystem, posts robot serial numbers and hardware telemetry directly to ByteDance's Feishu (Lark) infrastructure at `https://open.feishu.cn/open-apis/bot/v2/hook/149cc773-287a-42da-a40b-88873bcae33c`. The DNS resolvers Yarbo's firmware injects via `com.yarbo.script` include `223.5.5.5` (Alibaba DNS) and `114.114.114.114` (114DNS), both Chinese-operated. The MQTT migration the `installer` component currently runs moves robots from EMQX in US-East to Tencent TDMQ, by a server-side per-device flag the owner cannot see or set.\n\nThis is the context for `no third party has the ability to access or view your details`. The infrastructure transmitting that data is operated by Yarbo, Yarbo's Chinese parent, ByteDance, Tencent, and Alibaba. None of them are third parties under the wording of Yarbo's email. The wording is correct. The customer's reading of it is wrong, by Yarbo's own definitions. This is the [denial-by-pedantry](/posts/oracle-cloud-the-breach-they-technically-didnt-deny) shape: a statement whose technical accuracy depends on definitions the customer is not party to.\n\nIt is also the [trust-inversion](/posts/the-trust-inversion) shape, in the architecturally clearest form this catalog has seen. The remote-maintenance tunnel is the trusted lane. The credential-rotation script is the trusted lane. The cloud MQTT bus is the trusted lane. All three were authored by the vendor's parent company, all three carry the same token, and all three are restored if the customer touches them. The validation on the distrusted lane (an attacker on the LAN, which is what the CVE imagines) was never the relevant gate, because the trusted lane (the engineer at Hanyangtech with the master credential) was always going to authorize the action.\n\n## The disclosure is not a disclosure\n\nMakris did not file responsible disclosure on this. The writeup's \"Why I'm publishing this directly\" section is explicit: the FRP tunnel is documented on Yarbo's own developer wiki at `wiki.yarbo.com`; Yarbo's support engineers responded that the architecture is by design and there is no off switch; going back to a company that intentionally built this in would not get it removed.\n\nThis is the same disclosure shape Makris and Kevin Finisterre used on the [Unitree Go1](https://github.com/MAVProxyUser/YushuTechUnitreeGo1/blob/main/Unitree_report.pdf) in 2024: a manufacturer's persistent SSH tunnel into customer-owned devices, with shared credentials, where responsible disclosure was not on the table because the mechanism was the product. The credentials in the Yarbo writeup are partially redacted (`hy18129XXXXXX`, `2323232323@XX.XXX`, `00XXXXXX`) deliberately, so the writeup does not function as a one-click weaponizer. The serial-number enumeration step, the FRP HTTP CONNECT command, the AWS endpoint that returns RTK-precision GPS by serial number alone (`https://oczkojjxh5.execute-api.us-east-1.amazonaws.com/dev/?msg_type=shadow&sn=`), and the full request shape are present.\n\nThe result: a CVE-2026-7415 record that names a single MQTT bug, a CVE-2026-7413 record that names a single SSH bug, a CVE-2026-7414 record that names a single credentials-in-APK bug, and a writeup that explains all three are the same artifact written by the same engineers under the same prefix. The CVE catalog has the parts. The writeup has the assembly.\n\nCVE-2026-7415 will appear in vendor coverage as `Improper Authentication (CWE-306)` against the MQTT broker. The broker is not the unit being authenticated.\n\nPoC: [Bin4ry/yarbo-nat-in-my-back-yard](https://github.com/Bin4ry/yarbo-nat-in-my-back-yard)","closing_line":"The unit being authenticated is Yarbo, by Yarbo, to a backend Yarbo operates, with a credential Yarbo shipped to every customer's phone.","hook_md":"CVE-2026-7415 names \"the MQTT broker embedded in Yarbo firmware v2.3.9\" and says it allows anonymous connections with no topic-level read or write ACLs. The broker is not embedded in the firmware. It is EMQX Cloud, hosted at `t9db1d91.us-east-1.emqx.cloud:15736`. Connections to it are not anonymous. They require username `hytech` and password `hy18129XXXXXX`, hardcoded in five separate files on every robot's filesystem and in the public Android app `com.hanyang.yarbo`. The CVE describes a broker that does not exist and an authentication scheme that the broker is not running.","post_id":279,"slug":"yarbo-mqtt-broker-is-not-anonymous","title":"CVE-2026-7415: Yarbo's MQTT Broker Is Not Anonymous. The Password Is in the App.","type":"initial","unreadable_sentence":"The unit being authenticated is Yarbo, by Yarbo, to a backend Yarbo operates, with a credential Yarbo shipped to every customer's phone."} -----BEGIN PGP SIGNATURE----- iHUEARYIAB0WIQRf0htP5+SjynlxywneZjl4jgkQJgUCas5khQAKCRDeZjl4jgkQ Jvb6AQCp00n0KpplDOitLGeYlmkTIpus20hWX4Xe8tgFbdYWxgD/eI6ZzOiWDJbH ypBS68rOUiXJFzzTcp1/SwpUml0BZgY= =Y+hy -----END PGP SIGNATURE-----