Security News

Cybersecurity news aggregator

⚔️
MEDIUM Attacks Reddit r/netsec

BIGO Ads Deploys C2-Style Infrastructure to Survive Domain Bans. Here's the Decrypted Config.

  • What: BIGO Ads uses encrypted configuration files to maintain ad-serving infrastructure despite domain bans
  • Impact: Ad networks and apps using BIGO Ads may be affected by domain-blocking measures
Read Full Article →

The BIGO Ads SDK ships with an encrypted configuration file that maps out a global network of ad-serving domains, backup hosts, and failover infrastructure. The file is AES-encrypted with a hardcoded key, served from Alibaba Cloud, and designed to make the ad network resilient to domain blocking. The SDK source code calls the class that loads it AntiBanUtils . BIGO Ads is the ad platform under JOYY Inc. (NASDAQ: JOYY). It is integrated into thousands of apps through Google AdMob mediation and distributed as a CocoaPods/Maven dependency ( com.bigossp:bigo-ads ). How I Found It While reviewing mobile proxy traffic, I noticed recurring requests to an Alibaba Cloud OSS bucket: GET https://ad-host-backup-america.oss-us-west-1.aliyuncs.com/uni/v2/au.pj Every request carried a custom header: BIGO-Ad-Request-Id . The response was application/octet-stream , 8,544 bytes of uppercase hex characters. The same file, same content, served to every user. I observed 257 requests to this URL from 7 unique devices over 30 days. The requests originated from HelloTalk, a language learning app with millions of users, running through Google AdMob mediation. I identified this by correlating the BIGO-Ad-Request-Id header with adjacent AdMob bid requests from the same device, which contained the app bundle ID com.helloTalk.helloTalk . What the File Looks Like The file is a hex-encoded binary blob. Decoded, it is 4,272 bytes with near-perfect entropy (7.95 out of 8.0 bits per byte), aligned to 16-byte AES blocks, with zero repeated blocks. The first 16 bytes have lower entropy than the rest, consistent with an initialization vector. Finding the Key The BIGO Ads SDK is not bundled inside the HelloTalk APK. It is distributed separately as an Android AAR ( com.bigossp:bigo-ads on Maven Central) and an iOS framework via CocoaPods. I downloaded version 5.6.2 of the Android SDK and decompiled it with jadx. The URL appeared immediately: // sg/bigo/ads/controller/a/a/f.java arrayList.add(new a("AWS", "https://ad-host-backup-asia.oss-ap-southeast-1.aliyuncs.com/uni/v2/au.pj", true, "asia")); arrayList.add(new a("AWS", "https://ad-host-backup-europe.oss-eu-central-1.aliyuncs.com/uni/v2/au.pj", true, "europe")); arrayList.add(new a("AWS", "https://ad-host-backup-america.oss-us-west-1.aliyuncs.com/uni/v2/au.pj", true, "america")); Three regional copies. Asia, Europe, America. All on Alibaba Cloud OSS. The decryption function was in sg/bigo/ads/controller/a/a.java , with the key logged in plaintext: sg.bigo.ads.common.t.a.a(0, 3, "AntiBanUtils", "decrypt, cryptStr=" + str5 + ", hexStringSecKey=FEFFFFFFFFFAFFFDCBFFFFFFFFFFFF4F, decryptStr=" + strA); The cipher implementation in sg/bigo/ads/common/utils/o.java : SecretKeySpec secretKeySpec = new SecretKeySpec(bArr2, "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); AES-128-CBC. Hardcoded key: FEFFFFFFFFFAFFFDCBFFFFFFFFFFFF4F . First 16 bytes of the payload are the IV. Decryption from Crypto.Cipher import AES from Crypto.Util.Padding import unpad import binascii key = binascii.unhexlify("FEFFFFFFFFFAFFFDCBFFFFFFFFFFFF4F") data = binascii.unhexlify(open("au.pj").read().strip()) cipher = AES.new(key, AES.MODE_CBC, data[:16]) plaintext = unpad(cipher.decrypt(data[16:]), 16) Decrypted size: 4,253 bytes. Valid JSON. What Is Inside The decrypted config is a server routing map with three sections: cfg_svr (SDK configuration), ad_svr (ad serving), and report_svr (impression/click tracking). Each section contains per-country primary hosts and backup hosts. Ad Serving Domains ( ad_svr ) Country Primary Host Backup Host Global tr.acobt.tech api.antibanads.com Russia trk.appleads.ru edu.zoly.tech Saudi Arabia d10sbd116h2zht.cloudfront.net d10sbd116h2zht.cloudfront.net UAE api.companinons.site api.cpmmax.site India api.successwe.site api.successwe.site Config Delivery ( third_pay_svr and third_free_svr ) The config file contains URLs to itself, creating a self-bootstrapping loop: Provider URL Alibaba OSS (Asia) ad-host-backup-asia.oss-ap-southeast-1.aliyuncs.com/uni/v2/au.pj Alibaba OSS (Europe) ad-host-backup-europe.oss-eu-central-1.aliyuncs.com/uni/v2/au.pj Alibaba OSS (America) ad-host-backup-america.oss-us-west-1.aliyuncs.com/uni/v2/au.pj Yandex Cloud storage.yandexcloud.net/ad-host-config/nonvpn.pj Google Drive drive.google.com/uc?export=download&id=1ms4F7Cn_aInE9oFMMaZEiwMIuMKt1DZc The SDK refreshes the config hourly ( interval: 3600 ). If the primary host fails after 3 attempts ( threshold: 3 ), it falls back to the backup. The Google Drive URL serves as a last-resort free tier, refreshing daily on success and retrying every 30 minutes on failure. Domain Fronting The config includes a domain_front field for Saudi Arabia, indicating the SDK supports domain fronting: connecting to a legitimate CDN endpoint while routing traffic to a hidden backend. AWS and Google banned domain fronting in 2018 due to its use in censorship circumvention and C2 infrastructure. What This Means The AES encrypt...

Share this article