UPLINKSECURE
NODECAMHAK-01
TIME--:--:--
USERguest@setec
// 20 FINDINGS   /   3 LIVE CVES   /   1 BLINKING LIGHT //
a setec labs original investigation · april 2026 · report v1.0

Executive Summary

I bought a generic Chinese IP camera off a marketplace listing — the kind that costs less than dinner. Plugged it in, watched what it does, then started taking it apart. Three weeks later I had extracted hardcoded admin secrets, forged authenticated requests against the vendor's operator API, mapped the entire cloud backend, identified eight leaked Google & Alibaba API keys, confirmed three CVEs apply to the device, and put together this report.

The vendor is UBIA Technologies — legal name Shenzhen Qingshi Internet Technology Co., Ltd. (深圳市青视互联科技有限公司), founded 2014, based in Bao'an District, Shenzhen. They claim to have shipped over three million low-power cameras. The hardware is the same Ingenic T31 reference design sold under at least nine brand names — UBox, UCon, YBox, Javiscam, Funstorm, i-Cam+, Soliom+, icamplus, Jarvis-, xega — all the same firmware, all the same backend, all the same problems.

UBIA didn't respond when CISA tried to contact them about the existing CVE-2025-12636. They probably won't respond to this either. I'm publishing under a 90-day responsible-disclosure window from April 2026 with sensitive specifics redacted; CISA coordinators and UBIA security contacts can request the unredacted artifact pack at the email below.

This report covers 20 distinct findings, 3 applicable CVEs, the full toolchain we built, and the failed paths we tried so other researchers don't have to repeat them. Everything below is from research on a device I own. No production user data was touched. PII has been redacted from all example payloads. The source code for every tool is published at repo.seteclabs.io/SetecLabs/cam-mitm.

Methodology: passive observation first, MITM on a controlled LAN, decompilation of the official Android app, native binary analysis of the bundled libUBICAPIs.so series, original PoC verifiers built from scratch (no public exploit code reused), and direct reproduction against my own camera. No port scans were run against the vendor's infrastructure. No credentials beyond my own account were used. No production accounts were touched.


