ka3n1x
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # **HOTSHI** Mobile Application Security Assessment This document presents a detailed methodology for assessing the security of the HOTSHI mobile application. The approach adopted is aligned with recognized standards in the field of IT cybersecurity, with particular attention to the specificities of mobile applications. **1. Source code audit:** We carry out an in-depth examination of the application's source code to identify any security flaws and points of vulnerability. **2. Vulnerability assessment and Security Audit:** This includes the capture and analysis of network traffic, as well as dynamic evaluations to simulate real attacks and test the robustness of the application. Key aspects of our assessment focus on : **A. Exchange confidentiality:** - Transmission security: How is data secured during transmission over the network? - Encryption implementation: What encryption technology is used, and how appropriate is it? - Networks used: Identification and security assessment of the different types of network used by the application. **B. Exchange Integrity:** - Telephone Communications Security:** Ability to intercept or modify communications from the mobile device. - Communications Security from Network Elements:** Assessment of the possibility of intercepting or modifying communications via network components. The aim is to provide a comprehensive analysis to ensure data protection and application resilience against cybersecurity threats. Our test began by obtaining an .apk file, and checking its nature, we found that ## Recognition ```python ┌──(kali㉿kali)-[~/chi/lol/apk] └─$ file app-release.apk app-release.apk: Android package (APK), with zipflinger virtual entry ┌──(kali㉿kali)-[~/chi/lol/apk] └─$ exiftool app-release.apk ExifTool Version Number : 12.67 File Name : app-release.apk Directory : . File Size : 26 MB File Modification Date/Time : 2024:01:15 20:00:26-05:00 File Access Date/Time : 2024:01:15 20:00:40-05:00 File Inode Change Date/Time : 2024:01:15 20:00:26-05:00 File Permissions : -rwxr-x--- File Type : ZIP File Type Extension : zip MIME Type : application/zip Zip Required Version : 0 Zip Bit Flag : 0 Zip Compression : Deflated Zip Modify Date : 1981:01:01 01:01:02 Zip CRC : 0xfadd38bc Zip Compressed Size : 51 Zip Uncompressed Size : 56 Zip File Name : META-INF/com/android/build/gradle/app-metadata.properties Warning : [minor] Use the Duplicates option to extract tags for all 1698 files ``` ## Decompilation & Static Analys The aim now is to decompile it. Several tools come to mind, but we'll have to settle for JADX Pro and APKTOOL. As you can see, we manage to reverse the .apk perfectly. Starting with apktool, we can see that the application can be easily decompiled. ![Capture d'écran 2024-01-15 232401](https://hackmd.io/_uploads/SJvJpEmta.png) The presence of directories such as `res` `lib` indicates that the apk has been successfully decompiled. As for the `smali` directory, its presence suggests the use of obfuscation options in apk generation. ![Capture d'écran 2024-01-15 232408](https://hackmd.io/_uploads/HkEx64QY6.png) If you try to read and understand the first file in the first directory, you will realize that the code is pure nonsense. This confirms the obfuscation ![Capture d'écran 2024-01-15 232523](https://hackmd.io/_uploads/HJGJpEmta.png) We can see that our appplication decomposes just as well ![Capture d'écran 2024-01-15 213721](https://hackmd.io/_uploads/SyQkpNQFa.png) From an examination of the JADX Pro decompilation output, it is evident that there are no .smali files present. This absence strongly suggests that obfuscation techniques were not employed during the compilation of this APK. However, contrasting this with the findings from apktool, which did yield .smali files, it leads to a nuanced conclusion. The disparity in outcomes indicates that while obfuscation methods were indeed utilized in the compilation process, the level of obfuscation implemented was relatively minimal and not sufficiently robust to prevent the retrieval of .smali files using certain decompilation tools. ```python ┌──(kali㉿kali)-[~/chi/lol/lol] └─$ find . -type d -name *smali* ┌──(kali㉿kali)-[~/chi/lol/lol] └─$ find . -type f -name *smali* ┌──(kali㉿kali)-[~/chi/lol/lol] └─$ find . -type f -name *.smali* ┌──(kali㉿kali)-[~/chi/lol/lol] └─$ find . -type f -name *.smali ┌──(kali㉿kali)-[~/chi/lol/lol] └─$ find . -type f -name *.sm ``` And unlike apktool, here the obfuscated file seems totally digestible. ![Capture d'écran 2024-01-16 021911](https://hackmd.io/_uploads/rymXcIQtp.png) Let's start the analysis. It's vital to see the manifest, to know which technologies are used, which safeguards are in place, and which are not. Here is the Manifest file ```xml <manifest xmlns:android="http://schemas.android.com/apk/res/android"> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <application android:label="hotshi" android:name="${applicationName}" android:icon="@mipmap/ic_launcher"> <activity android:name=".MainActivity" android:exported="true" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize"> <!-- Specifies an Android theme to apply to this Activity as soon as the Android process has started. This theme is visible to the user while the Flutter UI initializes. After that, this theme continues to determine the Window background behind the Flutter UI. --> <meta-data android:name="io.flutter.embedding.android.NormalTheme" android:resource="@style/NormalTheme" /> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <!-- Don't delete the meta-data below. This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> <meta-data android:name="flutterEmbedding" android:value="2" /> </application> </manifest> ``` Let's start the analysis. It's vital to see the manifest, to know what technologies are used, what safeguards are in place, and which are not. --- ## SSL Pinning Warning My first concern is to see the system for assigning and using certificates (see if SSL pinning is in place). Looking at the Android manifest, there's no direct indication that SSL Pinning is used or protected. It may be implemented at the application source code level, specifically in the parts where it handles network communications (for example, using OkHttpClient for HTTP requests in Java/Kotlin). Looking arround, we've found these stuffs : The analysis clearly indicates that all network traffic is being encrypted using the SSL (Secure Sockets Layer) protocol, as evidenced by the presence of 'SSLSocketFactory' either 'OkHttpClient'. However, there is a notable absence of SSL Pinning mechanisms. This oversight in the configuration potentially leaves the door open for various types of Man-In-The-Middle (MITM) attacks. Tools such as Burp Suite, Wireshark, or other proxy tools could be exploited to intercept and manipulate the network traffic, thereby posing a significant security risk. It's crucial to address this vulnerability to ensure the integrity and confidentiality of the data in transit. ![Capture d'écran 2024-01-16 000329](https://hackmd.io/_uploads/SJIeT47Ka.png) ```js └─$ grep -ir 'OkHttpClient' grep: REV/resources/classes.dex: binary file matches REV/sources/n8/i.java: u8.c.c("OkHttpClientTransport$ClientFrameHandler.rstStream", hVar.y().h0()); REV/sources/n8/i.java: u8.c.c("OkHttpClientTransport$ClientFrameHandler.headers", hVar.y().h0()); REV/sources/n8/i.java: u8.c.c("OkHttpClientTransport$ClientFrameHandler.data", Z.y().h0()); REV/sources/n8/i.java: Thread.currentThread().setName("OkHttpClientTransport"); REV/sources/n8/h.java: u8.c.f("OkHttpClientStream$Sink.cancel"); REV/sources/n8/h.java: u8.c.h("OkHttpClientStream$Sink.cancel"); REV/sources/n8/h.java: u8.c.f("OkHttpClientStream$Sink.writeHeaders"); REV/sources/n8/h.java: u8.c.h("OkHttpClientStream$Sink.writeHeaders"); REV/sources/n8/h.java: u8.c.f("OkHttpClientStream$Sink.writeFrame"); REV/sources/n8/h.java: u8.c.h("OkHttpClientStream$Sink.writeFrame"); ``` --- ## Shared Lib and Binary Exploit Warning Also in the return of JADX Pro it happens that there are shared lib, one of them after decompilation through: Ghidra and BinaryNinja Pro, happens to be the application in ELF version. ```python ┌──(kali㉿kali)-[~/chi/lol/lol/REV] └─$ file ./resources/lib/arm64-v8a/lib* ./resources/lib/arm64-v8a/libapp.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[md5/uuid]=5640f66fed4fcbd4c26ef171e19f0768, stripped ./resources/lib/arm64-v8a/libflutter.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=eaead928a3da70c66b95dab9fd5da01824bd982f, stripped ``` ### Binary Ninja Pro Overview ![Capture d'écran 2024-01-15 223555](https://hackmd.io/_uploads/SyPJTNXFa.png) ### Ghidra Overview ![Capture d'écran 2024-01-15 223932](https://hackmd.io/_uploads/HJ7k6VQKp.png) It would be interesting to make these shared libs very difficult to manipulate. I can recommend : Using the visibility feature (-fvisibility=hidden): This option hides symbols that should not be exposed, thus reducing the number of visible entry points for an analysis. Symbol striping (-s): The -s option with GCC or when using the strip tool removes debugging information and symbols from the library, making it more difficult to understand the structure and inner workings of the code. Use of the visibility feature (-fvisibility=hidden): This option hides symbols that should not be exposed, reducing the number of visible entry points for analysis. Use macros and inlining (-D, -finline-functions): Define complex macros and use inlining to mix code, making static analysis more difficult. Independent position compilation (-fPIC): Although mainly used for shared library compatibility, it can also add a level of complexity when reverse engineering. --- ## Impersonification Warning It is imperative to eschew the implementation of unequivocal directives such as 'ADMIN_ONLY_OPERATION', which delineate the scope of an administrator's authorized activities. The rationale behind this recommendation is anchored in security concerns: such explicit rules can be readily exploited for the purpose of impersonation. Unscrupulous individuals may utilize these well-defined parameters to mimic administrative privileges, thereby facilitating the execution of numerous unauthorized actions. This approach not only undermines the integrity of the administrative role but also poses a significant risk to the overall security framework. ![Capture d'écran 2024-01-15 232711](https://hackmd.io/_uploads/SkUeT4mK6.png) ![Capture d'écran 2024-01-15 232726](https://hackmd.io/_uploads/Hk7epVXK6.png) --- ## SQLi Warning In this instance, it has been observed that numerous SQL queries are discernibly embedded within the source file, as decompiled by JADX. This situation warrants a more thorough investigation into the underlying practices of code management and security protocols. ![Capture d'écran 2024-01-15 215553](https://hackmd.io/_uploads/ByR1aEXtp.png) The full overview is just bellow : ```sh ┌──(kali㉿kali)-[~/chi/lol/lol] └─$ grep -nr ' FROM ' REV/resources/google/firestore/v1/query.proto:267: // * `SELECT * FROM Foo ORDER BY A` becomes REV/resources/google/firestore/v1/query.proto:268: // `SELECT * FROM Foo ORDER BY A, __name__` REV/resources/google/firestore/v1/query.proto:269: // * `SELECT * FROM Foo ORDER BY A DESC` becomes REV/resources/google/firestore/v1/query.proto:270: // `SELECT * FROM Foo ORDER BY A DESC, __name__ DESC` REV/resources/google/firestore/v1/query.proto:271: // * `SELECT * FROM Foo WHERE A > 1` becomes REV/resources/google/firestore/v1/query.proto:272: // `SELECT * FROM Foo WHERE A > 1 ORDER BY A, __name__` REV/resources/google/firestore/v1/query.proto:310: // SELECT COUNT_UP_TO(1000) FROM ( SELECT * FROM k ); REV/resources/google/firestore/v1/firestore.proto:151: // SELECT COUNT(*) FROM ( SELECT * FROM k where a = true ); grep: REV/resources/classes.dex: binary file matches grep: REV/resources/lib/arm64-v8a/libapp.so: binary file matches REV/sources/y4/z3.java:81: new a3.d(this.f18212a, "SELECT path FROM remote_documents").e(new d5.n() { // from class: y4.m3 REV/sources/y4/z3.java:87: new a3.d(this.f18212a, "SELECT path FROM document_mutations").e(new d5.n() { // from class: y4.n3 REV/sources/y4/z3.java:96: new a3.d(this.f18212a, "SELECT target_id, target_proto FROM targets").e(new d5.n() { // from class: y4.x3 REV/sources/y4/z3.java:117: a3.d b10 = new a3.d(this.f18212a, "SELECT path FROM remote_documents WHERE path_length IS NULL LIMIT ?").b(100); REV/sources/y4/z3.java:136: Long l10 = (Long) new a3.d(this.f18212a, "SELECT highest_listen_sequence_number FROM target_globals LIMIT 1").d(new d5.v() { // from class: y4.y3 REV/sources/y4/z3.java:147: a3.d b10 = new a3.d(this.f18212a, "SELECT RD.path FROM remote_documents AS RD WHERE NOT EXISTS (SELECT TD.path FROM target_documents AS TD WHERE RD.path = TD.path AND TD.target_id = 0) LIMIT ?").b(100); REV/sources/y4/z3.java:328: new a3.d(this.f18212a, "SELECT batch_id FROM mutations WHERE uid = ? AND batch_id <= ?").b(string, Long.valueOf(cursor.getLong(1))).e(new d5.n() { // from class: y4.p3 REV/sources/y4/z3.java:347: new a3.d(this.f18212a, "SELECT uid, last_acknowledged_batch_id FROM mutation_queues").e(new d5.n() { // from class: y4.v3 REV/sources/y4/z3.java:356: SQLiteStatement compileStatement = this.f18212a.compileStatement("DELETE FROM mutations WHERE uid = ? AND batch_id = ?"); REV/sources/y4/z3.java:360: this.f18212a.execSQL("DELETE FROM document_mutations WHERE uid = ? AND batch_id = ?", new Object[]{str, Integer.valueOf(i10)}); REV/sources/y4/z3.java:364: new a3.d(this.f18212a, "SELECT target_id, target_proto FROM targets").e(new d5.n() { // from class: y4.q3 REV/sources/y4/z3.java:377: return !new a3.d(this.f18212a, "SELECT 1=1 FROM sqlite_master WHERE tbl_name = ?").b(str).f(); REV/sources/y4/o1.java:48: return (v4.e) this.f18093a.E("SELECT schema_version, create_time_seconds, create_time_nanos, total_documents, total_bytes FROM bundles WHERE bundle_id = ?").b(str).d(new d5.v() { // from class: y4.m1 REV/sources/y4/o1.java:65: return (v4.j) this.f18093a.E("SELECT read_time_seconds, read_time_nanos, bundled_query_proto FROM named_queries WHERE name = ?").b(str).d(new d5.v() { // from class: y4.n1 REV/sources/y4/t2.java:120: this.f18147a.E("SELECT uid FROM mutation_queues").e(new d5.n() { // from class: y4.o2 REV/sources/y4/t2.java:129: this.f18147a.E("SELECT MAX(batch_id) FROM mutations WHERE uid = ?").b((String) it.next()).e(new d5.n() { // from class: y4.p2 REV/sources/y4/t2.java:150: this.f18147a.E("SELECT SUBSTR(mutations, ?, ?) FROM mutations WHERE uid = ? AND batch_id = ?").b(Integer.valueOf((aVar.d() * 1000000) + 1), 1000000, this.f18150d, Integer.valueOf(i10)).c(aVar); REV/sources/y4/t2.java:182: this.f18147a.E("SELECT path FROM document_mutations WHERE uid = ?").b(this.f18150d).e(new d5.n() { // from class: y4.r2 REV/sources/y4/t2.java:198: a3.b bVar = new a3.b(this.f18147a, "SELECT DISTINCT dm.batch_id, SUBSTR(m.mutations, 1, ?) FROM document_mutations dm, mutations m WHERE dm.uid = ? AND dm.path IN (", Arrays.asList(1000000, this.f18150d), arrayList, ") AND dm.uid = m.uid AND dm.batch_id = m.batch_id ORDER BY dm.batch_id"); REV/sources/y4/t2.java:230: SQLiteStatement D = this.f18147a.D("DELETE FROM mutations WHERE uid = ? AND batch_id = ?"); REV/sources/y4/t2.java:231: SQLiteStatement D2 = this.f18147a.D("DELETE FROM document_mutations WHERE uid = ? AND path = ? AND batch_id = ?"); REV/sources/y4/t2.java:243: return (a5.g) this.f18147a.E("SELECT batch_id, SUBSTR(mutations, 1, ?) FROM mutations WHERE uid = ? AND batch_id >= ? ORDER BY batch_id ASC LIMIT 1").b(1000000, this.f18150d, Integer.valueOf(i10 + 1)).d(new d5.v() { // from class: y4.j2 REV/sources/y4/t2.java:255: return ((Integer) this.f18147a.E("SELECT IFNULL(MAX(batch_id), ?) FROM mutations WHERE uid = ?").b(-1, this.f18150d).d(new d5.v() { // from class: y4.s2 REV/sources/y4/t2.java:267: return (a5.g) this.f18147a.E("SELECT SUBSTR(mutations, 1, ?) FROM mutations WHERE uid = ? AND batch_id = ?").b(1000000, this.f18150d, Integer.valueOf(i10)).d(new d5.v() { // from class: y4.q2 REV/sources/y4/t2.java:291: this.f18147a.E("SELECT batch_id, SUBSTR(mutations, 1, ?) FROM mutations WHERE uid = ? ORDER BY batch_id ASC").b(1000000, this.f18150d).e(new d5.n() { // from class: y4.k2 REV/sources/y4/t2.java:321: if (this.f18147a.E("SELECT last_stream_token FROM mutation_queues WHERE uid = ?").b(this.f18150d).c(new d5.n() { // from class: y4.l2 REV/sources/y4/t2.java:332: return this.f18147a.E("SELECT batch_id FROM mutations WHERE uid = ? LIMIT 1").b(this.f18150d).f(); REV/sources/y4/e2.java:160: sb2.append("SELECT document_key, directional_value FROM index_entries "); REV/sources/y4/e2.java:171: StringBuilder sb3 = new StringBuilder("SELECT document_key, directional_value FROM ("); REV/sources/y4/e2.java:197: this.f17926a.E("SELECT array_value, directional_value FROM index_entries WHERE index_id = ? AND document_key = ? AND uid = ?").b(Integer.valueOf(qVar.f()), lVar.toString(), this.f17928c).e(new d5.n() { // from class: y4.b2 REV/sources/y4/e2.java:366: this.f17926a.v("DELETE FROM index_entries WHERE index_id = ? AND uid = ? AND array_value = ? AND directional_value = ? AND document_key = ?", Integer.valueOf(eVar.j()), this.f17928c, eVar.f(), eVar.g(), iVar.getKey().toString()); REV/sources/y4/e2.java:402: this.f17926a.v("DELETE FROM index_configuration WHERE index_id = ?", Integer.valueOf(qVar.f())); REV/sources/y4/e2.java:403: this.f17926a.v("DELETE FROM index_entries WHERE index_id = ?", Integer.valueOf(qVar.f())); REV/sources/y4/e2.java:404: this.f17926a.v("DELETE FROM index_state WHERE index_id = ?", Integer.valueOf(qVar.f())); REV/sources/y4/e2.java:447: this.f17926a.E("SELECT parent FROM collection_parents WHERE collection_id = ?").b(str).e(new d5.n() { // from class: y4.a2 REV/sources/y4/e2.java:551: String str = "SELECT DISTINCT document_key FROM (" + sb.toString() + ")"; REV/sources/y4/e2.java:585: this.f17926a.E("SELECT index_id, sequence_number, read_time_seconds, read_time_nanos, document_key, largest_batch_id FROM index_state WHERE uid = ?").b(this.f17928c).e(new d5.n() { // from class: y4.c2 REV/sources/y4/e2.java:591: this.f17926a.E("SELECT index_id, collection_group, index_proto FROM index_configuration").e(new d5.n() { // from class: y4.d2 REV/sources/y4/f4.java:131: this.f17952a.v("DELETE FROM targets WHERE target_id = ?", Integer.valueOf(i10)); REV/sources/y4/f4.java:137: d5.b.d(this.f17952a.E("SELECT highest_target_id, highest_listen_sequence_number, last_remote_snapshot_version_seconds, last_remote_snapshot_version_nanos, target_count FROM target_globals LIMIT 1").c(new d5.n() { // from class: y4.a4 REV/sources/y4/f4.java:179: this.f17952a.E("SELECT path FROM target_documents WHERE target_id = ?").b(Integer.valueOf(i10)).e(new d5.n() { // from class: y4.c4 REV/sources/y4/f4.java:205: this.f17952a.E("SELECT target_proto FROM targets WHERE canonical_id = ?").b(c10).e(new d5.n() { // from class: y4.b4 REV/sources/y4/f4.java:216: this.f17952a.v("DELETE FROM target_documents WHERE target_id = ?", Integer.valueOf(i10)); REV/sources/y4/f4.java:221: SQLiteStatement D = this.f17952a.D("DELETE FROM target_documents WHERE target_id = ? AND path = ?"); REV/sources/y4/f4.java:232: this.f17952a.E("SELECT target_proto FROM targets").e(new d5.n() { // from class: y4.e4 REV/sources/y4/f4.java:251: this.f17952a.E("SELECT target_id FROM targets WHERE last_listen_sequence_number <= ?").b(Long.valueOf(j10)).e(new d5.n() { // from class: y4.d4 REV/sources/y4/i2.java:67: return !this.f18008a.E("SELECT 1 FROM document_mutations WHERE path = ?").b(f.c(lVar.q())).f(); REV/sources/y4/i2.java:71: this.f18008a.v("DELETE FROM target_documents WHERE path = ? AND target_id = 0", f.c(lVar.q())); REV/sources/y4/i2.java:124: return this.f18008a.h().s() + ((Long) this.f18008a.E("SELECT COUNT(*) FROM (SELECT sequence_number FROM target_documents GROUP BY path HAVING COUNT(*) = 1 AND target_id = 0)").d(new d5.v() { // from class: y4.f2 REV/sources/y4/g3.java:49: StringBuilder z9 = d5.i0.z("SELECT contents, read_time_seconds, read_time_nanos, path FROM remote_documents WHERE path >= ? AND path < ? AND path_length = ? AND (read_time_seconds > ? OR ( read_time_seconds = ? AND read_time_nanos > ?) OR ( read_time_seconds = ? AND read_time_nanos = ? and path > ?)) ", list.size(), " UNION "); REV/sources/y4/g3.java:169: a3.b bVar = new a3.b(this.f17973a, "SELECT contents, read_time_seconds, read_time_nanos FROM remote_documents WHERE path IN (", arrayList, ") ORDER BY path"); REV/sources/y4/g3.java:220: a3.b bVar = new a3.b(this.f17973a, "DELETE FROM remote_documents WHERE path IN (", arrayList, ")"); REV/sources/y4/x2.java:28: this.f18190a.E("SELECT DISTINCT uid FROM mutation_queues").e(new d5.n() { // from class: y4.w2 REV/sources/y4/x2.java:73: this.f18190a.v("DELETE FROM data_migrations WHERE migration_name = ?", e1.f17923b); REV/sources/y4/x2.java:78: this.f18190a.E("SELECT migration_name FROM data_migrations").e(new d5.n() { // from class: y4.v2 REV/sources/y4/v1.java:82: a3.b bVar = new a3.b(this.f18174a, "SELECT overlay_mutation, largest_batch_id FROM document_overlays WHERE uid = ? AND collection_path = ? AND document_id IN (", Arrays.asList(this.f18176c, f.c(uVar)), list, ")"); REV/sources/y4/v1.java:121: this.f18174a.E("SELECT overlay_mutation, largest_batch_id FROM document_overlays WHERE uid = ? AND collection_path = ? AND largest_batch_id > ?").b(this.f18176c, f.c(uVar), Integer.valueOf(i10)).e(new d5.n() { // from class: y4.r1 REV/sources/y4/v1.java:133: this.f18174a.v("DELETE FROM document_overlays WHERE uid = ? AND largest_batch_id = ?", this.f18176c, Integer.valueOf(i10)); REV/sources/y4/v1.java:151: this.f18174a.E("SELECT overlay_mutation, largest_batch_id, collection_path, document_id FROM document_overlays WHERE uid = ? AND collection_group = ? AND largest_batch_id > ? ORDER BY largest_batch_id, collection_path, document_id LIMIT ?").b(this.f18176c, str, Integer.valueOf(i10), Integer.valueOf(i11)).e(new d5.n() { // from class: y4.t1 REV/sources/y4/v1.java:160: a3.d E = this.f18174a.E("SELECT overlay_mutation, largest_batch_id FROM document_overlays WHERE uid = ? AND collection_group = ? AND (collection_path > ? OR (collection_path = ? AND document_id > ?)) AND largest_batch_id = ?"); REV/sources/y4/v1.java:174: return (a5.k) this.f18174a.E("SELECT overlay_mutation, largest_batch_id FROM document_overlays WHERE uid = ? AND collection_path = ? AND document_id = ?").b(this.f18176c, f.c(lVar.q().r()), lVar.q().j()).d(new d5.v() { // from class: y4.p1 REV/sources/v0/m0.java:94: h1(sQLiteDatabase.rawQuery("SELECT COUNT(*), transport_name FROM events WHERE timestamp_ms < ? GROUP BY transport_name", strArr), new b() { // from class: v0.q REV/sources/v0/m0.java:134: return (q0.f) h1(sQLiteDatabase.rawQuery("SELECT last_metrics_upload_ms FROM global_log_event_state LIMIT 1", new String[0]), new b() { // from class: v0.d0 REV/sources/v0/m0.java:155: return w02 == null ? Boolean.FALSE : (Boolean) h1(r0().rawQuery("SELECT 1 FROM events WHERE context_id = ? LIMIT 1", new String[]{w02.toString()}), new b() { // from class: v0.x REV/sources/v0/m0.java:165: return (List) h1(sQLiteDatabase.rawQuery("SELECT distinct t._id, t.backend_name, t.priority, t.extras FROM transport_contexts AS t, events AS e WHERE e.context_id = t._id", new String[0]), new b() { // from class: v0.j0 REV/sources/v0/m0.java:340: sQLiteDatabase.compileStatement("DELETE FROM events WHERE num_attempts >= 16").execute(); REV/sources/v0/m0.java:351: if (((Boolean) h1(sQLiteDatabase.rawQuery("SELECT 1 FROM log_event_dropped WHERE log_source = ? AND reason = ?", new String[]{str, Integer.toString(bVar.a())}), new b() { // from class: v0.t REV/sources/v0/m0.java:384: sQLiteDatabase.compileStatement("DELETE FROM log_event_dropped").execute(); REV/sources/v0/m0.java:758: r0().compileStatement("DELETE FROM events WHERE _id in " + g1(iterable)).execute(); REV/sources/v0/m0.java:764: return ((Long) h1(r0().rawQuery("SELECT next_request_ms FROM transport_contexts WHERE backend_name = ? and priority = ?", new String[]{oVar.b(), String.valueOf(y0.a.a(oVar.d()))}), new b() { // from class: v0.f0 REV/sources/com/google/android/recaptcha/internal/zzad.java:44: Cursor rawQuery = getReadableDatabase().rawQuery("SELECT COUNT(*) FROM ce", null); ``` # Summary ## Vulnerabilities *List of HOTSHI Mobile Application Security Flaws:*. 1. *Flaws in the source code:* - Availability of certain SQL queries that can be used to modify their behavior, leading to SQLi, BlindSQL, NoSQL, etc. vulnerabilities. - Presence of admin rules, enabling impersonation. - Absence of code obfuscation practices, making it possible to see in detail how the application works and thus bypass firewalls after decompilation. 2. *Network security risks:* - Lack of security for data transmitted over unsecured or public networks, due to the absence of clear SSL pinning configuration. 3. *Vulnerabilities linked to mobile communications:* - Potential risk of interception or modification of communications from a proxy (MITM Attack). ## Recommendations *Recommendations for improving safety:*. 1. *For Source Code:* - Perform regular code reviews to detect and correct vulnerabilities. - Implement secure coding practices: obfuscation techniques, code names for admin rules in particular. 3. *Secure network communications:* - Avoid using unsecured public networks for sensitive communications: check host networks and reduce application authorizations according to criticality. 4. *Protect mobile communications:* - Implement security solutions on mobile devices to detect and prevent interception attempts: Anti Proxy - Reinforce the security of network components to prevent unauthorized modification of communications: Add an unauthorized certificate

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully