前言近期,腾讯安全反诈骗实验室通过TRP-AI反病毒引擎发现了数个以应用拉活为获利手段的黑产团伙,通过恶意代码下发拉活子包擅自尝试启动或唤醒用户手机中的正常应用,执行应用“拉活”操作,目标包括了电商、新闻、视频、浏览器等类别的各大知名应用。 一、病毒解构1.1 市场竞争滋生黑产盈利渠道腾讯安全专家指出,DAU(DailyActive User)日活跃用户数,常用于反映网站、应用或网络游戏等的运营情况。移动互联网竞争激烈的现在,已很难从正规渠道获取到新流量,这些黑产团伙利用获得的黑产流量,通过技术手段篡改应用渠道活跃信息,将黑产流量转换成应用渠道流量,最终从中牟利。应用开发商投入的大量的渠道推广费用被黑产截流,造成巨大的损失。
流量转换示意图 1.2 黑产对抗经验丰富该类恶意家族具有以下对抗特征: 1、 云端隐匿 匿名云端下发子包以及任务执行,防止追溯;
2、 反逆向分析 关键恶意代码多次加密转换、自动删除关键文件等手段防止被逆向分析;
3、 运行环境对抗 检测杀软、ip数据、安装列表、机型数据等信息进行对抗;
1.3 已知的拉活方式1、 URLScheme技术,这是运用最多的方式,通过Intent机制的URI发送URL Scheme,从而启动特定应用进行拉活; 2、 直接使用startActivity函数启动特定应用的特定Activity; 3、 直接使用startService启动特定应用的特定Service;
1.4 目标知名应用目前已经发现的拉活目标涵盖了电商、新闻、视频等类别的各大知名应用,不完全统计拉活目标应用在30个以上,目标面广泛。
1.5 三大家族目前已知的拉活子包可以分成三大家族:cmder、QService、Sensor:
二、影响面分析根据腾讯反诈骗实验室安全大数据引擎的数据显示,这三个家族近一个月影响的用户量如下图所示: 三个家族在总量中占比如下:
三、cmder家族3.1 特点cmder家族的影响用户较小,子包内容本身也很少,基本上,cmder家族的每一个拉活子包只对应一个目标应用,子包不具备其他恶意功能。 cmder家族的拉活子包主要使用了URL Scheme进行唤醒指定应用的操作:
部分收集到的拉活子包:
3.2 技术手段捕获到的拉活子包样本均使用了URL Scheme来进行应用拉活,代码如下图所示,将URL Scheme传入Intent启动:
红框部分就是一个标准的URL Scheme。 头部的snssdk143标志着这是今日头条的scheme,这串URL Scheme通过uri信息包含在Intent中启动,一旦手机中存在今日头条应用,今日头条的Intent Filter就可以通过scheme头部的信息过滤到这个Intent,启动特定的Activity处理后面的参数,执行各种操作,拉活的目的也就达到了。
cmder家族中除了拉活之外还有一个特例: 拉活子包中有一个针对支付宝的,其URLScheme本质上并不是拉活,而是直接启动支付宝打开了黑产分子支付宝分享的“天天领红包”二维码,从而达到盈利的效果。 URL Scheme信息: alipays://platformapi/startapp?saId=10000007&clientVersion=3.7.0.0718&qrcode=https://qr.alipay.com/c1x07288n03sjhxkdzneza2?_s=web-other
3.3 涉及应用的渠道信息观察可以发现这批单功能拉活子包传输的信息中包含了一些渠道信息,如前文中拉活头条的URL Scheme中,就包含click_schema_jaw09这样的类似身份识别的字段,现将这些信息整理如下: 应用 | 渠道信息 |
---|
映客 | inkewname=shuqixiaomowuliaoshiguang_201807 source_url=huoqiangshou06 | 西瓜视频 | gd_label=click_schema_jaw51 gd_label=click_schema_hxhg18 | uc浏览器 | src_ch=juaiwan22 | 淘宝 | spm=2014.ugdhh.2075675568.1204-671 spm=2014.ugdhh.2075675568.1203-671 spm=2014.ugdhh.2075675568.1201-671 spm=2014.ugdhh.2075675568.1197-671 spm=2014.ugdhh.2075675568.1193-671 spm=2014.ugdhh.2075675568.1188-671 spm=2014.ugdhh.3907731441.1162-278 | 搜狐新闻 | channelId=13557 | 今日头条 | gd_label=click_schema_jaw09 gd_label=click_schema_hxhg20 | 火山小视频 | gd_label=click_schema_xdxd10 | 抖音短视频 | gd_label=click_schema_hxhg6 | 支付宝 | qrcode=https://qr.alipay.com/c1x07288n03sjhxkdzneza2 | 优酷 | refer=youkushijiebei_operation.liuxiao.liux_qudao05_006000_6nEZFr_18061126 |
启动新浪微博的URL Scheme为sinaweibo://browser/?url=http://f.swiftcn.io/wbs/98/letu0028,后面swiftcn.io是Swift中文网的域名,完整url无法打开,也无法判断是否构成渠道信息。 启动东方头条的URL Scheme为com.songheng.eastnews://wireless:80/wakeuphome?wakeUpType=51,同样无法判断何处为渠道信息,可能wakeUpType单独指向这个拉活渠道。 3.4 拉活子包下发流程母包从服务器获取下发应用列表:
抓取到的应用列表中单个应用的信息如下图所示:
然后执行pm install安装应用以及am start启动。
这里下发的应用除了拉活子包之外,目前还发现了一些正常安全应用和一些恶意推广、广告弹窗的应用,具体如下: 正常应用: sha1 | 包名 | 软件名 |
---|
e250728bdc98e608cb33372ea248329c35fce56d | com.sohu.newsclient | 搜狐新闻 | 79568ba9d67cbaa9ab4539cb17ade0f395e9527e | com.book2345.reader | 七猫精品小说 | 93125824932c1299c39403cbeb2107990388df84 | tv.yilan.gaoshou.aphone | 高手 | 4970714854dfe3fca6f214741c6faee15acc6ca1 | com.douban.radio | 豆瓣FM | 12b8b2ddaa75c7880d2fa4a5efa5f2a27f8a00a3 | com.qihoo.cleandroid_cn | 360清理大师 | ecab8e793a6c107fb5062c056fb58cae7c3e81b1 | com.qihoo.appstore | 安全市场 | 6339a35b598a2c419e19f7bcbd33eb9eb6550454 | com.qihoo.browser | 360浏览器 | 35120a28186d66409d0881f017599532d42676b0 | com.jd.jrapp | 京东金融 | 8ea1ae3029be26f880155c774b79037fcad62e97 | com.alibaba.wireless | 阿里巴巴 |
恶意应用: sha1 | 包名 | 软件名 |
---|
f79a2f6cc4e10f86cecaadd26a843fbbdc4bc31d | com.yaha.tot | 搜索服务 | db9ff0f965fca8b43dd41b2ca04cb4c0703a8847 | com.yaha.tot | 搜索服务 | e1cda3881bab8708ea48032bf0edc6e1e3d604da | com.menz.ernza | ernza | aaf1c47e96a8eb7a2344425ecbff0e0e6b8069af | com.haoo.app.tw | Hoo | ea20204a47cd2285e7a6cb55267cfa663bbeda33 | com.qihoo.loak | 天天特价 | e80c8dbacd21511d1278411d805b102738f71e74 | com.mm.invoker | 系统通知 | 36af2fb930545c20aec6dde6583c4ddd650690df | cn.ban.checkin | tools | 7b18025925861e730a2fcc81c3455deb0183165d | com.letbun.app.zh | LetBun | ce76079496bc2e9f6e6e69340992df6ace5caa20 | com.android.phonedevices | V3DTorVieweServer | 4f4d3d71c20d2c280e01646a050e636eb7db780b | com.android.phonedevices | phonedevices | 355157c55cf99425e399eea0fdafc50e33a632fc | com.android.phonedevicers | V3DTourViewers | 4a8ad3006031f064e04a36226179946c9eb5ad7a | com.android.phonedevices | V3DTourViewers | f836f5b9b0a6528b8359d0f91adff7621ce1cce9 | com.android.phonedevices | V3DTourViewers | f3a1535d5a24245f986db405693ada4340fbcc64 | com.android.phonedevices | V3DTourViewers |
3.5 c&c服务器整理整体运行流程中主要涉及以下几个域名,目前分析看来其内部api功能是一致的,主要包含了:获取子包、获取Root组件、下发应用列表等功能。 四、QService家族4.1 特点QService家族是目前发现的影响面最广的拉活子包家族,与cmder家族相同,子包本身也仅有拉活功能,不同的是采取了从云端获取加密后的拉活任务列表,然后本地解析后执行的方式,这种方式相比于cmder频繁地开发新的拉活子包更加简便高效。 同时QService使用了最丰富的拉活方式,startActivity、startService以及URL Scheme;执行拉活的时间、间隔以及方式都在云端下发的任务中给出了详细的定义。
4.2 技术手段QService家族从云端获取的数据解密后为json,部分数据截取如下:
json中各参数的解释见下表: startTime | 任务开始时间(小时) |
---|
endTime | 任务结束时间(小时) | intervalTime | 执行间隔时间(分钟) | screenState | 是否检查屏幕开启状态,0为不检查 | type | 拉活方式,0为startActivity;1为startService;2为URL Scheme | pkg | 目标应用包名 | link | type为0时,link为指定的Activity; type为1时,link为指定的Service; type为2时,link为URL Scheme的值 |
执行任务的关键代码如下: 1、 根据screenState的值判断是否需要判断屏幕状态:
2、 开始时间、结束时间、间隔时间是否满足需求的判断:
3、 记录执行时间,根据type执行任务:
type为0时为使用startActivity启动目标应用的特定Activity;type为1时为使用startService启动目标应用的特定Service;type为2时则是与cmder家族相同的URL Scheme。 4.3 涉及应用的渠道信息同样的,QService家族使用的URL Scheme涉及的渠道信息也整理如下:
可以看到QService家族也利用了支付宝的天天抢红包进行盈利,此外还有一些直接启动Activity或Service的拉活任务,因此无法直接获取到渠道信息。 4.4 c&c服务器整理 QService运行流程中访问的云端为: http://xgaxp.jkw***m.com/p/lwdeplik.zip http://vbxcf.xzh***j.cn/html/waeiksaz.zip
下载的文件经解密后即为下发任务。 五、Sensor家族5.1 特点Sensor家族虽然用户量相比于QService家族并不多,但功能比起QService来说则更加强大,他们自研开发了一种脚本语言,拉活子包则是对应的脚本解释器,执行云端下发的自研脚本,在脚本中包含了大量的拉活任务以及应用推广任务。 Sensor家族的拉活行为同样是靠URL Scheme实现,但由于是云端下发脚本,不排除更新为其他方式的可能性。 此外,Sensor家族也是目前发现的对抗最多的拉活子包,云端下发、加密不必说,脚本中还包含了ip检测、杀软检测等对抗。 目前抓取的脚本执行流程如下:
5.2 自研脚本语言Sensor家族背后的黑产团伙自研的脚本语言实现了多达70个功能函数,同时支持了所有常用的运算符(包括逻辑运算),脚本中包含明显的控制结构。 函数表和解释如下: Function | Explain |
---|
abs(double n) | 求绝对值 | log(String str) | 使用Android.Util.Log进行log | max(double a,double b) | 求二者最大值 | min(double a,double b) | 求二者最小值 | parseHexString(String hex) | hex转String | putVar(String name,double value) | 将键值对存入hashtable | delVar(String name) | 删除指定键值对 | clearVars() | 删除所有键值对 | random() | 随机数 | currentTimeMillis() | 取系统时间 | defined(String name) | 检测是否存在键 | increase(String tag) | 指定tag计数+1,上报服务器 | install(String apk) | 安装指定apk | ipBelongsTo(String address…) | ip所在地 | ipMatched(String ip…) | ip匹配(如192.168.1.*) | isDownloaded(String file…) | 检测文件是否存在 | isOnline() | 检测网络 | isScreenOn() | 检测屏幕是否开启 | isWifiOnline() | 检测是否在Wifi环境下 | macMatched(String mac…) | mac地址匹配 | manufacturerContains(String keywords…) | 供应商字段是否包含keywords | modelContains(String keywords…) | model字段是否包含keywords | packageExists(String package…) | 是否安装指定应用 | pathContains(String path) | 当前包下是否包含路径 | privAppExists() | 是否存在预装应用路径 | putTag(String key,double value) | 将键值对存入hashtable,不同于putVar | getTag(String key) | 获取指定键值 | removeTag(String key) | 删除指定键值对 | removeAutoExecCmd(String cmd) | 删除自动执行命令 | removeAutoStartActivity(String package,String activity) | 删除自动执行startActivity | removeAutoStartService(String package,String service) | 删除自动执行startService | rooted() | 检测是否root | setCommandUrl(String url) | 设置c&c服务器地址 | setStandbyServerUrl1(String url) | 设置备用c&c服务器地址1 | setStandbyServerUrl2(String url) | 设置备用c&c服务器地址2 | setDebugEnabled(int enabled) | 设置是否开启debug | setInterval(long interval) | 设置执行间隔 | setLogEnabled(int enabled) | 设置是否开启log | signatureEquals(String signature) | 判断签名 | startActivity(String package,String activity) | 运行指定Activity | startService(String package,String service) | 运行指定Service | stop(String package) | 停止指定应用 | submit(String event,String extra) | 上报设备信息以及指定extra | suexec(String cmd…) | 命令行执行命令 | uidMatched(String uid…) | 匹配指定uid | uninstall(String package) | 删除指定应用 | unzip(String file) | 解压指定文件 | waitForNetwork() | 等待联网 | autoExecCmd(String cmd,String increaseTag,int type,int startHour,int endHour) | 设置自动执行命令 | autoStartActivity(String package,String activity,String increaseTag,int type,int startHour,int endHour) | 设置自动执行startActivity | autoStartService(String package,String service,String increaseTag,int type,int startHour,int endHour) | 设置自动执行startService | boardContains(String keywords…) | board字段是否包含keywords | copy(String file,String newPath) | 复制指定文件到指定路径 | count(String tag) | 对指定tag的计数 | delete(String name) | 删除指定文件 | deviceContains(String keywords…) | device字段是否包含keywords | download(String url,String name,int wifiOnly) | 下载文件并储存 | fileExists(String path…) | 文件是否存在 | getApiLevel() | 获取ApiLevel | getWeeks(String date) | 获取星期 | getDays(String date) | 获取天数 | getHours() | 获取当前小时 | getFirstInstallTime() | 获取第一次安装时间 | getProviderCode() | 获取运营商代码 | getRealTime() | 获取当前时间 | getVersion() | 获取当前版本 | iccidMatched(String iccid…) | iccid匹配 | imeiMatched(String imei…) | imei匹配 | imsiMatched(String imsi…) | imsi匹配 | inKeyguardRestrictedInputMode() | 判断是否锁屏 |
这些函数中有明显可以用来对抗的函数,如ipMatched、stop、packageExists等,事实上下发的脚本也是这样做的:在执行拉活操作之前,脚本会先判断是否存在杀软,如果存在则关闭杀软;同时通过ipMatched函数禁止掉了腾讯云等ip地址。 被ban的ip如下: 180.153.228.*,183.232.175.*,183.3.234.*,183.60.163.*,183.61.51.*
在检测到这些ip之后,脚本将log信息“forbidden”,记录forbidden字段为TRUE,然后通过submit函数上传了forbidden:cloud antivirus信息,然后结束运行。 5.3 任务执行流程在执行具体任务之前,脚本首先判断了执行条件:
先判断是否为新一天以及母包应用是否安装,是的话就会重置pushCount为1000000,初始化计数用的变量;然后如果是测试模式或者未达到指定的pushCount,则开始执行任务。 接下来脚本判断了是否安装主流杀软,有则关闭。
当以上运行环境检测完毕之后,使用increase函数将计数用的变量加1,代表进行了一次拉活,同时increase函数内置的逻辑将记录上传至服务器。
最后使用URL Scheme执行拉活任务。
5.4 涉及应用的渠道信息Sensor子包中的渠道信息整理如下: 应用 | 渠道信息 |
---|
今日头条 | gd_label=click_schema_aguya15 | 抖音短视频 | gd_label=click_schema_jaw55 | 今日头条极速版 | gd_label=click_schema_aguya29 | 西瓜视频 | gd_label=click_schema_aguya25 | 火山小视频 | gd_label=click_schema_aguya39 | 淘宝 | spm=2014.ugdhh.3915747229.1194-189 | 优酷 | refer=home1808_operation.anne.hxl_qudao85_005000_jQRvyq_18080201 |
脚本中除了执行拉活任务之外,还有一些下载安装推广其他应用的任务,这部分的信息整理如下: 六、总结拉活子包不可能凭空出现,为防范成为黑产控制下的刷量拉活工具,安卓手机用户需要提高安全意识,养成良好的使用习惯,我们建议: 1. 通过正规应用市场或官方下载应用; 2. 不要轻易打开不明链接,谨慎对待来源不明的安装包、文件; 3. 养成良好的生活习惯,不下载安装“色情类”的应用; 4. 使用腾讯手机管家等手机安全软件进行实时防护。
|
最新评论
发表评论