Target Profile
Brand           Javiscam (one of nine OEM rebrands of the same hardware)
Model           2604  (Product ID 1619)
SoC             Ingenic T31 (Junzheng) — per UBIA marketing
Android App     cn.ubia.ubox v1.1.360 (Pro: com.ubianet.uboxpro)
Vendor          UBIA Technologies Co. / Shenzhen Qingshi Internet Technology Co.
Founded         2014  (Bao'an District, Shenzhen, Guangdong)
Firmware        2604.1.2.69 (current shipping)
P2P Stack       ThroughTek Kalay (rebranded internally as "UBIC")
MAC OUI         14:92:F9 (TP-Link reference design)
IOTC UID        20-char alphanumeric (Kalay format, REDACTED)
Cloud Portal    portal.ubianet.com (US, CN, EU regions)
OAM Portal      oam.ubianet.com (operator/admin tier)
Photo Storage   Alibaba OSS + AWS S3 (ubiasnap-{eu,as} multi-region)
OTA Storage     Tencent COS (ubiaota-us-1312441409, ubiaota-cn-1312441409)
Tencent APPID   1312441409
Push Service    TCP/20003
P2P Relay       UDP/10240 (Tencent + Alibaba clouds)
Master Servers  portal.{us,cn}.ubianet.com  + ThroughTek Kalay masters

Architecture is the standard Shenzhen IPC playbook: small ARM SoC, no inbound services, all comms outbound through a P2P relay run by ThroughTek's master servers and the vendor's portal. The camera never opens a port to the LAN. It just dials home, registers its UID against a Kalay master, and waits for the legitimate client app to connect through the relay. Local control requires the per-device IOTC credentials, which the cloud API leaks (V01).

The vendor's own marketing page (ubia.com.cn/intro/1.html) confirms the SoC family: UBIA describes themselves as having "launched a Junzheng T31 low-power doorbell / battery camera" with over three million units shipped. Junzheng is the Chinese name for Ingenic. T31 is the standard battery-IPC reference SoC, fully supported by the open-source OpenIPC project.


Methodology

Standard ISC research methodology, no unusual tradecraft:

  1. 01
    Passive observation. Plug the camera into a controlled LAN. Capture all traffic with tcpdump. Identify the cloud endpoints, DNS lookups, P2P registration packets, and connectivity-check destinations the device hits without prompting. Output: a list of every IP and hostname the camera ever talks to.
  2. 02
    Active MITM on the LAN. Build a small Python framework (later setec_suite/cam-mitm) that does ARP spoofing, DNS interception with our own answers, HTTP/HTTPS interception with auto-generated certs, raw packet sniffing per IP, and protocol fingerprinting from the first 6 bytes of every payload. Use it to capture the camera's API requests in cleartext and analyze them.
  3. 03
    App decompilation. Pull the official UBox Android app from APKPure (cn.ubia.ubox v1.1.360). Extract resources with jadx. Statically grep for: API endpoint strings, hardcoded credentials, cryptographic constants, OAuth/OAM signing schemes, hardcoded IPs and hostnames, third-party SDK identifiers. Cross-reference any interesting findings against the live MITM captures.
  4. 04
    Native binary analysis. The app's TUTK/Kalay stack is in libUBICAPIs.so (and ...23.so, ...29.so for ABI variants). Pull strings, list exported symbols with nm -D, locate the crypto init/encode/decode functions, disassemble those with arm-linux-gnueabi-objdump, and look for static keys, master server hostnames, and runtime-derived auth schemes.
  5. 05
    Authenticated API enumeration. Log into the cloud portal with my own account using our reproduced auth scheme. Hit every endpoint we harvested from the decompiled app (146 of them) with empty bodies first; flag any that return real data, an error code with a meaningful message, or a documented schema. Then mutate parameters on the interesting ones.
  6. 06
    Forged operator-API requests. The decompiled app contains an OamHttpClient class with a hardcoded HMAC secret used to sign requests against UBIA's operator/admin tier (oam.ubianet.com). Reproduce the signing scheme. Forge requests against the OAM endpoints we know exist. Confirm acceptance.
  7. 07
    CVE verification. Build original non-destructive verifiers for the CVEs we believe apply (CVE-2025-12636 cred leak, CVE-2021-28372 Kalay UID hijack, CVE-2023-6322/6323/6324 Kalay LAN parser chain). Each verifier probes the necessary preconditions on the live camera and reports VULN / NOT_VULN / UNKNOWN with evidence. No exploit payloads were sent. No overflow attempts. No spoofed master-server registrations.
  8. 08
    Documentation. Every finding gets a numbered V-record with severity, source location, vector summary, evidence, and remediation guidance. Sensitive specifics (actual leaked secret values, the alternate hardcoded password, the live API keys) are redacted from this public report and held back for the vendor.

What I did not do: scan the vendor's infrastructure with port scanners, test against accounts other than my own, perform any operation that would interfere with other users' devices, send overflow / fuzz payloads to the live camera, or use any public exploit code. Every PoC in this report is original.


Findings  [ V01 — V20 ]

Twenty distinct issues. Severity is mine, calibrated to "what an attacker can actually do" rather than CVSS theatre. Sensitive technical specifics are redacted on this public page; the unredacted artifact pack is available to CISA coordinators and UBIA security contacts on request.

IDSeverityTitle
V01CRITCloud API leaks IOTC device credentials in plaintext CVE-2025-12636
V02HIGHCloud API leaks Alibaba/Tencent/Google keys in login response
V03MEDPassword hashing is HMAC-SHA1 with an empty key (= plain SHA1)
V04HIGHSSL certificate validation disabled in app (ALLOW_ALL_HOSTNAME_VERIFIER)
V05CRITUses ThroughTek Kalay SDK CVE-2021-28372 CVE-2023-6322
V06HIGHFirmware connectivity checks over plain HTTP
V07MEDFirmware download URL is sent to camera via IOTC command 4631 (injectable)
V08INFOCloud infrastructure fully discoverable
V09HIGHIOTC command set allows full device control with leaked creds
V10MEDUser photo URL leaks Alibaba OSS access key ID
V11HIGHapp/getconfig leaks 8 cloud API keys (Google + AMap, per OEM × OS)
V12HIGHOTA bucket discovery via cloud config (Tencent COS, public-read on objects)
V13MEDSecond hardcoded camera password discovered [REDACTED]
V14HIGHOAM admin HMAC secret hardcoded — LIVE-CONFIRMED forging
V15MEDSIM2 cellular API AppID/Secret hardcoded
V16INFONative libUBICAPIs.so confirms rebranded ThroughTek Kalay stack
V17MEDuser/account/get_current_user leaks personal data
V18INFO146 API endpoints discoverable from decompiled APK
V19INFOSoC identified: Ingenic T31 (per UBIA marketing) — enables OpenIPC pivot
V20INFOVendor legal entity & disclosure contacts identified
V01 CRIT CVE-2025-12636

Cloud API leaks IOTC device credentials in plaintext

Vector
The vendor's POST /api/user/device_list endpoint, when called by an authenticated owner, returns each owned device with the fields cam_user and cam_pwd in plaintext. These are not metadata about the device account on the cloud — they are the IOTC P2P device-auth credentials used to connect to the camera over the Kalay relay. Any party who obtains them can take full local control of the camera over P2P.
Reproduction
$ curl -sX POST https://portal.ubianet.com/api/user/device_list \
       -H "Content-Type: application/json" \
       -H "X-Ubia-Auth-UserToken: <owner_token>" \
       -H "X-UbiaAPI-CallContext: source=app&app=ubox&ver=1.1.360&osver=14" \
       -d '{}'
Evidence (sanitized)
{
  "code": 0, "msg": "success",
  "data": {
    "list": [
      {
        "device_uid": "<REDACTED-20-char>",
        "name": "Living Room Cam",
        "model_num": "2604",
        "cam_user": "<REDACTED>",          // IOTC username
        "cam_pwd":  "<REDACTED-13-char>",  // IOTC password — plaintext
        ...
      }
    ]
  }
}
Impact
Anyone who obtains a user's API token (or compromises the user's account) can immediately enumerate every camera the user owns and pull the local-auth credentials for each one. Combined with the leaked IOTC UID (also in the same response), the attacker can connect to the camera over the Kalay P2P relay from anywhere on the internet and execute the full IOTC command set (V09): live video, live audio, file enumeration, snapshot capture, motion-config rewrite, factory reset, device reboot. Plaintext storage of device-auth credentials by an account-tier API is a textbook CWE-522 violation.
Mitigation
Stop returning cam_user / cam_pwd in any cloud-tier API response. The legitimate app uses these credentials only to authenticate the IOTC session — that authentication can be performed by the cloud on the user's behalf with a short-lived token, the way Wyze, Tapo, and other modern cloud cameras have been doing for years.
Discovery notes
Originally disclosed via CISA advisory ICSA-25-310-02; UBIA did not respond to coordination. Our independent verification reproduces the issue against current shipping firmware (2604.1.2.69) using a freshly created consumer account.
V02 HIGH

