概述
2016年1月起至今,双尾蝎组织对巴勒斯坦教育机构、军事机构等重要领域展开了有组织、有计划、有针对性的长时间不间断攻击。攻击平台包括Windows 与 Android,攻击范围主要为中东地区
此次捕获的恶意软件名为”Google Play Installer”,安装后伪装成Telegram应用程序类似的图标和界面。
样本信息
md5 | dd4596cf68c85eb135f7e0ad763e5dab |
---|---|
文件类型 | Apk |
包名 | org.telegram.light |
文件大小 | 26MB |
应用名 | Google Play Installer |
流程图

详细分析
AndroidManifest.xml分析
4.1.1权限声明
该程序申请了很多权限,包括读写短信、读取通讯录、录音、通过GPS获取当前位置等危险权限
如下是使用到的权限以及对应的描述
权限 | 描述 |
---|---|
android.permission.CHANGE_WIFI_STATE | 改变WIFI状态 |
android.permission.INTERNET | 访问网络连接 |
android.permission.ACCESS_NETWORK_STATE | 获取网络信息状态 |
android.permission.KILL_BACKGROUND_PROCESSES | 杀死后台进程 |
android.permission.READ_CALL_LOG | 读取通话记录 |
android.permission.READ_PHONE_STATE | 读取电话状态 |
android.permission.REORDER_TASKS | 排序系统任务 |
android.permission.WRITE_CONTACTS | 写入通讯录 |
android.permission.READ_CONTACTS | 读取通讯录 |
android.permission.GET_ACCOUNTS | 访问Gmail账户列表 |
android.permission.REQUEST_INSTALL_PACKAGES | 请求安装APP |
android.permission.ACCESS_FINE_LOCATION | 通过GPS获取当前位置 |
android.permission.RECEIVE_SMS | 接收短信 |
android.permission.READ_SMS | 读取短信 |
android.permission.GET_TASKS | 允许程序获取当前或者最近允许的应用 |
android.permission.USE_CREDENTIALS | 允许程序请求验证从AccountManager |
android.permission.SEND_SMS | 编写和发送短信 |
android.permission.WRITE_EXTERNAL_STORAGE | 写入内存卡 |
android.permission.READ_EXTERNAL_STORAGE | 读取内存卡 |
android.permission.CAMERA | 允许摄像头进行拍照 |
android.permission.RECORD_AUDIO | 通过手机或者耳机的麦克风来录音 |
android.permission.PROCESS_OUTGOING_CALLS | 允许程序修改监视、修改或者放弃拨打的电话 |
android.permission.CALL_PHONE | 拨打电话 |
android.permission.RECEIVE_BOOT_COMPLETED | 允许程序开机自动运行 |
android.permission.WRITE_CALL_LOG | 允许程序写入手机的呼叫记录数据 |
android.permission.WAKE_LOCK | 允许程序在手机屏幕关闭后后台程序仍然允许 |
android.permission.MODIFY_AUDIO_SETTINGS | 修改声音设置信息 |
android.permission.DISABLE_KEYGUARD | 禁止键盘锁 |
android.permission.READ_PROFILE | 读取配置文件 |
android.permission.SYSTEM_ALERT_WINDOW | 显示系统窗口 |
android.permission.ACCESS_WIFI_STATE | 访问WIFI状态 |
android.permission.CHANGE_WIFI_STATE | 改变WIFI状态 |
android.permission.ACCESS_NETWORK_STATE | 访问网络状态 |
android.permission.REORDER_TASKS | 允许程序重新排序系统任务 |
4.1.2 Application
设置App入口点为类”net.axel.app.app.AppControler”,App运行后,该类会在App的所有组件之前进行实例化。
APP使用”goole Play Installer”为应用名,从图标和应用名看出该程序伪装成Google安装程序来诱导受害者安装。安装后在应用列表显示的图标为Telegram。
4.1.3 组件activity
Activity-alias即activity的别名,可以重新定义当前某个activity的一些信息,这里用来动态更换图标和应用名,以便达到伪装其他应用或者使用透明图片来隐藏自身的目的。
通过targetActivity可以看出这些activity-alias调起的都是类”net.axel.app.activities.Main”。除了label为”Telegram”的activity-alias,其他activity-alias默认处于被禁用状态,因此在安装成功的时候显示的是Tekegram的图标。
对应的activity的lable和图标如下表
lable ID | Lable名 | Activity类名 | 图标 |
---|---|---|---|
app_wifi | Wifi | net.axel.app.Extra_wifi | ![]() |
app_chrome | Chrome | net.axel.app.Extra_chrom | ![]() |
app_play_services | Play Services | net.axel.app.Extra_Play_services | ![]() |
app_bixby | Maps | net.axel.app.Extra_Bixby | ![]() |
app_name | Google Play Installer | net.axel.app.Extra_Non_Trans | ![]() |
sys_name | 为空 | net.axel.app.Extra | 透明图标(用于隐藏自身图标) |
Telegram | net.axel.app.Launcher | ![]() |
以下4个activity伪装成正常界面,实际上在背后偷偷执行恶意代码。
第一个和第四个activity伪装成”Telegram Message”界面。
第二个伪装更新界面,其中标题、图标、描述和按钮文本信息通过FCM的云消息下发并显示在如下界面中。
第三个伪装成安全软件扫描界面,将要卸载的应用标记成恶意软件,诱导用户点击删除达到卸载的目的。
4.1.4组件service
注册多个service,用于在后台执行代码
注册无障碍服务用于完成模拟屏幕点击。
4.1.5组件receiver
注册多个receiver来接收来自系统和应用中的广播。
设备管理员权限
注册广播接收设备管理员权限的激活或禁止事件。
设置设备管理员操作界面的标题和描述,诱导用户激活设备管理员(获取超级管理员权限)。
一旦一个应用激活了设备管理员权限,是不能通过设置里的应用程序来卸载程序,必须要在设置->位置和安全->选择设备管理员器里找到要删除应用并取消激活,然后才能再去应用程序里删除。当收到禁用设备管理员权限的请求时,跳转到home界面并返回警告信息。
返回的警告信息如下图,翻译过来就是” Google PlayInstaller是系统APP,如果卸载了它,设备就处于危险的状态下。”
如果用户忽略警告,继续禁用则返回home界面。
跳转到home界面实现如下
短信接收
当接收到短信时判断是否是SMS指令,如果不是则将短消息内容写入文件并上传到C&C服务器,否则就执行SMS指令。详细分析见4.10.2。
网络变化
注册了两个广播用于接收网络状态改变的事件。当网络连接的事件发生时,上传窃取的数据,包括通讯录、短信、通话录音和屏幕截图等等。
APP卸载
注册广播接收App的卸载事件,当某些App被卸载时上传被卸载的应用名。
由于这些包名都包含”update”,初步猜测这些应该是FCM下发”update”指令时下发的更新包。
APP安装
注册广播接收安装应用的事件,App安装完成时默认不会启动App。
当安装的应用包名为”org.telegram.messenger”时并且已经安装在设备上时,则隐藏自身图标,删除asset.apk安装文件,启动要安装的应用。
当安装的应用包名为FCM下发”update”指令的字段App_package,如果已经安装,上传已安装的消息到C&C服务器,删除更新文件”mupdate.apk”和图标,禁用所有广播,启动包名为App_package的应用。
关机
注册广播接收受害者设备关机事件
关机时将关机时间写入文件”shutdown.nez”
屏幕解锁
注册广播接收屏幕解锁事件。
当屏幕解锁时,启动摄像头摄像功能。
开机或重启
注册广播接收受害者设备开机或者重启事件。
当手机开机时将当前时间写入shutdown.net文件中。
电话状态改变或拨出电话
注册广播接收电话状态改变和设备拨打电话的事件。
接收到拨出或接到来电时调用前置摄像头拍照并录音。
通知栏消息
注册广播接收通知栏消息,主要功能为窃取社交App的通知消息和关闭一些安全软件的消息通知等等。
当通知栏收到新通知消息时,取消部分应用发送的通知消息,不在通知栏中显示其消息内容;如三星手机内置安全应用和华为内置安全应用。
读取一些社交软件发送的通知栏消息,包括图标、标题和内容并且保存到wfv文件中。
如果接收到的消息是WhatApp发送的来电请求,开启录音服务准备录音。
如果移除的通知消息是WhatApp收到的来电请求,关闭正在运行的录音服务。
4.2不同组件之间的通信
Activity、Receiver、Service三个组件之间的相互通信通过闹钟服务alarmManager来实现。PendindIntent为闹钟触发时要执行的动作,比如发送广播消息、启动activity或者服务等。
启动activity
启动service
发送广播
4.4 计算设备标识
设备标识主要用于识别设备,与C&C通信时需要设置设备标识。根据系统版本的不同使用不同的计算方法。
4.4.1 版本号低于29
在低版本中,获取系统的Imei、macAddress或Device_ID作为设备标识。
其中wlan的mac地址获取方法如下图,遍历所有网络接口,找到wlan0接口并返回硬件地址作为mac地址。
4.4.2 版本号高于29
首先从SharePreferencces读取键为”UNIQUE_ID”的值,如果存在使用该值作为设备ID,不存在则从.pesudo.iso读取设备ID并将值保存到UNIQUE_ID。文件不存在则创建文件并计算设备ID。
其中psuedUniqueID计算方法如下:
Sim序列号获取方法如下
4.4 收集信息加密压缩
对于收集到的数据,比如通话记录、通讯录和短消息等等,大部分都是通过加密压缩成zip文件再上传到C&C服务器上。计算压缩数据时使用的密码,从计算方式可以看出密码是根据设备信息生成的。设备ID与设备标识通过某种方式组合后的字符串末尾再加上字符串”3K=H8N=O7S=H8A=N”得到新的字符串,最终压缩密码为新字符串的MD5值。
4.3类名方法名混淆
使用无意义的随机单词数字的组合来命名,加大分析人员的分析难度。如下左图为混淆后的代码,右图为Android库Volley的方法newRequestQueue代码。
4.4 Application入口
加载hydrogen.so,在so文件中实现了4个JNI接口,功能主要是返回字符串。
在so文件中实现的JNI接口
实现代码如下,其他接口函数的实现类似,不同之处是返回不同的字符串
函数名 | 返回的字符串 | 描述 |
---|---|---|
do932 | 3K=H8N=O7S=H8A=N-gZk3ctiqQ+MeznT8vuAt9fltaYUMk4kFd23LWNcoR4GGS5OQDgNXpYBZzzY8hqgZ | 加密字符串,解密后为url |
do933 | </title> | 网页Tag,用于从网页中提取数据 |
do934 | <title | |
do937 | com.miui.securitycenter | 小米内置安全应用程序包名,包名用于判断通知栏的消息来源App, |
解密C&C地址
do932函数返回的加密字符串有两个用途,连字符”-”前面部分用作密码的一部分,用来加密从受害者设备中提取的文件;第二部分首先解码(base64),然后解密(AES)。
然后从解密的url解析title标签。
最后一步是用”-”替换第一个空格和用”.”替换第二个空格,得到C&C地址”hxxps://amanda-hart.website”。
设置异常处理函数
当程序执行异常时执行logcat命令读取系统log并写入logs文件夹退出程序。Log文件名为log_{timestamp}
4.5 net.axel.app.activitit.Main类分析
1. 随机启动正常应用或系统应用
动态更换图标
该样本通过启用当前要显示的activity-alias,禁用其他的activity-alias来动态更换显示在应用程序列表中该样本的图标。
随机更换图标
收集手机网络信息和设备信息
在联网情况下将收集到的信息zip压缩后上传到连接”{C2C地址}/func/info”
4.6 net.axel.app.activities.Telegram类分析
利用弹出对话框的形式,设置诱导性的标题与对话框欺骗用户点击,并且只设置一个确定按钮,受害者只能点击确定不然不能正常使用。
为了获取多种权限,设置多种不同的且具有诱导性的内容来欺骗用户来激活权限,在onActivityResult处理操作结果,如果权限获取或者操作没有成功则再次弹窗直到获取权限成功为止。
对话框标题 | 对话框消息 | 对话框图标 | 描述 |
---|---|---|---|
Messages Encryption | It is a Chat App, If you don\‘t Enable this property system won\‘t encrypt chat messages. | ![]() |
为了获取通知栏消息权限。 |
Private Messages | It is a Chat App, If you don\‘t Enable this property system won\‘t allow to you to send private messages | ![]() |
关闭Google Play Procet |
Private Video Chat | It is a Chat App, If you don\‘t Enable this property you won\‘t use private video chat property | ![]() |
获取录屏和录音权限 |
Power Optimization | It is a Chat App, If you don\‘t Enable this property system will block some properties due to battery optimization. | ![]() |
设置自启动 |
Enable Notifications | It is a Chat App, If you don\‘t Enable this property you won\‘t receive chat notifications. | ![]() |
获取设备管理员权限 |
安装正版应用org.telegram.messenger
4.7 net.axel.app.activities.Real_App类分析
该类的主要功能为安装正版应用Telegram Message。APK文件位于assets目录,文件名为asset.apk。包名为”org.telegram.messenger”。
根据版本和手机型号使用三种安装APK的方法。
APK安装方法2:
APK安装方法3:
4.8 net.axel.app.activities.uninstall_other类分析
当收到FCM(Firebase Cloud Messaging)下发的云消息中指令为”uninstall_another”时,要卸载的App由云消息的字段package指定。
判断要卸载的App列表在目标手机上是否已经被安装。如果至少有一个需要卸载的App在受害者手机上安装,则打开卸载页面,实际上显示在用户面前的是伪装成安全软件扫描恶意软件界面。
获取要卸载的app的详细信息,比如应用名、图标、版本号等等,用于在扫描页面显示。
在列表控件显示要卸载App列表,这些App被标记成恶意软件,并提示受害者卸载这些软件。
点击在列表中显示的app项时打开卸载页面或者设备管理员权限管理页面,让受害者手动操作是否卸载App和禁用设备管理员权限。如果受害者在卸载页面取消卸载,则再次弹出卸载页面,直到成功卸载为止。
如果是卸载有设备管理员权限的App,需要先禁用设备管理员权限,才能成功卸载App。
4.9 net.axel.app.activities.Update_dialog分析
FCM(Firebase Cloud Messaging)下发指令”update”,并提供更新所需要的参数。Update_method为Notification时在通知栏中弹出更新消息,为message时使用更新界面更新应用。
使用通知栏更新
创建通知消息,设置更新链接、更新描述和图标等等。
当点击通知栏消息时,会跳转到安装界面,令人防不胜防。
使用更新界面更新
填充更新界面的通知栏标题、按键文本等等信息。
其中按键的点击事件在master_update_dialog.xml文件中声明。点击按键时触发安装应用操作。
4.10 拨打电话
当收到FCM(Firebase Cloud Messaging)下发的云消息中指令为”find_mobile_number”时,执行拨打电话的指令。拨打号码类型由字段action来决定。
Action有如下三种
Action | 描述 |
---|---|
1 | 使用当前正在使用的sim卡拨打余额查询业务,不会留下通话记录。 |
2 | 拨打正常号码,挂断电话后需要删除通话记录。 |
3 | 拨打增值业务号码,挂断电话后需要删除通话记录。 |
使用黑色背景图覆盖通话界面,达到隐藏通话的目的。
拨打电话时一般都会留下通话记录,在挂断电话后删除当前拨打号码的通话记录。这一切操作都是在受害者不知情或未交互的情况下完成。
Action1为使用当前正在使用的sim卡拨打特殊号码来查询话费,除了查询话费的号码不同外三家运营商实现拨号的代码大致相同。
各个运营商查询话费需要拨打的号码如下:
运营商 | 地点 | 查询话费号码 |
---|---|---|
Jawwal | 巴基斯坦 | *111*5*{设备balance}# |
wataniya | 巴基斯坦 | *130**00972{设备balance}# |
Etisalat | 阿富汗 | *199*00972{设备balance}# |
action2和action3可以选择使用sim卡1还是sim卡2来拨打电话。
action3拨打的号码是增值业务号码,支付方式有f和c两种,由于缺乏对巴基斯坦地区移动通信相关业务缺乏了解,尚不清楚是网银支付还是其他方式。
action2拨打号码时,号码由FCM下发的云消息中字段value指定。
4.11 窃取短消息和通讯录
FCM(Firebase Cloud
Messaging)下发指令”mess_cont”,字段Value指定要窃取的数据是短消息还是通讯录。
窃取短消息
读取设备中收件箱和发件箱中的所有短消息,加密压缩后上传到C&C服务器。
窃取通讯录
遍历通讯录的所有联系人,将其中有联系方式的加密压缩后上传到C&C服务器。
4.12 窃取通话记录
读取通话记录并保存到文件clogs.nez并上传到C&C服务器。
4.13 窃取文档
从外部存储器窃取指定后缀的文档。
4.14 录音
当FCM下发指令”record_sound”时,实现录音功能。其中参数”start_time”和”end_time”分别为录音开始时间和录音结束时间。
利用闹钟服务来设置录音服务的开始时间和结束时间。
使用类AudioRecord来实现录音的功能。
4.15 屏幕截图
当FCM下发指令”wxyz”或者”wxyz_period”指令时执行屏幕截图功能。其中指令”wxyz_period”多了一个参数”period”,表示每隔多久截一次屏幕。截图完成后保存为bmp图片并上传到C&C服务器。
首先需要获取MediaProjectionManager服务,然后再获取一个申请屏幕采集权限的intent并启动屏幕采集申请权限界面。
当用户允许屏幕录制时,在onActivityResult回调里根据返回的resultCode和data获取MediaProjection。
在方法g中设置屏幕截图的长宽和设置监听器监听新截图。
当屏幕方向变化时重新设置监听器和屏幕截图的长宽。
截图完成后加密压缩上传图片文件。
4.16 摄像头拍照
当收到FMC下发的指令为”take_photo”时,执行摄像头拍照功能。参数action为”rear”时,使用后置摄像头拍照。
设置为静音模式,避免拍照时被发现。
函数名被混淆,通过上下文信息可以确认是摄像头相关的API。
拍照成功后取消静音,保存到目录syscam,保存的图片分辨率为1024*768。
4.17命令与控制
注册服务用于在后台处理FCM下发的云消息。
1. FCM下发的指令
每条指令都包含两个基本参数Id和type,分别是设备ID和指令名。
指令名 | 指令描述 | 额外参数 | 附加信息 | 参数描述 |
---|---|---|---|---|
s_dom | 设置新的C&C域名 | basic | 要设置的域名 | |
uninstall_another | 卸载其他应用 | package | 要卸载的App列表,多个App用逗号隔开。 | |
take_photo | 使用摄像头拍照并上传 | Action | Rear | 使用后置摄像头拍照 |
其他值 | 使用前置摄像头拍照 | |||
record_sound | 录音并上传到C&C服务器 | Start_time | 录音开始时间 | |
End_time | 录音结束时间 | |||
S_perms | 检测激活的权限并上传到C&C服务器 | |||
Apps_info | 手机已安装应用的应用名、版本号和安装时间等等信息。 | |||
Wifi_restart | 重启wifi | |||
Kpa_elif_teg | Cke | |||
Find_mobile_number | 拨打号码 | Value | 电话号码 | |
Action | 1 | 拨打话费查询号码 | ||
2 | 拨打正常号码 | |||
3 | 拨打增值业务号码 | |||
Call_rec_encode | 将录音文件编码成mp3文件 | |||
wxyz | 屏幕截图 | Quality | 图片分辨率 | |
Wxyz_period | 周期性屏幕截图 | Period | 屏幕截图周期 | |
Quality | 图片分辨率 | |||
Call_logs | 读取通话记录并上传到C&C服务器。 | |||
W_S | 是否允许对WhatApp通话录音。 | Value | 为0时允许录音。 | |
Access_service_check | 检测无障碍服务是否被启用。 | |||
Disable_admin | 取消设备管理员权限。 | |||
Check_hide | 检测自身图标是否被隐藏 | |||
Mess_cont | 窃取短消息或者通讯录 | Value | Cont | 窃取通讯录 |
Mess | 窃取短消息 | |||
S_tree | 收集文件或文件夹信息并上传 | Custom | Custom为真遍历所有文件和文件夹,否则遍历符合条件的文件和文件夹。 | |
Stop_rec | 结束录音服务 | |||
Stop_custom_rec | 结束自定义录音服务 | |||
Stop_currect_rec | 结束当前正在运行的录音服务 | |||
Manage_files | 文件管理 | Src | 源路径 | |
Dst | 目标路径 | |||
action | Get | 上传文件 | ||
Fast_get | 快速上传 | |||
Download_file | 下载文件 | |||
Delete | 删除文件 | |||
Rename | 重命名文件 | |||
Copy | 复制文件 | |||
Move | 移动文件 | |||
download_url | 下载链接 | |||
download_file_name | 下载文件名 | |||
download_path | 下载路径 | |||
Update | 用来更新update apk | Icon_url | 图标链接 | |
url | 应用链接 | |||
Pkg | 包名 | |||
Update_method | 更新方法 | |||
App_type | 应用类型 | |||
title | 更新标题 | |||
Color | 更新界面中分割线的颜色 | |||
message | 更新描述 | |||
Button | 按钮文本 | |||
Delete_app | 删除App,未实现 | |||
Screen_on | 检测屏幕是否处于锁屏状态 | |||
Get_mess | 读取短消息 | |||
Hide_app | 隐藏自身 |
SMS指令
当受害者接收到手机短信时,App检测是否是包含C&C指令,短消息中包含链接并且连接中包含字符串”/version=”则为C&C指令。
如果不是C&C指令, 将消息写入文件并加密压缩然后上传到C&C服务器。
下表是SMS实现C&C的指令ID,SMS只负责下发指令,如有数据需要上传则上传到C&C服务器。
接收到的C&C链接为“{任意消息}{任意链接}/version={指令ID}”,如果对应的指令需要参数则在指令ID后面接”/{参数1}/{参数2}/…/{参数n}”。大部分指令与FCM下发的指令功能重合。
指令ID | 描述 |
---|---|
01 | 自定义时间录音 |
04 | 停止所有录音 |
03 | 监控短信接收和发送 |
59 | 激活所有监听器 |
95 | 停止所有监听器 |
34 | 使用手机流量 |
43 | 禁用手机流量 |
77 | 获取App详细信息 |
00 | 启用WIFI |
99 | 禁用WIFI |
44 | 获取通讯录里的联系方式 |
66 | 获取手机信息 |
88 | 获取文件和文件夹信息 |
07 | 设置C&C地址 |
5. 总结
针对此类恶意软件,我们建议
- 从google play商店等官方应用商店下载和安装应用。
- 如果在设备上发现任何可以应用程序,清立即卸载或删除他们。
- 将Android设备、操作系统和应用程序更新到最新版本。
7. IOC
dd4596cf68c85eb135f7e0ad763e5dab
8. ATT&CK矩阵
Tactic | ID | Name | Description |
---|---|---|---|
Initial Access | T1444 | Command and Scripting Interpreter | 伪装成合法应用 |
T1476 | Deliver Maliciour App via other Means | 该应用能从应用商店下载 | |
Execution | T1575 | Native Code | 使用jni函数返回被加密的C&C字符串。 |
Persistence | T1402 | Broadcast Receivers | 注册广播BOOT_COMPLETED确保设备启动时应用被激活。 |
Defense Evasion | T1508 | Supperss Application | 隐藏自身图标 |
Discovery | T1418 | Application Discovery | 遍历所有安装的应用 |
T1420 | File and Directory Discovery | ||
T1426 | System Information Discovery | 收集设备的详细信息。 | |
Collection | T1433 | Access Call Log | 收集历史通话记录 |
T1432 | Access Contact List | 收集通讯录 | |
T1517 | Access Notifications | 从社交App的通知消息中提取信息 | |
T1429 | Capture Audio | 对通话录音 | |
T1512 | Cature Camera | 使用前置或后置摄像头拍照。 | |
T1412 | Cature SMS Messages | 收集短消息 | |
T1533 | Data from Local System | 从外部媒体中窃取具有特定后缀名的文件。 | |
T1513 | Screen Capture | 屏幕截图 | |
Command and Control | T1438 | Alternative Network Mediums | 使用SMS接收C&C消息 |
T1437 | Standard Application Layper Protocol | 使用FCM下发C&C消息 | |
T1544 | Remote File Copy | 能从C&C服务器下载恶意应用 | |
Exfiltration | T1532 | Data Encrypted | 收集的文件使用zip加密压缩。 |
Impact | T1447 | Delete device data | 能够删除文件 |
9. 参考
https://www.welivesecurity.com/2020/09/30/aptc23-group-evolves-its-android-spyware/
https://blog.cyble.com/2021/09/15/apt-c-23-using-new-variant-of-android-spyware-to-target-users-in-the-middle-east/
最后更新: 2024年03月31日 13:05:40
本文链接: http://shxi.cc/post/326471a1.html
版权声明: 本作品采用 CC BY-NC-SA 4.0 许可协议进行许可,转载请注明出处!