1、前言
最近在做的渗透项目中刚好有一个APP的,之前也做过几次,没想着做记录,所以今天就顺便把思路给屡一下。
2、使用工具
这里我使用的工具如下:
dex2jar-2.0
apktool_2.3.4
jd-gui.exe
夜神模拟器
常规渗透工具等
3、具体操作
3.1、加固检查
拿到apk后,在我的理解中应该是先检查一下是否进行了加固,加固方式是什么,收集一切情报。
3.2、反编译部分
在获取加固信息的情报之后,再开始进行反编译工作,将APP中的AndroidManifest.xml配置文件给搞出来。AndroidManifest.xml清单文件时Android程序中必须的文件,是整个Android程序的全局描述文件。它为声明一个应用程序组件,还会指明应用程序所需链接到的库的名称,除默认Android库之外的,以及声明应用程序期望获得的各权限。
下面将记录一下AndroidManifest.xml的主要标签及其主要属性的说明,其中uses-permission标签中的参数最重要。
manifest标签
manifest标签是AndroidManifest.xml的根节点,必须包括一个节点, 并且设定xmlns:android和包属性。
xmlns:android:定义android命名空间,一般为http://schemas.android.com/apk/res/android,这样使得Android中各种标准属性能在文件中使用,提供了大部分元素中的数据。
package:指定本应用内java主程序包的包名,它也是一个应用进程的默认名称。它也是生成的应用程序资源文件的索引类(R)的包名。
sharedUserId:表明数据权限,因为默认情况下,Android给每个APK分配一个唯一的UserID,所以是默认禁止不同APK访问共享数据的。若要共享数据, 第一可以采用Share Preference方法,第二种就可以采用sharedUserId了,将不同APK的sharedUserId都设为一样,则这些APK之间就可以互相共享数据了。
sharedUserLabel:一个共享的用户名,它只有在设置了sharedUserId属性的前提下才会有意义。
versionCode:是给设备程序识别版本(升级)用的必须是一个interger值代表app更新过多少次,比如第一版一般为1,之后若要更新版本就设置为2,3等等。
versionName:这个名称是给用户看的,你可以将你的APP版本号设置为1.1版,后续更新版本设置为1.2、2.0版本等等。
installLocation:程序的安装位置,有三个值可以选择:internalOnly、auto、preferExternal
internalOnly--APK必须安装到内部存储空间。而且安装了之后,不能将程序移动到SD卡上。
auto--系统将会根据存储空间去选择将APK安装在内部存储空间还是SD卡上。安装之后,可以在内部存储空间和SD卡之间移动。
preferExternal--系统会优先考虑将APK安装到SD卡上(当然最终用户可以选择为内部ROM存储上,如果SD存储已满,也会安装到内部存储上)
permission标签
permission是定义一个安全访问许可。其它程序或组件若要访问该程序,必须先获取该permission。
android:description:权限描述。是用户可读的,它稍稍有点不同于android:label属性。label属性可以直接赋值为字符串,而description必须指定定义在string资源文件中的字符串。
android:name:该权限所属的权限组。若不设定,则默认不属于任何权限组。
android:protectionLeve:设置权限的安全级别。用来指出权限的安全级别,是否对系统的安全构成威胁。有以下4个值:
normal--表示权限是低风险的,不会对系统、用户或其他应用程序造成危害。用户使用该权限时,不会弹出对话框让用户确认是否允许使用该权限。
dangerous--表示权限是高风险的,系统将可能要求用户输入相关信息,才会授予此权限。用户使用该权限时,会弹出确认对话框是否同意使用该权限。
signature告诉Android,只有当应用程序所用数字签名与声明此权限的应用程序所有数字签名相同时,才能将权限授给它。
signatureOrSystem告诉Android,将权限授给具有相同数字签名的应用程序或Android包类,这一级别适用于非常特殊的情况,比如多个供应商需要通过系统影像共享功能时。
permission-group标签:
permission-group是描述permission是所属的组。permission-group本身并不定义权限,它只是权限所属的一个组。作用是来先区别不同的权限。
android:description:权限组描述。它稍稍有点不同于android:label属性。label属性可以直接赋值为字符串,而description必须指定定义在string资源文件中的字符串。
android:name:权限组的名称。当某权限要设置权限组时,就将该权限的permissionGroup设置权限组即可。
permission-tree标签:
permission-tree主要作用是用来动态添加一些所谓 Dynamic 的 permission ,这些 permission 可以动态修改。这些 permission 名称要以 permission-tree 的名称开头。它本身不是一种权限,没有 protectedLevel 和所属 group 。只是保存了所属的 packge 和权限名(带有 package 前缀的)。
android:name:这个属性定义了权限树根节点的名称。它被用于树中所有权限名称的前缀。应该使用Java样式命名规则,以确保名称的唯一性。在命名中必须要有两个以上的”.”来进行分离,例如:com.example.base是正确的,但com.example就是错误的。
uses-permission标签:
uses-permission程序需要指定以获取权限来进行有关操作。这里的权限值可以是Android系统自带的,也可以是自定义的。比如,android.permission.READ_CONTACTS是读取通讯录的必备权限;android.permission.SET_WALLPAPER是设置墙纸的必备权限。
下面是 uses-permission的资料,记录下来方便后期查询:
android.permission.ACCESS_CHECKIN_PROPERTIES:允许读写访问“properties”表在checkin数据库中,改值可以修改上传。
android.permission.ACCESS_COARSE_LOCATION:允许一个程序访问CellID或WiFi来获取粗略的位置
android.permission.ACCESS_FINE_LOCATION:允许一个程序访问精良位置(如GPS)
android.permission.ACCESS_LOCATION_EXTRA_COMMANDS:允许应用程序访问额外的位置提供命令
android.permission.ACCESS_MOCK_LOCATION:允许程序创建模拟位置用于测试
android.permission.ACCESS_NETWORK_STATE:允许程序访问有关的GSM网络信息
android.permission.ACCESS_SURFACE_FLINGER:允许程序使用SurfaceFlinger底层特性
android.permission.ACCESS_WIFI_STATE:允许程序访问Wi-Fi网络状态信息
android.permission.ADD_SYSTEM_SERVICE:允许程序发布系统级服务
android.permission.BATTERY_STATS:允许程序更新手机电池统计信息
android.permission.BLUETOOTH:允许程序连接到已配对的蓝牙设备
android.permission.BLUETOOTH_ADMIN:允许程序发现和配对蓝牙设备
android.permission.BRICK:请求能够禁用设备(非常危险)
android.permission.BROADCAST_PACKAGE_REMOVED:允许程序广播一个提示消息在一个应用程序包已经移除后
android.permission.BROADCAST_STICKY:允许一个程序广播常用intents
android.permission.CALL_PHONE:允许一个程序初始化一个电话拨号不需通过拨号用户界面需要用户确认
android.permission.CALL_PRIVILEGED:允许一个程序拨打任何号码,包含紧急号码无需通过拨号用户界面需要用户确认
android.permission.CAMERA:请求访问使用照相设备
android.permission.CHANGE_COMPONENT_ENABLED_STATE:允许一个程序是否改变一个组件或其他的启用或禁用
android.permission.CHANGE_CONFIGURATION:允许一个程序修改当前设置,如本地化
android.permission.CHANGE_NETWORK_STATE:允许程序改变网络连接状态
android.permission.CHANGE_WIFI_STATE:允许程序改变Wi-Fi连接状态
android.permission.CLEAR_APP_CACHE:允许一个程序清楚缓存从所有安装的程序在设备中
android.permission.CLEAR_APP_USER_DATA:允许一个程序清除用户设置
android.permission.CONTROL_LOCATION_UPDATES:允许启用禁止位置更新提示从无线模块
android.permission.DELETE_CACHE_FILES:允许程序删除缓存文件
android.permission.DELETE_PACKAGES:允许一个程序删除包
android.permission.DEVICE_POWER:允许访问底层电源管理
android.permission.DIAGNOSTIC:允许程序RW诊断资源
android.permission.DISABLE_KEYGUARD:允许程序禁用键盘锁
android.permission.DUMP:允许程序返回状态抓取信息从系统服务
android.permission.EXPAND_STATUS_BAR:允许一个程序扩展收缩在状态栏,android开发网提示应该是一个类似Windows Mobile中的托盘程序
android.permission.FACTORY_TEST:作为一个工厂测试程序,运行在root用户
android.permission.FLASHLIGHT:访问闪光灯,android开发网提示HTC Dream不包含闪光灯
android.permission.FORCE_BACK:允许程序强行一个后退操作是否在顶层activities
android.permission.FOTA_UPDATE:暂时不了解这是做什么使用的,android开发网分析可能是一个预留权限.
android.permission.GET_ACCOUNTS:访问一个帐户列表在AccountsService中
android.permission.GET_PACKAGE_SIZE:允许一个程序获取任何package占用空间容量
android.permission.GET_TASKS:允许一个程序获取信息有关当前或最近运行的任务,一个缩略的任务状态,是否活动等等
android.permission.HARDWARE_TEST:允许访问硬件
android.permission.INJECT_EVENTS:允许一个程序截获用户事件如按键、触摸、轨迹球等等到一个时间流,android开发网提醒算是hook技术吧
android.permission.INSTALL_PACKAGES:允许一个程序安装packages
android.permission.INTERNAL_SYSTEM_WINDOW:允许打开窗口使用系统用户界面
android.permission.INTERNET:允许程序打开网络套接字
android.permission.MANAGE_APP_TOKENS:允许程序管理(创建、催后、 z- order默认向z轴推移)程序引用在窗口管理器中
android.permission.MASTER_CLEAR:目前还没有明确的解释,android开发网分析可能是清除一切数据,类似硬格机
android.permission.MODIFY_AUDIO_SETTINGS:允许程序修改全局音频设置
android.permission.MODIFY_PHONE_STATE:允许修改话机状态,如电源,人机接口等
android.permission.MOUNT_UNMOUNT_FILESYSTEMS:允许挂载和反挂载文件系统可移动存储
android.permission.PERSISTENT_ACTIVITY:允许一个程序设置他的activities显示
android.permission.PROCESS_OUTGOING_CALLS:允许程序监视、修改有关播出电话
android.permission.READ_CALENDAR:允许程序读取用户日历数据
android.permission.READ_CONTACTS:允许程序读取用户联系人数据
android.permission.READ_FRAME_BUFFER:允许程序屏幕波或和更多常规的访问帧缓冲数据
android.permission.READ_INPUT_STATE:允许程序返回当前按键状态
android.permission.READ_LOGS:允许程序读取底层系统日志文件
android.permission.READ_OWNER_DATA:允许程序读取所有者数据
android.permission.READ_SMS:允许程序读取短信息
android.permission.READ_SYNC_SETTINGS:允许程序读取同步设置
android.permission.READ_SYNC_STATS:允许程序读取同步状态
android.permission.REBOOT:请求能够重新启动设备
android.permission.RECEIVE_BOOT_COMPLETED:允许一个程序接收到ACTION_BOOT_COMPLETED广播在系统完成启动
android.permission.RECEIVE_MMS:允许一个程序监控将收到MMS彩信,记录或处理
android.permission.RECEIVE_SMS:允许程序监控一个将收到短信息,记录或处理
android.permission.RECEIVE_WAP_PUSH:允许程序监控将收到WAPPUSH信息
android.permission.RECORD_AUDIO:允许程序录制音频
android.permission.REORDER_TASKS:允许程序改变Z轴排列任务
android.permission.RESTART_PACKAGES:允许程序重新启动其他程序
android.permission.SEND_SMS:允许程序发送SMS短信
android.permission.SET_ACTIVITY_WATCHER:允许程序监控或控制activities已经启动全局系统中
android.permission.SET_ALWAYS_FINISH:允许程序控制是否活动间接完成在处于后台时
android.permission.SET_ANIMATION_SCALE:修改全局信息比例
android.permission.SET_DEBUG_APP:配置一个程序用于调试
android.permission.SET_ORIENTATION:允许底层访问设置屏幕方向和实际旋转
android.permission.SET_PREFERRED_APPLICATIONS:允许一个程序修改列表参数PackageManager.addPackageToPreferred()和PackageManager.removePackageFromPreferred()方法
android.permission.SET_PROCESS_FOREGROUND:允许程序当前运行程序强行到前台
android.permission.SET_PROCESS_LIMIT:允许设置最大的运行进程数量
android.permission.SET_TIME_ZONE:允许程序设置时间区域
android.permission.SET_WALLPAPER:允许程序设置壁纸
android.permission.SET_WALLPAPER_HINTS:允许程序设置壁纸hits
android.permission.SIGNAL_PERSISTENT_PROCESSES:允许程序请求发送信号到所有显示的进程中
android.permission.STATUS_BAR:允许程序打开、关闭或禁用状态栏及图标
android.permission.SUBSCRIBED_FEEDS_READ:允许一个程序访问订阅RSSFeed内容提供
android.permission.SUBSCRIBED_FEEDS_WRITE:系统暂时保留改设置,android开发网认为未来版本会加入该功能。
android.permission.SYSTEM_ALERT_WINDOW:允许一个程序打开窗口使用TYPE_SYSTEM_ALERT,显示在其他所有程序的顶层
android.permission.VIBRATE:允许访问振动设备
android.permission.WAKE_LOCK:允许使用PowerManager的 WakeLocks保持进程在休眠时从屏幕消失
android.permission.WRITE_APN_SETTINGS:允许程序写入API设置
android.permission.WRITE_CALENDAR:允许一个程序写入但不读取用户日历数据
android.permission.WRITE_CONTACTS:允许程序写入但不读取用户联系人数据
android.permission.WRITE_GSERVICES:允许程序修改Google服务地图
android.permission.WRITE_OWNER_DATA:允许一个程序写入但不读取所有者数据
android.permission.WRITE_SETTINGS:允许程序读取或写入系统设置
android.permission.WRITE_SMS:允许程序写短信
android.permission.WRITE_SYNC_SETTINGS:允许程序写入同步设置
uses-configuration标签:
uses-configuration这个属性用于指定该应用程序所需要的硬件和软件功能。
android:reqHardKeyboard:这个属性用于指定应用程序是否需要硬键盘,如果设置为true,则需要,否则不需要
android:reqKeyboardType:这个属性用于指定该应用程序需要的任何键盘的类型。这个属性不区分软/硬键盘。如果需要某种类型的硬键盘,就用这个属性来指定类型,并把reqHardKeyboard属性设置为true。 它的属性值必须是下表中值之一:
undefined -- 应用程序不需要键盘。(键盘的需求没有被定义。)这是默认值。
nokeys -- 应用程序不需要键盘,明确定义该应用不需要键盘
qwerty -- 应用程序需要一个标准的QWERTY键盘。
twelvekey -- 应用程序需要一个像大多电话那样的12键的数字键盘,键盘中包括0~9的数字和“*”号键、“#”号键。
android:reqNavigation:这个属性定义了应用程序所需要的任何导航设备,属性值必须是下表中的值之一:
undefined -- 应用程序不需要任何类型的导航控制。(应用程序的导航需求没有被定义。)这是默认值。
nonav -- 应用程序不需要到导航控制。
dpad -- 应用程序要求使用D-pad(方向板)来进行导航控制
trackball -- 应用程序要求使用轨迹球来进行导航控制
wheel -- 应用程序要求使用一个导航滚轮来进行导航控制。
如果应用程序要求一个导航控制,但并不关心具体的控制类型,那么就要把reqFiveWayNav属性设置为true,而不是只设置这一个属性。
android:reqTouchScreen:这个属性用于设置应用程序所需要的任何触屏类型。属性值必须是下表中的字符串之一:
undefined -- 应用程序不需要触屏。(触屏的需求不被定义。)这是默认值。
notouch -- 应用程序不需要触屏
stylus -- 应用程序需要带有触控笔操作的触屏。
finger -- 应用程序需要能够用一个手指进行操作的触屏。
uses-feature标签:
声明的目的是通知其他外部实体,该应用程序所依赖的硬件和软件功能。这个元素提供的required属性会让你指定应用程序在所需的功能不存在时,应用程序是否能够正常运行。因为功能能够所支持的Android设备不同,所以元素被用于描述应用程序所依赖的、重要的、可用的设备功能。
android:required:这个属性用于指定应用程序是否需要有android:name属性所指定的类库,默认为true。
true:没有这个库应用程序无法工作。如果用户设备设备上没有这个类库,系统不允许该应用程序安装在这个设备上。
false:如果该类库存在,则应用程序能够使用这个类库,但是如果有必要,也可以设计成没有该类库,应用程序也能够工作。系统会允许应用程序安装,即使该类库不存在。如果使用false,就要在运行时对类库的有效性进行必要的检查。
android:qlEsVersion:APK需要的OpenGL ES的版本。它的高16位代表主版本号,低16位代表次要版本号,如:要是指定OpenGL ES的版本号是2.0,那么就要设置为0x00020000。要指定的OpenGL ES的版本号是2.1,就要设置为0x00020001。
application标签:
application应用程序的声明。它包含了每个应用程序组件所声明的子元素,并且还有能够影响所有组件的属性。此处最主要的是检查uses-permission中的是否合规,不必要的权限不应添加。
检查完AndroidManifest.xml中的配置后该去尝试反编译了,这里我使用dex2jar+jd-gui来编译获得Java源码。
将apk进行解压缩后将文件夹下的classes.dex拖到dex2jar-2.0文件夹下。cmd跳转到dex2jar-2.0的路径下,执行 d2j-dex2jar.bat classes.dex 命令。命令执行成功后文件夹下生成了一个classes-dex2jar.jar文件。接下来就将这个jar文件拖到jd-gui中,apk的java文件就在其中,前提是APP未进行混淆处理。(tips.由于是项目中的APP,就稍微打下码吧。)
走到这一步反编译基本完成了吧,剩下的就靠Android模拟器来进行如web渗透相差不大的渗透测试了。
4、结束
APP方面的项目做得也不多,以上思路是结合前人的思路进行整理扩展的记录,反编译方向接触也不深,了解过APP有页面劫持的问题,一直搞不清是怎么做的,希望各位大佬扩展指正。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)