Cloud API leaks Alibaba/Tencent/Google keys in login response

Vector
The login response (POST /api/v3/login) embeds an app_config object that includes Alibaba Cloud OSS keys, Tencent Cloud keys, Google API keys, and AMap (Chinese maps) API keys for the app's mapping/storage features.
Impact
Any authenticated user can pull these keys and incur Google Cloud / Alibaba / Tencent billing damage on the vendor's accounts, abuse the maps services to mass-resolve location data, or pivot if the keys grant access to other Google projects sharing the same restrictions.
Mitigation
Move all third-party API calls behind the vendor's own backend. Never ship API keys in client-facing responses.
V03 MED

Password hashing is HMAC-SHA1 with an empty key

Vector
From com/http/HttpClient.java:195 and NewApiHttpClient.java:737-744: account passwords are hashed with Base64(HmacSHA1(password, "")), then base64-encoded with character substitutions (+-, /_, =,). HMAC with an empty key is mathematically equivalent to plain SHA1. There is no salt and no iteration count.
Impact
If the cloud-side password store is ever compromised, the entire user-base is recoverable to weak passwords in seconds with any modern cracking rig. Trivial offline brute force.
Mitigation
Switch to bcrypt or argon2id with per-user salts and a server-side cost factor. The fact that the password hashing is performed client-side with a fixed scheme means changing it requires app + server coordination.
V04 HIGH

SSL certificate validation disabled in the app

Vector
NewApiHttpClient.java:1053 uses SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER. The app accepts any SSL certificate presented by any host, including self-signed and unrelated certs. There is no certificate pinning anywhere in the app's HTTP client.
Impact
Trivial MITM attack against the app. Anyone who can position themselves on the network path between the user's phone and portal.ubianet.com (rogue WiFi, ARP spoof on a hotel LAN, BGP hijack against an ISP) can intercept and modify all API traffic. We used exactly this approach for our own analysis.
Mitigation
Implement certificate pinning. The vendor controls a finite, stable set of TLS certificates for portal.ubianet.com — pin to those.
V05 CRIT CVE-2021-28372 CVE-2023-6322

Uses ThroughTek Kalay SDK (rebranded as "UBIC")

Vector
The app's native libraries (libUBICAPIs.so, libUBICAPIs23.so, libUBICAPIs29.so, libUBIENotify.so) are a rebranded ThroughTek Kalay SDK. We confirmed this from symbol inspection: the libraries export p4p_crypto_init, p4p_crypto_encode, p4p_crypto_decode, p4p_device_auth, p4p_device_update_auth, p4p_client_send_masterhello, and reference Java class names like com/tutk/IOTC/st_LanSearchInfo2. Master server hostnames in .rodata point at portal.ubianet.com et al.
Impact
Every CVE published against ThroughTek Kalay applies, in particular CVE-2021-28372 (UID-based session hijack against the master, CVSS 9.6) and the CVE-2023-6322 / -6323 / -6324 chain (LAN-side parser memory corruption + auth bypass + RCE). The rebrand has no impact on the vulnerability surface.
Mitigation
Upgrade to the latest patched ThroughTek SDK. The rebranding does not exempt the vendor from following ThroughTek's security advisories.
V06 HIGH

Firmware connectivity checks over plain HTTP

Vector
On boot, the camera makes plain HTTP (port 80) connectivity-check requests to www.microsoft.com, www.amazon.com, www.apple.com, and www.qq.com — the last entry is the strong tell that the firmware was compiled for the Chinese-domestic market. From cam_monitor.pcap in the engagement artifacts.
Impact
By itself this is mostly an information disclosure (clear-text proof of online connectivity). Combined with V07, it enables a MITM attacker to redirect the connectivity check, then intercept the subsequent firmware download path the camera triggers.
V07 MED

Firmware update URL is sent to the camera via IOTC command 4631

