Code Monkey home page Code Monkey logo

appshark's Introduction

Document Index

AppShark

Appshark is a static taint analysis platform to scan vulnerabilities in an Android app.

Prerequisites

Appshark requires a specific version of JDK -- JDK 11. After testing, it does not work on other LTS versions, JDK 8 and JDK 16, due to the dependency compatibility issue.

Building/Compiling AppShark

We assume that you are working in the root directory of the project repo. You can build the whole project with the gradle tool.

$ ./gradlew build  -x test 

After executing the above command, you will see an artifact file AppShark-0.1.2-all.jar in the directory build/libs.

Running AppShark

Like the previous step, we assume that you are still in the root folder of the project. You can run the tool with

$ java -jar build/libs/AppShark-0.1.2-all.jar  config/config.json5

The config.json5 has the following configuration contents.

{
  "apkPath": "/Users/apks/app1.apk"
} 

Each JSON has these basic field.

  • apkPath: the path of the apk file to analyze
  • out: the path of the output directory
  • rules: specifies the rules, split by ,. Default is all *.json files in the $rulePath directory
  • rulePath: specifies the rule's parent directory, default is ./config/rules
  • maxPointerAnalyzeTime: the timeout duration in seconds set for the analysis started from an entry point
  • debugRule: specify the rule name that enables logging for debugging

For more config field, please visit net.bytedance.security.app.ArgumentConfig

If you provide a configuration JSON file which sets the output path as out in the project root directory, you will find the result file out/results.json after running the analysis.

Interpreting the Results

Below is an example of the results.json.

{
  "AppInfo": {
    "AppName": "test",
    "PackageName": "net.bytedance.security.app",
    "min_sdk": 17,
    "target_sdk": 28,
    "versionCode": 1000,
    "versionName": "1.0.0"
  },
  "SecurityInfo": {
    "FileRisk": {
      "unZipSlip": {
        "category": "FileRisk",
        "detail": "",
        "model": "2",
        "name": "unZipSlip",
        "possibility": "4",
        "vulners": [
          {
            "details": {
              "position": "<net.bytedance.security.app.pathfinder.testdata.ZipSlip: void UnZipFolderFix1(java.lang.String,java.lang.String)>",
              "Sink": "<net.bytedance.security.app.pathfinder.testdata.ZipSlip: void UnZipFolderFix1(java.lang.String,java.lang.String)>->$r31",
              "entryMethod": "<net.bytedance.security.app.pathfinder.testdata.ZipSlip: void f()>",
              "Source": "<net.bytedance.security.app.pathfinder.testdata.ZipSlip: void UnZipFolderFix1(java.lang.String,java.lang.String)>->$r3",
              "url": "/Volumes/dev/zijie/appshark-opensource/out/vuln/1-unZipSlip.html",
              "target": [
                "<net.bytedance.security.app.pathfinder.testdata.ZipSlip: void UnZipFolderFix1(java.lang.String,java.lang.String)>->$r3",
                "pf{obj{<net.bytedance.security.app.pathfinder.testdata.ZipSlip: void UnZipFolderFix1(java.lang.String,java.lang.String)>:35=>java.lang.StringBuilder}(unknown)->@data}",
                "<net.bytedance.security.app.pathfinder.testdata.ZipSlip: void UnZipFolderFix1(java.lang.String,java.lang.String)>->$r11",
                "<net.bytedance.security.app.pathfinder.testdata.ZipSlip: void UnZipFolderFix1(java.lang.String,java.lang.String)>->$r31"
              ]
            },
            "hash": "ec57a2a3190677ffe78a0c8aaf58ba5aee4d2247",
            "possibility": "4"
          },
          {
            "details": {
              "position": "<net.bytedance.security.app.pathfinder.testdata.ZipSlip: void UnZipFolder(java.lang.String,java.lang.String)>",
              "Sink": "<net.bytedance.security.app.pathfinder.testdata.ZipSlip: void UnZipFolder(java.lang.String,java.lang.String)>->$r34",
              "entryMethod": "<net.bytedance.security.app.pathfinder.testdata.ZipSlip: void f()>",
              "Source": "<net.bytedance.security.app.pathfinder.testdata.ZipSlip: void UnZipFolder(java.lang.String,java.lang.String)>->$r3",
              "url": "/Volumes/dev/zijie/appshark-opensource/out/vuln/2-unZipSlip.html",
              "target": [
                "<net.bytedance.security.app.pathfinder.testdata.ZipSlip: void UnZipFolder(java.lang.String,java.lang.String)>->$r3",
                "pf{obj{<net.bytedance.security.app.pathfinder.testdata.ZipSlip: void UnZipFolder(java.lang.String,java.lang.String)>:33=>java.lang.StringBuilder}(unknown)->@data}",
                "<net.bytedance.security.app.pathfinder.testdata.ZipSlip: void UnZipFolder(java.lang.String,java.lang.String)>->$r14",
                "<net.bytedance.security.app.pathfinder.testdata.ZipSlip: void UnZipFolder(java.lang.String,java.lang.String)>->$r34"
              ]
            },
            "hash": "26c6d6ee704c59949cfef78350a1d9aef04c29ad",
            "possibility": "4"
          }
        ],
        "wiki": "",
        "deobfApk": "/Volumes/dev/zijie/appshark-opensource/app.apk"
      }
    }
  },
  "DeepLinkInfo": {
  },
  "HTTP_API": [
  ],
  "JsBridgeInfo": [
  ],
  "BasicInfo": {
    "ComponentsInfo": {
    },
    "JSNativeInterface": [
    ]
  },
  "UsePermissions": [
  ],
  "DefinePermissions": {
  },
  "Profile": "/Volumes/dev/zijie/appshark-opensource/out/vuln/3-profiler.json"
}