Vector
From com/apiv3/bean/AdvancedSettings.java:883-890: the legitimate app calls check_version/v3 on the cloud, receives an OTA URL in the response, then constructs a SMsgAVIOCtrlFirmwareUpdateReq struct and sends it to the camera over P2P as IOTC command 4631. The struct contains the URL, file size, MD5, and a "required" flag. The camera then downloads from the URL itself.
Impact
If the app's check_version response is intercepted (V04) or if an attacker can inject IOTC command 4631 directly (using leaked V01 credentials), the camera can be made to download firmware from any attacker-chosen URL. Combined with V06 (firmware downloaded over HTTP, not HTTPS), this is a full firmware-replacement vector.
Mitigation
Sign firmware images with a vendor private key and verify the signature on-device before flashing. Reject any URL that isn't on a hardcoded allow-list. Enforce TLS for the actual download.
V08 INFO

Cloud infrastructure fully discoverable

Vector
Every cloud component the device or app uses is discoverable from a single afternoon of MITM and decompilation: portal.{us,cn,eu}.ubianet.com (regional API tiers), oam.ubianet.com (operator/admin tier), ubiaota-{us,cn}-1312441409.cos.{na-siliconvalley,ap-guangzhou}.myqcloud.com (Tencent COS firmware buckets, with the APPID embedded in the hostname), ubiasnap-{eu,as}.oss-{eu-central-1,ap-southeast-1}.aliyuncs.com (Alibaba OSS photo storage), uboxphoto-us.oss-us-west-1.aliyuncs.com (US photo bucket), Tencent Cloud relay IPs in the 43.x range, and the SIM management portal at 118.178.150.203:9001 / api.iot400.com.
Impact
Information disclosure. By itself low severity, but it builds the target map for every other finding.
V09 HIGH

IOTC command set allows full device control with leaked creds

Vector
The IOTC P2P protocol exposes the standard ThroughTek command set. With the V01 credentials, an attacker can: stream live video (768) and audio (769), enumerate / download / upload / delete files on the SD card (48644877), trigger a firmware update (4631, V07), pull device info (816), read and rewrite motion-detection config (806), format the SD card (896), reassign the device's UID (241), capture pictures remotely (8482), and reboot the device (event type 16).
Impact
Full device takeover from anywhere on the internet that can reach the Kalay relay (which is anywhere). With V01, the attacker is one cloud API call away from having all of these abilities.
V10 MED

User photo URL leaks Alibaba OSS access key ID

Vector
The avatar_url field in user-account responses is a pre-signed Alibaba OSS URL with the access key ID embedded as a query parameter. The bucket itself is access-controlled (anonymous list returns AccessDenied) but the access key ID is leaked in cleartext to every authenticated user.
Impact
By itself low. If the corresponding secret is ever leaked from another endpoint, the access key becomes immediately useful for AWS-style S3-compatible operations against the bucket.
V11 HIGH

app/getconfig leaks 8 cloud API keys

Vector
The authenticated POST /api/app/getconfig endpoint returns an android_private_config and ios_private_config object containing Google Maps and AMap API keys for every OEM brand × OS combination — eight distinct keys in one response, plus AMap-by-Google translation keys for two brands. The same response also embeds the OTA bucket hostnames and the Tencent Cloud APPID.
Reproduction
$ curl -sX POST https://portal.ubianet.com/api/app/getconfig \
       -H "X-Ubia-Auth-UserToken: <owner_token>" \
       -H "Content-Type: application/json" -d '{}'
Evidence (sanitized)
{
  "code": 0, "msg": "success",
  "data": {
    "config_uboxpro": {
      "demo_video_en_url": "http://ubiaota-us-1312441409.cos.na-siliconvalley.myqcloud.com/...",
      "demo_video_zh_url": "http://ubiaota-cn-1312441409.cos.ap-guangzhou.myqcloud.com/..."
    },
    "android_private_config": {
      "ucon": {
        "AMapAPIKey":          "<REDACTED>",
        "GoogleAPIKey":        "<REDACTED>",
        "AMapByGoogleAPIKey":  "<REDACTED>"
      },
      "ybox": { ...four more keys, REDACTED... }
    },
    "ios_private_config": { ...four more keys, REDACTED... }
  }
}
Impact
An authenticated user can pull all eight keys and burn UBIA's quota / billing on Google Maps + Gaode (AMap) at will. If any key is shared with other UBIA Google Cloud projects, lateral abuse is possible.
Mitigation
Remove the keys from any client-facing response. Proxy all maps calls through the vendor's own backend.
V12 HIGH

OTA bucket discovery via cloud config

Vector
The same app/getconfig response (V11) leaks the firmware OTA bucket hostnames: ubiaota-us-1312441409.cos.na-siliconvalley.myqcloud.com and ubiaota-cn-1312441409.cos.ap-guangzhou.myqcloud.com. The Tencent Cloud APPID (1312441409) is part of the hostname. The example demo video URL embedded in the response (dev_add_doc/1159_video/...) confirmed individual objects in the bucket are public-read by ACL.
Impact
With the bucket name + product ID + model number, an attacker can attempt enumeration of firmware paths anonymously. Anonymous bucket listing is denied, but if any firmware object's path is guessable or leaks via another channel, anyone can download it without an account.
Discovery notes
We attempted 320 anonymous HEAD requests against plausible path templates (dev_add_doc/{pid}/{ver}.bin, firmware/{model}/{ver}.bin, etc.) and got zero hits. The real path scheme is non-obvious. MITM of the camera's own boot-time check should reveal it.
V13 MED