License

AppShark is licensed under the APACHE LICENSE, VERSION 2.0

Contact Us

Lark

appshark's People

Contributors

bdbubble avatar firmianay avatar i-shivamsoni avatar nkbai avatar renxin-bling avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

appshark's Issues

SignInfo没有具体实现

师傅,这个是没写还是开源删掉了,有没有建议的实现方式?

@Serializable
data class BasicInfo(
    var AppInfo: AppInfo? = null,
    var ComponentsInfo: MutableMap<String, MutableMap<String, ComponentDescription>>? = null,
    var PermissionInfo: MutableList<String>? = null,
    var SignInfo: SignInfo? = null,
    var JSNativeInterface: List<String>? = null
)

@Serializable
data class SignInfo(
    @SerialName("Is signed v1") var isSignedV1: Boolean,
    @SerialName("Is signed v2") var isSignedV2: Boolean,
    @SerialName("Is signed v3") var isSignedV3: Boolean,
    var certs: MutableList<Cert>,
    var pkeys: MutableList<String>
)

java.lang.NullPointerException: v().grabMethod("<android…id setContentView(int)>") must not be null

Hi, while setting supportFragment to true in config5.json, We got the following exception:

java.lang.NullPointerException: v().grabMethod("<android…id setContentView(int)>") must not be null
        at net.bytedance.security.app.Fragment.<init>(Fragment.kt:306)
        at net.bytedance.security.app.Fragment$Companion.processFragmentEntries(Fragment.kt:295)
        at net.bytedance.security.app.StaticAnalyzeMain.startAnalyze(StaticAnalyzeMain.kt:70)
        at net.bytedance.security.app.StaticAnalyzeMain$startAnalyze$1.invokeSuspend(StaticAnalyzeMain.kt)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:284)
        at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
        at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
        at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
        at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
        at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
        at net.bytedance.security.app.StaticAnalyzeMainKt.main(StaticAnalyzeMain.kt:99)
        at net.bytedance.security.app.KotlinEntry$Companion.callMain(KotlinEntry.kt:24)
        at net.bytedance.security.app.KotlinEntry.callMain(KotlinEntry.kt)
        at net.bytedance.security.app.JavaEntry.main(JavaEntry.java:6)

Is that option still experimental?

运行报错

java.io.IOException: Cannot run program "appshark/config/tools/ApkName.sh"CreateProcess error=193, %1 不是有效的 Win32 应用程序

[Appshark-UI] - init.sql file

Dear Team,
Appreciate for open-source this great tool.
I am learning to use it but cannot find the init.sql for Appshark-ui.
Can you help to share with me the init.sql for MySQL database?
Thanks,

不同入口的污点该如何传播

public class MainActivity extends AppCompatActivity {
    Intent intent;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intent = getIntent();
    }

    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("key",intent.getStringExtra("test"));
    }
}

以上是我的样例,我希望getIntent是source,outstate是sink,我的规则如下,但是好像并不能生效。

{
    "IntentBabyVersion": {
      "enable": true,
      "SliceMode": true,
      "traceDepth": 10,
      "desc": {
        "name": "reparcel",
        "category": "reparcel",
        "detail": "Intent reparcel, but a very basic version",
        "wiki": "",
        "possibility": "2",
        "model": "high"
      },
      "entry": {},
      "source": {
        "Return": [
            "<android.app.Activity: android.content.Intent getIntent()>"
                ]
      },
      "sink": {
        "<*: * onSaveInstanceState*(*)>": {
          "LibraryOnly": true,
          "TaintParamType": [
            "android.os.Bundle"
          ],
          "TaintCheck": [
            "p*"
          ]
        }
      }
    }
  }

函数签名的返回类型解析错误

对于包含,号复杂返回值,会解析出错然后退出。