Second hardcoded camera password discovered

Vector
From cn/ubia/activity/LiveView.java:413 (and LiveViewNew.java, LiveViewNew2.java, AddCarmeraSearchActivity.java): a second hardcoded camera credential is used as a fallback in the live-view code paths, alongside the primary admin/<V01-leaked-pwd> pair. The string is unique enough that it has zero hits on the public web — meaning it is UBIA-specific, not part of any common Yoosee/VStarcam shared default set. Specific password redacted from this public report.
Impact
Adds a second guessable local credential. Combined with V01 and the box-mode admin/admin from BoxWireReady.java:421, the camera local-auth attack surface has at least three default username/password pairs.
V14 HIGH

OAM admin HMAC secret hardcoded — LIVE-CONFIRMED forging

Vector
From com/http/OamHttpClient.java:28: the operator/admin client embeds a hardcoded HMAC-SHA1 secret used to sign requests against UBIA's operator tier at https://oam.ubianet.com/api/. The signing scheme (from the same file plus com/http/Encryption.java) is:
sig_str = <timestamp_ms> + ":" + <appid> + ":" + <clientId> + ":" + <body>
sig     = HmacSHA1(sig_str.utf8, secret.bytes)  // hex-encoded
Headers sent: OAM-SIGN, OAM-APPID: 30001, CLIENT-ID, timestamp. Specific secret value redacted from this public report.
Reproduction (live-confirmed)
We reproduced the signing scheme in our own client and posted to the only OAM endpoint visible in the app source (lgc/bind_err). The server accepted our forged signature and returned {"code": 0, "data": "", "msg": "success"}. We then posted to the second known OAM endpoint (app/push_channel_reg) and received a structured response back containing the registration schema ({app_id, account, channel_id, mobile_info, token_id, err_title, err_msg}) — confirming both endpoints are live and our signature is valid.
Impact
Any holder of the consumer APK can extract the secret in seconds and forge arbitrary requests against UBIA's operator/admin API. The full OAM endpoint set is not enumerated in the consumer app — only two endpoints are visible — but the existence of an authenticated operator tier with a fixed HMAC secret is itself a critical issue. Anyone willing to guess endpoint paths and replay them will eventually find the bulk-management routes.
Mitigation
Stop putting OAM credentials in the consumer APK at all. The consumer app has no business signing requests against an operator tier; if the consumer needs to report binding errors back to the vendor, that should be a regular authenticated user-tier endpoint, not the OAM tier. Rotate the secret immediately.
V15 MED

SIM2 cellular API AppID/Secret hardcoded

Vector
From com/http/NewApiHttpClient.java:190-191: a cellular SIM management API (China Mobile OneLink-style) is signed with a hardcoded AppID + AppSecret pair embedded directly in the consumer APK.
Impact
Only relevant for SIM-equipped UBIA models (cellular cameras) but completely exposed for those. Allows forging of SIM-activation, data-package, and cellular-management requests against the cellular provider's portal.
V16 INFO

Native libUBICAPIs.so confirms rebranded Kalay stack

Vector
The bundled native libraries are a rebranded ThroughTek Kalay SDK. Confirmed by:
  • Symbols: p4p_crypto_init, p4p_crypto_encode, p4p_crypto_decode, p4p_device_auth, p4p_device_update_auth, p4p_client_send_masterhello, g_P4PCrypto, device_update_master
  • JNI bridge classes: com/ubia/p4p/UBICAPIs/p4p_*
  • Java class references: com/tutk/IOTC/st_LanSearchInfo2
  • Format strings: STREAMREQ_COST: %u ms(P2P) UID:%s deviceSID:%d clientSID:%d
  • Master hostnames in .rodata: portal.us.ubianet.com, portal.cn.ubianet.com, portal.ubianet.com
  • Photo bucket hostnames in .rodata: ubiasnap-eu.oss-eu-central-1.aliyuncs.com, ubiasnap-as.oss-ap-southeast-1.aliyuncs.com
Notes on crypto material
OpenSSL is statically linked into the native lib and symbols are stripped. p4p_crypto_init does not load any static auth key — it allocates buffers and the key is supplied at runtime by a caller. The TUTK auth key is therefore either runtime-derived from the cloud login response, or compiled into the device-side firmware (not the app). Further extraction will require either Frida hooks on a running app or device-side firmware extraction.
V17 MED

user/account/get_current_user leaks personal data

Vector
The authenticated POST /api/user/account/get_current_user endpoint returns the full user profile: account email, internal numeric user ID (kuid), per-user identifier (uuid), login node, language code, mobile brand/version, app ID, app version, device type, email-verification flag, WeChat binding status, and a pre-signed Alibaba OSS avatar URL (V10) embedding the access key ID.
Impact
Combined with V11 (cloud config leak) and V10 (signed avatar URL), an authenticated user gets a complete account fingerprint suitable for IDOR testing on other users. Internal numeric IDs (kuid) are sequential, making horizontal privilege escalation worth probing.
V18 INFO