解决办法:
1、修改规则,把函数签名的返回类型改成*
2、修改程序MethodSignatureParseState.ReturnType -> {},把整个字符串作为返回类型,就是不知道对后续有没有影响?

{
    "READ_PHONE_STATE": {
        "APIMode": true,
        "desc": {
            "name": "READ_PHONE_STATE",
            "detail": "",
            "category": "ComplianceInfo",
            "complianceCategory": "",
            "complianceCategoryDetail": "",
            "level": ""
        },
        "entry": {},
        "source": {},
        "sink": {
            "<android.telephony.TelephonyManager: java.util.Map<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>> getEmergencyNumberList()>": {}
        }
    }
}

image

Running multiple rules and apps

Hi, Thankyou for open sourcing this tool. Its wonderful and I really enjoy how fast it is, i am still learning writing the rules correctly at the moment but the "Tutorial" for path traversal helped alot!

Is it possible to run the engine with multiple rules and apks? I tried to use "Rule1, Rule2" but it appears to error out, maybe something i am missing?

Thankyou!

多规则扫描显示json解析出错

java -jar AppShark-0.1.2-all.jar config/config.json5
kotlinx.serialization.json.internal.JsonDecodingException: Unexpected JSON token at offset 78: Expected beginning of the string, but got [ at path: $.rules
JSON input: {
"apkPath": "C:\Users\xxx\xxx.apk",
"out": "out",
"rules": [
"BadSer.json",
"HijackAction.json"
],
"rulePath": "config/rules"
}
at kotlinx.serialization.json.internal.JsonExceptionsKt.JsonDecodingException(JsonExceptions.kt:24)
at kotlinx.serialization.json.internal.JsonExceptionsKt.JsonDecodingException(JsonExceptions.kt:32)
at kotlinx.serialization.json.internal.AbstractJsonLexer.fail(AbstractJsonLexer.kt:528)
at kotlinx.serialization.json.internal.AbstractJsonLexer.fail$default(AbstractJsonLexer.kt:526)
at kotlinx.serialization.json.internal.AbstractJsonLexer.consumeStringLenient(AbstractJsonLexer.kt:397)
at kotlinx.serialization.json.internal.AbstractJsonLexer.unexpectedToken(AbstractJsonLexer.kt:204)
at kotlinx.serialization.json.internal.StringJsonLexer.consumeNextToken(StringJsonLexer.kt:74)
at kotlinx.serialization.json.internal.StringJsonLexer.consumeKeyString(StringJsonLexer.kt:85)
at kotlinx.serialization.json.internal.AbstractJsonLexer.consumeString(AbstractJsonLexer.kt:313)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeString(StreamingJsonDecoder.kt:292)
at kotlinx.serialization.encoding.AbstractDecoder.decodeStringElement(AbstractDecoder.kt:58)
at net.bytedance.security.app.ArgumentConfig$$serializer.deserialize(ArgumentConfig.kt:23)
at net.bytedance.security.app.ArgumentConfig$$serializer.deserialize(ArgumentConfig.kt:23)
at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:59)
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:38)
at kotlinx.serialization.json.Json.decodeFromString(Json.kt:100)
at net.bytedance.security.app.StaticAnalyzeMainKt.main(StaticAnalyzeMain.kt:108)
at net.bytedance.security.app.KotlinEntry$Companion.callMain(KotlinEntry.kt:24)
at net.bytedance.security.app.KotlinEntry.callMain(KotlinEntry.kt)
at net.bytedance.security.app.JavaEntry.main(JavaEntry.java:6)
this message should only appear in test case

When executing "java -jar AppShark-0.1.1-all.jar config/config.json5", an error occurred indicating that "ApkName.sh" is not a valid Win32 application.

java -jar AppShark-0.1.1-all.jar config/config.json5
�[0m2023-04-10 17:31:10:907:welcome to appshark 0.1.1
�[0m2023-04-10 17:31:10:926:started...
�[0m2023-04-10 17:31:10:968:memory usage=init = 266338304(260096K) used = 11178520(10916K) committed = 266338304(260096K) max = 4250927104(4151296K)
�[0m2023-04-10 17:31:10:970:loadNecessaryClasses
�[0m2023-04-10 17:31:11:972:memory usage=init = 266338304(260096K) used = 114869760(112177K) committed = 266338304(260096K) max = 4250927104(4151296K)
�[0m2023-04-10 17:31:12:979:memory usage=init = 266338304(260096K) used = 138734592(135483K) committed = 354418688(346112K) max = 4250927104(4151296K)
�[0m2023-04-10 17:31:14:7:memory usage=init = 266338304(260096K) used = 252706816(246784K) committed = 543162368(530432K) max = 4250927104(4151296K)
�[0m2023-04-10 17:31:15:12:memory usage=init = 266338304(260096K) used = 378969600(370087K) committed = 543162368(530432K) max = 4250927104(4151296K)
�[0m2023-04-10 17:31:16:17:loadNecessaryClasses Done classes=26561
�[0m2023-04-10 17:31:16:18:soot init done
�[0m2023-04-10 17:31:16:20:[C:\Users\fangjiantan\Desktop\Android\appshark-main\appshark-main/config/tools/ApkName.sh, C:/Users/fangjiantan/Desktop/Android/appshark-main/test.apk]
�[31m2023-04-10 17:31:16:22:C:/Users/fangjiantan/Desktop/Android/appshark-main/test.apk -> out
java.io.IOException: Cannot run program "C:\Users\Desktop\Android\appshark-main\appshark-main/config/tools/ApkName.sh": CreateProcess error=193, %1 不是有效的 Win32 应用程序。
at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1128)
at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1071)
at net.bytedance.security.app.android.AndroidUtils.parseApkInternal(AndroidUtils.kt:233)
at net.bytedance.security.app.android.AndroidUtils.parseApk(AndroidUtils.kt:215)
at net.bytedance.security.app.StaticAnalyzeMain.startAnalyze(StaticAnalyzeMain.kt:52)
at net.bytedance.security.app.StaticAnalyzeMainKt$main$2.invokeSuspend(StaticAnalyzeMain.kt:99)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:284)
at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
at net.bytedance.security.app.StaticAnalyzeMainKt.main(StaticAnalyzeMain.kt:99)
at net.bytedance.security.app.KotlinEntry$Companion.callMain(KotlinEntry.kt:24)
at net.bytedance.security.app.KotlinEntry.callMain(KotlinEntry.kt)
at net.bytedance.security.app.JavaEntry.main(JavaEntry.java:6)
Caused by: java.io.IOException: CreateProcess error=193, %1 不是有效的 Win32 应用程序。
at java.base/java.lang.ProcessImpl.create(Native Method)
at java.base/java.lang.ProcessImpl.(ProcessImpl.java:420)
at java.base/java.lang.ProcessImpl.start(ProcessImpl.java:151)
�[0m2023-04-10 17:31:16:27:memory usage=init = 266338304(260096K) used = 344393728(336322K) committed = 834666496(815104K) max = 4250927104(4151296K) at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1107)

    ... 17 more

污点链没有传播到List中对象的属性

大佬们,请帮忙解决一个问题

扫描的代码如下,source点设置为queryIntentActivities,sink点设置为startActivity,
"source": {
"Return": [
"<: * queryIntentActivities()>"
]
},
"sink": {
"<: * startActivit(*)>": {
"TaintParamType": [
"android.content.Intent"
],
"TaintCheck": [
"p0"
]
}
}
如下的传播链条是连起来的,可以扫描出来
Intent intent = new Intent();
intent.setClassName("com.test.app", "com.test.activity");
List queryIntentActivities = this.getPackageManager().queryIntentActivities(intent, 65536);
for(ResolveInfo i : queryIntentActivities) {
intent.setPackage(String.valueOf(i.describeContents()));
startActivity(intent);
}

但是将setPackage中的参数设置为列表对象的属性时,传播链条出现了断裂,无法扫描出来
List queryIntentActivities = this.getPackageManager().queryIntentActivities(intent, 65536);
for(ResolveInfo i : queryIntentActivities) {
intent.setPackage(i.resolvePackageName));
startActivity(intent);
}
似乎是污点仅仅传播到了ResolveInfo对象方法的返回值,而没有传播到ResolveInfo对象的属性,请大佬帮忙看看,应该怎样解决这个断裂问题

Appshark扫描优化

将appshark应用于devsecops流程时,不可避免的会出现同一个App的不同版本反复扫描的情况。 而这些app每一个版本之间的差异可能非常小,并且这些差异对于扫描结果也没有影响。
能否对此进行优化,避免重复的扫描以节省资源呢?

扫描漏报

使用mac.json进行检测,发现扫描结果中,有扫描到项目中引入的SDK中的调用,但是自身主项目中的调用没检测出来
apk已关闭加固与混淆
请问有可能是什么原因导致?

设置类型漏洞的检测问题

有一类常规漏洞是设置上的错误,比如针对WebView的setJavaScriptEnabled(true)setWebContentsDebuggingEnabled(true)setAllowContentAccess(true)等。
试过APIMode,但不能对函数的参数做过滤;如果用SliceMode,将1传播到setJavaScriptEnabled,但是source不支持整数类型。
大佬能否给一个规则示例。

检测未命中

配置检测规则为logSerial.json
image
检测代码为
image
检测结果未命中
image

能否支持aar、jar文件的扫描?

你好,作为一个大型APP的开发者,每次在APP中集成其他非自研的三方SDK(jar和aar)时,总担心这些SDK会存在隐私合规的问题,我尝试利用appShark对这些SDK进行接入前扫描,在initSoot时,我传入了AnalyzeStepByStep.TYPE.AAR,然后编译出新的AppShark-all.jar,,运行时soot报错,截图如下。查阅soot源码,发现其ClassSourceType不支持aar。本人对soot不太熟悉,无法继续深入研究,
请问appShark是否支持直接扫描jar和aar文件,或者能提供一些思路?谢谢
image

image

image

kali运行报错

环境:

  1. 刚更新好的Kali
  2. Java11.0.15
  3. gradle7.0

报错如下:
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
2022-09-14 12:31:20:117:welcome to appshark 0.1
2022-09-14 12:31:20:139:started...
java.lang.RuntimeException: Error when looking for manifest in apk: java.util.zip.ZipException: zip END header not found
at soot.Scene.getTargetSDKVersion(Scene.java:547)
at soot.Scene.getAndroidAPIVersion(Scene.java:461)
at soot.Scene.getAndroidJarPath(Scene.java:420)
at net.bytedance.security.app.AnalyzeStepByStep.initSoot(AnalyzeStepByStep.kt:131)
at net.bytedance.security.app.StaticAnalyzeMain.startAnalyze(StaticAnalyzeMain.kt:43)
at net.bytedance.security.app.StaticAnalyzeMainKt$main$2.invokeSuspend(StaticAnalyzeMain.kt:99)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:284)
at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
at net.bytedance.security.app.StaticAnalyzeMainKt.main(StaticAnalyzeMain.kt:99)
at net.bytedance.security.app.KotlinEntry$Companion.callMain(KotlinEntry.kt:24)
at net.bytedance.security.app.KotlinEntry.callMain(KotlinEntry.kt)
at net.bytedance.security.app.JavaEntry.main(JavaEntry.java:6)

image

SliceMode不能正确找到入口

这个应用存在漏洞CVE-2023-42468,我想写个规则来扫,先试了SliceMode,不行,好像是因为根据source和sink不能自动找到入口,后面跟不动了。

换成DirectMode并指定method可以扫出来,但如果指定的是"ExportedCompos": true,速度贼慢,最后也没扫出来。

请教下师傅,看看是哪儿的问题?

{
  placeCall: {
    DirectMode: true,
    // SliceMode: true,
    traceDepth: 20,
    desc: {
    },
    entry: {
      "methods": ["<com.cutestudio.dialer.activities.DialerActivity: void onCreate(android.os.Bundle)>"],
      // "ExportedCompos": true
    },
    source: {
      Return: ["<android.app.Activity: android.content.Intent getIntent(*)>"],
    },
    sink: {
      "<android.telecom.TelecomManager: void placeCall(android.net.Uri,android.os.Bundle)>": {
        TaintCheck: ["p0"],
      },
    },
    sanitizer: {},
  },
}
    "Sink": [
        "virtualinvoke $r4.<android.telecom.TelecomManager: void placeCall(android.net.Uri,android.os.Bundle)>($r5, $r1)"
    ],
    "position": "<com.cutestudio.dialer.activities.DialerActivity: void onCreate(android.os.Bundle)>",
    "Manifest": {
        "exported": true,
        "trace": [
            "<com.cutestudio.dialer.activities.DialerActivity: void onCreate(android.os.Bundle)>"
        ],
        "<activity exported=true name=com.cutestudio.dialer.activities.DialerActivity theme=2131952515 label=2131886319>": [
            {
                "<intent-filter>": [
                    {
                        "content": "<action name=android.intent.action.CALL>",
                        "isString": true
                    },
                    {
                        "content": "<category name=android.intent.category.DEFAULT>",
                        "isString": true
                    },
                    {
                        "content": "<data scheme=tel>",
                        "isString": true
                    }
                ]
            }
        ]
    },
    "entryMethod": "<com.cutestudio.dialer.activities.DialerActivity: void onCreate(android.os.Bundle)>",
    "Source": [
        "$r2_2 = virtualinvoke r0.<android.app.Activity: android.content.Intent getIntent()>()"
    ],
    "target": [
        "<com.cutestudio.dialer.activities.DialerActivity: void onCreate(android.os.Bundle)>->$r2_2",
        "<com.cutestudio.dialer.activities.DialerActivity: void onCreate(android.os.Bundle)>->$r4_1",
        "pf{obj{<CustomClass: void Main_Entry_CustomClass()>:0=>com.cutestudio.dialer.activities.DialerActivity}(android.net.Uri)->g0}",
        "<com.cutestudio.dialer.activities.DialerActivity: android.net.Uri O1(com.cutestudio.dialer.activities.DialerActivity)>->r1",
        "<com.cutestudio.dialer.activities.DialerActivity$a: void c(android.telecom.PhoneAccountHandle)>->$r5"
    ]

运行报错

WeChat Image_20221015174554

kali 运行报错,请问这是什么原因。

ConstString rule未找到调用链

测试代码如下:

package com.example.test.util;

public class HookInfo {
    public String className;
    public String methodName;

    public static List<HookInfo> infoList = new ArrayList<>();

    public HookInfo(String className, String methodName) {
        this.className = className;
        this.methodName = methodName;
    }

    public static List<HookInfo> getInfoList() {
        infoList.add(new HookInfo("android.telephony.TelephonyManager",
                "getDeviceId"
        ));

        infoList.add(new HookInfo("android.telephony.TelephonyManager",
                "getSubscriberId"
        ));

        return infoList;
    }

}

public class testInfo {

    public static void t(HookInfo info) throws ClassNotFoundException {
        Class cls = String.class.getClassLoader().loadClass(info.className);

        test.doTest(cls, info.methodName);

    }
}


public class test {
    public static void doTest(Class cls, String m) {

    }
}

package com.example.test;

public class Main {
    public void test() throws ClassNotFoundException {

        List<HookInfo> list = HookInfo.getInfoList();

        for (HookInfo info : list) {
            testInfo.t(info);
        }

    }
}

测试规则:

{
"ConstStringTest1": {
"ConstStringMode": true,
"traceDepth": 26,
"desc": {
"name": "test",
"category": "ConstStringTest",
"detail": "ConstStringTest",
"wiki": "",
"possibility": "4",
"model": "middle"
},
"targetStringArr": ["android.telephony.TelephonyManager"],
"minLen": 2,
"source": {
"ConstString": ["android.telephony.TelephonyManager"]
},
"sink": {
"<com.example.test.util.test: * doTest()>": {
"TaintCheck": [
"p
"
]
}
}
}
}

来自一个强迫症

大佬好,都说<source,sink,sanitizer>三元组,但在规则文件中偏偏将sanitizer(名词)写成了sanitize(动词)。强迫症难受,如果需要,我可以提交一个PR

在规则文件中增加permission字段来检查权限滥用

APIMode现在只是单纯的找API,是不是可以根据API-Permission的映射关系,如果扫描结果为空,但权限清单中包含该permission,就判断存在权限滥用

{
  "获取蓝牙设备信息": {
    "desc": {
      "category": "camille",
      "detail": "获取蓝牙设备信息",
      "name": "获取蓝牙设备信息",
      "complianceCategory": "ComplianceInfo"
    },
    "permission": "android.permission.BLUETOOTH_CONNECT", // 新增
    "sink": {
      "<android.bluetooth.BluetoothAdapter: * getName(*)>": {},
      "<android.bluetooth.BluetoothDevice: * getAddress(*)>": {},
      "<android.bluetooth.BluetoothDevice: * getName(*)>": {}
    },
    "APIMode": true
  }
}

windows上报错

windows上执行java -jar AppShark-0.1-all.jar config/config.json5,报错:%1 不是有效的 Win32 应用程序

扫描时如何筛选函数的参数

我想要扫描工程中获取Android ID的代码,代码如下:

    public static String getAndroidID(Context context) {
        try {
            if (CommonsConfig.getInstance().isAgreePrivacy()) {
                if (TextUtils.isEmpty(ANDROID_ID)) {
                    if (CommonsConfig.getInstance().getPreferenceCallback() != null) {
                        ANDROID_ID = CommonsConfig.getInstance().getPreferenceCallback().getPreference(AID_ANDROIDID);
                    }
                    if (TextUtils.isEmpty(ANDROID_ID)) {
                        ANDROID_ID = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
                        MyLog.info(AID_TAG, "getAndroidID = " + ANDROID_ID);

                        if (CommonsConfig.getInstance().getPreferenceCallback() != null) {
                            CommonsConfig.getInstance().getPreferenceCallback().setPreference(AID_ANDROIDID, ANDROID_ID);
                        }
                    }
                }
                return ANDROID_ID;
            }
        } catch (Exception e) {
        }
        return "";
    }

因为Settings.Secure.getString()是个通用的方法,我想通过限制第二个参数为android.provider.Settings.Secure.ANDROID_ID来找出获取ANDROID_ID的代码,我写的rule如下:

{
  "ANDROIDID": {
    "SliceMode": true,
    "traceDepth": 30,
    "desc": {
      "name": "ANDROID_ID",
      "detail": "call get ANDROID_ID",
      "category": "ComplianceInfo",
      "complianceCategory": "ANDROID_ID",
      "complianceCategoryDetail": "ANDROID_ID",
      "level": "3"
    },
    "source": {
      "Field": [
        "<android.provider.Settings.System: java.lang.String ANDROID_ID>",
        "<android.provider.Settings.Secure: java.lang.String ANDROID_ID>"
      ]
    },
    "sink": {
      "<android.provider.Settings.Secure: * getString(*)>": {
        "TaintCheck": [
          "p1"
        ]
      }
    }
  }
}

我使用此rule无法扫描出获取ANDROID_ID的代码,请问我应该如何调整rule呢?

有两个问题请教下

1:如果自己写规则?该怎么写?
2:假如我检测app的隐私合规项,比如检测app有没有在我的允许下,获取我的应用列表,那么这个工具怎么判定是我同意之后,app才获取的应用列表,还是我同意之前,他就获取了呢

switch-case语句的result.json只有第一个case的label部分

在实际测试当中,发现switch-case语句,我在MethodSSAVistor.kt中将SSA后的Jimple IR保存到了文件,在ssa后的jimple语句当中查看,只走了第一个case的goto label,然后这个label刚好又是最后一个label,case当中其他对应的分支对应的label当中出现的同样的函数污点,但是就没有在result.json里面出现,但是在html当中出现了高亮。

規則撰寫問題請教

  • 預計分析源碼
package com.tmh.vulnwebview;

import android.os.Bundle;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import androidx.appcompat.app.AppCompatActivity;

/* loaded from: classes.dex */
public class RegistrationWebView extends AppCompatActivity {
    /* JADX INFO: Access modifiers changed from: protected */
    @Override // androidx.appcompat.app.AppCompatActivity, androidx.fragment.app.FragmentActivity, androidx.activity.ComponentActivity, androidx.core.app.ComponentActivity, android.app.Activity
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(C0816R.layout.activity_registration_web_view);
        setTitle("Registration page");
        loadWebView();
    }

    private void loadWebView() {
        // source: webView
        WebView webView = (WebView) findViewById(C0816R.C0819id.webview);
        webView.setWebViewClient(new WebViewClient());
        
        // sink: setAllowFileAccess
        webView.getSettings().setAllowFileAccess(true);
        
        if (getIntent().getExtras().getBoolean("is_reg", false)) {
            // sink: load file:///
            webView.loadUrl("file:///android_asset/registration.html");
        } else {
            webView.loadUrl(getIntent().getStringExtra("reg_url"));
        }
    }
}
  • 預期分析結果希望 getsettings -> setAllowFileAccess -> loadUrl的流程,實際實作時卻被切分成兩個了
  • 以下是我的規則
{
    "WebView": {
        "SliceMode": true,
        "traceDepth": 8,
        "desc": {
            "name": "Webview setAllowFileAccess",
            "category": "webview",
            "detail": "Webview setAllowFileAccess(true) and loadurl",
            "wiki": "",
            "possibility": "4",
            "model": "middle"
        },
        "source": {
            "Return": [
                "<*: android.view.View findViewById(*)>",
            ],
            "NewInstance": [
                "android.webkit.WebView"
            ]
        },
        "sink": {
            "<android.webkit.WebView: android.webkit.WebSettings getSettings(*)>": {
                "TaintCheck": [
                    "@this"
                ]
            },
            "<android.webkit.WebSettings: * setAllowFileAccess(boolean)>": {
                "TaintCheck": [
                    "@this"
                ],
                "p0": [
                    "0"
                ]
            },
            "<android.webkit.WebView: * loadUrl(java.lang.String)>": {
                "TaintCheck": [
                    "@this"
                ],
                "p0": [
                    "file:///*"
                ]
            }
        }
    }
}

污点传播不支持gson.fromJson

一个简单的例子

1、如果source设置为getJson()的return,sink设置为fromJson的return,可以扫出来;

2、source相同,sink设置为println()的p0,就不能扫出来了,也就是说污点只能传播到person,但不能传播到它的name

class testActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_arbitrary_install)

        val gson = Gson()
        val jsonString = getJson()
        val person: Person = gson.fromJson(jsonString, Person::class.java)

        val name = person.name
        println(name)
    }

    data class Person(var name: String, var age: Int)

    fun getJson(): String {
        return "{\"name\":\"Tom\",\"age\":20}"
    }
}

如何区分source的原始对象和传播中被污染的对象

https://codeql.github.com/codeql-query-help/java/java-android-intent-uri-permission-manipulation/

下面分别是有漏洞和没漏洞的例子:

    // BAD: the user-provided Intent is returned as-is
    public void dangerous() {
        Intent intent = getIntent();
        intent.putExtra("result", "resultData");
        setResult(intent);
    }

    // GOOD: a new Intent is created and returned
    public void safe() {
        Intent intent = new Intent();
        intent.putExtra("result", "resultData");
        setResult(intent);
    }

那如果是这种情况,intent1虽然是新建的,但是被intent2污染了,如果不能区分这两者,那就会产生误报:

    public void safe() {
        Intent intent1 = new Intent();
        Intent intent2 = getIntent();
        String string2 = intent2.getDataString();
        intent1.putExtra("result", string2);
        setResult(intent1);
    }

Centos7报SSL错误

运行build.sh时,下载gradle-7.0,报SSL错误

错误如下:

Downloading https://services.gradle.org/distributions/gradle-7.0-bin.zip

Exception in thread "main" javax.net.ssl.SSLHandshakeException: PKIX path validation failed: java.security.cert.CertPathValidatorException: validity check failed
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:353)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:296)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:291)
at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:654)
at java.base/sun.security.ssl.CertificateStatus$CertificateStatusConsumer.consume(CertificateStatus.java:295)
at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:443)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:421)
at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:183)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:172)
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1506)
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1416)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:456)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:427)
at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:572)
at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:197)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1592)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1520)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:250)
at org.gradle.wrapper.Download.downloadInternal(Download.java:87)
at org.gradle.wrapper.Download.download(Download.java:67)
at org.gradle.wrapper.Install$1.call(Install.java:68)
at org.gradle.wrapper.Install$1.call(Install.java:48)
at org.gradle.wrapper.ExclusiveFileAccessManager.access(ExclusiveFileAccessManager.java:69)
at org.gradle.wrapper.Install.createDist(Install.java:48)
at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:107)
at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:63)
Caused by: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: validity check failed
at java.base/sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:369)
at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:275)
at java.base/sun.security.validator.Validator.validate(Validator.java:264)
at java.base/sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:313)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:222)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:129)
at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:638)
... 23 more
Caused by: java.security.cert.CertPathValidatorException: validity check failed
at java.base/sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:135)
at java.base/sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:224)
at java.base/sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:144)
at java.base/sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:83)
at java.base/java.security.cert.CertPathValidator.validate(CertPathValidator.java:309)
at java.base/sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:364)
... 29 more
Caused by: java.security.cert.CertificateNotYetValidException: NotBefore: Mon May 09 20:00:00 EDT 2022
at java.base/sun.security.x509.CertificateValidity.valid(CertificateValidity.java:273)
at java.base/sun.security.x509.X509CertImpl.checkValidity(X509CertImpl.java:675)
at java.base/sun.security.provider.certpath.BasicChecker.verifyValidity(BasicChecker.java:190)
at java.base/sun.security.provider.certpath.BasicChecker.check(BasicChecker.java:144)
at java.base/sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:125)
... 34 more
[root@localhost appshark]# ./build.sh
Downloading https://services.gradle.org/distributions/gradle-7.0-bin.zip