146 API endpoints discoverable from the decompiled APK

Vector
A static grep for getAbsoluteUrl(...) and okPost(...) across the decompiled com/ package returns 146 distinct endpoint paths — every cloud API call the consumer app can make. We harvested all of them into our fuzzer's KNOWN_ENDPOINTS list.
Notable categories
  • pub/usersupport/* — guest IM endpoints, less authenticated
  • mt/biz/* — payment / business endpoints (Alipay, PayPal, WeChat Pay)
  • user/qry/* — query endpoints (notifications, orders, devices, dynamic info)
  • user/auth* — alternate auth flows (user/auth, user/auth-email, user/faceId)
  • interface, interface.php, old — legacy paths worth probing for unauthenticated access
  • user/device-temp-token, temp_token — short-lived token paths
V19 INFO

SoC identified: Ingenic T31 — enables OpenIPC pivot

Vector
UBIA's own corporate intro page (ubia.com.cn/intro/1.html, Chinese-language) explicitly states they "launched a Junzheng T31 low-power doorbell / battery camera" and have shipped over three million low-power units. Junzheng is the Chinese name for Ingenic. Combined with the Kalay/UBIC P2P stack, the battery use case, and the standard cheap-IPC reference design, the SoC family is the Ingenic T31 (likely T31N or T31X).
Why it matters
Ingenic T31 is fully supported by the open-source OpenIPC project: open-source u-boot, kernel, ISP libraries, NAND tools, hack-ingenic toolchain. Once the SoC is physically confirmed (PCB chip marking on a ~10×10mm QFN package marked INGENIC T31), the path to firmware extraction is well-known: enter U-Boot via UART, dump NAND, mount the rootfs, and read the device-side libIOTCAPIs.so — which is where the runtime TUTK auth key (V16) lives.
V20 INFO

Vendor legal entity & disclosure contacts identified

Legal entity
Shenzhen Qingshi Internet Technology Co., Ltd. (深圳市青视互联科技有限公司), trading as UBIA Technologies Co., Ltd. Founded 2014. Address: Room 1801–1805, Huafeng International Business Building, Xixiang Street, Bao'an District, Shenzhen, Guangdong, China.
Disclosure contacts
Allen_fang@ubia.cn and support@ubia.cn. CISA already attempted contact regarding CVE-2025-12636 and UBIA did not respond. Worth a direct attempt to Allen_fang@ubia.cn with the V11–V20 findings before publication.
Sister app
com.ubianet.uboxpro — installer / professional SKU using the same backend. Worth pulling and diffing for additional admin-tier endpoints.

CVEs Verified On This Device
CVE-2025-12636 CVSSv3 6.5 / CVSSv4 7.1 VULN · LIVE

Ubia Ubox Insufficiently Protected Credentials (CWE-522)

Reproduces V01 above. The vendor's user/device_list endpoint returns the IOTC P2P device-auth password in plaintext to any authenticated owner. CISA tried to coordinate disclosure via advisory ICSA-25-310-02 in October 2025; UBIA did not respond. Our independent verification reproduces the issue against current shipping firmware (2604.1.2.69) using a fresh consumer account — no privileged access required, no other tricks. The relevant verifier in our toolchain is api/cve_checks.py verify_cve_2025_12636().

CVE-2021-28372 CVSS 9.6 VULN · PRECONDITIONS MET

ThroughTek Kalay UID-based session hijack

The Kalay master server identifies cameras by 20-character alphanumeric UID alone. An attacker who knows the UID can register the same identifier against the master and intercept the next legitimate client login. The UBIC stack on this device is the rebranded Kalay SDK (V05, V16); the vector applies. We verified preconditions — UID format, P2P stack alive, master servers reachable — without performing the spoof against my own device. Verifier: verify_cve_2021_28372(). CISA advisory: ICSA-21-229-01.

CVE-2023-6322 / 6323 / 6324 RCE chain POTENTIAL

ThroughTek Kalay LAN parser chain (Bitdefender)

Three flaws in the Kalay LAN protocol parser: an auth bypass, a heap overflow, and a stack overflow. The native binary on this device is confirmed Kalay (V05, V16); the chain applies. Verified non-destructively — no overflow payloads were sent to the live camera. The verifier uses only safe small probes against the device's UDP P2P listener and reports based on stack fingerprint and pre/post-probe liveness. Verifier: verify_cve_2023_6322_chain().


Tools Built For This Engagement

Every tool used in this engagement is original. None of the off-the-shelf IoT pentest frameworks knew anything about this device. The whole stack is published as repo.seteclabs.io/SetecLabs/cam-mitm and is reusable as a template for any TUTK Kalay-based camera (or any IP camera with cloud + P2P architecture).

setec_suite/cam-mitm

Camera MITM & pentesting framework. PyQt6 GUI on top of a curses TUI on top of a service controller. Real-time intercept, fuzz, inject, attack-chain runner.

  • gui.py — PyQt6 dashboard, nine tabs (Dashboard, Live Log, Intruders, Cloud API, Fuzzer, Inject, CVEs, Config, Help). Wraps the same Controller as the curses TUI so both UIs work.
  • mitm.py — curses TUI + Controller class with per-service start/stop and iptables management.
  • services/arp_spoof.py — ARP poisoning with auto-cleanup on exit.
  • services/dns_spoof.py — Selective DNS hijack for cloud hostnames.
  • services/http_server.py — HTTP/HTTPS interception with peek-before-wrap (so non-TLS traffic on :443 doesn't get lost when we wrap_socket too aggressively).
  • services/udp_listener.py — UDP P2P / push capture on configurable ports.
  • services/sniffer.py — Raw packet sniffer with conntrack-based original-destination lookup and per-packet protocol fingerprinting.
  • services/intruder_watch.py — Detects ARP-spoof attempts against the camera, unknown LAN peers contacting the camera, and outbound destinations not on the known cloud whitelist.
  • api/ubox_client.py — UBox cloud client. Login, devices, firmware check, families, raw POST. Plus the OAM HMAC signing client that forges admin requests with the V14-leaked secret.
  • api/fuzzer.py — API endpoint discovery (146 known + ~600-entry wordlist), parameter mutation, auth-bypass tests.
  • api/firmware_fetch.py — Multi-version check_version caller, walks the response for any URL, downloads any firmware-shaped object found.
  • api/ota_bucket_probe.py — Anonymous HEAD enumeration of UBIA's Tencent COS firmware buckets across 320 path templates.
  • api/cve_checks.py — Original PoC verifiers for CVE-2025-12636, CVE-2021-28372, CVE-2023-6322/3/4 + markdown report generator. Non-destructive — every verifier reports VULN/NOT_VULN/UNKNOWN with evidence and never sends an exploit payload.
  • api/server.py — Local REST API on :9090 for external tool integration / AI-assisted automation.
  • inject/packet.py — UDP/ARP/DNS packet injection.
  • utils/log.py — Shared logging with 1 GiB log rotation.
  • utils/proto.py — Payload-to-protocol fingerprinting from the first 6 bytes (TLS, HTTP, RTSP, IOTC, STUN, DNS, NTP, MQTT, SSDP, etc.).
  • regen_cert.sh — Regenerates the MITM SSL cert with full SAN list (*.ubianet.com, *.aliyuncs.com, *.myqcloud.com, target IP).

The Tool In Action

Live screenshots from the engagement. All sensitive specifics (account email, JWTs, tokens, API keys) are blacked out where they appeared.

SetecSuite Dashboard tab — services running, protocols counted, target identified
Dashboard. Eight services live (ARP, DNS, HTTP, HTTPS, UDP/10240, UDP/20001, sniffer, intruder watch). Clickable per-service toggle. Protocol counter at the bottom. Target camera at 192.168.1.187 on the same /24 as the analysis box.
SetecSuite Live Log — DNS spoof entries plus intruder events for the camera contacting unlisted hosts
Live Log. The camera does an absolute storm of DNS lookups on every boot. Shown: it's resolving m1.ubianet.com through m8.ubianet.com (its own Kalay master servers, which we hadn't enumerated until this run), plus device-log.ubianet.com, and a previously-unknown EU bucket family at ubiabox-eu-1312441409.cos.eu-frankfurt.myqcloud.com, ubiabox-eu.oss-eu-central-1.aliyuncs.com, and ubiabox-eu.s3-accelerate.dualstack.amazonaws.com. The intruder watcher also caught the camera contacting an unlisted host on TCP/80 (top of the trace).
Intruder events table showing ARP spoof and unknown destination flags
Intruders. 28 events captured during a single boot cycle. One ARP_SPOOF event (the camera observed an ARP reply for its own IP from a non-camera MAC during our positioning) and 27 UNKNOWN_DST events (the camera reaching out to internet hosts that aren't on our pre-built whitelist of known UBIA / Tencent / Alibaba / Akamai blocks).
Cloud API tab showing the credential leak response — sensitive fields redacted
Cloud API tab. The result panel at the bottom shows a real POST /api/user/noti/device/info_changed response. Email, password, and the JWT preview have been blacked out at the field level — only the field labels and the redaction markers are visible.

What We Couldn't Get

The one thing this engagement could not extract was the actual firmware binary. Three reasons.

  1. 01
    The cloud refuses to push it. Multiple check_version/v3 calls with progressively older fake versions (down to 2604.0.0.1) all return {"data":{"result":{}},"msg":"success"}. The cloud accepts the request shape — we verified against com/apiv3/bean/AdvancedSettings.java:827-857 byte-for-byte — but has no OTA campaign active for this model. The vendor either retired the model or pinned it to its current shipped version permanently.
  2. 02
    The OTA bucket name leaked but listing is locked. We extracted ubiaota-us-1312441409.cos.na-siliconvalley.myqcloud.com from app/getconfig. We confirmed individual files can be public-read (a demo MP4 at dev_add_doc/1159_video/... is anonymous-readable). But anonymous bucket listing returns AccessDenied, and 320 guessed paths for our product ID returned zero hits. Without the real filename pattern, blind enumeration is hopeless.
  3. 03
    The TUTK auth key isn't in the app. We dumped every native library in the APK. libUBICAPIs.so has the symbols (p4p_crypto_init, p4p_device_auth, p4p_client_send_masterhello) but no static auth key. p4p_crypto_init allocates buffers and the key is supplied at runtime by a caller. The TUTK key is therefore either runtime-derived from the cloud login response, or compiled into the device-side firmware (not the app).

The path forward is one of: (a) MITM the camera's own boot-time firmware check on a live network and capture the URL the cloud serves to the device itself; (b) Frida-hook the running app and dump p4p_crypto_init's arguments at runtime; (c) physical UART access to the camera, drop into U-Boot, dump NAND, extract the device-side libraries — the standard OpenIPC T31 flow now that we've identified the SoC (V19).

Phase 2 — Hardware Teardown (planned)

The next phase of this engagement, scheduled for the disclosure-window period, is a full physical teardown and hardware-side analysis:

  • Open the case — non-destructive disassembly, document every screw and clip for reassembly
  • Identify the SoC by chip marking on the QFN package (~10×10mm). UBIA's own marketing says Ingenic T31 (V19); we confirm with the eyeball
  • Map the PCB — identify UART TX/RX/GND test points (often labeled, often four pads in a row near the SoC), SPI flash chip, NAND chip, status LEDs, and any debug headers
  • Hook a USB-UART adapter at standard 115200 8N1 and capture the U-Boot boot log + Linux dmesg. The boot log alone almost always reveals: kernel version, rootfs layout, MTD partition map, secondary boot args, and any failsafe modes
  • Drop into U-Boot by hitting Enter during the 1-second boot countdown. From U-Boot we can md arbitrary memory, nand dump the entire flash, and load custom kernels via TFTP
  • Dump NAND — either via U-Boot's nand dump command, or by physically lifting the SPI flash with a clip programmer (CH341A or similar). Image is then mounted with jefferson / ubidump / binwalk to extract the rootfs
  • Extract the device-side libIOTCAPIs.so — this is the missing piece from the app-side analysis (V16). The device-side library is where the runtime TUTK auth key actually lives, and where any encryption key derivation happens. With the rootfs in hand, this is a 60-second find + strings job
  • Identify any custom firmware obfuscation — UBIA may apply XOR, AES, or simple bit-rotation to firmware images on the OTA path. Whatever scheme they use is hardcoded in the device-side bootloader and trivially recovered with rootfs access
  • Build OpenIPC for the confirmed T31 variant and flash a known-good bootable image. This gives us a permanent root shell on the device for ongoing research, and lets us replay traffic against UBIA's cloud as the camera
  • Document everything — PCB photos, pinout diagrams, U-Boot environment, partition layout, and the firmware extraction recipe. Shipped as a Phase 2 addendum to this report so other researchers don't have to repeat the same work

Once Phase 2 is complete, the remaining gaps in this report — specifically, the runtime TUTK auth key (V16) and the actual filename string the cloud uses for OTA paths (V12) — should both be filled in. Phase 2 will be published as camhak.seteclabs.io/phase2 when complete, or merged into this report if the disclosure window has not yet closed.


Disclosure Timeline
DateEvent
2025-10-XXCISA publishes ICSA-25-310-02 (CVE-2025-12636); UBIA does not respond to coordination
2026-03-30Setec Labs begins independent investigation of the Javiscam 2604
2026-04-09Findings V01–V20 documented; live verification of CVE-2025-12636 and OAM secret forging completed
2026-04-09This report published with sensitive specifics redacted; vendor notified at Allen_fang@ubia.cn
2026-07-08+90 days. If no vendor response by this date, full unredacted artifact pack is released publicly

One CVE on this device is already public: CVE-2025-12636 went out via CISA in October 2025. The advisory specifically notes that UBIA did not respond to coordination attempts. Our independent verification reproduces the exact issue against current shipping firmware.

The other findings (V11–V20) are new. We are sitting on the most sensitive specifics — the actual leaked secret values, the alternate hardcoded password, and any working OAM endpoint paths discovered after publication — and will not publish those until either:

  • UBIA acknowledges the report and ships fixes for V11–V20, OR
  • 90 days pass with no response, matching standard responsible-disclosure practice.

If you are at UBIA and want to talk before the clock runs out, the contact is below. If you are a CISA coordinator who handled the original ICSA-25-310-02 disclosure and want the unredacted technical pack, same address.


Contact

For the unredacted artifact pack, coordinated disclosure inquiries, or follow-up questions on methodology:

sssnake [at] seteclabs.io

PGP key: seteclabs.io/sssnake.asc

Source code: repo.seteclabs.io/SetecLabs/cam-mitm

This report: camhak.seteclabs.io

SsSnake  //  Lord of the Abyss


"The only secure system is one that's powered off, cast in a block of concrete and sealed in a lead-lined room with armed guards — and even then I have my doubts."
— Gene Spafford

guest@setec:~/camhak$ cat report.md | wc -w