Exception in thread "main" javax.net.ssl.SSLHandshakeException: PKIX path validation failed: java.security.cert.CertPathValidatorException: validity check failed
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:353)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:296)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:291)
at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:654)
at java.base/sun.security.ssl.CertificateStatus$CertificateStatusConsumer.consume(CertificateStatus.java:295)
at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:443)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:421)
at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:183)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:172)
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1506)
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1416)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:456)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:427)
at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:572)
at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:197)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1592)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1520)
at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:250)
at org.gradle.wrapper.Download.downloadInternal(Download.java:87)
at org.gradle.wrapper.Download.download(Download.java:67)
at org.gradle.wrapper.Install$1.call(Install.java:68)
at org.gradle.wrapper.Install$1.call(Install.java:48)
at org.gradle.wrapper.ExclusiveFileAccessManager.access(ExclusiveFileAccessManager.java:69)
at org.gradle.wrapper.Install.createDist(Install.java:48)
at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:107)
at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:63)
Caused by: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: validity check failed
at java.base/sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:369)
at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:275)
at java.base/sun.security.validator.Validator.validate(Validator.java:264)
at java.base/sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:313)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:222)
at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:129)
at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:638)
... 23 more
Caused by: java.security.cert.CertPathValidatorException: validity check failed
at java.base/sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:135)
at java.base/sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:224)
at java.base/sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:144)
at java.base/sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:83)
at java.base/java.security.cert.CertPathValidator.validate(CertPathValidator.java:309)
at java.base/sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:364)
... 29 more
Caused by: java.security.cert.CertificateNotYetValidException: NotBefore: Mon May 09 20:00:00 EDT 2022
at java.base/sun.security.x509.CertificateValidity.valid(CertificateValidity.java:273)
at java.base/sun.security.x509.X509CertImpl.checkValidity(X509CertImpl.java:675)
at java.base/sun.security.provider.certpath.BasicChecker.verifyValidity(BasicChecker.java:190)
at java.base/sun.security.provider.certpath.BasicChecker.check(BasicChecker.java:144)
at java.base/sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:125)
... 34 more

image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.