diff --git a/.github/workflows/checkLinks.yml b/.github/workflows/checkLinks.yml index 378b1b894f..040e408d2b 100644 --- a/.github/workflows/checkLinks.yml +++ b/.github/workflows/checkLinks.yml @@ -1,10 +1,9 @@ name: URLs Checker on: - push: - branches: - - master + workflow_dispatch: pull_request: + push: branches: - master diff --git a/.github/workflows/checkLint.yml b/.github/workflows/checkLint.yml index 056f6ace9f..b2651193bf 100644 --- a/.github/workflows/checkLint.yml +++ b/.github/workflows/checkLint.yml @@ -1,6 +1,11 @@ name: Markdown Linter -on: [push, pull_request] +on: + workflow_dispatch: + pull_request: + push: + branches: + - master jobs: markdown-lint-check: @@ -11,8 +16,8 @@ jobs: with: fetch-depth: 1 - name: markdownlint-cli - uses: nosborn/github-action-markdown-cli@v2.0.0 + uses: nosborn/github-action-markdown-cli@v3.0.1 with: files: Document - config_file: ".markdownlint.json" + config_file: ".markdownlint.jsonc" ignore_files: "Tools, node_modules, Crackmes, Samples" diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml index 6041f0eae3..a36f3c620a 100644 --- a/.github/workflows/codespell.yml +++ b/.github/workflows/codespell.yml @@ -1,5 +1,12 @@ name: codespell -on: [pull_request, push] + +on: + workflow_dispatch: + pull_request: + push: + branches: + - master + jobs: codespell: runs-on: ubuntu-latest diff --git a/.github/workflows/config/mlc_config.json b/.github/workflows/config/mlc_config.json index 5dbfe70ba0..4a4c98ca8b 100644 --- a/.github/workflows/config/mlc_config.json +++ b/.github/workflows/config/mlc_config.json @@ -44,6 +44,15 @@ }, { "pattern": "^http://damnvulnerableiosapp.com/" + }, + { + "pattern": "http://owaspsummit.org" + }, + { + "pattern": "^https://docs.github.com" + }, + { + "pattern": "^https://busybox.net" } ], "httpHeaders": [ diff --git a/.github/workflows/docgenerator.yml b/.github/workflows/docgenerator.yml index 802f55b941..48e7664898 100644 --- a/.github/workflows/docgenerator.yml +++ b/.github/workflows/docgenerator.yml @@ -6,6 +6,8 @@ on: paths: - 'Document/**.md' push: + branches: + - master paths: - 'Document/**.md' diff --git a/.markdownlint.json b/.markdownlint.json deleted file mode 100644 index d2e61b7a66..0000000000 --- a/.markdownlint.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "MD004": {"style": "dash"}, - "MD013": false, - "MD014": false, - "MD024": false, - "MD033": false, - "MD036": { - "punctuation": ".,;:!。" - }, - "MD041": false -} \ No newline at end of file diff --git a/.markdownlint.jsonc b/.markdownlint.jsonc new file mode 100644 index 0000000000..7a2d0d8ecb --- /dev/null +++ b/.markdownlint.jsonc @@ -0,0 +1,16 @@ +{ + // https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md + + "MD004": {"style": "dash"}, // ul-style + "MD013": false, // line-length + "MD024": {"allow_different_nesting": true}, // no-duplicate-header + "MD026": {"punctuation": "!?"}, // no-trailing-punctuation + "MD033": false, // no-inline-html + "MD035": {"style": "---"}, // hr-style + "MD036": {"punctuation": ".,;:!。"}, // no-emphasis-as-header + "MD041": false, // first-line-h1 + "MD046": {"style": "fenced"} , // code-block-style + "MD049": {"style": "underscore"}, // emphasis-style + "MD050": {"style": "asterisk"} // strong-style + + } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index acfa45d590..86ea53b8cb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,3 @@ # Contributing -Learn how you can contribute to the OWASP Mobile Security Project [here](docs/contributors/1_How_Can_You_Contribute.md). +Learn how you can contribute to the OWASP Mobile Security Project [here](docs/contributing/1_How_Can_You_Contribute.md). diff --git a/Crackmes/README.md b/Crackmes/README.md index 1d060e1a3b..7c3c405722 100644 --- a/Crackmes/README.md +++ b/Crackmes/README.md @@ -11,7 +11,7 @@ Welcome to the UnCrackable Apps for Android and iOS, a collection of mobile reve This app holds a secret inside. Can you find it? - Objective: A secret string is hidden somewhere in this app. Find a way to extract it. -- Author: [Bernhard Mueller](https://github.com/b-mueller "Bernhard Mueller"). +- Author: [Bernhard Mueller](https://github.com/muellerberndt "Bernhard Mueller"). - Maintained by the OWASP MSTG leaders. #### Installation @@ -38,7 +38,7 @@ This app is compatible with Android 4.4 and up. This app holds a secret inside. May include traces of native code. - Objective: A secret string is hidden somewhere in this app. Find a way to extract it. -- Author: [Bernhard Mueller](https://github.com/b-mueller "Bernhard Mueller"). +- Author: [Bernhard Mueller](https://github.com/muellerberndt "Bernhard Mueller"). - Special thanks to Michael Helwig for finding and fixing an oversight in the anti-tampering mechanism. - Maintained by the OWASP MSTG leaders. @@ -64,7 +64,7 @@ This app is compatible with Android 4.4 and up. The crackme from hell! - Objective: A secret string is hidden somewhere in this app. Find a way to extract it. -- Author: [Bernhard Mueller](https://github.com/b-mueller "Bernhard Mueller"). +- Author: [Bernhard Mueller](https://github.com/muellerberndt "Bernhard Mueller"). - Special thanks to Eduardo Novella for testing, feedback and pointing out flaws in the initial build(s). - Maintained by the OWASP MSTG leaders. @@ -122,7 +122,7 @@ $ adb install r2pay-v0.9.apk A brand new Android app sparks your interest. Of course, you are planning to purchase a license for the app eventually, but you'd still appreciate a test run before shelling out $1. Unfortunately no keygen is available! - Objective: Generate a valid serial key that is accepted by this app. -- Author: [Bernhard Mueller](https://github.com/b-mueller "Bernhard Mueller"). +- Author: [Bernhard Mueller](https://github.com/muellerberndt "Bernhard Mueller"). - Maintained by the OWASP MSTG leaders. #### Installation @@ -155,7 +155,7 @@ Product activation passed. Congratulations! This app holds a secret inside. Can you find it? - Objective: A secret string is hidden somewhere in this binary. Find a way to extract it. The app will give you a hint when started. -- Author: [Bernhard Mueller](https://github.com/b-mueller "Bernhard Mueller") +- Author: [Bernhard Mueller](https://github.com/muellerberndt "Bernhard Mueller") - Maintained by the OWASP MSTG leaders. #### Installation @@ -176,7 +176,7 @@ Note: The IPA is signed with an Enterprise distribution certificate. You'll need This app holds a secret inside - and this time it won't be tampered with! - Objective: Find the secret code - it is related to alcoholic beverages. -- Author: [Bernhard Mueller](https://github.com/b-mueller "Bernhard Mueller"). +- Author: [Bernhard Mueller](https://github.com/muellerberndt "Bernhard Mueller"). - Maintained by the OWASP MSTG leaders. Note: Due to its anti-tampering the app won't run correctly if the main executable is modified and/or re-signed. You'll need to trust the developer run it the standard way on a non-jailbroken device (General Settings -> Profile & Device Management) and to verify the solution. diff --git a/Document/0x02a-Frontispiece.md b/Document/0x02a-Frontispiece.md index 8c3a0cfc82..796682e48a 100644 --- a/Document/0x02a-Frontispiece.md +++ b/Document/0x02a-Frontispiece.md @@ -22,9 +22,9 @@ The OWASP MASVS and MSTG are trusted by the following platform providers and sta ## 🥇 MSTG Advocates -MSTG Advocates are industry adopters of the OWASP MASVS and MSTG who have invested a significant and consistent amount of resources to push the project forward by providing consistent high-impact contributions and continuously spreading the word. [Learn more](0x02a-Acknowledgements.md#our-mstg-advocates). +MSTG Advocates are industry adopters of the OWASP MASVS and MSTG who have invested a significant and consistent amount of resources to push the project forward by providing consistent high-impact contributions and continuously spreading the word. [Learn more](0x02c-Acknowledgements.md#our-mstg-advocates). - + diff --git a/Document/0x02c-Acknowledgements.md b/Document/0x02c-Acknowledgements.md index 4e11b1819f..1adf14b979 100644 --- a/Document/0x02c-Acknowledgements.md +++ b/Document/0x02c-Acknowledgements.md @@ -23,7 +23,7 @@ We will validate this status according to these categories: - etc. 3. **Spreading the word** and promoting the project with many presentations each year, public trainings, high social media involvement (e.g. liking, re-sharing, doing own posting specifically to promote the project). -*NOTE: You don't need to fulfill each and every bullet point (they are examples). However, you must be able to clearly show the continuity of your contributions and high impact for the project. For example, to fulfill "2." you could demonstrate that you've been sending high-impact Pull Request in the initial 6 months period and intend to continue to do so.* +_NOTE: You don't need to fulfill each and every bullet point (they are examples). However, you must be able to clearly show the continuity of your contributions and high impact for the project. For example, to fulfill "2." you could demonstrate that you've been sending high-impact Pull Request in the initial 6 months period and intend to continue to do so._ ### 🎁 Benefits @@ -35,11 +35,11 @@ We will validate this status according to these categories: ### 📝 How to Apply -If you'd like to apply please contact the project leaders by sending an email to [Sven Schleier](mailto:sven.schleier@owasp.org) and [Carlos Holguera](mailto:carlos.holguera@owasp.org) who will validate your application. Please be sure to include sufficient evidence (usually in the form of a *contribution report* including URLs linking to the corresponding elements) showing what you've done in the 6 months period that goes inline with the three categories described above. +If you'd like to apply please contact the project leaders by sending an email to [Sven Schleier](mailto:sven.schleier@owasp.org) and [Carlos Holguera](mailto:carlos.holguera@owasp.org) who will validate your application. Please be sure to include sufficient evidence (usually in the form of a _contribution report_ including URLs linking to the corresponding elements) showing what you've done in the 6 months period that goes inline with the three categories described above. ### ❗ Important Disclaimers -- If the "MSTG Advocate" status is granted and you'd like to maintain it, the aforementioned contributions must remain consistent after the initial period as well. You should keep collecting this evidence and send us a *contribution report* yearly. +- If the "MSTG Advocate" status is granted and you'd like to maintain it, the aforementioned contributions must remain consistent after the initial period as well. You should keep collecting this evidence and send us a _contribution report_ yearly. - [Financial donations](https://owasp.org/www-project-mobile-security-testing-guide/#div-donate) are not part of the eligibility criteria but will be listed for completion. - Re-shared publications and blog posts linked in MSTG text must be **educational** and focus on mobile security or MASVS/MSTG and **not endorse company products/services**. - Advocate Companies may use the logo and links to MASVS/MSTG resources as part of their communication but cannot use them as an endorsement by OWASP as a preferred provider of software and services. @@ -90,7 +90,7 @@ A special mention goes for the **contribution to the MASVS Refactoring**: - Feedback on each category proposal - Statistics from internal analysis -In the past, NowSecure has also contributed to the project, has sponsored it becoming a "God Mode Sponsor" and has donated the [UnCrackable App for Android Level 4: Radare2 Pay](Crackmes/Android/Level_04/). +In the past, NowSecure has also contributed to the project, has sponsored it becoming a "God Mode Sponsor" and has donated the [UnCrackable App for Android Level 4: Radare2 Pay](https://github.com/OWASP/owasp-mstg/tree/master/Crackmes/Android/Level_04). **Spreading the Word:** @@ -165,6 +165,6 @@ Reviewers have consistently provided useful feedback through GitHub issues and p ### Donators -While both the MASVS and the MSTG are created and maintained by the community on a voluntary basis, sometimes a little bit of outside help is required. We therefore thank our donators for providing the funds to be able to hire technical editors. Note that their donation does not influence the content of the MASVS or MSTG in any way. The Donation Packages are described on the [OWASP Project Wiki](https://www.owasp.org/index.php/OWASP_Mobile_Security_Testing_Guide#tab=Sponsorship_Packages "OWASP Mobile Security Testing Guide Donation Packages"). +While both the MASVS and the MSTG are created and maintained by the community on a voluntary basis, sometimes a little bit of outside help is required. We therefore thank our donators for providing the funds to be able to hire technical editors. Note that their donation does not influence the content of the MASVS or MSTG in any way. The Donation Packages are described on the [OWASP Project Wiki](https://owasp.org/www-project-mobile-security-testing-guide/#donation-packagess "OWASP Mobile Security Testing Guide Donation Packages"). diff --git a/Document/0x04a-Mobile-App-Taxonomy.md b/Document/0x04a-Mobile-App-Taxonomy.md index 4d220fde3a..8e9ebb163d 100644 --- a/Document/0x04a-Mobile-App-Taxonomy.md +++ b/Document/0x04a-Mobile-App-Taxonomy.md @@ -8,33 +8,33 @@ In a basic sense, apps are designed to run either directly on the platform for w ## Native App -Mobile operating systems, including Android and iOS, come with a Software Development Kit (SDK) for developing applications specific to the OS. Such applications are referred to as *native* to the system for which they have been developed. When discussing an app, the general assumption is that it is a native app implemented in a standard programming language for the respective operating system - Objective-C or Swift for iOS, and Java or Kotlin for Android. +Mobile operating systems, including Android and iOS, come with a Software Development Kit (SDK) for developing applications specific to the OS. Such applications are referred to as _native_ to the system for which they have been developed. When discussing an app, the general assumption is that it is a native app implemented in a standard programming language for the respective operating system - Objective-C or Swift for iOS, and Java or Kotlin for Android. -Native apps inherently have the capability to provide the fastest performance with the highest degree of reliability. They usually adhere to platform-specific design principles (e.g. the [Android Design Principles](https://developer.android.com/design "Android Design Principles")), which tends to result in a more consistent user interface (UI) compared to *hybrid* or *web* apps. Due to their close integration with the operating system, native apps can directly access almost every component of the device (camera, sensors, hardware-backed key stores, etc.). +Native apps inherently have the capability to provide the fastest performance with the highest degree of reliability. They usually adhere to platform-specific design principles (e.g. the [Android Design Principles](https://developer.android.com/design "Android Design Principles")), which tends to result in a more consistent user interface (UI) compared to _hybrid_ or _web_ apps. Due to their close integration with the operating system, native apps can directly access almost every component of the device (camera, sensors, hardware-backed key stores, etc.). -Some ambiguity exists when discussing *native apps* for Android as the platform provides two development kits - the Android SDK and the Android NDK. The SDK, which is based on the Java and Kotlin programming language, is the default for developing apps. The NDK (or Native Development Kit) is a C/C++ development kit used for developing binary libraries that can directly access lower level APIs (such as OpenGL). These libraries can be included in regular apps built with the SDK. Therefore, we say that Android *native apps* (i.e. built with the SDK) may have *native* code built with the NDK. +Some ambiguity exists when discussing _native apps_ for Android as the platform provides two development kits - the Android SDK and the Android NDK. The SDK, which is based on the Java and Kotlin programming language, is the default for developing apps. The NDK (or Native Development Kit) is a C/C++ development kit used for developing binary libraries that can directly access lower level APIs (such as OpenGL). These libraries can be included in regular apps built with the SDK. Therefore, we say that Android _native apps_ (i.e. built with the SDK) may have _native_ code built with the NDK. -The most obvious downside of *native apps* is that they target only one specific platform. To build the same app for both Android and iOS, one needs to maintain two independent code bases, or introduce often complex development tools to port a single code base to two platforms. The following frameworks are an example of the latter and allow you to compile a single codebase for both Android and iOS. +The most obvious downside of _native apps_ is that they target only one specific platform. To build the same app for both Android and iOS, one needs to maintain two independent code bases, or introduce often complex development tools to port a single code base to two platforms. The following frameworks are an example of the latter and allow you to compile a single codebase for both Android and iOS. - [Xamarin](https://dotnet.microsoft.com/apps/xamarin "Xamarin") - [Google Flutter](https://flutter.dev/ "Google Flutter") - [React Native](https://reactnative.dev/ "React Native") -Applications developed using these frameworks internally use the APIs native to the system and offer performance equivalent to native applications. Also, these apps can make use of all device capabilities, including the GPS, accelerometer, camera, the notification system, etc. Since the final output is very similar to previously discussed *native apps*, apps developed using these frameworks can also be considered as *native apps*. +Applications developed using these frameworks internally use the APIs native to the system and offer performance equivalent to native applications. Also, these apps can make use of all device capabilities, including the GPS, accelerometer, camera, the notification system, etc. Since the final output is very similar to previously discussed _native apps_, apps developed using these frameworks can also be considered as _native apps_. ## Web App -Mobile web apps (or simply, *web apps*) are websites designed to look and feel like a *native app*. These apps run on top of a device’s browser and are usually developed in HTML5, much like a modern web page. Launcher icons may be created to parallel the same feel of accessing a *native app*; however, these icons are essentially the same as a browser bookmark, simply opening the default web browser to load the referenced web page. +Mobile web apps (or simply, _web apps_) are websites designed to look and feel like a _native app_. These apps run on top of a device’s browser and are usually developed in HTML5, much like a modern web page. Launcher icons may be created to parallel the same feel of accessing a _native app_; however, these icons are essentially the same as a browser bookmark, simply opening the default web browser to load the referenced web page. Web apps have limited integration with the general components of the device as they run within the confines of a browser (i.e. they are "sandboxed") and usually lack in performance compared to native apps. Since a web app typically targets multiple platforms, their UIs do not follow some of the design principles of a specific platform. The biggest advantage is reduced development and maintenance costs associated with a single code base as well as enabling developers to distribute updates without engaging the platform-specific app stores. For example, a change to the HTML file for a web app can serve as viable, cross-platform update whereas an update to a store-based app requires considerably more effort. ## Hybrid App -Hybrid apps attempt to fill the gap between *native* and *web apps*. A *hybrid app* executes like a *native app*, but a majority of the processes rely on web technologies, meaning a portion of the app runs in an embedded web browser (commonly called "WebView"). As such, hybrid apps inherit both pros and cons of *native* and *web apps*. +Hybrid apps attempt to fill the gap between _native_ and _web apps_. A _hybrid app_ executes like a _native app_, but a majority of the processes rely on web technologies, meaning a portion of the app runs in an embedded web browser (commonly called "WebView"). As such, hybrid apps inherit both pros and cons of _native_ and _web apps_. -A web-to-native abstraction layer enables access to device capabilities for *hybrid apps* not accessible to a pure *web app*. Depending on the framework used for development, one code base can result in multiple applications that target different platforms, with a UI closely resembling that of the original platform for which the app was developed. +A web-to-native abstraction layer enables access to device capabilities for _hybrid apps_ not accessible to a pure _web app_. Depending on the framework used for development, one code base can result in multiple applications that target different platforms, with a UI closely resembling that of the original platform for which the app was developed. -Following is a non-exhaustive list of more popular frameworks for developing *hybrid apps*: +Following is a non-exhaustive list of more popular frameworks for developing _hybrid apps_: - [Apache Cordova](https://cordova.apache.org/ "Apache Cordova") - [Framework 7](https://framework7.io/ "Framework 7") @@ -56,4 +56,4 @@ PWAs are supported by Android and iOS, but not all hardware features are yet ava Throughout this guide, we will focus on apps for Android and iOS running on smartphones. These platforms are currently dominating the market and also run on other device classes including tablets, smartwatches, smart TVs, automotive infotainment units, and other embedded systems. Even if these additional device classes are out of scope, you can still apply most of the knowledge and testing techniques described in this guide with some deviance depending on the target device. -Given the vast amount of mobile app frameworks available it would be impossible to cover all of them exhaustively. Therefore, we focus on *native* apps on each operating system. However, the same techniques are also useful when dealing with web or hybrid apps (ultimately, no matter the framework, every app is based on native components). +Given the vast amount of mobile app frameworks available it would be impossible to cover all of them exhaustively. Therefore, we focus on _native_ apps on each operating system. However, the same techniques are also useful when dealing with web or hybrid apps (ultimately, no matter the framework, every app is based on native components). diff --git a/Document/0x04b-Mobile-App-Security-Testing.md b/Document/0x04b-Mobile-App-Security-Testing.md index e3263ff288..41b91b2662 100644 --- a/Document/0x04b-Mobile-App-Security-Testing.md +++ b/Document/0x04b-Mobile-App-Security-Testing.md @@ -27,7 +27,7 @@ Vulnerability analysis is usually the process of looking for vulnerabilities in ### Static versus Dynamic Analysis Static Application Security Testing (SAST) involves examining an application's components without executing them, by analyzing the source code either manually or automatically. -OWASP provides information about [Static Code Analysis](https://www.owasp.org/index.php/Static_Code_Analysis "OWASP Static Code Analysis") that may help you understand techniques, strengths, weaknesses, and limitations. +OWASP provides information about [Static Code Analysis](https://owasp.org/www-community/controls/Static_Code_Analysis "OWASP Static Code Analysis") that may help you understand techniques, strengths, weaknesses, and limitations. Dynamic Application Security Testing (DAST) involves examining the app during runtime. This type of analysis can be manual or automatic. It usually doesn't provide the information that static analysis provides, but it is a good way to detect interesting elements (assets, features, entry points, etc.) from a user's point of view. @@ -164,7 +164,7 @@ Environmental information includes: - The organization's goals for the app. Functionality shapes users' interaction with the app and may make some surfaces more likely than others to be targeted by attackers. - The relevant industry. Different industries may have different risk profiles. - Stakeholders and investors; understanding who is interested in and responsible for the app. -- Internal processes, workflows, and organizational structures. Organization-specific internal processes and workflows may create opportunities for [business logic exploits](https://www.owasp.org/index.php/Testing_for_business_logic "Testing business logic"). +- Internal processes, workflows, and organizational structures. Organization-specific internal processes and workflows may create opportunities for [business logic vulnerabilities](https://owasp.org/www-community/vulnerabilities/Business_logic_vulnerability "Business logic vulnerability"). ##### Architectural Information @@ -184,7 +184,7 @@ DAST tools may support black-box testing and automatically scan the app: whereas Threat Modeling is an important artifact: documents from the workshop usually greatly support the identification of much of the information a security tester needs (entry points, assets, vulnerabilities, severity, etc.). Testers are strongly advised to discuss the availability of such documents with the client. Threat modeling should be a key part of the software development life cycle. It usually occurs in the early phases of a project. -The [threat modeling guidelines defined in OWASP](https://www.owasp.org/index.php/Application_Threat_Modeling "OWASP Application Threat Modeling") are generally applicable to mobile apps. +The [threat modeling guidelines defined in OWASP](https://owasp.org/www-community/Threat_Modeling "OWASP Threat Modeling") are generally applicable to mobile apps. #### Exploitation diff --git a/Document/0x04c-Tampering-and-Reverse-Engineering.md b/Document/0x04c-Tampering-and-Reverse-Engineering.md index 95b430f408..a73ac20754 100644 --- a/Document/0x04c-Tampering-and-Reverse-Engineering.md +++ b/Document/0x04c-Tampering-and-Reverse-Engineering.md @@ -2,9 +2,9 @@ Reverse engineering and tampering techniques have long belonged to the realm of crackers, modders, malware analysts, etc. For "traditional" security testers and researchers, reverse engineering has been more of a complementary skill. But the tides are turning: mobile app black-box testing increasingly requires disassembling compiled apps, applying patches, and tampering with binary code or even live processes. The fact that many mobile apps implement defenses against unwelcome tampering doesn't make things easier for security testers. -Reverse engineering a mobile app is the process of analyzing the compiled app to extract information about its source code. The goal of reverse engineering is *comprehending* the code. +Reverse engineering a mobile app is the process of analyzing the compiled app to extract information about its source code. The goal of reverse engineering is _comprehending_ the code. -*Tampering* is the process of changing a mobile app (either the compiled app or the running process) or its environment to affect its behavior. For example, an app might refuse to run on your rooted test device, making it impossible to run some of your tests. In such cases, you'll want to alter the app's behavior. +_Tampering_ is the process of changing a mobile app (either the compiled app or the running process) or its environment to affect its behavior. For example, an app might refuse to run on your rooted test device, making it impossible to run some of your tests. In such cases, you'll want to alter the app's behavior. Mobile security testers are served well by understanding basic reverse engineering concepts. They should also know mobile devices and operating systems inside out: processor architecture, executable format, programming language intricacies, and so forth. @@ -20,7 +20,7 @@ Mobile security testing requires at least basic reverse engineering skills for s **2. To enhance static analysis in black-box security testing.** In a black-box test, static analysis of the app bytecode or binary code helps you understand the internal logic of the app. It also allows you to identify flaws such as hardcoded credentials. -**3. To assess resilience against reverse engineering.** Apps that implement the software protection measures listed in the Mobile Application Security Verification Standard Anti-Reversing Controls (MASVS-R) should withstand reverse engineering to a certain degree. To verify the effectiveness of such controls, the tester may perform a *resilience assessment* as part of the general security test. For the resilience assessment, the tester assumes the role of the reverse engineer and attempts to bypass defenses. +**3. To assess resilience against reverse engineering.** Apps that implement the software protection measures listed in the Mobile Application Security Verification Standard Anti-Reversing Controls (MASVS-R) should withstand reverse engineering to a certain degree. To verify the effectiveness of such controls, the tester may perform a _resilience assessment_ as part of the general security test. For the resilience assessment, the tester assumes the role of the reverse engineer and attempts to bypass defenses. Before we dive into the world of mobile app reversing, we have some good news and some bad news. Let's start with the good news: @@ -38,7 +38,7 @@ In the following section. we'll give an overview of the techniques most commonly ### Binary Patching -*Patching* is the process of changing the compiled app, e.g., changing code in binary executables, modifying Java bytecode, or tampering with resources. This process is known as *modding* in the mobile game hacking scene. Patches can be applied in many ways, including editing binary files in a hex editor and decompiling, editing, and re-assembling an app. We'll give detailed examples of useful patches in later chapters. +_Patching_ is the process of changing the compiled app, e.g., changing code in binary executables, modifying Java bytecode, or tampering with resources. This process is known as _modding_ in the mobile game hacking scene. Patches can be applied in many ways, including editing binary files in a hex editor and decompiling, editing, and re-assembling an app. We'll give detailed examples of useful patches in later chapters. Keep in mind that modern mobile operating systems strictly enforce code signing, so running modified apps is not as straightforward as it used to be in desktop environments. Security experts had a much easier life in the 90s! Fortunately, patching is not very difficult if you work on your own device. You simply have to re-sign the app or disable the default code signature verification facilities to run modified code. @@ -77,7 +77,7 @@ Over the past decades many tools have perfected the process of disassembly and d In the traditional sense, debugging is the process of identifying and isolating problems in a program as part of the software development life cycle. The same tools used for debugging are valuable to reverse engineers even when identifying bugs is not the primary goal. Debuggers enable program suspension at any point during runtime, inspection of the process' internal state, and even register and memory modification. These abilities simplify program inspection. -*Debugging* usually means interactive debugging sessions in which a debugger is attached to the running process. In contrast, *tracing* refers to passive logging of information about the app's execution (such as API calls). Tracing can be done in several ways, including debugging APIs, function hooks, and Kernel tracing facilities. Again, we'll cover many of these techniques in the OS-specific "Reverse Engineering and Tampering" chapters. +_Debugging_ usually means interactive debugging sessions in which a debugger is attached to the running process. In contrast, _tracing_ refers to passive logging of information about the app's execution (such as API calls). Tracing can be done in several ways, including debugging APIs, function hooks, and Kernel tracing facilities. Again, we'll cover many of these techniques in the OS-specific "Reverse Engineering and Tampering" chapters. ## Advanced Techniques @@ -124,20 +124,20 @@ Internally SMT solvers use various equation solving techniques to generate solut In a real world situation, the functions are much more complex than the above example. The increased complexity of the functions can pose significant challenges for classical symbolic execution. Some of the challenges are summarised below: -- Loops and recursions in a program may lead to *infinite execution tree*. -- Multiple conditional branches or nested conditions may lead to *path explosion*. +- Loops and recursions in a program may lead to _infinite execution tree_. +- Multiple conditional branches or nested conditions may lead to _path explosion_. - Complex equations generated by symbolic execution may not be solvable by SMT solvers because of their limitations. - Program is using system calls, library calls or network events which cannot be handled by symbolic execution. -To overcome these challenges, typically, symbolic execution is combined with other techniques such as _dynamic execution_ (also called _concrete execution_) to mitigate the path explosion problem specific to classical symbolic execution. This combination of concrete (actual) and symbolic execution is referred to as _concolic execution_ (the name concolic stems from **conc**rete and symb**olic**), sometimes also called as *dynamic symbolic execution*. +To overcome these challenges, typically, symbolic execution is combined with other techniques such as _dynamic execution_ (also called _concrete execution_) to mitigate the path explosion problem specific to classical symbolic execution. This combination of concrete (actual) and symbolic execution is referred to as _concolic execution_ (the name concolic stems from **conc**rete and symb**olic**), sometimes also called as _dynamic symbolic execution_. To visualize this, in the above example, we can obtain the value of the external variable by performing further reverse engineering or by dynamically executing the program and feeding this information into our symbolic execution analysis. This extra information will reduce the complexity of our equations and may produce more accurate analysis results. Together with improved SMT solvers and current hardware speeds, concolic execution allows to explore paths in medium-size software modules (i.e., on the order of 10 KLOC). -In addition, symbolic execution also comes in handy for supporting de-obfuscation tasks, such as simplifying control flow graphs. For example, Jonathan Salwan and Romain Thomas have [shown how to reverse engineer VM-based software protections using Dynamic Symbolic Execution](https://triton.quarkslab.com/files/csaw2016-sos-rthomas-jsalwan.pdf "Jonathan Salwan and Romain Thomas: How Triton can help to reverse virtual machine based software protections") [#salwan] (i.e., using a mix of actual execution traces, simulation, and symbolic execution). +In addition, symbolic execution also comes in handy for supporting de-obfuscation tasks, such as simplifying control flow graphs. For example, Jonathan Salwan and Romain Thomas have [shown how to reverse engineer VM-based software protections using Dynamic Symbolic Execution](https://drive.google.com/file/d/1EzuddBA61jEMy8XbjQKFF3jyoKwW7tLq/view?usp=sharing "Jonathan Salwan and Romain Thomas: How Triton can help to reverse virtual machine based software protections") [#salwan] (i.e., using a mix of actual execution traces, simulation, and symbolic execution). In the Android section, you'll find a walkthrough for cracking a simple license check in an Android application using symbolic execution. ## References - [#vadla] Ole André Vadla Ravnås, Anatomy of a code tracer - -- [#salwan] Jonathan Salwan and Romain Thomas, How Triton can help to reverse virtual machine based software protections - +- [#salwan] Jonathan Salwan and Romain Thomas, How Triton can help to reverse virtual machine based software protections - diff --git a/Document/0x04e-Testing-Authentication-and-Session-Management.md b/Document/0x04e-Testing-Authentication-and-Session-Management.md index 693645ce07..291fd77caa 100644 --- a/Document/0x04e-Testing-Authentication-and-Session-Management.md +++ b/Document/0x04e-Testing-Authentication-and-Session-Management.md @@ -1,6 +1,6 @@ # Mobile App Authentication Architectures -Authentication and authorization problems are prevalent security vulnerabilities. In fact, they consistently rank second highest in the [OWASP Top 10](https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project). +Authentication and authorization problems are prevalent security vulnerabilities. In fact, they consistently rank second highest in the [OWASP Top 10](https://owasp.org/www-project-top-ten/). Most mobile apps implement some kind of user authentication. Even though part of the authentication and state management logic is performed by the backend service, authentication is such an integral part of most mobile app architectures that understanding its common implementations is important. @@ -39,9 +39,9 @@ You can find details on how to test for the requirements above in the following You'll usually find that the mobile app uses HTTP as the transport layer. The HTTP protocol itself is stateless, so there must be a way to associate a user's subsequent HTTP requests with that user. Otherwise, the user's log in credentials would have to be sent with every request. Also, both the server and client need to keep track of user data (e.g., the user's privileges or role). This can be done in two different ways: -- With *stateful* authentication, a unique session id is generated when the user logs in. In subsequent requests, this session ID serves as a reference to the user details stored on the server. The session ID is *opaque*; it doesn't contain any user data. +- With _stateful_ authentication, a unique session id is generated when the user logs in. In subsequent requests, this session ID serves as a reference to the user details stored on the server. The session ID is _opaque_; it doesn't contain any user data. -- With *stateless* authentication, all user-identifying information is stored in a client-side token. The token can be passed to any server or micro service, eliminating the need to maintain session state on the server. Stateless authentication is often factored out to an authorization server, which produces, signs, and optionally encrypts the token upon user login. +- With _stateless_ authentication, all user-identifying information is stored in a client-side token. The token can be passed to any server or micro service, eliminating the need to maintain session state on the server. Stateless authentication is often factored out to an authorization server, which produces, signs, and optionally encrypts the token upon user login. Web applications commonly use stateful authentication with a random session ID that is stored in a client-side cookie. Although mobile apps sometimes use stateful sessions in a similar fashion, stateless token-based approaches are becoming popular for a variety of reasons: @@ -72,7 +72,7 @@ Perform the following steps when testing authentication and authorization: Authentication bypass vulnerabilities exist when authentication state is not consistently enforced on the server and when the client can tamper with the state. While the backend service is processing requests from the mobile client, it must consistently enforce authorization checks: verifying that the user is logged in and authorized every time a resource is requested. -Consider the following example from the [OWASP Web Testing Guide](https://www.owasp.org/index.php/Testing_for_Bypassing_Authentication_Schema_%28OTG-AUTHN-004%29 "Testing for Bypassing Authentication Schema (OTG-AUTHN-004)"). In the example, a web resource is accessed through a URL, and the authentication state is passed through a GET parameter: +Consider the following example from the [OWASP Web Testing Guide](https://owasp.org/www-project-web-security-testing-guide/stable/4-Web_Application_Security_Testing/04-Authentication_Testing/04-Testing_for_Bypassing_Authentication_Schema "Testing for Bypassing Authentication Schema (WSTG-ATHN-04)"). In the example, a web resource is accessed through a URL, and the authentication state is passed through a GET parameter: ```html http://www.site.com/page.asp?authenticated=no @@ -86,7 +86,7 @@ Although this is a simplistic example that you probably won't find in the wild, isAdmin=True ``` -Security experts used to recommend using session-based authentication and maintaining session data on the server only. This prevents any form of client-side tampering with the session state. However, the whole point of using stateless authentication instead of session-based authentication is to *not* have session state on the server. Instead, state is stored in client-side tokens and transmitted with every request. In this case, seeing client-side parameters such as `isAdmin` is perfectly normal. +Security experts used to recommend using session-based authentication and maintaining session data on the server only. This prevents any form of client-side tampering with the session state. However, the whole point of using stateless authentication instead of session-based authentication is to _not_ have session state on the server. Instead, state is stored in client-side tokens and transmitted with every request. In this case, seeing client-side parameters such as `isAdmin` is perfectly normal. To prevent tampering cryptographic signatures are added to client-side tokens. Of course, things may go wrong, and popular implementations of stateless authentication have been vulnerable to attacks. For example, the signature verification of some JSON Web Token (JWT) implementations could be deactivated by [setting the signature type to "None"](https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/ "Critical vulnerabilities in JSON Web Token libraries"). We'll discuss this attack in more detail in the "Testing JSON Web Tokens" chapter. @@ -147,7 +147,7 @@ Observe the following best practices when implementing anti-brute-force controls - The controls must be implemented on the server because client-side controls are easily bypassed. - Unauthorized login attempts must be tallied with respect to the targeted account, not a particular session. -Additional brute force mitigation techniques are described on the OWASP page [Blocking Brute Force Attacks](https://www.owasp.org/index.php/Blocking_Brute_Force_Attacks "OWASP - Blocking Brute Force Attacks"). +Additional brute force mitigation techniques are described on the OWASP page [Blocking Brute Force Attacks](https://owasp.org/www-community/controls/Blocking_Brute_Force_Attacks "OWASP - Blocking Brute Force Attacks"). ### Dynamic Testing (MSTG-AUTH-6) @@ -349,13 +349,13 @@ eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikpva G4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ ``` -The *header* typically consists of two parts: the token type, which is JWT, and the hashing algorithm being used to compute the signature. In the example above, the header decodes as follows: +The _header_ typically consists of two parts: the token type, which is JWT, and the hashing algorithm being used to compute the signature. In the example above, the header decodes as follows: ```json {"alg":"HS256","typ":"JWT"} ``` -The second part of the token is the *payload*, which contains so-called claims. Claims are statements about an entity (typically, the user) and additional metadata. For example: +The second part of the token is the _payload_, which contains so-called claims. Claims are statements about an entity (typically, the user) and additional metadata. For example: ```json {"sub":"1234567890","name":"John Doe","admin":true} @@ -405,7 +405,7 @@ DecodedJWT decodedToken = verifier.verify(token); Once signed, a stateless authentication token is valid forever unless the signing key changes. A common way to limit token validity is to set an expiration date. Make sure that the tokens include an ["exp" expiration claim](https://tools.ietf.org/html/rfc7519#section-4.1.4 "RFC 7519") and the backend doesn't process expired tokens. -A common method of granting tokens combines [access tokens and refresh tokens](https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/ "Refresh tokens & access tokens"). When the user logs in, the backend service issues a short-lived *access token* and a long-lived *refresh token*. The application can then use the refresh token to obtain a new access token, if the access token expires. +A common method of granting tokens combines [access tokens and refresh tokens](https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/ "Refresh tokens & access tokens"). When the user logs in, the backend service issues a short-lived _access token_ and a long-lived _refresh token_. The application can then use the refresh token to obtain a new access token, if the access token expires. For apps that handle sensitive data, make sure that the refresh token expires after a reasonable period of time. The following example code shows a refresh token API that checks the refresh token's issue date. If the token is not older than 14 days, a new access token is issued. Otherwise, access is denied and the user is prompted to login again. @@ -459,7 +459,7 @@ Common uses for OAuth2 include: - Authenticating to an online service on behalf of the user. - Handling authentication errors. -According to OAuth 2.0, a mobile client seeking access to a user's resources must first ask the user to authenticate against an *authentication server*. With the users' approval, the authorization server then issues a token that allows the app to act on behalf of the user. Note that the OAuth2 specification doesn't define any particular kind of authentication or access token format. +According to OAuth 2.0, a mobile client seeking access to a user's resources must first ask the user to authenticate against an _authentication server_. With the users' approval, the authorization server then issues a token that allows the app to act on behalf of the user. Note that the OAuth2 specification doesn't define any particular kind of authentication or access token format. OAuth 2.0 defines four roles: @@ -516,7 +516,7 @@ Tokens: OAuth2 authentication can be performed either through an external user agent (e.g. Chrome or Safari) or in the app itself (e.g. through a WebView embedded into the app or an authentication library). None of the two modes is intrinsically "better" - instead, what mode to choose depends on the context. -Using an *external user agent* is the method of choice for apps that need to interact with social media accounts (Facebook, Twitter, etc.). Advantages of this method include: +Using an _external user agent_ is the method of choice for apps that need to interact with social media accounts (Facebook, Twitter, etc.). Advantages of this method include: - The user's credentials are never directly exposed to the app. This guarantees that the app cannot obtain the credentials during the login process ("credential phishing"). @@ -524,7 +524,7 @@ Using an *external user agent* is the method of choice for apps that need to int On the negative side, there is no way to control the behavior of the browser (e.g. to activate certificate pinning). -For apps that operate within a closed ecosystem, *embedded authentication* is the better choice. For example, consider a banking app that uses OAuth2 to retrieve an access token from the bank's authentication server, which is then used to access a number of micro services. In that case, credential phishing is not a viable scenario. It is likely preferable to keep the authentication process in the (hopefully) carefully secured banking app, instead of placing trust on external components. +For apps that operate within a closed ecosystem, _embedded authentication_ is the better choice. For example, consider a banking app that uses OAuth2 to retrieve an access token from the bank's authentication server, which is then used to access a number of micro services. In that case, credential phishing is not a viable scenario. It is likely preferable to keep the authentication process in the (hopefully) carefully secured banking app, instead of placing trust on external components. ### Other OAuth2 Best Practices diff --git a/Document/0x04f-Testing-Network-Communication.md b/Document/0x04f-Testing-Network-Communication.md index cb61f8ecc6..d92b4f226b 100644 --- a/Document/0x04f-Testing-Network-Communication.md +++ b/Document/0x04f-Testing-Network-Communication.md @@ -4,7 +4,7 @@ Practically every network-connected mobile app uses the Hypertext Transfer Proto ## Intercepting HTTP(S) Traffic -In many cases, it is most practical to configure a system proxy on the mobile device, so that HTTP(S) traffic is redirected through an *interception proxy* running on your host computer. By monitoring the requests between the mobile app client and the backend, you can easily map the available server-side APIs and gain insight into the communication protocol. Additionally, you can replay and manipulate requests to test for server-side vulnerabilities. +In many cases, it is most practical to configure a system proxy on the mobile device, so that HTTP(S) traffic is redirected through an _interception proxy_ running on your host computer. By monitoring the requests between the mobile app client and the backend, you can easily map the available server-side APIs and gain insight into the communication protocol. Additionally, you can replay and manipulate requests to test for server-side vulnerabilities. Several free and commercial proxy tools are available. Here are some of the most popular: @@ -87,7 +87,7 @@ Following scenarios are possible: The scenario with an external USB WiFi card require that the card has the capability to create an access point. Additionally, you need to install some tools and/or configure the network to enforce a man-in-the-middle position (see below). You can verify if your WiFi card has AP capabilities by using the command `iwconfig` on Kali Linux: ```bash -$ iw list | grep AP +iw list | grep AP ``` The scenario with a separate access point requires access to the configuration of the AP and you should check first if the AP supports either: @@ -120,8 +120,8 @@ For all major Linux and Unix operating systems you need tools such as: For Kali Linux you can install these tools with `apt-get`: ```bash -$ apt-get update -$ apt-get install hostapd dnsmasq aircrack-ng +apt-get update +apt-get install hostapd dnsmasq aircrack-ng ``` > iptables and wpa_supplicant are installed by default on Kali Linux. @@ -248,7 +248,7 @@ When testing a Xamarin app and when you are trying to set the system proxy in th - For Linux systems you can use `iptables`: ```bash - $ sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to-destination 127.0.0.1:8080 + sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to-destination 127.0.0.1:8080 ``` - As last step, you need to set the option 'Support invisible proxy' in the listener settings of Burp Suite. diff --git a/Document/0x04g-Testing-Cryptography.md b/Document/0x04g-Testing-Cryptography.md index ce14db2c0b..0b40bf9943 100644 --- a/Document/0x04g-Testing-Cryptography.md +++ b/Document/0x04g-Testing-Cryptography.md @@ -46,7 +46,7 @@ Please make sure that: - Cryptographic algorithms are up to date and in-line with industry standards. This includes, but is not limited to outdated block ciphers (e.g. DES), stream ciphers (e.g. RC4), as well as hash functions (e.g. MD5) and broken random number generators like Dual_EC_DRBG (even if they are NIST certified). All of these should be marked as insecure and should not be used and removed from the application and server. - Key lengths are in-line with industry standards and provide protection for sufficient amount of time. A comparison of different key lengths and protection they provide taking into account Moore's law is available [online](https://www.keylength.com/ "Keylength comparison"). -- Cryptographic means are not mixed with each other: e.g. you do not sign with a public key, or try to reuse a keypair used for a signature to do encryption. +- Cryptographic means are not mixed with each other: e.g. you do not sign with a public key, or try to reuse a key pair used for a signature to do encryption. - Cryptographic parameters are well defined within reasonable range. This includes, but is not limited to: cryptographic salt, which should be at least the same length as hash function output, reasonable choice of password derivation function and iteration count (e.g. PBKDF2, scrypt or bcrypt), IVs being random and unique, fit-for-purpose block encryption modes (e.g. ECB should not be used, except specific cases), key management being done properly (e.g. 3DES should have three independent keys) and so on. The following algorithms are recommended: @@ -104,7 +104,7 @@ Ensure that passwords aren't directly passed into an encryption function. Instea ### Weak Random Number Generators -It is fundamentally impossible to produce truly random numbers on any deterministic device. Pseudo-random number generators (RNG) compensate for this by producing a stream of pseudo-random numbers - a stream of numbers that *appear* as if they were randomly generated. The quality of the generated numbers varies with the type of algorithm used. *Cryptographically secure* RNGs generate random numbers that pass statistical randomness tests, and are resilient against prediction attacks (e.g. it is statistically infeasible to predict the next number produced). +It is fundamentally impossible to produce truly random numbers on any deterministic device. Pseudo-random number generators (RNG) compensate for this by producing a stream of pseudo-random numbers - a stream of numbers that appear as if they were randomly generated. The quality of the generated numbers varies with the type of algorithm used. Cryptographically secure RNGs generate random numbers that pass statistical randomness tests, and are resilient against prediction attacks (e.g. it is statistically infeasible to predict the next number produced). Mobile SDKs offer standard implementations of RNG algorithms that produce numbers with sufficient artificial randomness. We'll introduce the available APIs in the Android and iOS specific sections. @@ -169,7 +169,7 @@ Note: given the ease of memory dumping, never share the same key among accounts ### Protecting Keys in Transport -When keys need to be transported from one device to another, or from the app to a backend, make sure that proper key protection is in place, by means of an transport keypair or another mechanism. Often, keys are shared with obfuscation methods which can be easily reversed. Instead, make sure asymmetric cryptography or wrapping keys are used. +When keys need to be transported from one device to another, or from the app to a backend, make sure that proper key protection is in place, by means of an transport key pair or another mechanism. Often, keys are shared with obfuscation methods which can be easily reversed. Instead, make sure asymmetric cryptography or wrapping keys are used. ## Cryptographic APIs on Android and iOS diff --git a/Document/0x04h-Testing-Code-Quality.md b/Document/0x04h-Testing-Code-Quality.md index eedf814581..fbbee0e028 100644 --- a/Document/0x04h-Testing-Code-Quality.md +++ b/Document/0x04h-Testing-Code-Quality.md @@ -6,7 +6,7 @@ The same programming flaws may affect both Android and iOS apps to some degree, ## Injection Flaws (MSTG-ARCH-2 and MSTG-PLATFORM-2) -An *injection flaw* describes a class of security vulnerability occurring when user input is inserted into backend queries or commands. By injecting meta-characters, an attacker can execute malicious code that is inadvertently interpreted as part of the command or query. For example, by manipulating a SQL query, an attacker could retrieve arbitrary database records or manipulate the content of the backend database. +An _injection flaw_ describes a class of security vulnerability occurring when user input is inserted into backend queries or commands. By injecting meta-characters, an attacker can execute malicious code that is inadvertently interpreted as part of the command or query. For example, by manipulating a SQL query, an attacker could retrieve arbitrary database records or manipulate the content of the backend database. Vulnerabilities of this class are most prevalent in server-side web services. Exploitable instances also exist within mobile apps, but occurrences are less common, plus the attack surface is smaller. @@ -14,7 +14,7 @@ For example, while an app might query a local SQLite database, such databases us ### SQL Injection -A *SQL injection* attack involves integrating SQL commands into input data, mimicking the syntax of a predefined SQL command. A successful SQL injection attack allows the attacker to read or write to the database and possibly execute administrative commands, depending on the permissions granted by the server. +A _SQL injection_ attack involves integrating SQL commands into input data, mimicking the syntax of a predefined SQL command. A successful SQL injection attack allows the attacker to read or write to the database and possibly execute administrative commands, depending on the permissions granted by the server. Apps on both Android and iOS use SQLite databases as a means to control and organize local data storage. Assume an Android app handles local user authentication by storing the user credentials in a local database (a poor programming practice we’ll overlook for the sake of this example). Upon login, the app queries the database to search for a record with the username and password entered by the user: @@ -49,9 +49,9 @@ Another real-world instance of client-side SQL injection was discovered by Mark ### XML Injection -In a *XML injection* attack, the attacker injects XML meta-characters to structurally alter XML content. This can be used to either compromise the logic of an XML-based application or service, as well as possibly allow an attacker to exploit the operation of the XML parser processing the content. +In a _XML injection_ attack, the attacker injects XML meta-characters to structurally alter XML content. This can be used to either compromise the logic of an XML-based application or service, as well as possibly allow an attacker to exploit the operation of the XML parser processing the content. -A popular variant of this attack is [XML eXternal Entity (XXE)](https://www.owasp.org/index.php/XML_External_Entity_%28XXE%29_Processing "XML eXternal Entity attack (XXE)"). Here, an attacker injects an external entity definition containing an URI into the input XML. During parsing, the XML parser expands the attacker-defined entity by accessing the resource specified by the URI. The integrity of the parsing application ultimately determines capabilities afforded to the attacker, where the malicious user could do any (or all) of the following: access local files, trigger HTTP requests to arbitrary hosts and ports, launch a [cross-site request forgery (CSRF)](https://owasp.org/www-community/attacks/csrf "Cross-Site Request Forgery (CSRF)") attack, and cause a denial-of-service condition. The OWASP web testing guide contains the [following example for XXE](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/07-Input_Validation_Testing/07-Testing_for_XML_Injection "Testing for XML Injection"): +A popular variant of this attack is [XML eXternal Entity (XXE)](https://owasp.org/www-community/vulnerabilities/XML_External_Entity_%28XXE%29_Processing "XML eXternal Entity attack (XXE)"). Here, an attacker injects an external entity definition containing an URI into the input XML. During parsing, the XML parser expands the attacker-defined entity by accessing the resource specified by the URI. The integrity of the parsing application ultimately determines capabilities afforded to the attacker, where the malicious user could do any (or all) of the following: access local files, trigger HTTP requests to arbitrary hosts and ports, launch a [cross-site request forgery (CSRF)](https://owasp.org/www-community/attacks/csrf "Cross-Site Request Forgery (CSRF)") attack, and cause a denial-of-service condition. The OWASP web testing guide contains the [following example for XXE](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/07-Input_Validation_Testing/07-Testing_for_XML_Injection "Testing for XML Injection"): ```xml @@ -95,7 +95,7 @@ We will cover details related to input sources and potentially vulnerable APIs f Cross-site scripting (XSS) issues allow attackers to inject client-side scripts into web pages viewed by users. This type of vulnerability is prevalent in web applications. When a user views the injected script in a browser, the attacker gains the ability to bypass the same origin policy, enabling a wide variety of exploits (e.g. stealing session cookies, logging key presses, performing arbitrary actions, etc.). -In the context of *native apps*, XSS risks are far less prevalent for the simple reason these kinds of applications do not rely on a web browser. However, apps using WebView components, such as `WKWebView` or the deprecated `UIWebView` on iOS and `WebView` on Android, are potentially vulnerable to such attacks. +In the context of _native apps_, XSS risks are far less prevalent for the simple reason these kinds of applications do not rely on a web browser. However, apps using WebView components, such as `WKWebView` or the deprecated `UIWebView` on iOS and `WebView` on Android, are potentially vulnerable to such attacks. An older but well-known example is the [local XSS issue in the Skype app for iOS, first identified by Phil Purviance](https://superevr.com/blog/2011/xss-in-skype-for-ios "XSS in Skype for iOS"). The Skype app failed to properly encode the name of the message sender, allowing an attacker to inject malicious JavaScript to be executed when a user views the message. In his proof-of-concept, Phil showed how to exploit the issue and steal a user's address book. @@ -212,15 +212,15 @@ Memory corruption bugs are a popular mainstay with hackers. This class of bug re - **Out-of-bounds-access**: Buggy pointer arithmetic may cause a pointer or index to reference a position beyond the bounds of the intended memory structure (e.g. buffer or list). When an app attempts to write to an out-of-bounds address, a crash or unintended behavior occurs. If the attacker can control the target offset and manipulate the content written to some extent, [code execution exploit is likely possible](https://www.zerodayinitiative.com/advisories/ZDI-17-110/ "Adobe Flash Mediaplayer example"). -- **Dangling pointers**: These occur when an object with an incoming reference to a memory location is deleted or deallocated, but the object pointer is not reset. If the program later uses the *dangling* pointer to call a virtual function of the already deallocated object, it is possible to hijack execution by overwriting the original vtable pointer. Alternatively, it is possible to read or write object variables or other memory structures referenced by a dangling pointer. +- **Dangling pointers**: These occur when an object with an incoming reference to a memory location is deleted or deallocated, but the object pointer is not reset. If the program later uses the _dangling_ pointer to call a virtual function of the already deallocated object, it is possible to hijack execution by overwriting the original vtable pointer. Alternatively, it is possible to read or write object variables or other memory structures referenced by a dangling pointer. - **Use-after-free**: This refers to a special case of dangling pointers referencing released (deallocated) memory. After a memory address is cleared, all pointers referencing the location become invalid, causing the memory manager to return the address to a pool of available memory. When this memory location is eventually re-allocated, accessing the original pointer will read or write the data contained in the newly allocated memory. This usually leads to data corruption and undefined behavior, but crafty attackers can set up the appropriate memory locations to leverage control of the instruction pointer. -- **Integer overflows**: When the result of an arithmetic operation exceeds the maximum value for the integer type defined by the programmer, this results in the value "wrapping around" the maximum integer value, inevitably resulting in a small value being stored. Conversely, when the result of an arithmetic operation is smaller than the minimum value of the integer type, an *integer underflow* occurs where the result is larger than expected. Whether a particular integer overflow/underflow bug is exploitable depends on how the integer is used. For example, if the integer type were to represent the length of a buffer, this could create a buffer overflow vulnerability. +- **Integer overflows**: When the result of an arithmetic operation exceeds the maximum value for the integer type defined by the programmer, this results in the value "wrapping around" the maximum integer value, inevitably resulting in a small value being stored. Conversely, when the result of an arithmetic operation is smaller than the minimum value of the integer type, an _integer underflow_ occurs where the result is larger than expected. Whether a particular integer overflow/underflow bug is exploitable depends on how the integer is used. For example, if the integer type were to represent the length of a buffer, this could create a buffer overflow vulnerability. - **Format string vulnerabilities**: When unchecked user input is passed to the format string parameter of the `printf` family of C functions, attackers may inject format tokens such as ‘%c’ and ‘%n’ to access memory. Format string bugs are convenient to exploit due to their flexibility. Should a program output the result of the string formatting operation, the attacker can read and write to memory arbitrarily, thus bypassing protection features such as ASLR. -The primary goal in exploiting memory corruption is usually to redirect program flow into a location where the attacker has placed assembled machine instructions referred to as *shellcode*. On iOS, the data execution prevention feature (as the name implies) prevents execution from memory defined as data segments. To bypass this protection, attackers leverage return-oriented programming (ROP). This process involves chaining together small, pre-existing code chunks ("gadgets") in the text segment where these gadgets may execute a function useful to the attacker or, call `mprotect` to change memory protection settings for the location where the attacker stored the *shellcode*. +The primary goal in exploiting memory corruption is usually to redirect program flow into a location where the attacker has placed assembled machine instructions referred to as _shellcode_. On iOS, the data execution prevention feature (as the name implies) prevents execution from memory defined as data segments. To bypass this protection, attackers leverage return-oriented programming (ROP). This process involves chaining together small, pre-existing code chunks ("gadgets") in the text segment where these gadgets may execute a function useful to the attacker or, call `mprotect` to change memory protection settings for the location where the attacker stored the _shellcode_. Android apps are, for the most part, implemented in Java which is inherently safe from memory corruption issues by design. However, native apps utilizing JNI libraries are susceptible to this kind of bug. Similarly, iOS apps can wrap C/C++ calls in Obj-C or Swift, making them susceptible to these kind of attacks. @@ -269,7 +269,7 @@ Memory corruption bugs are best discovered via input fuzzing: an automated black Fuzz testing techniques or scripts (often called "fuzzers") will typically generate multiple instances of structured input in a semi-correct fashion. Essentially, the values or arguments generated are at least partially accepted by the target application, yet also contain invalid elements, potentially triggering input processing flaws and unexpected program behaviors. A good fuzzer exposes a substantial amount of possible program execution paths (i.e. high coverage output). Inputs are either generated from scratch ("generation-based") or derived from mutating known, valid input data ("mutation-based"). -For more information on fuzzing, refer to the [OWASP Fuzzing Guide](https://www.owasp.org/index.php/Fuzzing "OWASP Fuzzing Guide"). +For more information on fuzzing, refer to the [OWASP Fuzzing Guide](https://owasp.org/www-community/Fuzzing "OWASP Fuzzing Guide"). ## References diff --git a/Document/0x04i-Testing-User-Privacy-Protection.md b/Document/0x04i-Testing-User-Privacy-Protection.md index a368cbe536..2d0ed9fb48 100644 --- a/Document/0x04i-Testing-User-Privacy-Protection.md +++ b/Document/0x04i-Testing-User-Privacy-Protection.md @@ -21,7 +21,7 @@ There are two main dimensions to consider here: - **Principle of Least Privilege** ("Every program and every user of the system should operate using the least set of privileges necessary to complete the job.") - **User Education**: Users need to be educated about their sensitive data and informed about how to use the application properly (to ensure secure handling and processing of their information). -> Note: More often than not apps will claim to handle certain data, but in reality that's not the case. The IEEE article ["Engineering Privacy in Smartphone Apps: A Technical Guideline Catalog for App Developers" by Majid Hatamian](https://www.researchgate.net/publication/339349349_Engineering_Privacy_in_Smartphone_Apps_A_Technical_Guideline_Catalog_for_App_Developers) gives a very nice introduction to this topic. +> Note: More often than not apps will claim to handle certain data, but in reality that's not the case. The IEEE article ["Engineering Privacy in Smartphone Apps: A Technical Guideline Catalog for App Developers" by Majid Hatamian](https://drive.google.com/file/d/1cp7zrqJuVkftJ0DARNN40Ga_m_tEhIrQ/view?usp=sharing) gives a very nice introduction to this topic. ### Protection Goals for Data Protection diff --git a/Document/0x05a-Platform-Overview.md b/Document/0x05a-Platform-Overview.md index e4c071e9e9..bab56b9c37 100644 --- a/Document/0x05a-Platform-Overview.md +++ b/Document/0x05a-Platform-Overview.md @@ -26,7 +26,7 @@ Android apps are usually written in Java and compiled to Dalvik bytecode, which The current version of Android executes this bytecode on the Android runtime (ART). ART is the successor to Android's original runtime, the Dalvik Virtual Machine (DVM). The key difference between Dalvik and ART is the way the bytecode is executed. -In the DVM, bytecode is translated into machine code at execution time, a process known as *just-in-time* (JIT) compilation. This enables the runtime to benefit from the speed of compiled code while maintaining the flexibility of code interpretation. To further improve performance, Android introduced the [Android Runtime (ART)](https://source.android.com/devices/tech/dalvik/configure#how_art_works) to replace the DVM. ART uses a hybrid combination of *ahead-of-time* (AOT), JIT and profile-guided compilation. Apps are recompiled on the device when they are installed, or when the OS undergoes a major update. While the code is being recompiled, device-specific and advanced code optimizations techniques can be applied. The final recompiled code is then used for all subsequent executions. AOT improves performance by a factor of two while reducing power consumption, due to the device-specific optimizations. +In the DVM, bytecode is translated into machine code at execution time, a process known as _just-in-time_ (JIT) compilation. This enables the runtime to benefit from the speed of compiled code while maintaining the flexibility of code interpretation. To further improve performance, Android introduced the [Android Runtime (ART)](https://source.android.com/devices/tech/dalvik/configure#how_art_works) to replace the DVM. ART uses a hybrid combination of _ahead-of-time_ (AOT), JIT and profile-guided compilation. Apps are recompiled on the device when they are installed, or when the OS undergoes a major update. While the code is being recompiled, device-specific and advanced code optimizations techniques can be applied. The final recompiled code is then used for all subsequent executions. AOT improves performance by a factor of two while reducing power consumption, due to the device-specific optimizations. Android apps don't have direct access to hardware resources, and each app runs in its own virtual machine or sandbox. This enables the OS to have precise control over resources and memory access on the device. For instance, a crashing app doesn't affect other apps running on the same device. Android controls the maximum number of system resources allocated to apps, preventing any one app from monopolizing too many resources. At the same time, this sandbox design can be considered as one of the many principles in Android's global defense-in-depth strategy. A malicious third-party application, with low privileges, shouldn't be able to escape its own runtime and read the memory of a victim application on the same device. In the following section we take a closer look at the different defense layers in the Android operating system. @@ -238,7 +238,7 @@ Android applications can be shipped in two forms: the Android Package Kit (APK) If you have an Android App Bundle, you can best use the [bundletool](https://developer.android.com/studio/command-line/bundletool "bundletool") command line tool from Google to build unsigned APKs in order to use the existing tooling on the APK. You can create an APK from an AAB file by running the following command: ```bash -$ bundletool build-apks --bundle=/MyApp/my_app.aab --output=/MyApp/my_app.apks +bundletool build-apks --bundle=/MyApp/my_app.aab --output=/MyApp/my_app.apks ``` If you want to create signed APKs ready for deployment to a test device, use: @@ -399,7 +399,7 @@ Services are Android OS components (based on the Service class) that perform tas As we've already learned, every Android process has its own sandboxed address space. Inter-process communication facilities allow apps to exchange signals and data securely. Instead of relying on the default Linux IPC facilities, Android's IPC is based on Binder, a custom implementation of OpenBinder. Most Android system services and all high-level IPC services depend on Binder. -The term *Binder* stands for a lot of different things, including: +The term _Binder_ stands for a lot of different things, including: - Binder Driver: the kernel-level driver - Binder Protocol: low-level ioctl-based protocol used to communicate with the binder driver @@ -408,13 +408,13 @@ The term *Binder* stands for a lot of different things, including: - Binder service: implementation of the Binder object; for example, location service, and sensor service - Binder client: an object using the Binder service -The Binder framework includes a client-server communication model. To use IPC, apps call IPC methods in proxy objects. The proxy objects transparently *marshall* the call parameters into a *parcel* and send a transaction to the Binder server, which is implemented as a character driver (/dev/binder). The server holds a thread pool for handling incoming requests and delivers messages to the destination object. From the perspective of the client app, all of this seems like a regular method call, all the heavy lifting is done by the Binder framework. +The Binder framework includes a client-server communication model. To use IPC, apps call IPC methods in proxy objects. The proxy objects transparently _marshall_ the call parameters into a _parcel_ and send a transaction to the Binder server, which is implemented as a character driver (/dev/binder). The server holds a thread pool for handling incoming requests and delivers messages to the destination object. From the perspective of the client app, all of this seems like a regular method call, all the heavy lifting is done by the Binder framework. -*Binder Overview - Image source: [Android Binder by Thorsten Schreiber](https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.710.6498&rep=rep1&type=pdf "Android Binder")* +- _Binder Overview - Image source: [Android Binder by Thorsten Schreiber](https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.710.6498&rep=rep1&type=pdf "Android Binder")_ -Services that allow other applications to bind to them are called *bound services*. These services must provide an IBinder interface to clients. Developers use the Android Interface Descriptor Language (AIDL) to write interfaces for remote services. +Services that allow other applications to bind to them are called _bound services_. These services must provide an IBinder interface to clients. Developers use the Android Interface Descriptor Language (AIDL) to write interfaces for remote services. ServiceManager is a system daemon that manages the registration and lookup of system services. It maintains a list of name/Binder pairs for all registered services. Services are added with `addService` and retrieved by name with the static `getService` method in `android.os.ServiceManager`: @@ -466,7 +466,7 @@ Found 99 services: #### Intents -*Intent messaging* is an asynchronous communication framework built on top of Binder. This framework allows both point-to-point and publish-subscribe messaging. An *Intent* is a messaging object that can be used to request an action from another app component. Although intents facilitate inter-component communication in several ways, there are three fundamental use cases: +_Intent messaging_ is an asynchronous communication framework built on top of Binder. This framework allows both point-to-point and publish-subscribe messaging. An _Intent_ is a messaging object that can be used to request an action from another app component. Although intents facilitate inter-component communication in several ways, there are three fundamental use cases: - Starting an activity - An activity represents a single screen in an app. You can start a new instance of an activity by passing an intent to `startActivity`. The intent describes the activity and carries necessary data. @@ -503,7 +503,7 @@ Example in Kotlin: var intent = Intent(Intent.MY_ACTION, Uri.parse("https://www.owasp.org")) ``` -An *intent filter* is an expression in Android Manifest files that specifies the type of intents the component would like to receive. For instance, by declaring an intent filter for an activity, you make it possible for other apps to directly start your activity with a certain kind of intent. Likewise, your activity can only be started with an explicit intent if you don't declare any intent filters for it. +An _intent filter_ is an expression in Android Manifest files that specifies the type of intents the component would like to receive. For instance, by declaring an intent filter for an activity, you make it possible for other apps to directly start your activity with a certain kind of intent. Likewise, your activity can only be started with an explicit intent if you don't declare any intent filters for it. Android uses intents to broadcast messages to apps (such as an incoming call or SMS) important power supply information (low battery, for example), and network changes (loss of connection, for instance). Extra data may be added to intents (through `putExtra`/`getExtras`). @@ -640,7 +640,7 @@ App creators can either reuse an existing private/public key pair that is in an In the Android SDK, a new key pair is generated with the `keytool` command. The following command creates a RSA key pair with a key length of 2048 bits and an expiry time of 7300 days = 20 years. The generated key pair is stored in the file 'myKeyStore.jks', which is in the current directory): ```bash -$ keytool -genkey -alias myDomain -keyalg RSA -keysize 2048 -validity 7300 -keystore myKeyStore.jks -storepass myStrongPassword +keytool -genkey -alias myDomain -keyalg RSA -keysize 2048 -validity 7300 -keystore myKeyStore.jks -storepass myStrongPassword ``` Safely storing your secret key and making sure it remains secret during its entire life cycle is of paramount importance. Anyone who gains access to the key will be able to publish updates to your apps with content that you don't control (thereby adding insecure features or accessing shared content with signature-based permissions). The trust that a user places in an app and its developers is based totally on such certificates; certificate protection and secure management are therefore vital for reputation and customer retention, and secret keys must never be shared with other individuals. Keys are stored in a binary file that can be protected with a password; such files are referred to as _KeyStores_. KeyStore passwords should be strong and known only to the key creator. For this reason, keys are usually stored on a dedicated build machine that developers have limited access to. @@ -654,7 +654,7 @@ Many Integrated Development Environments (IDE) integrate the app signing process Apps can be signed from the command line with the 'apksigner' tool provided by the Android SDK (API level 24 and higher). It is located at `[SDK-Path]/build-tools/[version]`. For API 24.0.2 and below, you can use 'jarsigner', which is part of the Java JDK. Details about the whole process can be found in official Android documentation; however, an example is given below to illustrate the point. ```bash -$ apksigner sign --out mySignedApp.apk --ks myKeyStore.jks myUnsignedApp.apk +apksigner sign --out mySignedApp.apk --ks myKeyStore.jks myUnsignedApp.apk ``` In this example, an unsigned app ('myUnsignedApp.apk') will be signed with a private key from the developer KeyStore 'myKeyStore.jks' (located in the current directory). The app will become a signed app called 'mySignedApp.apk' and will be ready to release to stores. diff --git a/Document/0x05b-Basic-Security_Testing.md b/Document/0x05b-Basic-Security_Testing.md index 2252f3d3b8..7b59b6377c 100644 --- a/Document/0x05b-Basic-Security_Testing.md +++ b/Document/0x05b-Basic-Security_Testing.md @@ -66,7 +66,7 @@ AVD supports some hardware emulation, such as [GPS](https://developer.android.co You can either start an Android Virtual Device (AVD) by using the AVD Manager in Android Studio or start the AVD manager from the command line with the `android` command, which is found in the tools directory of the Android SDK: ```bash -$ ./android avd +./android avd ``` Several tools and VMs that can be used to test an app within an emulator environment are available: @@ -78,7 +78,7 @@ Please also verify the "[Testing Tools](0x08-Testing-Tools.md)" chapter at the e #### Getting Privileged Access -*Rooting* (i.e., modifying the OS so that you can run commands as the root user) is recommended for testing on a real device. This gives you full control over the operating system and allows you to bypass restrictions such as app sandboxing. These privileges in turn allow you to use techniques like code injection and function hooking more easily. +_Rooting_ (i.e., modifying the OS so that you can run commands as the root user) is recommended for testing on a real device. This gives you full control over the operating system and allows you to bypass restrictions such as app sandboxing. These privileges in turn allow you to use techniques like code injection and function hooking more easily. Note that rooting is risky, and three main consequences need to be clarified before you proceed. Rooting can have the following negative effects: @@ -123,7 +123,7 @@ In order to connect to the shell of an Android device from your host computer, [ For this section we assume that you've properly enabled Developer Mode and USB debugging as explained in "Testing on a Real Device". Once you've connected your Android device via USB, you can access the remote device's shell by running: ```bash -$ adb shell +adb shell ``` > press Control + D or type `exit` to quit @@ -179,7 +179,7 @@ While usually using an on-device shell (terminal emulator) such as [Termux](0x08 You can copy files to and from a device by using the [adb](0x08-Testing-Tools.md#adb) commands `adb pull ` and `adb push ` [commands](https://developer.android.com/studio/command-line/adb#copyfiles "Copy files to/from a device"). Their usage is very straightforward. For example, the following will copy `foo.txt` from your current directory (local) to the `sdcard` folder (remote): ```bash -$ adb push foo.txt /sdcard/foo.txt +adb push foo.txt /sdcard/foo.txt ``` This approach is commonly used when you know exactly what you want to copy and from/to where and also supports bulk file transfer, e.g. you can pull (copy) a whole directory from the Android device to your host computer. @@ -307,19 +307,19 @@ Obtaining app packages from the device is the recommended method as we can guara Use `adb pull` to retrieve the APK. If you don't know the package name, the first step is to list all the applications installed on the device: ```bash -$ adb shell pm list packages +adb shell pm list packages ``` Once you have located the package name of the application, you need the full path where it is stored on the system to download it. ```bash -$ adb shell pm path +adb shell pm path ``` With the full path to the APK, you can now simply use `adb pull` to extract it. ```bash -$ adb pull +adb pull ``` The APK will be downloaded in your working directory. @@ -354,7 +354,7 @@ There are multiple ways to start the dynamic analysis of your instant app. In al The installation of instant app support is taken care off through the following command: ```bash -$ cd path/to/android/sdk/tools/bin && ./sdkmanager 'extras;google;instantapps' +cd path/to/android/sdk/tools/bin && ./sdkmanager 'extras;google;instantapps' ``` Next, you have to add `path/to/android/sdk/extras/google/instantapps/ia` to your `$PATH`. @@ -365,7 +365,7 @@ After the preparation, you can test instant apps locally on a device running And Deploy the app via Android Studio (and enable the `Deploy as instant app` checkbox in the Run/Configuration dialog) or deploy the app using the following command: ```bash - $ ia run output-from-build-command + ia run output-from-build-command ``` - Test the app using the Play Console: @@ -614,13 +614,13 @@ On Android you can easily inspect the log of system messages by using [`Logcat`] - You can execute Logcat with adb to store the log output permanently: ```bash -$ adb logcat > logcat.log +adb logcat > logcat.log ``` With the following command you can specifically grep for the log output of the app in scope, just insert the package name. Of course your app needs to be running for `ps` to be able to get its PID. ```bash -$ adb logcat | grep "$(adb shell ps | grep | awk '{print $2}')" +adb logcat | grep "$(adb shell ps | grep | awk '{print $2}')" ``` ## Setting up a Network Testing Environment @@ -630,21 +630,21 @@ $ adb logcat | grep "$(adb shell ps | grep | awk '{print $2}')" [Remotely sniffing all Android traffic in real-time is possible](https://blog.dornea.nu/2015/02/20/android-remote-sniffing-using-tcpdump-nc-and-wireshark/ "Android remote sniffing using Tcpdump, nc and Wireshark") with [tcpdump](0x08-Testing-Tools.md#tcpdump), netcat (nc), and [Wireshark](0x08-Testing-Tools.md#wireshark). First, make sure that you have the latest version of [Android tcpdump](https://www.androidtcpdump.com/) on your phone. Here are the [installation steps](https://wladimir-tm4pda.github.io/porting/tcpdump.html "Installing tcpdump"): ```bash -$ adb root -$ adb remount -$ adb push /wherever/you/put/tcpdump /system/xbin/tcpdump +adb root +adb remount +adb push /wherever/you/put/tcpdump /system/xbin/tcpdump ``` If execution of `adb root` returns the error `adbd cannot run as root in production builds`, install tcpdump as follows: ```bash -$ adb push /wherever/you/put/tcpdump /data/local/tmp/tcpdump -$ adb shell -$ su -$ mount -o rw,remount /system; -$ cp /data/local/tmp/tcpdump /system/xbin/ -$ cd /system/xbin -$ chmod 755 tcpdump +adb push /wherever/you/put/tcpdump /data/local/tmp/tcpdump +adb shell +su +mount -o rw,remount /system; +cp /data/local/tmp/tcpdump /system/xbin/ +cd /system/xbin +chmod 755 tcpdump ``` In certain production builds, you might encounter an error `mount: '/system' not in /proc/mounts`. @@ -671,7 +671,7 @@ listening on wlan0, link-type EN10MB (Ethernet), capture size 262144 bytes To remotely sniff the Android phone's network traffic, first execute `tcpdump` and pipe its output to `netcat` (nc): ```bash -$ tcpdump -i wlan0 -s0 -w - | nc -l -p 11111 +tcpdump -i wlan0 -s0 -w - | nc -l -p 11111 ``` The tcpdump command above involves @@ -685,13 +685,13 @@ By using the pipe (`|`), we sent all output from tcpdump to netcat, which opens To access port 11111, you need to forward the port to your host computer via adb. ```bash -$ adb forward tcp:11111 tcp:11111 +adb forward tcp:11111 tcp:11111 ``` The following command connects you to the forwarded port via netcat and piping to Wireshark. ```bash -$ nc localhost 11111 | wireshark -k -S -i - +nc localhost 11111 | wireshark -k -S -i - ``` Wireshark should start immediately (-k). It gets all data from stdin (-i -) via netcat, which is connected to the forwarded port. You should see all the phone's traffic from the wlan0 interface. @@ -788,7 +788,7 @@ HTTP and HTTPS requests should now be routed over the proxy on the host computer A proxy for an AVD can also be configured on the command line by using the [emulator command](https://developer.android.com/studio/run/emulator-commandline "Emulator Command") when starting an AVD. The following example starts the AVD Nexus_5X_API_23 and setting a proxy to 127.0.0.1 and port 8080. ```bash -$ emulator @Nexus_5X_API_23 -http-proxy 127.0.0.1:8080 +emulator @Nexus_5X_API_23 -http-proxy 127.0.0.1:8080 ``` ##### Installing a CA Certificate on the Virtual Device @@ -800,7 +800,7 @@ An easy way to install a CA certificate is to push the certificate to the device 3. Push the file to the emulator: ```bash - $ adb push cacert.cer /sdcard/ + adb push cacert.cer /sdcard/ ``` 4. Navigate to **Settings** -> **Security** -> **Install from SD Card**. @@ -888,14 +888,14 @@ To implement this new setting you must follow the steps below: - Decompile the app using a decompilation tool like apktool: ```bash - $ apktool d .apk + apktool d .apk ``` - Make the application trust user certificates by creating a Network Security Configuration that includes `` as explained above - Go into the directory created by apktool when decompiling the app and rebuild the app using apktool. The new apk will be in the `dist` directory. ```bash - $ apktool b + apktool b ``` - You need to repackage the app, as explained in the "[Repackaging](0x05c-Reverse-Engineering-and-Tampering.md#repackaging "Repackaging")" section of the "Reverse Engineering and Tampering" chapter. For more details on the repackaging process you can also consult the [Android developer documentation](https://developer.android.com/studio/publish/app-signing#signing-manually), that explains the process as a whole. @@ -995,7 +995,7 @@ What to do if the Wi-Fi we need for testing has client isolation? You can configure the proxy on your Android device to point to 127.0.0.1:8080, connect your phone via USB to your host computer and use adb to make a reverse port forwarding: ```bash -$ adb reverse tcp:8080 tcp:8080 +adb reverse tcp:8080 tcp:8080 ``` Once you have done this all proxy traffic on your Android phone will be going to port 8080 on 127.0.0.1 and it will be redirected via adb to 127.0.0.1:8080 on your host computer and you will see now the traffic in your Burp. With this trick you are able to test and intercept traffic also in Wi-Fis that have client isolation. @@ -1018,7 +1018,7 @@ You could also use an access point that is under your control to redirect the tr You can use iptables on the Android device to redirect all traffic to your interception proxy. The following command would redirect port 80 to your proxy running on port 8080 ```bash -$ iptables -t nat -A OUTPUT -p tcp --dport 80 -j DNAT --to-destination :8080 +iptables -t nat -A OUTPUT -p tcp --dport 80 -j DNAT --to-destination :8080 ``` Verify the iptables settings and check the IP and port. @@ -1048,7 +1048,7 @@ target prot opt source destination In case you want to reset the iptables configuration you can flush the rules: ```bash -$ iptables -t nat -F +iptables -t nat -F ``` ##### bettercap diff --git a/Document/0x05c-Reverse-Engineering-and-Tampering.md b/Document/0x05c-Reverse-Engineering-and-Tampering.md index bbb8017873..d9f5c1ac54 100644 --- a/Document/0x05c-Reverse-Engineering-and-Tampering.md +++ b/Document/0x05c-Reverse-Engineering-and-Tampering.md @@ -84,7 +84,7 @@ It is worth highlighting that analyzing disassembled native code is much more ch In the next example we'll reverse the HelloWorld-JNI.apk from the OWASP MSTG repository. Installing and running it in an emulator or Android device is optional. ```bash -$ wget https://github.com/OWASP/owasp-mstg/raw/master/Samples/Android/01_HelloWorld-JNI/HelloWord-JNI.apk +wget https://github.com/OWASP/owasp-mstg/raw/master/Samples/Android/01_HelloWorld-JNI/HelloWord-JNI.apk ``` > This app is not exactly spectacular, all it does is show a label with the text "Hello from C++". This is the app Android generates by default when you create a new project with C/C++ support, which is just enough to show the basic principles of JNI calls. @@ -160,7 +160,7 @@ Most disassemblers can handle any of those architectures. Below, we'll be viewin ##### radare2 -To open the file in radare2 you only have to run `r2 -A HelloWord-JNI/lib/armeabi-v7a/libnative-lib.so`. The chapter "[Android Basic Security Testing](0x05b-Basic-Security_Testing.md "Android Basic Security Testing")" already introduced radare2. Remember that you can use the flag `-A` to run the `aaa` command right after loading the binary in order to analyze all referenced code. +To open the file in [radare2](0x08-Testing-Tools.md#radare2) you only have to run `r2 -A HelloWord-JNI/lib/armeabi-v7a/libnative-lib.so`. The chapter "[Android Basic Security Testing](0x05b-Basic-Security_Testing.md "Android Basic Security Testing")" already introduced radare2. Remember that you can use the flag `-A` to run the `aaa` command right after loading the binary in order to analyze all referenced code. ```bash $ r2 -A HelloWord-JNI/lib/armeabi-v7a/libnative-lib.so @@ -210,17 +210,17 @@ Usage: aa[0*?] # see also 'af' and 'afna' | aav [sat] find values referencing a specific section or map ``` -There is a thing that is worth noticing about radare2 vs other disassemblers like e.g. IDA Pro. The following quote from an [article](http://radare.today/posts/analysis-by-default/ "radare2 - Analysis By Default") of radare2's blog () pretty summarizes this. +There is a thing that is worth noticing about radare2 vs other disassemblers like e.g. IDA Pro. The following quote from this [article](http://radare.today/posts/analysis-by-default/ "radare2 - Analysis By Default") of radare2's blog () offers a good summary. > Code analysis is not a quick operation, and not even predictable or taking a linear time to be processed. This makes starting times pretty heavy, compared to just loading the headers and strings information like it’s done by default. > -> People that are used to IDA or Hopper just load the binary, go out to make a coffee and then when the analysis is done, they start doing the manual analysis to understand what the program is doing. It’s true that those tools perform the analysis in background, and the GUI is not blocked. But this takes a lot of CPU time, and r2 aims to run in many more platforms than just high-end desktop computers. +> People that are used to [IDA](0x08-Testing-Tools.md#ida-pro-commercial-tool) or [Hopper](0x08-Testing-Tools.md#hopper-commercial-tool) just load the binary, go out to make a coffee and then when the analysis is done, they start doing the manual analysis to understand what the program is doing. It’s true that those tools perform the analysis in background, and the GUI is not blocked. But this takes a lot of CPU time, and r2 aims to run in many more platforms than just high-end desktop computers. This said, please see section "[Reviewing Disassembled Native Code](#reviewing-disassembled-native-code "Reviewing Disassembled Native Code")" to learn more bout how radare2 can help us performing our reversing tasks much faster. For example, getting the disassembly of an specific function is a trivial task that can be performed in one command. ##### IDA Pro -If you own an IDA Pro license, open the file and once in the "Load new file" dialog, choose "ELF for ARM (Shared Object)" as the file type (IDA should detect this automatically), and "ARM Little-Endian" as the processor type. +If you own an [IDA Pro](0x08-Testing-Tools.md#ida-pro-commercial-tool) license, open the file and once in the "Load new file" dialog, choose "ELF for ARM (Shared Object)" as the file type (IDA should detect this automatically), and "ARM Little-Endian" as the processor type. @@ -616,7 +616,7 @@ Dalvik and ART support the JDWP, a protocol for communication between the debugg A JDWP debugger allows you to step through Java code, set breakpoints on Java methods, and inspect and modify local and instance variables. You'll use a JDWP debugger most of the time you debug "normal" Android apps (i.e., apps that don't make many calls to native libraries). -In the following section, we'll show how to solve the UnCrackable App for Android Level 1 with jdb alone. Note that this is not an *efficient* way to solve this crackme. Actually you can do it much faster with Frida and other methods, which we'll introduce later in the guide. This, however, serves as an introduction to the capabilities of the Java debugger. +In the following section, we'll show how to solve the UnCrackable App for Android Level 1 with jdb alone. Note that this is not an _efficient_ way to solve this crackme. Actually you can do it much faster with Frida and other methods, which we'll introduce later in the guide. This, however, serves as an introduction to the capabilities of the Java debugger. #### Debugging with jdb @@ -804,13 +804,13 @@ Native code on Android is packed into ELF shared libraries and runs just like an You'll now set up your JNI demo app, HelloWorld-JNI.apk, for debugging. It's the same APK you downloaded in "Statically Analyzing Native Code". Use `adb install` to install it on your device or on an emulator. ```bash -$ adb install HelloWorld-JNI.apk +adb install HelloWorld-JNI.apk ``` If you followed the instructions at the beginning of this chapter, you should already have the Android NDK. It contains prebuilt versions of gdbserver for various architectures. Copy the gdbserver binary to your device: ```bash -$ adb push $NDK/prebuilt/android-arm/gdbserver/gdbserver /data/local/tmp +adb push $NDK/prebuilt/android-arm/gdbserver/gdbserver /data/local/tmp ``` The `gdbserver --attach` command causes gdbserver to attach to the running process and bind to the IP address and port specified in `comm`, which in this case is a HOST:PORT descriptor. Start HelloWorldJNI on the device, then connect to the device and determine the PID of the HelloWorldJNI process (sg.vantagepoint.helloworldjni). Then switch to the root user and attach `gdbserver`: @@ -828,7 +828,7 @@ Listening on port 1234 The process is now suspended, and `gdbserver` is listening for debugging clients on port `1234`. With the device connected via USB, you can forward this port to a local port on the host with the `abd forward` command: ```bash -$ adb forward tcp:1234 tcp:1234 +adb forward tcp:1234 tcp:1234 ``` You'll now use the prebuilt version of `gdb` included in the NDK toolchain. @@ -931,7 +931,7 @@ Strace is a standard Linux utility that is not included with Android by default, If the "Wait for debugger" feature in **Settings > Developer options** is unavailable, you can use a shell script to launch the process and immediately attach strace (not an elegant solution, but it works): ```bash -$ while true; do pid=$(pgrep 'target_process' | head -1); if [[ -n "$pid" ]]; then strace -s 2000 - e "!read" -ff -p "$pid"; break; fi; done +while true; do pid=$(pgrep 'target_process' | head -1); if [[ -n "$pid" ]]; then strace -s 2000 - e "!read" -ff -p "$pid"; break; fi; done ``` ##### Ftrace @@ -941,7 +941,7 @@ Ftrace is a tracing utility built directly into the Linux kernel. On a rooted de Conveniently, the stock Android kernel on both Lollipop and Marshmallow include ftrace functionality. The feature can be enabled with the following command: ```bash -$ echo 1 > /proc/sys/kernel/ftrace_enabled +echo 1 > /proc/sys/kernel/ftrace_enabled ``` The `/sys/kernel/debug/tracing` directory holds all control and output files related to ftrace. The following files are found in this directory: @@ -971,7 +971,7 @@ Native methods tracing can be performed with relative ease than compared to Java In order to use `frida-trace`, a Frida server should be running on the device. An example for tracing libc's `open` function using `frida-trace` is demonstrated below, where `-U` connects to the USB device and `-i` specifies the function to be included in the trace. ```bash -$ frida-trace -U -i "open" com.android.chrome +frida-trace -U -i "open" com.android.chrome ``` @@ -1009,13 +1009,13 @@ Another thing to notice in the output above is that it's colorized. An applicati - Tracing functions by address when no function name symbols are available (stripped binaries), e.g. `-a "libjpeg.so!0x4793c"`. ```bash -$ frida-trace -U -i "Java_*" com.android.chrome +frida-trace -U -i "Java_*" com.android.chrome ``` Many binaries are stripped and don't have function name symbols available with them. In such cases, a function can be traced using its address as well. ```bash -$ frida-trace -p 1372 -a "libjpeg.so!0x4793c" +frida-trace -p 1372 -a "libjpeg.so!0x4793c" ``` Frida 12.10 introduces a new useful syntax to query Java classes and methods as well as Java method tracing support for frida-trace via `-j` (starting on frida-tools 8.0). @@ -1034,7 +1034,7 @@ As detailed in section [Reviewing Disassembled Native Code](#reviewing-disassemb You can easily install it by running `pip install jnitrace` and run it straight away as follows: ```bash -$ jnitrace -l libnative-lib.so sg.vantagepoint.helloworldjni +jnitrace -l libnative-lib.so sg.vantagepoint.helloworldjni ``` > The `-l` option can be provided multiple times to trace multiple libraries, or `*` can be provided to trace all libraries. This, however, may provide a lot of output. @@ -1054,7 +1054,7 @@ The Android emulator is based on QEMU, a generic and open source machine emulato Because the Android emulator is a fork of QEMU, it comes with all QEMU features, including monitoring, debugging, and tracing facilities. QEMU-specific parameters can be passed to the emulator with the `-qemu` command line flag. You can use QEMU's built-in tracing facilities to log executed instructions and virtual register values. Starting QEMU with the `-d` command line flag will cause it to dump the blocks of guest code, micro operations, or host instructions being executed. With the `-d_asm` flag, QEMU logs all basic blocks of guest code as they enter QEMU's translation function. The following command logs all translated blocks to a file: ```bash -$ emulator -show-kernel -avd Nexus_4_API_19 -snapshot default-boot -no-snapshot-save -qemu -d in_asm,cpu 2>/tmp/qemu.log +emulator -show-kernel -avd Nexus_4_API_19 -snapshot default-boot -no-snapshot-save -qemu -d in_asm,cpu 2>/tmp/qemu.log ``` Unfortunately, generating a complete guest instruction trace with QEMU is impossible because code blocks are written to the log only at the time they are translated, not when they're taken from the cache. For example, if a block is repeatedly executed in a loop, only the first iteration will be printed to the log. There's no way to disable TB caching in QEMU (besides hacking the source code). Nevertheless, the functionality is sufficient for basic tasks, such as reconstructing the disassembly of a natively executed cryptographic algorithm. @@ -1274,7 +1274,7 @@ To conclude, learning symbolic execution might look a bit intimidating at first, ## Tampering and Runtime Instrumentation -First, we'll look at some simple ways to modify and instrument mobile apps. *Tampering* means making patches or runtime changes to the app to affect its behavior. For example, you may want to deactivate SSL pinning or binary protections that hinder the testing process. *Runtime Instrumentation* encompasses adding hooks and runtime patches to observe the app's behavior. In mobile application security however, the term loosely refers to all kinds of runtime manipulation, including overriding methods to change behavior. +First, we'll look at some simple ways to modify and instrument mobile apps. _Tampering_ means making patches or runtime changes to the app to affect its behavior. For example, you may want to deactivate SSL pinning or binary protections that hinder the testing process. _Runtime Instrumentation_ encompasses adding hooks and runtime patches to observe the app's behavior. In mobile application security however, the term loosely refers to all kinds of runtime manipulation, including overriding methods to change behavior. ### Patching, Repackaging, and Re-Signing @@ -1288,7 +1288,7 @@ In most cases, both issues can be fixed by making minor changes to the app (aka. The first step is unpacking and disassembling the APK with `apktool`: ```bash -$ apktool d target_apk.apk +apktool d target_apk.apk ``` > Note: To save time, you may use the flag `--no-src` if you only want to unpack the APK but not disassemble the code. For example, when you only want to modify the Android Manifest and repack immediately. @@ -1328,7 +1328,7 @@ This modification will break the APK signature, so you'll also have to re-sign t Every debugger-enabled process runs an extra thread for handling JDWP protocol packets. This thread is started only for apps that have the `android:debuggable="true"` flag set in their manifest file's `` element. This is the typical configuration of Android devices shipped to end users. -When reverse engineering apps, you'll often have access to the target app's release build only. Release builds aren't meant to be debugged, that's the purpose of *debug builds*. If the system property `ro.debuggable` is set to "0", Android disallows both JDWP and native debugging of release builds. Although this is easy to bypass, you're still likely to encounter limitations, such as a lack of line breakpoints. Nevertheless, even an imperfect debugger is still an invaluable tool, being able to inspect the runtime state of a program makes understanding the program *a lot* easier. +When reverse engineering apps, you'll often have access to the target app's release build only. Release builds aren't meant to be debugged, that's the purpose of _debug builds_. If the system property `ro.debuggable` is set to "0", Android disallows both JDWP and native debugging of release builds. Although this is easy to bypass, you're still likely to encounter limitations, such as a lack of line breakpoints. Nevertheless, even an imperfect debugger is still an invaluable tool, being able to inspect the runtime state of a program makes understanding the program _a lot_ easier. To _convert_ a release build into a debuggable build, you need to modify a flag in the Android Manifest file (AndroidManifest.xml). Once you've unpacked the app (e.g. `apktool d --no-src UnCrackable-Level1.apk`) and decoded the Android Manifest, add `android:debuggable="true"` to it using a text editor: @@ -1343,9 +1343,9 @@ Even if we haven't altered the source code, this modification also breaks the AP You can easily repackage an app by doing the following: ```bash -$ cd UnCrackable-Level1 -$ apktool b -$ zipalign -v 4 dist/UnCrackable-Level1.apk ../UnCrackable-Repackaged.apk +cd UnCrackable-Level1 +apktool b +zipalign -v 4 dist/UnCrackable-Level1.apk ../UnCrackable-Repackaged.apk ``` Note that the Android Studio build tools directory must be in the path. It is located at `[SDK-Path]/build-tools/[version]`. The `zipalign` and `apksigner` tools are in this directory. @@ -1357,26 +1357,26 @@ Before re-signing, you first need a code-signing certificate. If you have built The standard Java distribution includes `keytool` for managing KeyStores and certificates. You can create your own signing certificate and key, then add it to the debug KeyStore: ```bash -$ keytool -genkey -v -keystore ~/.android/debug.keystore -alias signkey -keyalg RSA -keysize 2048 -validity 20000 +keytool -genkey -v -keystore ~/.android/debug.keystore -alias signkey -keyalg RSA -keysize 2048 -validity 20000 ``` After the certificate is available, you can re-sign the APK with it. Be sure that `apksigner` is in the path and that you run it from the folder where your repackaged APK is located. ```bash -$ apksigner sign --ks ~/.android/debug.keystore --ks-key-alias signkey UnCrackable-Repackaged.apk +apksigner sign --ks ~/.android/debug.keystore --ks-key-alias signkey UnCrackable-Repackaged.apk ``` Note: If you experience JRE compatibility issues with `apksigner`, you can use `jarsigner` instead. When you do this, `zipalign` must be called **after** signing. ```bash -$ jarsigner -verbose -keystore ~/.android/debug.keystore ../UnCrackable-Repackaged.apk signkey -$ zipalign -v 4 dist/UnCrackable-Level1.apk ../UnCrackable-Repackaged.apk +jarsigner -verbose -keystore ~/.android/debug.keystore ../UnCrackable-Repackaged.apk signkey +zipalign -v 4 dist/UnCrackable-Level1.apk ../UnCrackable-Repackaged.apk ``` Now you may reinstall the app: ```bash -$ adb install UnCrackable-Repackaged.apk +adb install UnCrackable-Repackaged.apk ``` #### The "Wait For Debugger" Feature @@ -1403,7 +1403,7 @@ The following approach can be used in order to patch the JavaScript file: 2. Copy the content of the file `assets/index.android.bundle` into a temporary file. 3. Use `JStillery` to beautify and deobfuscate the content of the temporary file. 4. Identify where the code should be patched in the temporary file and implement the changes. -5. Put the *patched code* on a single line and copy it in the original `assets/index.android.bundle` file. +5. Put the _patched code_ on a single line and copy it in the original `assets/index.android.bundle` file. 6. Repack the APK archive using `apktool` tool and sign it before to install it on the target device/emulator. #### Library Injection @@ -1460,7 +1460,7 @@ As the [ld.so man page](http://man7.org/linux/man-pages/man8/ld.so.8.html "LD.SO On Android, setting `LD_PRELOAD` is slightly different compared to other Linux distributions. If you recall from the "[Platform Overview](0x05a-Platform-Overview.md#zygote "Platform Overview")" section, every application in Android is forked from Zygote, which is started very early during the Android boot-up. Thus, setting `LD_PRELOAD` on Zygote is not possible. As a workaround for this problem, Android supports the `setprop` (set property) functionality. Below you can see an example for an application with package name `com.foo.bar` (note the additional `wrap.` prefix): ```bash -$ setprop wrap.com.foo.bar LD_PRELOAD=/data/local/tmp/libpreload.so +setprop wrap.com.foo.bar LD_PRELOAD=/data/local/tmp/libpreload.so ``` > Please note that if the library to be preloaded does not have SELinux context assigned, from Android 5.0 (API level 21) onwards, you need to disable SELinux to make `LD_PRELOAD` work, which may require root. @@ -1724,7 +1724,7 @@ Wrap your code in the function `setImmediate` to prevent timeouts (you may or ma Save the above script as `uncrackable1.js` and load it: ```bash -$ frida -U -f owasp.mstg.uncrackable1 -l uncrackable1.js --no-pause +frida -U -f owasp.mstg.uncrackable1 -l uncrackable1.js --no-pause ``` After you see the "MainActivity.a modified" message and the app will not exit anymore. @@ -1814,7 +1814,7 @@ $ frida -U -f owasp.mstg.uncrackable1 -l uncrackable1.js --no-pause The hooked function outputted the decrypted string. You extracted the secret string without having to dive too deep into the application code and its decryption routines. -You've now covered the basics of static/dynamic analysis on Android. Of course, the only way to *really* learn it is hands-on experience: build your own projects in Android Studio, observe how your code gets translated into bytecode and native code, and try to crack our challenges. +You've now covered the basics of static/dynamic analysis on Android. Of course, the only way to _really_ learn it is hands-on experience: build your own projects in Android Studio, observe how your code gets translated into bytecode and native code, and try to crack our challenges. In the remaining sections, we'll introduce a few advanced subjects, including process exploration, kernel modules and dynamic execution. @@ -1833,7 +1833,7 @@ As you can see, these passive tasks help us collect information. This Informatio In the following sections you will be using [r2frida](0x08-Testing-Tools.md#r2frida) to retrieve information straight from the app runtime. Please refer to [r2frida's official installation instructions](https://github.com/nowsecure/r2frida/blob/master/README.md#installation "r2frida installation instructions"). First start by opening an r2frida session to the target app (e.g. [HelloWorld JNI](https://github.com/OWASP/owasp-mstg/raw/master/Samples/Android/01_HelloWorld-JNI/HelloWord-JNI.apk "HelloWorld JNI") APK) that should be running on your Android phone (connected per USB). Use the following command: ```bash -$ r2 frida://usb//sg.vantagepoint.helloworldjni +r2 frida://usb//sg.vantagepoint.helloworldjni ``` > See all options with `r2 frida://?`. @@ -2224,19 +2224,19 @@ Setting `ro.debuggable` to "1" makes all running apps debuggable (i.e., the debu To modify initrd on any Android device, back up the original boot image with TWRP or dump it with the following command: ```bash -$ adb shell cat /dev/mtd/mtd0 >/mnt/sdcard/boot.img -$ adb pull /mnt/sdcard/boot.img /tmp/boot.img +adb shell cat /dev/mtd/mtd0 >/mnt/sdcard/boot.img +adb pull /mnt/sdcard/boot.img /tmp/boot.img ``` To extract the contents of the boot image, use the abootimg tool as described in Krzysztof Adamski's how-to : ```bash -$ mkdir boot -$ cd boot -$ ../abootimg -x /tmp/boot.img -$ mkdir initrd -$ cd initrd -$ cat ../initrd.img | gunzip | cpio -vid +mkdir boot +cd boot +../abootimg -x /tmp/boot.img +mkdir initrd +cd initrd +cat ../initrd.img | gunzip | cpio -vid ``` Note the boot parameters written to bootimg.cfg; you'll need them when booting your new kernel and ramdisk. @@ -2256,8 +2256,8 @@ cmdline = console=ttyHSL0,115200,n8 androidboot.hardware=hammerhead user_debug=3 Modify default.prop and package your new ramdisk: ```bash -$ cd initrd -$ find . | cpio --create --format='newc' | gzip > ../myinitd.img +cd initrd +find . | cpio --create --format='newc' | gzip > ../myinitd.img ``` ### Customizing the Android Kernel @@ -2275,13 +2275,13 @@ For hacking, I recommend an AOSP-supported device. Google's Nexus smartphones an For example, to get kernel sources for Lollipop that are compatible with the Nexus 5, you need to clone the `msm` repository and check out one of the `android-msm-hammerhead` branches (hammerhead is the codename of the Nexus 5, and finding the right branch is confusing). Once you have downloaded the sources, create the default kernel config with the command `make hammerhead_defconfig` (replacing "hammerhead" with your target device). ```bash -$ git clone https://android.googlesource.com/kernel/msm.git -$ cd msm -$ git checkout origin/android-msm-hammerhead-3.4-lollipop-mr1 -$ export ARCH=arm -$ export SUBARCH=arm -$ make hammerhead_defconfig -$ vim .config +git clone https://android.googlesource.com/kernel/msm.git +cd msm +git checkout origin/android-msm-hammerhead-3.4-lollipop-mr1 +export ARCH=arm +export SUBARCH=arm +make hammerhead_defconfig +vim .config ``` I recommend using the following settings to add loadable module support, enable the most important tracing facilities, and open kernel memory for patching. @@ -2305,25 +2305,25 @@ CONFIG KDB=Y Once you're finished editing save the .config file, build the kernel. ```bash -$ export ARCH=arm -$ export SUBARCH=arm -$ export CROSS_COMPILE=/path_to_your_ndk/arm-eabi-4.8/bin/arm-eabi- -$ make +export ARCH=arm +export SUBARCH=arm +export CROSS_COMPILE=/path_to_your_ndk/arm-eabi-4.8/bin/arm-eabi- +make ``` You can now create a standalone toolchain for cross-compiling the kernel and subsequent tasks. To create a toolchain for Android 7.0 (API level 24), run make-standalone-toolchain.sh from the Android NDK package: ```bash -$ cd android-ndk-rXXX -$ build/tools/make-standalone-toolchain.sh --arch=arm --platform=android-24 --install-dir=/tmp/my-android-toolchain +cd android-ndk-rXXX +build/tools/make-standalone-toolchain.sh --arch=arm --platform=android-24 --install-dir=/tmp/my-android-toolchain ``` Set the CROSS_COMPILE environment variable to point to your NDK directory and run "make" to build the kernel. ```bash -$ export CROSS_COMPILE=/tmp/my-android-toolchain/bin/arm-eabi- -$ make +export CROSS_COMPILE=/tmp/my-android-toolchain/bin/arm-eabi- +make ``` ### Booting the Custom Environment @@ -2343,14 +2343,14 @@ lrwxrwxrwx root root 1970-08-30 22:31 userdata -> /dev/block/mm Then dump the whole thing into a file: ```bash -$ adb shell "su -c dd if=/dev/block/mmcblk0p19 of=/data/local/tmp/boot.img" -$ adb pull /data/local/tmp/boot.img +adb shell "su -c dd if=/dev/block/mmcblk0p19 of=/data/local/tmp/boot.img" +adb pull /data/local/tmp/boot.img ``` Next, extract the ramdisk and information about the structure of the boot image. There are various tools that can do this; I used Gilles Grandou's abootimg tool. Install the tool and run the following command on your boot image: ```bash -$ abootimg -x boot.img +abootimg -x boot.img ``` This should create the files bootimg.cfg, initrd.img, and zImage (your original kernel) in the local directory. @@ -2358,13 +2358,13 @@ This should create the files bootimg.cfg, initrd.img, and zImage (your original You can now use fastboot to test the new kernel. The `fastboot boot` command allows you to run the kernel without actually flashing it (once you're sure everything works, you can make the changes permanent with fastboot flash, but you don't have to). Restart the device in fastboot mode with the following command: ```bash -$ adb reboot bootloader +adb reboot bootloader ``` Then use the `fastboot boot` command to boot Android with the new kernel. Specify the kernel offset, ramdisk offset, tags offset, and command line (use the values listed in your extracted bootimg.cfg) in addition to the newly built kernel and the original ramdisk. ```bash -$ fastboot boot zImage-dtb initrd.img --base 0 --kernel-offset 0x8000 --ramdisk-offset 0x2900000 --tags-offset 0x2700000 -c "console=ttyHSL0,115200,n8 androidboot.hardware=hammerhead user_debug=31 maxcpus=2 msm_watchdog_v2.enable=1" +fastboot boot zImage-dtb initrd.img --base 0 --kernel-offset 0x8000 --ramdisk-offset 0x2900000 --tags-offset 0x2700000 -c "console=ttyHSL0,115200,n8 androidboot.hardware=hammerhead user_debug=31 maxcpus=2 msm_watchdog_v2.enable=1" ``` The system should now boot normally. To quickly verify that the correct kernel is running, navigate to **Settings** -> **About phone** and check the **kernel version** field. @@ -2529,9 +2529,9 @@ int main(int argc, char *argv[]) { Beginning with Android 5.0 (API level 21), all executables must be compiled with PIE support. Build kmem_util.c with the prebuilt toolchain and copy it to the device: ```bash -$ /tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc -pie -fpie -o kmem_util kmem_util.c -$ adb push kmem_util /data/local/tmp/ -$ adb shell chmod 755 /data/local/tmp/kmem_util +/tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc -pie -fpie -o kmem_util kmem_util.c +adb push kmem_util /data/local/tmp/ +adb shell chmod 755 /data/local/tmp/kmem_util ``` Before you start accessing kernel memory, you still need to know the correct offset into the system call table. The `openat` system call is defined in unistd.h, which is in the kernel sources: @@ -2551,7 +2551,7 @@ bf000000 t new_openat [kernel_hook] Now you have everything you need to overwrite the `sys_call_table` entry. The syntax for kmem_util is: ```bash -$ ./kmem_util +./kmem_util ``` The following command patches the `openat` system call table so that it points to your new function. diff --git a/Document/0x05d-Testing-Data-Storage.md b/Document/0x05d-Testing-Data-Storage.md index 3310f9fb02..d49a6968f1 100644 --- a/Document/0x05d-Testing-Data-Storage.md +++ b/Document/0x05d-Testing-Data-Storage.md @@ -181,7 +181,7 @@ Realm realm = Realm.getInstance(config); ``` -If the database is not encrypted, you should be able to obtain the data. If the database *is* encrypted, determine whether the key is hard-coded in the source or resources and whether it is stored unprotected in shared preferences or some other location. +If the database _is not_ encrypted, you should be able to obtain the data. If the database _is_ encrypted, determine whether the key is hard-coded in the source or resources and whether it is stored unprotected in shared preferences or some other location. ### Internal Storage @@ -363,14 +363,14 @@ When defining the KeyDescription AuthorizationList, the following parameters wil #### Older KeyStore Implementations -Older Android versions don't include KeyStore, but they *do* include the KeyStore interface from JCA (Java Cryptography Architecture). You can use KeyStores that implement this interface to ensure the secrecy and integrity of keys stored with KeyStore; BouncyCastle KeyStore (BKS) is recommended. All implementations are based on the fact that files are stored on the filesystem; all files are password-protected. +Older Android versions don't include KeyStore, but they _do_ include the KeyStore interface from JCA (Java Cryptography Architecture). You can use KeyStores that implement this interface to ensure the secrecy and integrity of keys stored with KeyStore; BouncyCastle KeyStore (BKS) is recommended. All implementations are based on the fact that files are stored on the filesystem; all files are password-protected. To create one, you can use the `KeyStore.getInstance("BKS", "BC") method`, where "BKS" is the KeyStore name (BouncyCastle Keystore) and "BC" is the provider (BouncyCastle). You can also use SpongyCastle as a wrapper and initialize the KeyStore as follows: `KeyStore.getInstance("BKS", "SC")`. Be aware that not all KeyStores properly protect the keys stored in the KeyStore files. #### KeyChain -The [KeyChain class](https://developer.android.com/reference/android/security/KeyChain.html "Android KeyChain") is used to store and retrieve *system-wide* private keys and their corresponding certificates (chain). The user will be prompted to set a lock screen pin or password to protect the credential storage if something is being imported into the KeyChain for the first time. Note that the KeyChain is system-wide, every application can access the materials stored in the KeyChain. +The [KeyChain class](https://developer.android.com/reference/android/security/KeyChain.html "Android KeyChain") is used to store and retrieve _system-wide_ private keys and their corresponding certificates (chain). The user will be prompted to set a lock screen pin or password to protect the credential storage if something is being imported into the KeyChain for the first time. Note that the KeyChain is system-wide, every application can access the materials stored in the KeyChain. Inspect the source code to determine whether native Android mechanisms identify sensitive information. Sensitive information should be encrypted, not stored in clear text. For sensitive information that must be stored on the device, several API calls are available to protect the data via the `KeyChain` class. Complete the following steps: @@ -725,7 +725,7 @@ Many application developers still use `System.out.println` or `printStackTrace` Remember that you can target a specific app by filtering the Logcat output as follows: ```bash -$ adb logcat | grep "$(adb shell ps | grep | awk '{print $2}')" +adb logcat | grep "$(adb shell ps | grep | awk '{print $2}')" ``` > If you already know the app PID you may give it directly using `--pid` flag. @@ -1160,13 +1160,13 @@ To check for key/value backup implementations, look for these classes in the sou After executing all available app functions, attempt to back up via `adb`. If the backup is successful, inspect the backup archive for sensitive data. Open a terminal and run the following command: ```bash -$ adb backup -apk -nosystem +adb backup -apk -nosystem ``` ADB should respond now with "Now unlock your device and confirm the backup operation" and you should be asked on the Android phone for a password. This is an optional step and you don't need to provide one. If the phone does not prompt this message, try the following command including the quotes: ```bash -$ adb backup "-apk -nosystem " +adb backup "-apk -nosystem " ``` The problem happens when your device has an adb version prior to 1.0.31. If that's the case you must use an adb version of 1.0.31 also on your host computer. Versions of adb after 1.0.32 [broke the backwards compatibility.](https://issuetracker.google.com/issues/37096097 "adb backup is broken since ADB version 1.0.32") @@ -1175,37 +1175,37 @@ Approve the backup from your device by selecting the _Back up my data_ option. A Run the following command to convert the .ab file to tar. ```bash -$ dd if=mybackup.ab bs=24 skip=1|openssl zlib -d > mybackup.tar +dd if=mybackup.ab bs=24 skip=1|openssl zlib -d > mybackup.tar ``` In case you get the error `openssl:Error: 'zlib' is an invalid command.` you can try to use Python instead. ```bash -$ dd if=backup.ab bs=1 skip=24 | python -c "import zlib,sys;sys.stdout.write(zlib.decompress(sys.stdin.read()))" > backup.tar +dd if=backup.ab bs=1 skip=24 | python -c "import zlib,sys;sys.stdout.write(zlib.decompress(sys.stdin.read()))" > backup.tar ``` The [_Android Backup Extractor_](https://github.com/nelenkov/android-backup-extractor "Android Backup Extractor") is another alternative backup tool. To make the tool to work, you have to download the Oracle JCE Unlimited Strength Jurisdiction Policy Files for [JRE7](https://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html "Oracle JCE Unlimited Strength Jurisdiction Policy Files JRE7") or [JRE8](http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html "Oracle JCE Unlimited Strength Jurisdiction Policy Files JRE8") and place them in the JRE lib/security folder. Run the following command to convert the tar file: ```bash -$ java -jar abe.jar unpack backup.ab +java -jar abe.jar unpack backup.ab ``` if it shows some Cipher information and usage, which means it hasn't unpacked successfully. In this case you can give a try with more arguments: ```bash -$ abe [-debug] [-useenv=yourenv] unpack [password] +abe [-debug] [-useenv=yourenv] unpack [password] ``` [password]: is the password when your android device asked you earlier. For example here is: 123 ```bash -$ java -jar abe.jar unpack backup.ab backup.tar 123 +java -jar abe.jar unpack backup.ab backup.tar 123 ``` Extract the tar file to your working directory. ```bash -$ tar xvf mybackup.tar +tar xvf mybackup.tar ``` ## Finding Sensitive Information in Auto-Generated Screenshots (MSTG-STORAGE-9) @@ -1605,7 +1605,7 @@ For more advanced analysis of the memory dump, use the [Eclipse Memory Analyzer To analyze the dump in MAT, use the _hprof-conv_ platform tool, which comes with the Android SDK. ```bash -$ ./hprof-conv memory.hprof memory-mat.hprof +./hprof-conv memory.hprof memory-mat.hprof ``` MAT provides several tools for analyzing the memory dump. For example, the _Histogram_ provides an estimate of the number of objects that have been captured from a given type, and the _Thread Overview_ shows processes' threads and stack frames. The _Dominator Tree_ provides information about keep-alive dependencies between objects. You can use regular expressions to filter the results these tools provide. diff --git a/Document/0x05e-Testing-Cryptography.md b/Document/0x05e-Testing-Cryptography.md index 798c47ec47..b775b0c2e0 100644 --- a/Document/0x05e-Testing-Cryptography.md +++ b/Document/0x05e-Testing-Cryptography.md @@ -267,7 +267,7 @@ As an example we illustrate how to locate the use of a hardcoded encryption key. Now search the files for the usage of the `SecretKeySpec` class, e.g. by simply recursively grepping on them or using jadx search function: ```bash -$ grep -r "SecretKeySpec" +grep -r "SecretKeySpec" ``` This will return all classes using the `SecretKeySpec` class. Now examine those files and trace which variables are used to pass the key material. The figure below shows the result of performing this assessment on a production ready application. We can clearly locate the use of a static encryption key that is hardcoded and initialized in the static byte array `Encrypt.keyBytes`. diff --git a/Document/0x05f-Testing-Local-Authentication.md b/Document/0x05f-Testing-Local-Authentication.md index 56a1095497..cfa6c756d8 100644 --- a/Document/0x05f-Testing-Local-Authentication.md +++ b/Document/0x05f-Testing-Local-Authentication.md @@ -306,7 +306,7 @@ Make sure that fingerprint authentication and/or other types of biometric authen ### Dynamic Analysis -Please take a look at this detailed [blog article about the Android KeyStore and Biometric authentication](https://labs.f-secure.com/blog/how-secure-is-your-android-keystore-authentication "How Secure is your Android Keystore Authentication?"). This research includes two Frida scripts which can be used to test insecure implementations of biometric authentication and try to bypass them: +Please take a look at this detailed [blog article about the Android KeyStore and Biometric authentication](https://labs.withsecure.com/blog/how-secure-is-your-android-keystore-authentication "How Secure is your Android Keystore Authentication?"). This research includes two Frida scripts which can be used to test insecure implementations of biometric authentication and try to bypass them: - [Fingerprint bypass](https://github.com/FSecureLABS/android-keystore-audit/blob/master/frida-scripts/fingerprint-bypass.js "Fingerprint Bypass"): This Frida script will bypass authentication when the `CryptoObject` is not used in the `authenticate` method of the `BiometricPrompt` class. The authentication implementation relies on the callback `onAuthenticationSucceded` being called. - [Fingerprint bypass via exception handling](https://github.com/FSecureLABS/android-keystore-audit/blob/master/frida-scripts/fingerprint-bypass-via-exception-handling.js "Fingerprint bypass via exception handling"): This Frida script will attempt to bypass authentication when the `CryptoObject` is used, but used in an incorrect way. The detailed explanation can be found in the section "Crypto Object Exception Handling" in the blog post. diff --git a/Document/0x05g-Testing-Network-Communication.md b/Document/0x05g-Testing-Network-Communication.md index a7a8836931..f0c3873aaa 100644 --- a/Document/0x05g-Testing-Network-Communication.md +++ b/Document/0x05g-Testing-Network-Communication.md @@ -365,13 +365,13 @@ As an example, let's say that you find an application which uses a BKS (BouncyCa To add your proxy's certificate use the following command: ```bash -$ keytool -importcert -v -trustcacerts -file proxy.cer -alias aliascert -keystore "res/raw/truststore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "providerpath/bcprov-jdk15on-164.jar" -storetype BKS -storepass password +keytool -importcert -v -trustcacerts -file proxy.cer -alias aliascert -keystore "res/raw/truststore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "providerpath/bcprov-jdk15on-164.jar" -storetype BKS -storepass password ``` To list certificates in the BKS truststore use the following command: ```bash -$ keytool -list -keystore "res/raw/truststore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "providerpath/bcprov-jdk15on-164.jar" -storetype BKS -storepass password +keytool -list -keystore "res/raw/truststore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "providerpath/bcprov-jdk15on-164.jar" -storetype BKS -storepass password ``` After making these modifications, repackage the application using apktool and install it on your device. diff --git a/Document/0x05h-Testing-Platform-Interaction.md b/Document/0x05h-Testing-Platform-Interaction.md index a9b10be59e..988a3e4b72 100644 --- a/Document/0x05h-Testing-Platform-Interaction.md +++ b/Document/0x05h-Testing-Platform-Interaction.md @@ -43,7 +43,7 @@ The [following changes](https://developer.android.com/about/versions/pie/android - **Restricted access to call logs**: `READ_CALL_LOG`, `WRITE_CALL_LOG`, and `PROCESS_OUTGOING_CALLS` (dangerous) permissions are moved from `PHONE` to the new `CALL_LOG` permission group. This means that being able to make phone calls (e.g. by having the permissions of the `PHONE` group granted) is not sufficient to get access to the call logs. - **Restricted access to phone numbers**: apps wanting to read the phone number require the `READ_CALL_LOG` permission when running on Android 9 (API level 28). -- **Restricted access to Wi-Fi location and connection information**: SSID and BSSID values cannot be retrieved (e.g. via [`WifiManager.getConnectionInfo`](https://developer.android.com/reference/android/net/wifi/WifiManager#getConnectionInfo%28%29 "WifiManager.getConnectionInfo") unless *all* of the following is true: +- **Restricted access to Wi-Fi location and connection information**: SSID and BSSID values cannot be retrieved (e.g. via [`WifiManager.getConnectionInfo`](https://developer.android.com/reference/android/net/wifi/WifiManager#getConnectionInfo%28%29 "WifiManager.getConnectionInfo") unless _all_ of the following is true: - The `ACCESS_FINE_LOCATION` or `ACCESS_COARSE_LOCATION` permission. - The `ACCESS_WIFI_STATE` permission. - Location services are enabled (under **Settings** -> **Location**). @@ -100,7 +100,7 @@ This allows a common capability-style model where user interaction drives ad-hoc Android allows apps to expose their services/components to other apps. Custom permissions are required for app access to the exposed components. You can define [custom permissions](https://developer.android.com/guide/topics/permissions/defining.html "Custom Permissions") in `AndroidManifest.xml` by creating a permission tag with two mandatory attributes: `android:name` and `android:protectionLevel`. -It is crucial to create custom permissions that adhere to the *Principle of Least Privilege*: permission should be defined explicitly for its purpose, with a meaningful and accurate label and description. +It is crucial to create custom permissions that adhere to the _Principle of Least Privilege_: permission should be defined explicitly for its purpose, with a meaningful and accurate label and description. Below is an example of a custom permission called `START_MAIN_ACTIVITY`, which is required when launching the `TEST_ACTIVITY` Activity. @@ -316,9 +316,9 @@ install permissions: The output shows all permissions using the following categories: -- **declared permissions**: list of all *custom* permissions. -- **requested and install permissions**: list of all install-time permissions including *normal* and *signature* permissions. -- **runtime permissions**: list of all *dangerous* permissions. +- **declared permissions**: list of all _custom_ permissions. +- **requested and install permissions**: list of all install-time permissions including _normal_ and _signature_ permissions. +- **runtime permissions**: list of all _dangerous_ permissions. When doing the dynamic analysis: @@ -350,7 +350,7 @@ The following portions of the source code should be checked if any app functiona An example of a vulnerable IPC mechanism is shown below. -You can use *ContentProviders* to access database information, and you can probe services to see if they return data. If data is not validated properly, the content provider may be prone to SQL injection while other apps are interacting with it. See the following vulnerable implementation of a *ContentProvider*. +You can use _ContentProviders_ to access database information, and you can probe services to see if they return data. If data is not validated properly, the content provider may be prone to SQL injection while other apps are interacting with it. See the following vulnerable implementation of a _ContentProvider_. ```xml ``` -#### Inspect the source code +#### Inspect the Source Code By inspecting the `PWList.java` activity, we see that it offers options to list all keys, add, delete, etc. If we invoke it directly, we will be able to bypass the LoginActivity. More on this can be found in the dynamic analysis below. @@ -947,7 +947,7 @@ In the "Sieve" app, we find two exported services, identified by ``: ``` -#### Inspect the source code +#### Inspect the Source Code Check the source code for the class `android.app.Service`: @@ -984,7 +984,7 @@ By reversing the target application, we can see that the service `AuthService` p } ``` -#### Broadcast Receivers +### Broadcast Receivers #### Inspect the AndroidManifest @@ -998,7 +998,7 @@ In the "Android Insecure Bank" app, we find a broadcast receiver in the manifest ``` -#### Inspect the source code +#### Inspect the Source Code Search the source code for strings like `sendBroadcast`, `sendOrderedBroadcast`, and `sendStickyBroadcast`. Make sure that the application doesn't send any sensitive data. @@ -1585,7 +1585,7 @@ String json = gson.toJson(obj); #### XML There are several ways to serialize the contents of an object to XML and back. Android comes with the `XmlPullParser` interface which allows for easily maintainable XML parsing. There are two implementations within Android: `KXmlParser` and `ExpatPullParser`. The [Android Developer Guide](https://developer.android.com/training/basics/network-ops/xml#java "Instantiate the parser") provides a great write-up on how to use them. Next, there are various alternatives, such as a `SAX` parser that comes with the Java runtime. For more information, see [a blogpost from ibm.com](https://www.ibm.com/developerworks/opensource/library/x-android/index.html "Working with XML on Android on IBM Developer"). -Similarly to JSON, XML has the issue of working mostly String based, which means that String-type secrets will be harder to remove from memory. XML data can be stored anywhere (database, files), but do need additional protection in case of secrets or information that should not be changed. See the chapter "[Data Storage on Android](0x05d-Testing-Data-Storage.md)" for more details. As stated earlier: the true danger in XML lies in the [XML eXternal Entity (XXE)](https://owasp.org/www-community/vulnerabilities/XML_External_Entity_(XXE)_Processing "XML eXternal Entity attack (XXE)") attack as it might allow for reading external data sources that are still accessible within the application. +Similarly to JSON, XML has the issue of working mostly String based, which means that String-type secrets will be harder to remove from memory. XML data can be stored anywhere (database, files), but do need additional protection in case of secrets or information that should not be changed. See the chapter "[Data Storage on Android](0x05d-Testing-Data-Storage.md)" for more details. As stated earlier: the true danger in XML lies in the [XML eXternal Entity (XXE)](https://owasp.org/www-community/vulnerabilities/XML_External_Entity_%28XXE%29_Processing "XML eXternal Entity attack (XXE)") attack as it might allow for reading external data sources that are still accessible within the application. #### ORM diff --git a/Document/0x05i-Testing-Code-Quality-and-Build-Settings.md b/Document/0x05i-Testing-Code-Quality-and-Build-Settings.md index 683fb2d320..c00f9f4863 100644 --- a/Document/0x05i-Testing-Code-Quality-and-Build-Settings.md +++ b/Document/0x05i-Testing-Code-Quality-and-Build-Settings.md @@ -175,20 +175,20 @@ Symbols are usually stripped during the build process, so you need the compiled First, find the `nm` binary in your Android NDK and export it (or create an alias). ```bash -export $NM = $ANDROID_NDK_DIR/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-nm +export NM = $ANDROID_NDK_DIR/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-nm ``` To display debug symbols: ```bash -$ $NM -a libfoo.so +$NM -a libfoo.so /tmp/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-nm: libfoo.so: no symbols ``` To display dynamic symbols: ```bash -$ $NM -D libfoo.so +$NM -D libfoo.so ``` Alternatively, open the file in your favorite disassembler and check the symbol tables manually. @@ -310,8 +310,8 @@ apply plugin: 'org.owasp.dependencycheck' Once gradle has invoked the plugin, you can create a report by running: ```bash -$ gradle assemble -$ gradle dependencyCheckAnalyze --info +gradle assemble +gradle dependencyCheckAnalyze --info ``` The report will be in `build/reports` unless otherwise configured. Use the report in order to analyze the vulnerabilities found. See remediation on what to do given the vulnerabilities found with the libraries. @@ -346,8 +346,8 @@ plugins { Now, after the plugin is picked up, use the following commands: ```bash -$ gradle assemble -$ gradle downloadLicenses +gradle assemble +gradle downloadLicenses ``` Now a license-report will be generated, which can be used to consult the licenses used by the third party libraries. Please check the license agreements to see whether a copyright notice needs to be included into the app and whether the license type requires to open-source the code of the application. diff --git a/Document/0x05j-Testing-Resiliency-Against-Reverse-Engineering.md b/Document/0x05j-Testing-Resiliency-Against-Reverse-Engineering.md index ce85257066..f58aa91428 100644 --- a/Document/0x05j-Testing-Resiliency-Against-Reverse-Engineering.md +++ b/Document/0x05j-Testing-Resiliency-Against-Reverse-Engineering.md @@ -20,7 +20,7 @@ SafetyNet is an Android API that provides a set of services and creates profiles How exactly SafetyNet works is not well documented and may change at any time. When you call this API, SafetyNet downloads a binary package containing the device validation code provided from Google, and the code is then dynamically executed via reflection. An [analysis by John Kozyrakis](https://koz.io/inside-safetynet/ "SafetyNet: Google's tamper detection for Android") showed that SafetyNet also attempts to detect whether the device is rooted, but exactly how that's determined is unclear. -To use the API, an app may call the `SafetyNetApi.attest` method (which returns a JWS message with the *Attestation Result*) and then check the following fields: +To use the API, an app may call the `SafetyNetApi.attest` method (which returns a JWS message with the _Attestation Result_) and then check the following fields: - `ctsProfileMatch`: If 'true', the device profile matches one of Google's listed devices. - `basicIntegrity`: If 'true', the device running the app likely hasn't been tampered with. @@ -82,7 +82,7 @@ Perhaps the most widely used method of programmatic detection is checking for fi /system/xbin/daemonsu ``` -Detection code also often looks for binaries that are usually installed once a device has been rooted. These searches include checking for busybox and attempting to open the *su* binary at different locations: +Detection code also often looks for binaries that are usually installed once a device has been rooted. These searches include checking for busybox and attempting to open the _su_ binary at different locations: ```default /sbin/su @@ -568,7 +568,7 @@ The following methods describe different approaches to bypass debugger detection When dealing with obfuscated apps, you'll often find that developers purposely "hide away" data and functionality in native libraries. You'll find an example of this in level 2 of the "UnCrackable App for Android". -At first glance, the code looks like the prior challenge. A class called `CodeCheck` is responsible for verifying the code entered by the user. The actual check appears to occur in the `bar` method, which is declared as a *native* method. +At first glance, the code looks like the prior challenge. A class called `CodeCheck` is responsible for verifying the code entered by the user. The actual check appears to occur in the `bar` method, which is declared as a _native_ method. ```java package sg.vantagepoint.uncrackable2; @@ -769,7 +769,7 @@ Refer to the "[Tampering and Reverse Engineering on Android](0x05c-Reverse-Engin ### Effectiveness Assessment -#### For application-source integrity checks +**Application-source integrity checks:** Run the app in an unmodified state and make sure that everything works. Apply simple patches to `classes.dex` and any .so libraries in the app package. Re-package and re-sign the app as described in the "Basic Security Testing" chapter, then run the app. The app should detect the modification and respond in some way. At the very least, the app should alert the user and/or terminate. Work on bypassing the defenses and answer the following questions: @@ -778,7 +778,7 @@ Run the app in an unmodified state and make sure that everything works. Apply si - Did you need to write custom code to disable the defenses? How much time did you need? - What is your assessment of the difficulty of bypassing the mechanisms? -#### For storage integrity checks +**Storage integrity checks:** An approach similar to that for application-source integrity checks applies. Answer the following questions: @@ -826,9 +826,9 @@ Looking at these two _traces_ that Frida _lefts behind_, you might already imagi | **Check The Environment For Related Artifacts** | Artifacts can be package files, binaries, libraries, processes, and temporary files. For Frida, this could be the frida-server running in the target (rooted) system (the daemon responsible for exposing Frida over TCP). Inspect the running services ([`getRunningServices`](https://developer.android.com/reference/android/app/ActivityManager.html#getRunningServices%28int%29 "getRunningServices")) and processes (`ps`) searching for one whose name is "frida-server". You could also walk through the list of loaded libraries and check for suspicious ones (e.g. those including "frida" in their names). | Since Android 7.0 (API level 24), inspecting the running services/processes won't show you daemons like the frida-server as it is not being started by the app itself. Even if it would be possible, bypassing this would be as easy just renaming the corresponding Frida artifact (frida-server/frida-gadget/frida-agent). | | **Checking For Open TCP Ports** | The frida-server process binds to TCP port 27042 by default. Check whether this port is open is another method of detecting the daemon. | This method detects frida-server in its default mode, but the listening port can be changed via a command line argument, so bypassing this is a little too trivial. | | **Checking For Ports Responding To D-Bus Auth** | `frida-server` uses the D-Bus protocol to communicate, so you can expect it to respond to D-Bus AUTH. Send a D-Bus AUTH message to every open port and check for an answer, hoping that `frida-server` will reveal itself. | This is a fairly robust method of detecting `frida-server`, but Frida offers alternative modes of operation that don't require frida-server. | -| **Scanning Process Memory for Known Artifacts** | Scan the memory for artifacts found in Frida's libraries, e.g. the string "LIBFRIDA" present in all versions of frida-gadget and frida-agent. For example, use `Runtime.getRuntime().exec` and iterate through the memory mappings listed in `/proc/self/maps` or `/proc//maps` (depending on the Android version) searching for the string. | This method is a bit more effective, and it is difficult to bypass with Frida only, especially if some obfuscation has been added and if multiple artifacts are being scanned. However, the chosen artifacts might be patched in the Frida binaries. Find the source code on [Berdhard Mueller's GitHub](https://github.com/b-mueller/frida-detection-demo/blob/master/AntiFrida/app/src/main/cpp/native-lib.cpp "frida-detection-demo"). | +| **Scanning Process Memory for Known Artifacts** | Scan the memory for artifacts found in Frida's libraries, e.g. the string "LIBFRIDA" present in all versions of frida-gadget and frida-agent. For example, use `Runtime.getRuntime().exec` and iterate through the memory mappings listed in `/proc/self/maps` or `/proc//maps` (depending on the Android version) searching for the string. | This method is a bit more effective, and it is difficult to bypass with Frida only, especially if some obfuscation has been added and if multiple artifacts are being scanned. However, the chosen artifacts might be patched in the Frida binaries. Find the source code on [Berdhard Mueller's GitHub](https://github.com/muellerberndt/frida-detection-demo/blob/master/AntiFrida/app/src/main/cpp/native-lib.cpp "frida-detection-demo"). | -Please remember that this table is far from exhaustive. We could start talking about [named pipes](https://en.wikipedia.org/wiki/Named_pipe "Named Pipes") (used by frida-server for external communication), detecting [trampolines](https://en.wikipedia.org/wiki/Trampoline_%28computing%29 "Trampolines") (indirect jump vectors inserted at the prologue of functions), which would _help_ detecting Substrate or Frida's Interceptor but, for example, won't be effective against Frida's Stalker; and many other, more or less, effective detection methods. Each of them will depend on whether you're using a rooted device, the specific version of the rooting method and/or the version of the tool itself. Further, the app can try to make it harder to detect the implemented protection mechanisms by using various obfuscation techniques, as discussed below in section "[Testing Resiliency Against Reverse Engineering](#testing-obfuscation-mstg-resilience-9 "Testing Resiliency Against Reverse Engineering")". At the end, this is part of the cat and mouse game of protecting data being processed on an untrusted environment (an app running in the user device). +Please remember that this table is far from exhaustive. We could start talking about [named pipes](https://en.wikipedia.org/wiki/Named_pipe "Named Pipes") (used by frida-server for external communication), detecting [trampolines](https://en.wikipedia.org/wiki/Trampoline_%28computing%29 "Trampolines") (indirect jump vectors inserted at the prologue of functions), which would help detecting Substrate or Frida's Interceptor but, for example, won't be effective against Frida's Stalker; and many other, more or less, effective detection methods. Each of them will depend on whether you're using a rooted device, the specific version of the rooting method and/or the version of the tool itself. Further, the app can try to make it harder to detect the implemented protection mechanisms by using various obfuscation techniques, as discussed below in section "[Testing Resiliency Against Reverse Engineering](#testing-obfuscation-mstg-resilience-9 "Testing Resiliency Against Reverse Engineering")". At the end, this is part of the cat and mouse game of protecting data being processed on an untrusted environment (an app running in the user device). > It is important to note that these controls are only increasing the complexity of the reverse engineering process. If used, the best approach is to combine the controls cleverly instead of using them individually. However, none of them can assure a 100% effectiveness, as the reverse engineer will always have full access to the device and will therefore always win! You also have to consider that integrating some of the controls into your app might increase the complexity of your app and even have an impact on its performance. @@ -979,13 +979,13 @@ catch(Exception e) { By using ELF binaries, native function hooks can be installed by overwriting function pointers in memory (e.g., Global Offset Table or PLT hooking) or patching parts of the function code itself (inline hooking). Checking the integrity of the respective memory regions is one way to detect this kind of hook. -The Global Offset Table (GOT) is used to resolve library functions. During runtime, the dynamic linker patches this table with the absolute addresses of global symbols. *GOT hooks* overwrite the stored function addresses and redirect legitimate function calls to adversary-controlled code. This type of hook can be detected by enumerating the process memory map and verifying that each GOT entry points to a legitimately loaded library. +The Global Offset Table (GOT) is used to resolve library functions. During runtime, the dynamic linker patches this table with the absolute addresses of global symbols. _GOT hooks_ overwrite the stored function addresses and redirect legitimate function calls to adversary-controlled code. This type of hook can be detected by enumerating the process memory map and verifying that each GOT entry points to a legitimately loaded library. In contrast to GNU `ld`, which resolves symbol addresses only after they are needed for the first time (lazy binding), the Android linker resolves all external functions and writes the respective GOT entries immediately after a library is loaded (immediate binding). You can therefore expect all GOT entries to point to valid memory locations in the code sections of their respective libraries during runtime. GOT hook detection methods usually walk the GOT and verify this. -*Inline hooks* work by overwriting a few instructions at the beginning or end of the function code. During runtime, this so-called trampoline redirects execution to the injected code. You can detect inline hooks by inspecting the prologues and epilogues of library functions for suspect instructions, such as far jumps to locations outside the library. +_Inline hooks_ work by overwriting a few instructions at the beginning or end of the function code. During runtime, this so-called trampoline redirects execution to the injected code. You can detect inline hooks by inspecting the prologues and epilogues of library functions for suspect instructions, such as far jumps to locations outside the library. -### Bypass and Effectiveness Assessment +### Effectiveness Assessment Make sure that all file-based detection of reverse engineering tools is disabled. Then, inject code by using Xposed, Frida, and Substrate, and attempt to install native hooks and Java method hooks. The app should detect the "hostile" code in its memory and respond accordingly. diff --git a/Document/0x06a-Platform-Overview.md b/Document/0x06a-Platform-Overview.md index 03becbcdbe..b62d62d963 100644 --- a/Document/0x06a-Platform-Overview.md +++ b/Document/0x06a-Platform-Overview.md @@ -84,7 +84,7 @@ When data protection is enabled, by simply establishing a passcode in the mobile The [appsandbox](https://developer.apple.com/library/content/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html "File System Basics") is an iOS access control technology. It is enforced at the kernel level. Its purpose is limiting system and user data damage that may occur when an app is compromised. -Sandboxing has been a core security feature since the first release of iOS. All third-party apps run under the same user (`mobile`), and only a few system applications and services run as `root` (or other specific system users). Regular iOS apps are confined to a *container* that restricts access to the app's own files and a very limited number of system APIs. Access to all resources (such as files, network sockets, IPCs, and shared memory) are controlled by the sandbox. These restrictions work as follows [#levin]: +Sandboxing has been a core security feature since the first release of iOS. All third-party apps run under the same user (`mobile`), and only a few system applications and services run as `root` (or other specific system users). Regular iOS apps are confined to a _container_ that restricts access to the app's own files and a very limited number of system APIs. Access to all resources (such as files, network sockets, IPCs, and shared memory) are controlled by the sandbox. These restrictions work as follows [#levin]: - The app process is restricted to its own directory (under /var/mobile/Containers/ Bundle/Application/ or /var/containers/Bundle/Application/, depending on the iOS version) via a chroot-like process. - The `mmap` and `mmprotect` system calls are modified to prevent apps from making writable memory pages executable and stopping processes from executing dynamically generated code. In combination with code signing and FairPlay, this strictly limits what code can run under specific circumstances (e.g., all code in apps distributed via the App Store is approved by Apple). diff --git a/Document/0x06b-Basic-Security-Testing.md b/Document/0x06b-Basic-Security-Testing.md index e5649c209a..20f2976732 100644 --- a/Document/0x06b-Basic-Security-Testing.md +++ b/Document/0x06b-Basic-Security-Testing.md @@ -28,7 +28,7 @@ If you don't have access to a jailbroken device, you can apply the workarounds d #### Testing on the iOS Simulator -Unlike the Android emulator, which fully emulates the hardware of an actual Android device, the iOS SDK simulator offers a higher-level *simulation* of an iOS device. Most importantly, emulator binaries are compiled to x86 code instead of ARM code. Apps compiled for a real device don't run, making the simulator useless for black box analysis and reverse engineering. +Unlike the Android emulator, which fully emulates the hardware of an actual Android device, the iOS SDK simulator offers a higher-level _simulation_ of an iOS device. Most importantly, emulator binaries are compiled to x86 code instead of ARM code. Apps compiled for a real device don't run, making the simulator useless for black box analysis and reverse engineering. #### Testing on an Emulator @@ -58,7 +58,7 @@ End users often jailbreak their devices to tweak the iOS system's appearance, ad ##### Jailbreak Types -There are *tethered*, *semi-tethered*, *semi-untethered*, and *untethered* jailbreaks. +There are _tethered_, _semi-tethered_, _semi-untethered_, and _untethered_ jailbreaks. - Tethered jailbreaks don't persist through reboots, so re-applying jailbreaks requires the device to be connected (tethered) to a computer during every reboot. The device may not reboot at all if the computer is not connected. @@ -133,7 +133,7 @@ It is also possible to get the UDID via various command line tools on macOS whil - By using instruments: ```sh - $ instruments -s devices + instruments -s devices ``` ## Basic Testing Operations @@ -208,7 +208,7 @@ iPhone:~ root# While usually using an on-device shell (terminal emulator) might be very tedious compared to a remote shell, it can prove handy for debugging in case of, for example, network issues or check some configuration. For example, you can install [NewTerm 2](https://repo.chariz.io/package/ws.hbang.newterm2/ "NewTerm 2") via Cydia for this purpose (it supports iOS 6.0 to 12.1.2 at the time of this writing). -In addition, there are a few jailbreaks that explicitly disable incoming SSH *for security reasons*. In those cases, it is very convenient to have an on-device shell app, which you can use to first SSH out of the device with a reverse shell, and then connect from your host computer to it. +In addition, there are a few jailbreaks that explicitly disable incoming SSH _for security reasons_. In those cases, it is very convenient to have an on-device shell app, which you can use to first SSH out of the device with a reverse shell, and then connect from your host computer to it. Opening a reverse shell over SSH can be done by running the command `ssh -R :localhost:22 @`. @@ -221,7 +221,7 @@ ssh -R 2222:localhost:22 mstg@192.168.197.235 On your host computer run the following command and, when asked, enter the password of the `root` user of the iOS device: ```bash -$ ssh -p 2222 root@localhost +ssh -p 2222 root@localhost ``` ### Host-Device Data Transfer @@ -295,7 +295,7 @@ itms-services://?action=download-manifest&url=https://s3-ap-southeast-1.amazonaw You can use the [ITMS services asset downloader](https://www.npmjs.com/package/itms-services "ITMS services asset downloader") tool to download the IPA from an OTA distribution URL. Install it via npm: ```bash -$ npm install -g itms-services +npm install -g itms-services ``` Save the IPA file locally with the following command: @@ -469,8 +469,8 @@ On Linux and also macOS, you can alternatively use [libimobiledevice](https://ww The package for libimobiledevice will be available in your Linux package manager. On macOS you can install libimobiledevice via brew: ```bash -$ brew install libimobiledevice -$ brew install ideviceinstaller +brew install libimobiledevice +brew install ideviceinstaller ``` After the installation you have several new command line tools available, such as `ideviceinfo`, `ideviceinstaller` or `idevicedebug`. @@ -491,7 +491,7 @@ $ idevicedebug -d run OWASP.iGoat-Swift The IPA can also be directly installed on the iOS device via the command line with [ipainstaller](https://github.com/autopear/ipainstaller "IPA Installer"). After copying the file over to the device, for example via scp, you can execute ipainstaller with the IPA's filename: ```bash -$ ipainstaller App_name.ipa +ipainstaller App_name.ipa ``` #### ios-deploy @@ -499,14 +499,14 @@ $ ipainstaller App_name.ipa On macOS you can also use the [ios-deploy](0x08-Testing-Tools.md#ios-deploy) tool to install iOS apps from the command line. You'll need to unzip your IPA since ios-deploy uses the app bundles to install apps. ```bash -$ unzip Name.ipa -$ ios-deploy --bundle 'Payload/Name.app' -W -d -v +unzip Name.ipa +ios-deploy --bundle 'Payload/Name.app' -W -d -v ``` After the app is installed on the iOS device, you can simply start it by adding the `-m` flag which will directly start debugging without installing the app again. ```bash -$ ios-deploy --bundle 'Payload/Name.app' -W -d -v -m +ios-deploy --bundle 'Payload/Name.app' -W -d -v -m ``` #### Xcode @@ -636,21 +636,21 @@ The file might be formatted in XML or binary (bplist). You can convert it to XML - On macOS with `plutil`, which is a tool that comes natively with macOS 10.2 and above versions (no official online documentation is currently available): ```bash - $ plutil -convert xml1 Info.plist + plutil -convert xml1 Info.plist ``` - On Linux: ```bash - $ apt install libplist-utils - $ plistutil -i Info.plist -o Info_xml.plist + apt install libplist-utils + plistutil -i Info.plist -o Info_xml.plist ``` Here's a non-exhaustive list of some info and the corresponding keywords that you can easily search for in the `Info.plist` file by just inspecting the file or by using `grep -i Info.plist`: - App permissions Purpose Strings: `UsageDescription` (see "[iOS Platform APIs](0x06h-Testing-Platform-Interaction.md)") - Custom URL schemes: `CFBundleURLTypes` (see "[iOS Platform APIs](0x06h-Testing-Platform-Interaction.md)") -- Exported/imported *custom document types*: `UTExportedTypeDeclarations` / `UTImportedTypeDeclarations` (see "[iOS Platform APIs](0x06h-Testing-Platform-Interaction.md)") +- Exported/imported _custom document types_: `UTExportedTypeDeclarations` / `UTImportedTypeDeclarations` (see "[iOS Platform APIs](0x06h-Testing-Platform-Interaction.md)") - App Transport Security (ATS) configuration: `NSAppTransportSecurity` (see "[iOS Network APIs](0x06g-Testing-Network-Communication.md)") Please refer to the mentioned chapters to learn more about how to test each of these points. @@ -945,7 +945,7 @@ Keychain Data: WOg1DfuH ``` In newer versions of iOS (iOS 11 and up), additional steps are necessary. See the README.md for more details. -Note that this binary is signed with a self-signed certificate that has a "wildcard" entitlement. The entitlement grants access to *all* items in the Keychain. If you are paranoid or have very sensitive private data on your test device, you may want to build the tool from source and manually sign the appropriate entitlements into your build; instructions for doing this are available in the GitHub repository. +Note that this binary is signed with a self-signed certificate that has a "wildcard" entitlement. The entitlement grants access to _all_ items in the Keychain. If you are paranoid or have very sensitive private data on your test device, you may want to build the tool from source and manually sign the appropriate entitlements into your build; instructions for doing this are available in the GitHub repository. ## Setting Up a Network Testing Environment @@ -1002,7 +1002,7 @@ You should now be able to reach Burp on your iOS device. Open Safari on iOS and The last step would be to set the proxy globally on your iOS device: 1. Go to **Settings** -> **Wi-Fi** -2. Connect to *any* Wi-Fi (you can literally connect to any Wi-Fi as the traffic for port 80 and 443 will be routed through USB, as we are just using the Proxy Setting for the Wi-Fi so we can set a global Proxy) +2. Connect to _any_ Wi-Fi (you can literally connect to any Wi-Fi as the traffic for port 80 and 443 will be routed through USB, as we are just using the Proxy Setting for the Wi-Fi so we can set a global Proxy) 3. Once connected click on the small blue icon on the right side of the connect Wi-Fi 4. Configure your Proxy by selecting **Manual** 5. Type in 127.0.0.1 as **Server** diff --git a/Document/0x06c-Reverse-Engineering-and-Tampering.md b/Document/0x06c-Reverse-Engineering-and-Tampering.md index 351c320cc9..4a0b5d6dcd 100644 --- a/Document/0x06c-Reverse-Engineering-and-Tampering.md +++ b/Document/0x06c-Reverse-Engineering-and-Tampering.md @@ -91,12 +91,12 @@ iOS8-jailbreak:~ root# class-dump DVIA32 Note the plus sign, which means that this is a class method that returns a BOOL type. A minus sign would mean that this is an instance method. Refer to later sections to understand the practical difference between these. -Alternatively, you can easily decompile the application with [Hopper Disassembler](https://www.hopperapp.com/ "Hopper Disassembler"). All these steps would be executed automatically, and you'd be able to see the disassembled binary and class information. +> Some commercial disassemblers (such as [Hopper](0x08-Testing-Tools.md#hopper-commercial-tool) execute these steps automatically, and you'd be able to see the disassembled binary and class information. The following command is listing shared libraries: ```bash -$ otool -L +otool -L ``` #### Retrieving Strings @@ -261,13 +261,13 @@ To reproduce the steps listed below, download [UnCrackable iOS App Level 1](http #### Getting a Developer Provisioning Profile and Certificate -The *provisioning profile* is a plist file signed by Apple, which adds your code-signing certificate to its list of accepted certificates on one or more devices. In other words, this represents Apple explicitly allowing your app to run for certain reasons, such as debugging on selected devices (development profile). The provisioning profile also includes the *entitlements* granted to your app. The *certificate* contains the private key you'll use to sign. +The _provisioning profile_ is a plist file signed by Apple, which adds your code-signing certificate to its list of accepted certificates on one or more devices. In other words, this represents Apple explicitly allowing your app to run for certain reasons, such as debugging on selected devices (development profile). The provisioning profile also includes the _entitlements_ granted to your app. The _certificate_ contains the private key you'll use to sign. Depending on whether you're registered as an iOS developer, you can obtain a certificate and provisioning profile in one of the following ways: **With an iOS developer account:** -If you've developed and deployed iOS apps with Xcode before, you already have your own code-signing certificate installed. Use the *security* tool to list your signing identities: +If you've developed and deployed iOS apps with Xcode before, you already have your own code-signing certificate installed. Use the [`security`](0x08-Testing-Tools.md#security) command (macOS only) to list your signing identities: ```bash $ security find-identity -v @@ -275,7 +275,7 @@ $ security find-identity -v 2) 8004380F331DCA22CC1B47FB1A805890AE41C938 "iPhone Developer: Bernhard Müller (RV852WND79)" ``` -Log into the Apple Developer portal to issue a new App ID, then issue and download the profile. An App ID is a two-part string: a Team ID supplied by Apple and a bundle ID search string that you can set to an arbitrary value, such as `com.example.myapp`. Note that you can use a single App ID to re-sign multiple apps. Make sure you create a *development* profile and not a *distribution* profile so that you can debug the app. +Log into the Apple Developer portal to issue a new App ID, then issue and download the profile. An App ID is a two-part string: a Team ID supplied by Apple and a bundle ID search string that you can set to an arbitrary value, such as `com.example.myapp`. Note that you can use a single App ID to re-sign multiple apps. Make sure you create a _development_ profile and not a _distribution_ profile so that you can debug the app. In the examples below, I use my signing identity, which is associated with my company's development team. I created the App ID "sg.vp.repackaged" and the provisioning profile "AwesomeRepackaging" for these examples. I ended up with the file `AwesomeRepackaging.mobileprovision`-replace this with your own filename in the shell commands below. @@ -283,7 +283,7 @@ In the examples below, I use my signing identity, which is associated with my co Apple will issue a free development provisioning profile even if you're not a paying developer. You can obtain the profile via Xcode and your regular Apple account: simply create an empty iOS project and extract `embedded.mobileprovision` from the app container, which is in the Xcode subdirectory of your home directory: `~/Library/Developer/Xcode/DerivedData//Build/Products/Debug-iphoneos/.app/`. The [NCC blog post "iOS instrumentation without jailbreak"](https://www.nccgroup.trust/au/about-us/newsroom-and-events/blogs/2016/october/ios-instrumentation-without-jailbreak/ "iOS instrumentation without jailbreak") explains this process in great detail. -Once you've obtained the provisioning profile, you can check its contents with the *security* tool. You'll find the entitlements granted to the app in the profile, along with the allowed certificates and devices. You'll need these for code-signing, so extract them to a separate plist file as shown below. Have a look at the file contents to make sure everything is as expected. +Once you've obtained the provisioning profile, you can check its contents with the [`security`](0x08-Testing-Tools.md#security) command. You'll find the entitlements granted to the app in the profile, along with the allowed certificates and devices. You'll need these for code-signing, so extract them to a separate plist file as shown below. Have a look at the file contents to make sure everything is as expected. ```bash $ security cms -D -i AwesomeRepackaging.mobileprovision > profile.plist @@ -311,7 +311,7 @@ Note the application identifier, which is a combination of the Team ID (LRUD9L35 ### Basic Information Gathering -On iOS, collecting basic information about a running process or an application can be slightly more challenging than compared to Android. On Android (or any Linux-based OS), process information is exposed as readable text files via *procfs*. Thus, any information about a target process can be obtained on a rooted device by parsing these text files. In contrast, on iOS there is no procfs equivalent present. Also, on iOS many standard UNIX command line tools for exploring process information, for instance lsof and vmmap, are removed to reduce the firmware size. +On iOS, collecting basic information about a running process or an application can be slightly more challenging than compared to Android. On Android (or any Linux-based OS), process information is exposed as readable text files via _procfs_. Thus, any information about a target process can be obtained on a rooted device by parsing these text files. In contrast, on iOS there is no procfs equivalent present. Also, on iOS many standard UNIX command line tools for exploring process information, for instance lsof and vmmap, are removed to reduce the firmware size. In this section, we will learn how to collect process information on iOS using command line tools like lsof. Since many of these tools are not present on iOS by default, we need to install them via alternative methods. For instance, lsof can be installed using [Cydia](0x08-Testing-Tools.md#cydia) (the executable is not the latest version available, but nevertheless addresses our purpose). @@ -406,14 +406,14 @@ You'll find the debugserver executable in the `/usr/bin/` directory on the mount Apply the entitlement with codesign: ```bash -$ codesign -s - --entitlements entitlements.plist -f debugserver +codesign -s - --entitlements entitlements.plist -f debugserver ``` Copy the modified binary to any directory on the test device. The following examples use usbmuxd to forward a local port through USB. ```bash -$ iproxy 2222 22 -$ scp -P 2222 debugserver root@localhost:/tmp/ +iproxy 2222 22 +scp -P 2222 debugserver root@localhost:/tmp/ ``` Note: On iOS 12 and higher, use the following procedure to sign the debugserver binary obtained from the XCode image. @@ -463,13 +463,13 @@ Note: On iOS 12 and higher, use the following procedure to sign the debugserver 3) Type the following command to sign the debugserver binary: ```bash - $ ldid -Sentitlements.xml debugserver + ldid -Sentitlements.xml debugserver ``` 4) Verify that the debugserver binary can be executed via the following command: ```bash - $ ./debugserver + ./debugserver ``` You can now attach debugserver to any process running on the device. @@ -581,7 +581,7 @@ Next, navigate to a new website in Safari. You should see traced function calls As discussed earlier in this chapter, iOS applications can also contain native code (C/C++ code) and it can be traced using the `frida-trace` CLI as well. For example, you can trace calls to the `open` function by running the following command: ```bash -$ frida-trace -U -i "open" sg.vp.UnCrackable1 +frida-trace -U -i "open" sg.vp.UnCrackable1 ``` The overall approach and further improvisation for tracing native code using Frida is similar to the one discussed in the Android "[Tracing](0x05c-Reverse-Engineering-and-Tampering.md#tracing "Tracing")" section. @@ -744,7 +744,7 @@ Above, Angr executed an ARM64 code in an execution environment provided by one o Time to get serious! As you already know, IPA files are actually ZIP archives, so you can use any ZIP tool to unpack the archive. ```bash -$ unzip UnCrackable_Level1.ipa +unzip UnCrackable_Level1.ipa ``` #### Patching Example: Installing Frida Gadget @@ -752,7 +752,7 @@ $ unzip UnCrackable_Level1.ipa IF you want to use Frida on non-jailbroken devices you'll need to include `FridaGadget.dylib`. Download it first: ```bash -$ curl -O https://build.frida.re/frida/ios/lib/FridaGadget.dylib +curl -O https://build.frida.re/frida/ios/lib/FridaGadget.dylib ``` Copy `FridaGadget.dylib` into the app directory and use [optool](0x08-Testing-Tools.md#optool) to add a load command to the "UnCrackable Level 1" binary. @@ -784,16 +784,16 @@ Of course, tampering an app invalidates the main executable's code signature, so First, let's add our own provisioning profile to the package: ```bash -$ cp AwesomeRepackaging.mobileprovision Payload/UnCrackable\ Level\ 1.app/embedded.mobileprovision +cp AwesomeRepackaging.mobileprovision Payload/UnCrackable\ Level\ 1.app/embedded.mobileprovision ``` Next, we need to make sure that the Bundle ID in `Info.plist` matches the one specified in the profile because the codesign tool will read the Bundle ID from `Info.plist` during signing; the wrong value will lead to an invalid signature. ```bash -$ /usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier sg.vantagepoint.repackage" Payload/UnCrackable\ Level\ 1.app/Info.plist +/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier sg.vantagepoint.repackage" Payload/UnCrackable\ Level\ 1.app/Info.plist ``` -Finally, we use the codesign tool to re-sign both binaries. You need to use *your* signing identity (in this example 8004380F331DCA22CC1B47FB1A805890AE41C938), which you can output by executing the command `security find-identity -v`. +Finally, we use the codesign tool to re-sign both binaries. You need to use _your own_ signing identity (in this example 8004380F331DCA22CC1B47FB1A805890AE41C938), which you can output by executing the command `security find-identity -v`. ```bash $ rm -rf Payload/UnCrackable\ Level\ 1.app/_CodeSignature @@ -811,7 +811,7 @@ Payload/UnCrackable Level 1.app/UnCrackable Level 1: replacing existing signatur Now you should be ready to run the modified app. Deploy and run the app on the device using [ios-deploy](0x08-Testing-Tools.md#ios-deploy): ```bash -$ ios-deploy --debug --bundle Payload/UnCrackable\ Level\ 1.app/ +ios-deploy --debug --bundle Payload/UnCrackable\ Level\ 1.app/ ``` If everything went well, the app should start in debugging mode with LLDB attached. Frida should then be able to attach to the app as well. You can verify this via the frida-ps command: @@ -845,7 +845,7 @@ Use the following approach to patch the JavaScript file: 2. Copy the contents of the file `Payload/[APP].app/main.jsbundle` to a temporary file. 3. Use `JStillery` to beautify and de-obfuscate the contents of the temporary file. 4. Identify the code in the temporary file that should be patched and patch it. -5. Put the *patched code* on a single line and copy it into the original `Payload/[APP].app/main.jsbundle` file. +5. Put the _patched code_ on a single line and copy it into the original `Payload/[APP].app/main.jsbundle` file. 6. Close and restart the application. ### Dynamic Instrumentation @@ -1032,7 +1032,7 @@ As you can see, these tasks are rather supportive and/or passive, they'll help u In the following sections you will be using [r2frida](0x08-Testing-Tools.md#r2frida) to retrieve information straight from the app runtime. First start by opening an r2frida session to the target app (e.g. iGoat-Swift) that should be running on your iPhone (connected per USB). Use the following command: ```bash -$ r2 frida://usb//iGoat-Swift +r2 frida://usb//iGoat-Swift ``` ##### Memory Maps and Inspection diff --git a/Document/0x06d-Testing-Data-Storage.md b/Document/0x06d-Testing-Data-Storage.md index ad6248d0a1..edf3d7ef4a 100644 --- a/Document/0x06d-Testing-Data-Storage.md +++ b/Document/0x06d-Testing-Data-Storage.md @@ -8,7 +8,7 @@ As little sensitive data as possible should be saved in permanent local storage. ### Data Protection API -App developers can leverage the iOS *Data Protection* APIs to implement fine-grained access control for user data stored in flash memory. The APIs are built on top of the Secure Enclave Processor (SEP), which was introduced with the iPhone 5S. The SEP is a coprocessor that provides cryptographic operations for data protection and key management. A device-specific hardware key-the device UID (Unique ID)-is embedded in the secure enclave, ensuring the integrity of data protection even when the operating system kernel is compromised. +App developers can leverage the iOS _Data Protection_ APIs to implement fine-grained access control for user data stored in flash memory. The APIs are built on top of the Secure Enclave Processor (SEP), which was introduced with the iPhone 5S. The SEP is a coprocessor that provides cryptographic operations for data protection and key management. A device-specific hardware key-the device UID (Unique ID)-is embedded in the secure enclave, ensuring the integrity of data protection even when the operating system kernel is compromised. The data protection architecture is based on a hierarchy of keys. The UID and the user passcode key (which is derived from the user's passphrase via the PBKDF2 algorithm) sit at the top of this hierarchy. Together, they can be used to "unlock" so-called class keys, which are associated with different device states (e.g., device locked/unlocked). @@ -312,7 +312,7 @@ awk '{print $9}' | sed -n '1!p')/data/Containers/Data/Application The command above will automatically find the UUID of the latest simulator started. Now you still need to grep for your app name or a keyword in your app. This will show you the UUID of the app. ```bash -$ grep -iRn keyword . +grep -iRn keyword . ``` Then you can monitor and verify the changes in the filesystem of the app and investigate if any sensitive information is stored within the files while using the app. @@ -371,7 +371,7 @@ DocumentDirectory /var/mobile/Containers/Data/Application/264C23B8-07B5-4B5D-87 LibraryDirectory /var/mobile/Containers/Data/Application/264C23B8-07B5-4B5D-8701-C020C301C151/Library ``` -Go to Documents directory and list files there by *ls* command. +Go to the Documents directory and list all files using `ls`. ```bash ...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # ls @@ -386,7 +386,7 @@ Unknown 384 n/a True True mo Readable: True Writable: True ``` -Execute the *ios plist cat userInfo.plist* command to inspect the content of userInfo.plist file. +Execute the `ios plist cat` command to inspect the content of userInfo.plist file. ```bash ...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # ios plist cat userInfo.plist @@ -765,8 +765,8 @@ Therefore, it's not straightforward to navigate through it and you will not find Without iMazing or similar software you may need to resort to using grep to identify sensitive data. This is not the most thorough approach but you can try searching for sensitive data that you have keyed in while using the app before you made the backup. For example: the username, password, credit card data, PII or any data that is considered sensitive in the context of the app. ```bash -$ ~/Library/Application Support/MobileSync/Backup/ -$ grep -iRn "password" . +~/Library/Application Support/MobileSync/Backup/ +grep -iRn "password" . ``` As described in the Static Analysis section, any sensitive data that you're able to find should be excluded from the backup, encrypted properly by using the Keychain or not stored on the device in the first place. diff --git a/Document/0x06e-Testing-Cryptography.md b/Document/0x06e-Testing-Cryptography.md index 88631592bc..a1bbbd4c0a 100644 --- a/Document/0x06e-Testing-Cryptography.md +++ b/Document/0x06e-Testing-Cryptography.md @@ -10,29 +10,32 @@ Apple provides libraries that include implementations of most common cryptograph #### CryptoKit -Apple CryptoKit was released with iOS 13 and is built on top of Apple's native cryptographic library `corecrypto`. The Swift framework provides a strongly typed API interface, has effective memory management, conforms to equatable, and supports generics. CryptoKit contains secure algorithms for hashing, symmetric-key cryptography, and public-key cryptography. The framework can also utilize the hardware based key manager from the Secure Enclave. +Apple CryptoKit was released with iOS 13 and is built on top of Apple's native cryptographic library corecrypto. The Swift framework provides a strongly typed API interface, has effective memory management, conforms to equatable, and supports generics. CryptoKit contains secure algorithms for hashing, symmetric-key cryptography, and public-key cryptography. The framework can also utilize the hardware based key manager from the Secure Enclave. Apple CryptoKit contains the following algorithms: -*Hashes* - - MD5 (Insecure Module) - - SHA1 (Insecure Module) - - SHA-2 256-bit digest - - SHA-2 384-bit digest - - SHA-2 512-bit digest - -*Symmetric-Key* - - Message Authentication Codes (HMAC) - - Authenticated Encryption - - AES-GCM - - ChaCha20-Poly1305 - -*Public-Key* - - Key Agreement - - Curve25519 - - NIST P-256 - - NIST P-384 - - NIST P-512 +**Hashes:** + +- MD5 (Insecure Module) +- SHA1 (Insecure Module) +- SHA-2 256-bit digest +- SHA-2 384-bit digest +- SHA-2 512-bit digest + +**Symmetric-Key:** + +- Message Authentication Codes (HMAC) +- Authenticated Encryption + - AES-GCM + - ChaCha20-Poly1305 + +**Public-Key:** + +- Key Agreement + - Curve25519 + - NIST P-256 + - NIST P-384 + - NIST P-512 Examples: @@ -183,8 +186,7 @@ func testKeyDerivation() { } ``` - *Source: [https://stackoverflow.com/questions/8569555/pbkdf2-using-commoncrypto-on-ios](https://stackoverflow.com/questions/8569555/pbkdf2-using-commoncrypto-on-ios "PBKDF2 using CommonCrypto on iOS -"), tested in the test suite of the `Arcane` library* +- _Source: [https://stackoverflow.com/questions/8569555/pbkdf2-using-commoncrypto-on-ios](https://stackoverflow.com/questions/8569555/pbkdf2-using-commoncrypto-on-ios "PBKDF2 using CommonCrypto on iOS"), tested in the test suite of the `Arcane` library_ When you need to store the key, it is recommended to use the Keychain as long as the protection class chosen is not `kSecAttrAccessibleAlways`. Storing keys in any other location, such as the `NSUserDefaults`, property list files or by any other sink from Core Data or Realm, is usually less secure than using the KeyChain. Even when the sync of Core Data or Realm is protected by using `NSFileProtectionComplete` data protection class, we still recommend using the KeyChain. See the chapter "[Data Storage on iOS](0x06d-Testing-Data-Storage.md)" for more details. @@ -197,7 +199,7 @@ Next, when you have a predictable key derivation function based on identifiers w Two more notions you should never forget when it comes to cryptography: 1. Always encrypt/verify with the public key and always decrypt/sign with the private key. -2. Never reuse the key(pair) for another purpose: this might allow leaking information about the key: have a separate keypair for signing and a separate key(pair) for encryption. +2. Never reuse the key(pair) for another purpose: this might allow leaking information about the key: have a separate key pair for signing and a separate key(pair) for encryption. ### Static Analysis diff --git a/Document/0x06f-Testing-Local-Authentication.md b/Document/0x06f-Testing-Local-Authentication.md index be01dd1c6f..b4b6d69dc9 100644 --- a/Document/0x06f-Testing-Local-Authentication.md +++ b/Document/0x06f-Testing-Local-Authentication.md @@ -8,7 +8,7 @@ As stated before in chapter "[Mobile App Authentication Architectures](0x04e-Tes On iOS, a variety of methods are available for integrating local authentication into apps. The [Local Authentication framework](https://developer.apple.com/documentation/localauthentication "Local Authentication framework") provides a set of APIs for developers to extend an authentication dialog to a user. In the context of connecting to a remote service, it is possible (and recommended) to leverage the [keychain](https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/01introduction/introduction.html "Keychain Services") for implementing local authentication. -Fingerprint authentication on iOS is known as *Touch ID*. The fingerprint ID sensor is operated by the [SecureEnclave security coprocessor](https://www.blackhat.com/docs/us-16/materials/us-16-Mandt-Demystifying-The-Secure-Enclave-Processor.pdf "Demystifying the Secure Enclave Processor by Tarjei Mandt, Mathew Solnik, and David Wang") and does not expose fingerprint data to any other parts of the system. Next to Touch ID, Apple introduced *Face ID*: which allows authentication based on facial recognition. Both use similar APIs on an application level, the actual method of storing the data and retrieving the data (e.g. facial data or fingerprint related data is different). +Fingerprint authentication on iOS is known as _Touch ID_. The fingerprint ID sensor is operated by the [SecureEnclave security coprocessor](https://www.blackhat.com/docs/us-16/materials/us-16-Mandt-Demystifying-The-Secure-Enclave-Processor.pdf "Demystifying the Secure Enclave Processor by Tarjei Mandt, Mathew Solnik, and David Wang") and does not expose fingerprint data to any other parts of the system. Next to Touch ID, Apple introduced _Face ID_: which allows authentication based on facial recognition. Both use similar APIs on an application level, the actual method of storing the data and retrieving the data (e.g. facial data or fingerprint related data is different). Developers have two options for incorporating Touch ID/Face ID authentication: @@ -48,7 +48,7 @@ context.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: "Please, pas } ``` -*Touch ID authentication in Swift using the Local Authentication Framework (official code sample from Apple).* +- _Touch ID authentication in Swift using the Local Authentication Framework (official code sample from Apple)._ ### Using Keychain Services for Local Authentication @@ -60,8 +60,8 @@ In the following example we will save the string "test_strong_password" to the k #### Swift -```default -// 1. create AccessControl object that will represent authentication settings +```swift +// 1. Create the AccessControl object that will represent authentication settings var error: Unmanaged? @@ -74,7 +74,7 @@ guard let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, return } -// 2. define keychain services query. Pay attention that kSecAttrAccessControl is mutually exclusive with kSecAttrAccessible attribute +// 2. Create the keychain services query. Pay attention that kSecAttrAccessControl is mutually exclusive with kSecAttrAccessible attribute var query: [String: Any] = [:] @@ -84,7 +84,7 @@ query[kSecAttrAccount as String] = "OWASP Account" as CFString query[kSecValueData as String] = "test_strong_password".data(using: .utf8)! as CFData query[kSecAttrAccessControl as String] = accessControl -// 3. save item +// 3. Save the item let status = SecItemAdd(query as CFDictionary, nil) @@ -93,45 +93,10 @@ if status == noErr { } else { // error while saving } -``` - -#### Objective-C - -```objectivec - // 1. create AccessControl object that will represent authentication settings - CFErrorRef *err = nil; - - SecAccessControlRef sacRef = SecAccessControlCreateWithFlags(kCFAllocatorDefault, - kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, - kSecAccessControlUserPresence, - err); - - // 2. define keychain services query. Pay attention that kSecAttrAccessControl is mutually exclusive with kSecAttrAccessible attribute - NSDictionary* query = @{ - (_ _bridge id)kSecClass: (__bridge id)kSecClassGenericPassword, - (__bridge id)kSecAttrLabel: @"com.me.myapp.password", - (__bridge id)kSecAttrAccount: @"OWASP Account", - (__bridge id)kSecValueData: [@"test_strong_password" dataUsingEncoding:NSUTF8StringEncoding], - (__bridge id)kSecAttrAccessControl: (__bridge_transfer id)sacRef - }; - - // 3. save item - OSStatus status = SecItemAdd((__bridge CFDictionaryRef)query, nil); - - if (status == noErr) { - // successfully saved - } else { - // error while saving - } -``` - -Now we can request the saved item from the keychain. Keychain services will present the authentication dialog to the user and return data or nil depending on whether a suitable fingerprint was provided or not. +// 4. Now we can request the saved item from the keychain. Keychain services will present the authentication dialog to the user and return data or nil depending on whether a suitable fingerprint was provided or not. -#### Swift - -```default -// 1. define query +// 5. Create the query var query = [String: Any]() query[kSecClass as String] = kSecClassGenericPassword query[kSecReturnData as String] = kCFBooleanTrue @@ -139,7 +104,7 @@ query[kSecAttrAccount as String] = "My Name" as CFString query[kSecAttrLabel as String] = "com.me.myapp.password" as CFString query[kSecUseOperationPrompt as String] = "Please, pass authorisation to enter this area" as CFString -// 2. get item +// 6. Get the item var queryResult: AnyObject? let status = withUnsafeMutablePointer(to: &queryResult) { SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0)) @@ -151,19 +116,48 @@ if status == noErr { } else { // authorization not passed } + ``` #### Objective-C ```objectivec -// 1. define query +// 1. Create the AccessControl object that will represent authentication settings +CFErrorRef *err = nil; + +SecAccessControlRef sacRef = SecAccessControlCreateWithFlags(kCFAllocatorDefault, + kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, + kSecAccessControlUserPresence, + err); + +// 2. Create the keychain services query. Pay attention that kSecAttrAccessControl is mutually exclusive with kSecAttrAccessible attribute +NSDictionary* query = @{ + (_ _bridge id)kSecClass: (__bridge id)kSecClassGenericPassword, + (__bridge id)kSecAttrLabel: @"com.me.myapp.password", + (__bridge id)kSecAttrAccount: @"OWASP Account", + (__bridge id)kSecValueData: [@"test_strong_password" dataUsingEncoding:NSUTF8StringEncoding], + (__bridge id)kSecAttrAccessControl: (__bridge_transfer id)sacRef +}; + +// 3. Save the item +OSStatus status = SecItemAdd((__bridge CFDictionaryRef)query, nil); + +if (status == noErr) { + // successfully saved +} else { + // error while saving +} + +// 4. Now we can request the saved item from the keychain. Keychain services will present the authentication dialog to the user and return data or nil depending on whether a suitable fingerprint was provided or not. + +// 5. Create the query NSDictionary *query = @{(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword, (__bridge id)kSecReturnData: @YES, (__bridge id)kSecAttrAccount: @"My Name1", (__bridge id)kSecAttrLabel: @"com.me.myapp.password", (__bridge id)kSecUseOperationPrompt: @"Please, pass authorisation to enter this area" }; -// 2. get item +// 6. Get the item CFTypeRef queryResult = NULL; OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &queryResult); @@ -176,10 +170,10 @@ if (status == noErr){ } ``` -Usage of frameworks in an app can also be detected by analyzing the app binary's list of shared dynamic libraries. This can be done by using otool: +The usage of frameworks in an app can also be detected by analyzing the app binary's list of shared dynamic libraries. This can be done by using [otool](0x08-Testing-Tools.md#otool): ```bash -$ otool -L .app/ +otool -L .app/ ``` If `LocalAuthentication.framework` is used in an app, the output will contain both of the following lines (remember that `LocalAuthentication.framework` uses `Security.framework` under the hood): diff --git a/Document/0x06g-Testing-Network-Communication.md b/Document/0x06g-Testing-Network-Communication.md index 34713b89b9..823b52088a 100644 --- a/Document/0x06g-Testing-Network-Communication.md +++ b/Document/0x06g-Testing-Network-Communication.md @@ -284,7 +284,7 @@ If you don't have access to the source, you can try binary patching: It is also possible to bypass SSL Pinning on non-jailbroken devices by using Frida and Objection (this also works on jailbroken devices). After repackaging your application with Objection as described in "iOS Basic Security Testing", you can use the following command in Objection to disable common SSL Pinning implementations: ```bash -$ ios sslpinning disable +ios sslpinning disable ``` You can look into the [pinning.ts](https://github.com/sensepost/objection/blob/master/agent/src/ios/pinning.ts "pinning.ts") file to understand how the bypass works. diff --git a/Document/0x06h-Testing-Platform-Interaction.md b/Document/0x06h-Testing-Platform-Interaction.md index 7a8a67a7cd..fad29f815f 100644 --- a/Document/0x06h-Testing-Platform-Interaction.md +++ b/Document/0x06h-Testing-Platform-Interaction.md @@ -4,7 +4,7 @@ ### Overview -In contrast to Android, where each app runs on its own user ID, iOS makes all third-party apps run under the non-privileged `mobile` user. Each app has a unique home directory and is sandboxed, so that they cannot access protected system resources or files stored by the system or by other apps. These restrictions are implemented via sandbox policies (aka. *profiles*), which are enforced by the [Trusted BSD (MAC) Mandatory Access Control Framework](http://www.trustedbsd.org/mac.html "TrustedBSD Mandatory Access Control (MAC) Framework") via a kernel extension. iOS applies a generic sandbox profile to all third-party apps called *container*. Access to protected resources or data (some also known as [app capabilities](https://developer.apple.com/support/app-capabilities/ "Advanced App Capabilities")) is possible, but it's strictly controlled via special permissions known as *entitlements*. +In contrast to Android, where each app runs on its own user ID, iOS makes all third-party apps run under the non-privileged `mobile` user. Each app has a unique home directory and is sandboxed, so that they cannot access protected system resources or files stored by the system or by other apps. These restrictions are implemented via sandbox policies (aka. _profiles_), which are enforced by the [Trusted BSD (MAC) Mandatory Access Control Framework](http://www.trustedbsd.org/mac.html "TrustedBSD Mandatory Access Control (MAC) Framework") via a kernel extension. iOS applies a generic sandbox profile to all third-party apps called _container_. Access to protected resources or data (some also known as [app capabilities](https://developer.apple.com/support/app-capabilities/ "Advanced App Capabilities")) is possible, but it's strictly controlled via special permissions known as _entitlements_. Some permissions can be configured by the app's developers (e.g. Data Protection or Keychain Sharing) and will directly take effect after the installation. However, for others, the user will be explicitly asked the first time the app attempts to access a protected resource, [for example](https://developer.apple.com/library/archive/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/ExpectedAppBehaviors/ExpectedAppBehaviors.html#//apple_ref/doc/uid/TP40007072-CH3-SW7 "Data and resources protected by system authorization settings"): @@ -57,7 +57,7 @@ Regarding testing, you can consider `UIRequiredDeviceCapabilities` as a mere ind For example, if BLE is a core feature of the app, Apple's [Core Bluetooth Programming Guide](https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/CoreBluetoothOverview/CoreBluetoothOverview.html#//apple_ref/doc/uid/TP40013257-CH2-SW1 "Core Bluetooth Overview") explains the different things to be considered: -- The `bluetooth-le` device capability can be set in order to *restrict* non-BLE capable devices from downloading their app. +- The `bluetooth-le` device capability can be set in order to _restrict_ non-BLE capable devices from downloading their app. - App capabilities like `bluetooth-peripheral` or `bluetooth-central` (both `UIBackgroundModes`) should be added if [BLE background processing](https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/CoreBluetoothBackgroundProcessingForIOSApps/PerformingTasksWhileYourAppIsInTheBackground.html "Core Bluetooth Background Processing for iOS Apps") is required. However, this is not yet enough for the app to get access to the Bluetooth peripheral, the `NSBluetoothPeripheralUsageDescription` key has to be included in the `Info.plist` file, meaning that the user has to actively give permission. See "Purpose Strings in the Info.plist File" below for more information. @@ -116,7 +116,7 @@ Since iOS 10, these are the main areas which you need to inspect for permissions #### Purpose Strings in the Info.plist File -[*Purpose strings*](https://developer.apple.com/documentation/uikit/core_app/protecting_the_user_s_privacy/accessing_protected_resources?language=objc#3037322 "Provide a Purpose String") or *usage description strings* are custom texts that are offered to users in the system's permission request alert when requesting permission to access protected data or resources. +[_Purpose strings_](https://developer.apple.com/documentation/uikit/core_app/protecting_the_user_s_privacy/accessing_protected_resources?language=objc#3037322 "Provide a Purpose String") or_usage description strings_ are custom texts that are offered to users in the system's permission request alert when requesting permission to access protected data or resources. @@ -136,7 +136,7 @@ If only having the IPA: - Unzip the IPA. - The `Info.plist` is located in `Payload/.app/Info.plist`. - Convert it if needed (e.g. `plutil -convert xml1 Info.plist`) as explained in the chapter "iOS Basic Security Testing", section "The Info.plist File". -- Inspect all *purpose strings Info.plist keys*, usually ending with `UsageDescription`: +- Inspect all _purpose strings Info.plist keys_, usually ending with `UsageDescription`: ```xml @@ -145,7 +145,7 @@ If only having the IPA: Your location is used to provide turn-by-turn directions to your destination. ``` -For an overview of the different *purpose strings Info.plist keys* available see Table 1-2 at the [Apple App Programming Guide for iOS](https://developer.apple.com/library/archive/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/ExpectedAppBehaviors/ExpectedAppBehaviors.html#//apple_ref/doc/uid/TP40007072-CH3-SW7 "Data and resources protected by system authorization settings"). Click on the provided links to see the full description of each key in the [CocoaKeys reference](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html "Cocoa Keys"). +For an overview of the different _purpose strings Info.plist keys_ available see Table 1-2 at the [Apple App Programming Guide for iOS](https://developer.apple.com/library/archive/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/ExpectedAppBehaviors/ExpectedAppBehaviors.html#//apple_ref/doc/uid/TP40007072-CH3-SW7 "Data and resources protected by system authorization settings"). Click on the provided links to see the full description of each key in the [CocoaKeys reference](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html "Cocoa Keys"). Following these guidelines should make it relatively simple to evaluate each and every entry in the `Info.plist` file to check if the permission makes sense. @@ -192,12 +192,12 @@ Depending on the data to-be-shared it might be more appropriate to share it usin #### Embedded Provisioning Profile File -When you do not have the original source code, you should analyze the IPA and search inside for the *embedded provisioning profile* that is usually located in the root app bundle folder (`Payload/.app/`) under the name `embedded.mobileprovision`. +When you do not have the original source code, you should analyze the IPA and search inside for the _embedded provisioning profile_ that is usually located in the root app bundle folder (`Payload/.app/`) under the name `embedded.mobileprovision`. This file is not a `.plist`, it is encoded using [Cryptographic Message Syntax](https://en.wikipedia.org/wiki/Cryptographic_Message_Syntax "Cryptographic Message Syntax"). On macOS you can [inspect an embedded provisioning profile's entitlements](https://developer.apple.com/library/archive/technotes/tn2415/_index.html#//apple_ref/doc/uid/DTS40016427-CH1-PROFILESENTITLEMENTS "Inspecting a profile\'s entitlements") using the following command: ```bash -$ security cms -D -i embedded.mobileprovision +security cms -D -i embedded.mobileprovision ``` and then search for the Entitlements key region (`Entitlements`). @@ -221,7 +221,7 @@ DECIMAL HEXADECIMAL DESCRIPTION 1458814 0x16427E XML document, version: "1.0" ``` -Or you can use radare2 (`-qc` to *quietly* run one command and exit) to search all strings on the app binary (`izz`) containing "PropertyList" (`~PropertyList`): +Or you can use radare2 (`-qc` to _quietly_ run one command and exit) to search all strings on the app binary (`izz`) containing "PropertyList" (`~PropertyList`): ```bash $ r2 -qc 'izz~PropertyList' ./Telegram\ X @@ -264,7 +264,7 @@ After having checked the `.entitlements` file and the `Info.plist` file When doing a source code review, pay attention to: -- whether the *purpose strings* in the `Info.plist` file match the programmatic implementations. +- whether the _purpose strings_ in the `Info.plist` file match the programmatic implementations. - whether the registered capabilities are used in such a way that no confidential information is leaking. Users can grant or revoke authorization at any time via "Settings", therefore apps normally check the authorization status of a feature before accessing it. This can be done by using dedicated APIs available for many system frameworks that provide access to protected resources. @@ -307,7 +307,7 @@ In the following example we use Telegram to open the share dialog from a chat an First we launch Telegram and start a trace for all methods matching the string "authorizationStatus" (this is a general approach because more classes apart from `CLLocationManager` implement this method): ```bash -$ frida-trace -U "Telegram" -m "*[* *authorizationStatus*]" +frida-trace -U "Telegram" -m "*[* *authorizationStatus*]" ``` > `-U` connects to the USB device. `-m` includes an Objective-C method to the traces. You can use a [glob pattern](https://en.wikipedia.org/wiki/Glob_%28programming%29 "Glob (programming)") (e.g. with the "*" wildcard, `-m "*[* *authorizationStatus*]"` means "include any Objective-C method of any class containing 'authorizationStatus'"). Type `frida-trace -h` for more information. @@ -365,7 +365,7 @@ RET: 0x4 We see that `+[CLLocationManager authorizationStatus]` returned `0x4` ([CLAuthorizationStatus.authorizedWhenInUse](https://developer.apple.com/documentation/corelocation/clauthorizationstatus/authorizedwheninuse "CLAuthorizationStatus.authorizedWhenInUse")) and was called by `+[TGLocationUtils requestWhenInUserLocationAuthorizationWithLocationManager:]`. As we anticipated before, you might use this kind of information as an entry point when reverse engineering the app and from there get inputs (e.g. names of classes or methods) to keep feeding the dynamic analysis. -Next, there is a *visual* way to inspect the status of some app permissions when using the iPhone/iPad by opening "Settings" and scrolling down until you find the app you're interested in. When clicking on it, this will open the "ALLOW APP_NAME TO ACCESS" screen. However, not all permissions might be displayed yet. You will have to *trigger* them in order to be listed on that screen. +Next, there is a _visual_ way to inspect the status of some app permissions when using the iPhone/iPad by opening "Settings" and scrolling down until you find the app you're interested in. When clicking on it, this will open the "ALLOW APP_NAME TO ACCESS" screen. However, not all permissions might be displayed yet. You will have to trigger them in order to be listed on that screen. @@ -402,7 +402,7 @@ For example, the Telegram app supports both custom URL schemes and universal lin Both result in the same action, the user will be redirected to the specified chat in Telegram ("fridadotre" in this case). However, universal links give several key benefits that are not applicable when using custom URL schemes and are the recommended way to implement deep linking, according to the [Apple Developer Documentation](https://developer.apple.com/library/archive/documentation/General/Conceptual/AppSearch/UniversalLinks.html "Universal Links"). Specifically, universal links are: -- **Unique**: Unlike custom URL schemes, universal links can’t be claimed by other apps, because they use standard HTTP or HTTPS links to the app's website. They were introduced as a way to *prevent* URL scheme hijacking attacks (an app installed after the original app may declare the same scheme and the system might target all new requests to the last installed app). +- **Unique**: Unlike custom URL schemes, universal links can’t be claimed by other apps, because they use standard HTTP or HTTPS links to the app's website. They were introduced as a way to _prevent_ URL scheme hijacking attacks (an app installed after the original app may declare the same scheme and the system might target all new requests to the last installed app). - **Secure**: When users install the app, iOS downloads and checks a file (the Apple App Site Association or AASA) that was uploaded to the web server to make sure that the website allows the app to open URLs on its behalf. Only the legitimate owners of the URL can upload this file, so the association of their website with the app is secure. - **Flexible**: Universal links work even when the app is not installed. Tapping a link to the website would open the content in Safari, as users expect. - **Simple**: One URL works for both the website and the app. @@ -482,7 +482,7 @@ Remember that universal links verification occurs at installation time. iOS retr - The AASA file is not served over HTTPS. - The AASA is not available. -- The `appID`s do not match (this would be the case of a *malicious* app). iOS would successfully prevent any possible hijacking attacks. +- The `appID`s do not match (this would be the case of a _malicious_ app). iOS would successfully prevent any possible hijacking attacks. ##### Checking the Link Receiver Method @@ -656,7 +656,7 @@ If we long press on the second (`http://www.apple.com/today`) it shows options t If we repeat the process on the method `application:continueUserActivity: restorationHandler:` by either hooking or tracing, we will see how it gets called as soon as we open the allowed universal link. For this you can use for example `frida-trace`: ```bash -$ frida-trace -U "Apple Store" -m "*[* *restorationHandler*]" +frida-trace -U "Apple Store" -m "*[* *restorationHandler*]" ``` ##### Tracing the Link Receiver Method @@ -694,7 +694,7 @@ This section explains how to trace the link receiver method and how to extract a In order to open the links we will also use the Notes app and frida-trace with the following pattern: ```bash -$ frida-trace -U Telegram -m "*[* *restorationHandler*]" +frida-trace -U Telegram -m "*[* *restorationHandler*]" ``` Write `https://t.me/addstickers/radare` (found through a quick Internet research) and open it from the Notes app. @@ -756,7 +756,7 @@ If you want to know more about which function actually opens the URL and how the Extend the previous command in order to find out if there are any other functions involved into opening the URL. ```bash -$ frida-trace -U Telegram -m "*[* *restorationHandler*]" -i "*open*Url*" +frida-trace -U Telegram -m "*[* *restorationHandler*]" -i "*open*Url*" ``` > `-i` includes any method. You can also use a glob pattern here (e.g. `-i "*open*Url*"` means "include any function containing 'open', then 'Url' and something else") @@ -863,7 +863,7 @@ There you can observe the following: - `application:continueUserActivity:restorationHandler:` handles the URL but does not open it, it calls `TelegramUI.openExternalUrl` for that. - The URL being opened is `https://t.me/addstickers/radare`. -You can now keep going and try to trace and verify how the data is being validated. For example, if you have two apps that *communicate* via universal links you can use this to see if the sending app is leaking sensitive data by hooking these methods in the receiving app. This is especially useful when you don't have the source code as you will be able to retrieve the full URL that you wouldn't see other way as it might be the result of clicking some button or triggering some functionality. +You can now keep going and try to trace and verify how the data is being validated. For example, if you have two apps that _communicate_ via universal links you can use this to see if the sending app is leaking sensitive data by hooking these methods in the receiving app. This is especially useful when you don't have the source code as you will be able to retrieve the full URL that you wouldn't see other way as it might be the result of clicking some button or triggering some functionality. In some cases, you might find data in `userInfo` of the `NSUserActivity` object. In the previous case there was no data being transferred but it might be the case for other scenarios. To see this, be sure to hook the `userInfo` property or access it directly from the `continueUserActivity` object in your hook (e.g. by adding a line like this `log("userInfo:" + ObjC.Object(args[3]).userInfo().toString());`). @@ -904,7 +904,7 @@ This knowledge should help you when testing apps supporting Handoff. #### Overview -Starting on iOS 6 it is possible for third-party apps to share data (items) via specific mechanisms [like AirDrop, for example](https://developer.apple.com/library/archive/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Inter-AppCommunication/Inter-AppCommunication.html#//apple_ref/doc/uid/TP40007072-CH6-SW3 "Supporting AirDrop"). From a user perspective, this feature is the well-known system-wide *share activity sheet* that appears after clicking on the "Share" button. +Starting on iOS 6 it is possible for third-party apps to share data (items) via specific mechanisms [like AirDrop, for example](https://developer.apple.com/library/archive/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Inter-AppCommunication/Inter-AppCommunication.html#//apple_ref/doc/uid/TP40007072-CH6-SW3 "Supporting AirDrop"). From a user perspective, this feature is the well-known system-wide "Share Activity Sheet" that appears after clicking on the "Share" button. @@ -951,14 +951,14 @@ $ rabin2 -zq Telegram\ X.app/Telegram\ X | grep -i activityItems When receiving items, you should check: -- if the app declares *custom document types* by looking into Exported/Imported UTIs ("Info" tab of the Xcode project). The list of all system declared UTIs (Uniform Type Identifiers) can be found in the [archived Apple Developer Documentation](https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html#//apple_ref/doc/uid/TP40009259 "System-Declared Uniform Type Identifiers"). -- if the app specifies any *document types that it can open* by looking into Document Types ("Info" tab of the Xcode project). If present, they consist of name and one or more UTIs that represent the data type (e.g. "public.png" for PNG files). iOS uses this to determine if the app is eligible to open a given document (specifying Exported/Imported UTIs is not enough). -- if the app properly *verifies the received data* by looking into the implementation of [`application:openURL:options:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623112-application?language=objc "UIApplicationDelegate application:openURL:options:") (or its deprecated version [`UIApplicationDelegate application:openURL:sourceApplication:annotation:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623073-application?language=objc "UIApplicationDelegate application:openURL:sourceApplication:annotation:")) in the app delegate. +- if the app declares _custom document types_ by looking into Exported/Imported UTIs ("Info" tab of the Xcode project). The list of all system declared UTIs (Uniform Type Identifiers) can be found in the [archived Apple Developer Documentation](https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html#//apple_ref/doc/uid/TP40009259 "System-Declared Uniform Type Identifiers"). +- if the app specifies any _document types that it can open_ by looking into Document Types ("Info" tab of the Xcode project). If present, they consist of name and one or more UTIs that represent the data type (e.g. "public.png" for PNG files). iOS uses this to determine if the app is eligible to open a given document (specifying Exported/Imported UTIs is not enough). +- if the app properly _verifies the received data_ by looking into the implementation of [`application:openURL:options:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623112-application?language=objc "UIApplicationDelegate application:openURL:options:") (or its deprecated version [`UIApplicationDelegate application:openURL:sourceApplication:annotation:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623073-application?language=objc "UIApplicationDelegate application:openURL:sourceApplication:annotation:")) in the app delegate. If not having the source code you can still take a look into the `Info.plist` file and search for: -- `UTExportedTypeDeclarations`/`UTImportedTypeDeclarations` if the app declares exported/imported *custom document types*. -- `CFBundleDocumentTypes` to see if the app specifies any *document types that it can open*. +- `UTExportedTypeDeclarations`/`UTImportedTypeDeclarations` if the app declares exported/imported _custom document types_. +- `CFBundleDocumentTypes` to see if the app specifies any _document types that it can open_. A very complete explanation about the use of these keys can be found [on Stackoverflow](https://stackoverflow.com/questions/21937978/what-are-utimportedtypedeclarations-and-utexportedtypedeclarations-used-for-on-i "What are UTImportedTypeDeclarations and UTExportedTypeDeclarations used for on iOS?"). @@ -968,7 +968,7 @@ Let's see a real-world example. We will take a File Manager app and take a look objection --gadget SomeFileManager run ios plist cat Info.plist ``` -> Note that this is the same as if we would retrieve the IPA from the phone or accessed via e.g. SSH and navigated to the corresponding folder in the IPA / app sandbox. However, with objection we are just *one command away* from our goal and this can be still considered static analysis. +> Note that this is the same as if we would retrieve the IPA from the phone or accessed via e.g. SSH and navigated to the corresponding folder in the IPA / app sandbox. However, with objection we are just _one command away_ from our goal and this can be still considered static analysis. The first thing we noticed is that app does not declare any imported custom document types but we could find a couple of exported ones: @@ -1085,7 +1085,7 @@ function printRet(retval) { You can store this as a JavaScript file, e.g. `inspect_send_activity_data.js` and load it like this: ```bash -$ frida -U Telegram -l inspect_send_activity_data.js +frida -U Telegram -l inspect_send_activity_data.js ``` Now observe the output when you first share a picture: @@ -1157,9 +1157,9 @@ RET @ 0x14797c3e0: ##### Receiving Items -After performing the static analysis you would know the *document types that the app can open* and *if it declares any custom document types* and (part of) the methods involved. You can use this now to test the receiving part: +After performing the static analysis you would know the _document types that the app can open_ and _if it declares any custom document types_ and (part of) the methods involved. You can use this now to test the receiving part: -- *Share* a file with the app from another app or send it via AirDrop or e-mail. Choose the file so that it will trigger the "Open with..." dialogue (that is, there is no default app that will open the file, a PDF for example). +- _Share_ a file with the app from another app or send it via AirDrop or e-mail. Choose the file so that it will trigger the "Open with..." dialogue (that is, there is no default app that will open the file, a PDF for example). - Hook `application:openURL:options:` and any other methods that were identified in a previous static analysis. - Observe the app behavior. - In addition, you could send specific malformed files and/or use a fuzzing technique. @@ -1222,7 +1222,7 @@ A final thing worth noticing here is that this way of handling incoming files is Together with iOS 8, Apple introduced App Extensions. According to [Apple App Extension Programming Guide](https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/index.html#//apple_ref/doc/uid/TP40014214-CH20-SW1 "App Extensions Increase Your Impact"), app extensions let apps offer custom functionality and content to users while they’re interacting with other apps or the system. In order to do this, they implement specific, well scoped tasks like, for example, define what happens after the user clicks on the "Share" button and selects some app or action, provide the content for a Today widget or enable a custom keyboard. -Depending on the task, the app extension will have a particular type (and only one), the so-called *extension points*. Some notable ones are: +Depending on the task, the app extension will have a particular type (and only one), the so-called _extension points_. Some notable ones are: - Custom Keyboard: replaces the iOS system keyboard with a custom keyboard for use in all apps. - Share: post to a sharing website or share content with others. @@ -1236,7 +1236,7 @@ There are three important elements here: - Host app: is the (third-party) app that triggers the app extension of another app. - Containing app: is the app that contains the app extension bundled into it. -For example, the user selects text in the *host app*, clicks on the "Share" button and selects one "app" or action from the list. This triggers the *app extension* of the *containing app*. The app extension displays its view within the context of the host app and uses the items provided by the host app, the selected text in this case, to perform a specific task (post it on a social network, for example). See this picture from the [Apple App Extension Programming Guide](https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/ExtensionOverview.html#//apple_ref/doc/uid/TP40014214-CH2-SW13 "An app extension can communicate indirectly with its containing app") which pretty good summarizes this: +For example, the user selects text in the _host app_, clicks on the "Share" button and selects one "app" or action from the list. This triggers the _app extension_ of the _containing app_. The app extension displays its view within the context of the host app and uses the items provided by the host app, the selected text in this case, to perform a specific task (post it on a social network, for example). See this picture from the [Apple App Extension Programming Guide](https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/ExtensionOverview.html#//apple_ref/doc/uid/TP40014214-CH2-SW13 "An app extension can communicate indirectly with its containing app") which pretty good summarizes this: @@ -1423,7 +1423,7 @@ The [`UIPasteboard`](https://developer.apple.com/documentation/uikit/uipasteboar Some security considerations: - Users cannot grant or deny permission for apps to read the pasteboard. -- Since iOS 9, apps [cannot access the pasteboard while in background](https://forums.developer.apple.com/thread/13760 "UIPasteboard returning null from Today extension"), this mitigates background pasteboard monitoring. However, if the *malicious* app is brought to foreground again and the data remains in the pasteboard, it will be able to retrieve it programmatically without the knowledge nor the consent of the user. +- Since iOS 9, apps [cannot access the pasteboard while in background](https://forums.developer.apple.com/thread/13760 "UIPasteboard returning null from Today extension"), this mitigates background pasteboard monitoring. However, if the _malicious_ app is brought to foreground again and the data remains in the pasteboard, it will be able to retrieve it programmatically without the knowledge nor the consent of the user. - [Apple warns about persistent named pasteboards](https://developer.apple.com/documentation/uikit/uipasteboard?language=objc "Pasteboard Security and Privacy Changes in iOS 10") and discourages their use. Instead, shared containers should be used. - Starting in iOS 10 there is a new Handoff feature called Universal Clipboard that is enabled by default. It allows the general pasteboard contents to automatically transfer between devices. This feature can be disabled if the developer chooses to do so and it is also possible to set an expiration time and date for copied data. @@ -1461,7 +1461,7 @@ When monitoring the pasteboards, there is several details that may be dynamicall - Get the first available pasteboard item: e.g. for strings use `string` method. Or use any of the other methods for the [standard data types](https://developer.apple.com/documentation/uikit/uipasteboard?language=objc#1654275 "Getting and Setting Pasteboard Items of Standard Data Types"). - Get the number of items with `numberOfItems`. - Check for existence of standard data types with the [convenience methods](https://developer.apple.com/documentation/uikit/uipasteboard?language=objc#2107142 "Checking for Data Types on a Pasteboard"), e.g. `hasImages`, `hasStrings`, `hasURLs` (starting in iOS 10). -- Check for other data types (typically UTIs) with [`containsPasteboardTypes: inItemSet:`](https://developer.apple.com/documentation/uikit/uipasteboard/1622100-containspasteboardtypes?language=objc "UIPasteboard containsPasteboardTypes:inItemSet:"). You may inspect for more concrete data types like, for example an picture as public.png and public.tiff ([UTIs](http://web.archive.org/web/20190616231857/https://developer.apple.com/documentation/mobilecoreservices/uttype "MobileCoreServices UTType")) or for custom data such as com.mycompany.myapp.mytype. Remember that, in this case, only those apps that *declare knowledge* of the type are able to understand the data written to the pasteboard. This is the same as we have seen in the "[UIActivity Sharing](#uiactivity-sharing "UIActivity Sharing")" section. Retrieve them using [`itemSetWithPasteboardTypes:`](https://developer.apple.com/documentation/uikit/uipasteboard/1622071-itemsetwithpasteboardtypes?language=objc "UIPasteboard itemSetWithPasteboardTypes:") and setting the corresponding UTIs. +- Check for other data types (typically UTIs) with [`containsPasteboardTypes: inItemSet:`](https://developer.apple.com/documentation/uikit/uipasteboard/1622100-containspasteboardtypes?language=objc "UIPasteboard containsPasteboardTypes:inItemSet:"). You may inspect for more concrete data types like, for example an picture as public.png and public.tiff ([UTIs](http://web.archive.org/web/20190616231857/https://developer.apple.com/documentation/mobilecoreservices/uttype "MobileCoreServices UTType")) or for custom data such as com.mycompany.myapp.mytype. Remember that, in this case, only those apps that _declare knowledge_ of the type are able to understand the data written to the pasteboard. This is the same as we have seen in the "[UIActivity Sharing](#uiactivity-sharing "UIActivity Sharing")" section. Retrieve them using [`itemSetWithPasteboardTypes:`](https://developer.apple.com/documentation/uikit/uipasteboard/1622071-itemsetwithpasteboardtypes?language=objc "UIPasteboard itemSetWithPasteboardTypes:") and setting the corresponding UTIs. - Check for excluded or expiring items by hooking `setItems:options:` and inspecting its options for `UIPasteboardOptionLocalOnly` or `UIPasteboardOptionExpirationDate`. If only looking for strings you may want to use objection's command `ios pasteboard monitor`: @@ -1781,7 +1781,7 @@ If only having the compiled application (IPA) you can still try to identify whic You can do that by first verifying that the app binary contains those strings by e.g. using unix `strings` command: ```bash -$ strings | grep "someURLscheme://" +strings | grep "someURLscheme://" ``` or even better, use radare2's `iz/izz` command or rafind2, both will find strings where the unix `strings` command won't. Example from iGoat-Swift: @@ -1827,13 +1827,13 @@ Once you've identified the custom URL schemes the app has registered, there are ##### Using Safari -To quickly test one URL scheme you can open the URLs on Safari and observe how the app behaves. For example, if you write `tel://123456789` in the address bar of Safari, a pop up will appear with the *telephone number* and the options "Cancel" and "Call". If you press "Call" it will open the Phone app and directly make the call. +To quickly test one URL scheme you can open the URLs on Safari and observe how the app behaves. For example, if you write `tel://123456789` in the address bar of Safari, a pop up will appear with the _telephone number_ and the options "Cancel" and "Call". If you press "Call" it will open the Phone app and directly make the call. You may also know already about pages that trigger custom URL schemes, you can just navigate normally to those pages and Safari will automatically ask when it finds a custom URL scheme. ##### Using the Notes App -As already seen in "Triggering Universal Links", you may use the Notes app and long press the links you've written in order to test custom URL schemes. Remember to exit the editing mode in order to be able to open them. Note that you can click or long press links including custom URL schemes only if the app is installed, if not they won't be highlighted as *clickable links*. +As already seen in "Triggering Universal Links", you may use the Notes app and long press the links you've written in order to test custom URL schemes. Remember to exit the editing mode in order to be able to open them. Note that you can click or long press links including custom URL schemes only if the app is installed, if not they won't be highlighted as _clickable links_. ##### Using Frida @@ -2143,7 +2143,7 @@ true nil ``` -Nothing happens. This tells us already that this method is not being used for that as we cannot find any *app-package-looking* string like `OWASP.iGoat-Swift` or `com.apple.mobilesafari` between the hook and the text of the tweet. However, consider that we are just probing one method, the app might be using other approach for the comparison. +Nothing happens. This tells us already that this method is not being used for that as we cannot find any _app-package-looking_ string like `OWASP.iGoat-Swift` or `com.apple.mobilesafari` between the hook and the text of the tweet. However, consider that we are just probing one method, the app might be using other approach for the comparison. #### Fuzzing URL Schemes @@ -2266,10 +2266,10 @@ Enabling the [Safari Web Inspector](https://developer.apple.com/library/archive/ To activate the web inspection you have to follow these steps: -1. On the iOS device open the Settings app: Go to **Safari -> Advanced** and toggle on *Web Inspector*. -2. On the macOS device, open Safari: in the menu bar, go to **Safari -> Preferences -> Advanced** and enable *Show Develop menu in menu bar*. -3. Connect your iOS device to the macOS device and unlock it: the iOS device name should appear in the *Develop* menu. -4. (If not yet trusted) On macOS's Safari, go to the *Develop* menu, click on the iOS device name, then on "Use for Development" and enable trust. +1. On the iOS device open the Settings app: Go to **Safari -> Advanced** and toggle on _Web Inspector_. +2. On the macOS device, open Safari: in the menu bar, go to **Safari -> Preferences -> Advanced** and enable _Show Develop menu in menu bar_. +3. Connect your iOS device to the macOS device and unlock it: the iOS device name should appear in the _Develop_ menu. +4. (If not yet trusted) On macOS's Safari, go to the _Develop_ menu, click on the iOS device name, then on "Use for Development" and enable trust. To open the web inspector and debug a WebView: @@ -2458,7 +2458,7 @@ URL: file:///var/mobile/Containers/Data/Application/A654D169-1DB7-429C-9DB9-A87 We will extend this example in the following sections in order to get more information from the WebViews. We recommend to store this code to a file, e.g. webviews_inspector.js and run it like this: ```javascript -$ frida -U com.authenticationfailure.WheresMyBrowser -l webviews_inspector.js +frida -U com.authenticationfailure.WheresMyBrowser -l webviews_inspector.js ``` #### Checking if JavaScript is Enabled @@ -3015,7 +3015,7 @@ JSON itself can be stored anywhere, e.g., a (NoSQL) database or a file. You just #### Property Lists and Codable -You can persist objects to *property lists* (also called plists in previous sections). You can find two examples below of how to use it: +You can persist objects to _property lists_ (also called plists in previous sections). You can find two examples below of how to use it: ```default @@ -3031,7 +3031,7 @@ if let data = NSUserDefaults.standardUserDefaults().objectForKey("customPoint") ``` -In this first example, the `NSUserDefaults` are used, which is the primary *property list*. We can do the same with the `Codable` version: +In this first example, the `NSUserDefaults` are used, which is the primary _property list_. We can do the same with the `Codable` version: ```default struct CustomPointStruct: Codable { diff --git a/Document/0x06i-Testing-Code-Quality-and-Build-Settings.md b/Document/0x06i-Testing-Code-Quality-and-Build-Settings.md index e3593052c5..9b628a37d2 100644 --- a/Document/0x06i-Testing-Code-Quality-and-Build-Settings.md +++ b/Document/0x06i-Testing-Code-Quality-and-Build-Settings.md @@ -198,7 +198,7 @@ In case [Swift Package Manager](https://swift.org/package-manager "Swift Package First, at the root of the project, where the Package.swift file is located, type ```bash -$ swift build +swift build ``` Next, check the file Package.resolved for the actual versions used and inspect the given libraries for known vulnerabilities. @@ -206,7 +206,7 @@ Next, check the file Package.resolved for the actual versions used and inspect t You can utilize the [OWASP Dependency-Check](https://owasp.org/www-project-dependency-check/ "OWASP Dependency-Check")'s experimental [Swift Package Manager Analyzer](https://jeremylong.github.io/DependencyCheck/analyzers/swift.html "dependency-check - SWIFT Package Manager Analyzer") to identify the [Common Platform Enumeration (CPE)](https://nvd.nist.gov/products/cpe "CPE") naming scheme of all dependencies and any corresponding [Common Vulnerability and Exposure (CVE)](https://cve.mitre.org/ "CVE") entries. Scan the application's Package.swift file and generate a report of known vulnerable libraries with the following command: ```bash -$ dependency-check --enableExperimental --out . --scan Package.swift +dependency-check --enableExperimental --out . --scan Package.swift ``` ##### CocoaPods @@ -216,15 +216,15 @@ In case [CocoaPods](https://cocoapods.org "CocoaPods.org") is used for managing First, at the root of the project, where the Podfile is located, execute the following commands: ```bash -$ sudo gem install cocoapods -$ pod install +sudo gem install cocoapods +pod install ``` Next, now that the dependency tree has been built, you can create an overview of the dependencies and their versions by running the following commands: ```bash -$ sudo gem install cocoapods-dependencies -$ pod dependencies +sudo gem install cocoapods-dependencies +pod dependencies ``` The result of the steps above can now be used as input for searching different vulnerability feeds for known vulnerabilities. @@ -239,7 +239,7 @@ You can utilize the [OWASP Dependency-Check](https://owasp.org/www-project-depen to identify the [Common Platform Enumeration (CPE)](https://nvd.nist.gov/products/cpe "CPE") naming scheme of all dependencies and any corresponding [Common Vulnerability and Exposure (CVE)](https://cve.mitre.org/ "CVE") entries. Scan the application's \*.podspec and/or Podfile.lock files and generate a report of known vulnerable libraries with the following command: ```bash -$ dependency-check --enableExperimental --out . --scan Podfile.lock +dependency-check --enableExperimental --out . --scan Podfile.lock ``` ##### Carthage @@ -249,8 +249,8 @@ In case [Carthage](https://github.com/Carthage/Carthage "Carthage on GitHub") is First, at the root of the project, where the Cartfile is located, type ```bash -$ brew install carthage -$ carthage update --platform iOS +brew install carthage +carthage update --platform iOS ``` Next, check the Cartfile.resolved for actual versions used and inspect the given libraries for known vulnerabilities. @@ -284,7 +284,7 @@ In order to ensure that the copyright laws are not infringed, one can best check When the application sources are available and Swift Package Manager is used, execute the following code in the root directory of the project, where the Package.swift file is located: ```bash -$ swift build +swift build ``` The sources of each of the dependencies have now been downloaded to `/.build/checkouts/` folder in the project. Here you can find the license for each of the libraries in their respective folder. @@ -295,8 +295,8 @@ When the application sources are available and CocoaPods is used, then execute t First, at the root of the project, where the Podfile is located, type ```bash -$ sudo gem install CocoaPods -$ pod install +sudo gem install CocoaPods +pod install ``` This will create a Pods folder where all libraries are installed, each in their own folder. You can now check the licenses for each of the libraries by inspecting the license files in each of the folders. @@ -306,8 +306,8 @@ This will create a Pods folder where all libraries are installed, each in their When the application sources are available and Carthage is used, execute the following code in the root directory of the project, where the Cartfile is located: ```bash -$ brew install carthage -$ carthage update --platform iOS +brew install carthage +carthage update --platform iOS ``` The sources of each of the dependencies have now been downloaded to `Carthage/Checkouts` folder in the project. Here you can find the license for each of the libraries in their respective folder. diff --git a/Document/0x06j-Testing-Resiliency-Against-Reverse-Engineering.md b/Document/0x06j-Testing-Resiliency-Against-Reverse-Engineering.md index 8c5516647c..726c9c3b06 100644 --- a/Document/0x06j-Testing-Resiliency-Against-Reverse-Engineering.md +++ b/Document/0x06j-Testing-Resiliency-Against-Reverse-Engineering.md @@ -53,9 +53,9 @@ Check for files and directories typically associated with jailbreaks, such as: Another way to check for jailbreaking mechanisms is to try to write to a location that's outside the application's sandbox. You can do this by having the application attempt to create a file in, for example, the `/private directory`. If the file is created successfully, the device has been jailbroken. -Swift: +**Swift:** -```objectivec +```swift do { let pathToFileInRestrictedDirectory = "/private/jailbreak.txt" try "This is a test.".write(toFile: pathToFileInRestrictedDirectory, atomically: true, encoding: String.Encoding.utf8) @@ -66,7 +66,7 @@ do { } ``` -Objective-C: +**Objective-C:** ```objectivec NSError *error; @@ -86,15 +86,15 @@ if(error==nil){ You can check protocol handlers by attempting to open a Cydia URL. The [Cydia](0x08-Testing-Tools.md#cydia) app store, which practically every jailbreaking tool installs by default, installs the cydia:// protocol handler. -Swift: +**Swift:** -```objectivec +```swift if let url = URL(string: "cydia://package/com.example.package"), UIApplication.shared.canOpenURL(url) { // Device is jailbroken } ``` -Objective-C: +**Objective-C:** ```objectivec if([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"cydia://package/com.example.package"]]){ @@ -104,14 +104,14 @@ if([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"cydia:// ### Bypassing Jailbreak Detection -Once you start an application that has jailbreak detection enabled on a jailbroken device, you'll notice one of the following things: +Once you start an application that has jailbreak detection enabled on a jailbroken device, you might notice one of the following things: 1. The application closes immediately, without any notification. 2. A pop-up window indicates that the application won't run on a jailbroken device. In the first case, make sure the application is fully functional on non-jailbroken devices. The application may be crashing or it may have a bug that causes it to terminate. This may happen while you're testing a preproduction version of the application. -Let's look at bypassing jailbreak detection using the Damn Vulnerable iOS application as an example again. After loading the binary into Hopper, you need to wait until the application is fully disassembled (look at the top bar to check the status). Then look for the "jail" string in the search box. You'll see two classes: `SFAntiPiracy` and `JailbreakDetectionVC`. You may want to decompile the functions to see what they are doing and, in particular, what they return. +Let's look at bypassing jailbreak detection using the Damn Vulnerable iOS application as an example again. After loading the binary into [Hopper](0x08-Testing-Tools.md#hopper-commercial-tool) (commercial tool), you need to wait until the application is fully disassembled (look at the top bar to check the status). Then look for the "jail" string in the search box. You'll see two classes: `SFAntiPiracy` and `JailbreakDetectionVC`. You may want to decompile the functions to see what they are doing and, in particular, what they return. @@ -166,7 +166,7 @@ One feature of Frida that we will use to bypass jailbreak detection is so-called 4. Use `frida-trace` on your host computer: ```bash -$ frida-trace -U -f /Applications/DamnVulnerableIOSApp.app/DamnVulnerableIOSApp -m "-[JailbreakDetectionVC isJailbroken]" +frida-trace -U -f /Applications/DamnVulnerableIOSApp.app/DamnVulnerableIOSApp -m "-[JailbreakDetectionVC isJailbroken]" ``` This will start DamnVulnerableIOSApp, trace calls to `-[JailbreakDetectionVC isJailbroken]`, and create a JavaScript hook with the `onEnter` and `onLeave` callback functions. Now, replacing the return value via `value.replace` is trivial, as shown in the following example: @@ -198,7 +198,7 @@ Changing the return value to:0x0 Note the two calls to `-[JailbreakDetectionVC isJailbroken]`, which correspond to two physical taps on the app's GUI. -One more way to bypass Jailbreak detection mechanisms that rely on file system checks is objection. You can find the implementation of the jailbreak bypass in the [jailbreak.ts script](https://github.com/sensepost/objection/blob/master/agent/src/ios/jailbreak.ts "jailbreak.ts"). +One more way to bypass Jailbreak detection mechanisms that rely on file system checks is [objection](0x08-Testing-Tools.md#objection). You can find the implementation of the jailbreak bypass in the [jailbreak.ts script](https://github.com/sensepost/objection/blob/master/agent/src/ios/jailbreak.ts "jailbreak.ts"). See below a Python script for hooking Objective-C methods and native functions: @@ -531,7 +531,8 @@ When verifying the HMAC with CC, follow these steps: ### Effectiveness Assessment -*For the application source code integrity checks* +**Application source code integrity checks:** + Run the app on the device in an unmodified state and make sure that everything works. Then apply patches to the executable using optool, re-sign the app as described in the chapter "Basic Security Testing", and run it. The app should detect the modification and respond in some way. At the very least, the app should alert the user and/or terminate the app. Work on bypassing the defenses and answer the following questions: @@ -540,7 +541,8 @@ The app should detect the modification and respond in some way. At the very leas - Did you need to write custom code to disable the defenses? How much time did you need? - What is your assessment of the difficulty of bypassing the mechanisms? -*For the storage integrity checks* +**Storage integrity checks:** + A similar approach works. Answer the following questions: - Can the mechanisms be bypassed trivially (e.g., by changing the contents of a file or a key-value pair)? @@ -710,7 +712,7 @@ A sample Swift project is used to demonstrate the usage of SwiftShield. - Go to the directory where you downloaded SwiftShield and copy the swiftshield executable to `/usr/local/bin`: ```bash -$ cp swiftshield/swiftshield /usr/local/bin/ +cp swiftshield/swiftshield /usr/local/bin/ ``` - In your terminal go into the SwiftSecurity directory (which you checked out in step 1) and execute the command swiftshield (which you downloaded in step 3): diff --git a/Document/0x08-Testing-Tools.md b/Document/0x08-Testing-Tools.md index cc888aa582..87f947c860 100644 --- a/Document/0x08-Testing-Tools.md +++ b/Document/0x08-Testing-Tools.md @@ -19,7 +19,7 @@ Angr allows for disassembly, program instrumentation, symbolic execution, contro Since version 8, Angr is based on Python 3, and can be installed with pip on \*nix operating systems, macOS and Windows: ```bash -$ pip install angr +pip install angr ``` > Some of angr's dependencies contain forked versions of the Python modules Z3 and PyVEX, which would overwrite the original versions. If you're using those modules for anything else, you should create a dedicated virtual environment with [Virtualenv](https://docs.python.org/3/tutorial/venv.html "Virtualenv documentation"). Alternatively, you can always use the provided docker container. See the [installation guide](https://docs.angr.io/introductory-errata/install "angr Installation Guide") for more details. @@ -35,7 +35,7 @@ You can use angr from a Python REPL - such as iPython - or script your approache To install Frida locally, simply run: ```bash -$ pip install frida-tools +pip install frida-tools ``` Or refer to the [installation page](https://www.frida.re/docs/installation/ "Frida Installation") for more details. @@ -50,7 +50,7 @@ In contrast, Frida implements code injection by writing code directly into the p -- *Frida Architecture, source: [https://www.frida.re/docs/hacking/](https://www.frida.re/docs/hacking "Frida - Hacking")* +- _Frida Architecture, source: [https://www.frida.re/docs/hacking/](https://www.frida.re/docs/hacking "Frida - Hacking")_ Frida offers three modes of operation: @@ -117,21 +117,21 @@ In order to set up Frida on your Android device: We assume a rooted device here unless otherwise noted. Download the frida-server binary from the [Frida releases page](https://github.com/frida/frida/releases). Make sure that you download the right frida-server binary for the architecture of your Android device or emulator: x86, x86_64, arm or arm64. Make sure that the server version (at least the major version number) matches the version of your local Frida installation. PyPI usually installs the latest version of Frida. If you're unsure which version is installed, you can check with the Frida command line tool: ```bash -$ frida --version +frida --version ``` Or you can run the following command to automatically detect Frida version and download the right frida-server binary: ```bash -$ wget https://github.com/frida/frida/releases/download/$(frida --version)/frida-server-$(frida --version)-android-arm.xz +wget https://github.com/frida/frida/releases/download/$(frida --version)/frida-server-$(frida --version)-android-arm.xz ``` Copy frida-server to the device and run it: ```bash -$ adb push frida-server /data/local/tmp/ -$ adb shell "chmod 755 /data/local/tmp/frida-server" -$ adb shell "su -c /data/local/tmp/frida-server &" +adb push frida-server /data/local/tmp/ +adb shell "chmod 755 /data/local/tmp/frida-server" +adb shell "su -c /data/local/tmp/frida-server &" ``` ##### Using Frida on Android @@ -176,7 +176,7 @@ This will show the names and identifiers of all apps, if they are currently runn To trace specific (low-level) library calls, you can use the `frida-trace` command line tool: ```bash -$ frida-trace -U com.android.chrome -i "open" +frida-trace -U com.android.chrome -i "open" ``` This generates a little JavaScript in `__handlers__/libc.so/open.js`, which Frida injects into the process. The script traces all calls to the `open` function in `libc.so`. You can modify the generated script according to your needs with Frida [JavaScript API](https://www.frida.re/docs/javascript-api/). @@ -188,13 +188,13 @@ Unfortunately tracing high-level methods of Java classes is not yet supported (b Use the Frida CLI tool (`frida`) to work with Frida interactively. It hooks into a process and gives you a command line interface to Frida's API. ```bash -$ frida -U com.android.chrome +frida -U com.android.chrome ``` With the `-l` option, you can also use the Frida CLI to load scripts , e.g., to load `myscript.js`: ```bash -$ frida -U -l myscript.js com.android.chrome +frida -U -l myscript.js com.android.chrome ``` Frida also provides a [Java API](https://www.frida.re/docs/javascript-api/#java "Frida - Java API"), which is especially helpful for dealing with Android apps. It lets you work with Java classes and objects directly. Here is a script to overwrite the `onResume` function of an Activity class: @@ -283,7 +283,7 @@ Remember that on iOS, you can also benefit from the built-in tools provided when There's a `frida-trace` feature exclusive on iOS worth highlighting: tracing Objective-C APIs using the `-m` flag and wildcards. For example, tracing all methods including "HTTP" in their name and belonging to any class whose name starts with "NSURL" is as easy as running: ```bash -$ frida-trace -U YourApp -m "*[NSURL* *HTTP*]" +frida-trace -U YourApp -m "*[NSURL* *HTTP*]" ``` For a quick start you can go through the [iOS examples](https://www.frida.re/docs/examples/ios/ "Frida iOS examples"). @@ -405,7 +405,7 @@ In the end, it is up to you to decide where would you like to work with the data Using them is as simple as including the `--codeshare ` flag and a handler when using the Frida CLI. For example, to use "ObjC method observer", enter the following: ```bash -$ frida --codeshare mrmacete/objc-method-observer -f YOUR_BINARY +frida --codeshare mrmacete/objc-method-observer -f YOUR_BINARY ``` ### Ghidra @@ -453,8 +453,8 @@ The purpose of LIEF is to provide a cross platform library to parse, modify and [MobSF](https://github.com/MobSF/Mobile-Security-Framework-MobSF "MobSF") (Mobile Security Framework) is an automated, all-in-one mobile application pentesting framework capable of performing static and dynamic analysis. The easiest way of getting MobSF started is via Docker. ```bash -$ docker pull opensecurity/mobile-security-framework-mobsf -$ docker run -it -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest +docker pull opensecurity/mobile-security-framework-mobsf +docker run -it -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest ``` Or install and start it locally on your host computer by running: @@ -532,7 +532,7 @@ Objection achieves this goal by providing you with the tools to easily inject th Objection can be installed through pip as described on [Objection's Wiki](https://github.com/sensepost/objection/wiki/Installation "Objection Wiki - Installation"). ```bash -$ pip3 install objection +pip3 install objection ``` #### Objection for Android @@ -551,7 +551,7 @@ The ability to perform advanced dynamic analysis on non-rooted devices is one of Finally, in case you do have access to a rooted device, Objection can connect directly to the running Frida server to provide all its functionality without needing to repackage the application. However, if you want to test on a non-rooted device, you will first need to include the Frida gadget in the application. The [Objection Wiki](https://github.com/sensepost/objection/wiki/Patching-Android-Applications "Patching Android Applications") describes the needed steps in detail, but after making the right preparations, you'll be able to patch an APK by calling the objection command: ```bash -$ objection patchapk --source app-release.apk +objection patchapk --source app-release.apk ``` The patched application then needs to be installed using adb, as explained in "Basic Testing Operations - Installing Apps". @@ -615,13 +615,13 @@ The ability to perform advanced dynamic analysis on non-jailbroken devices is on Finally, in case you do have access to a jailbroken device, Objection can connect directly to the running Frida server to provide all its functionality without needing to repackage the application. However, if you want to test on a non-jailbroken device, you will first need to include the Frida gadget in the application. The [Objection Wiki](https://github.com/sensepost/objection/wiki/Patching-iOS-Applications "Patching iOS Applications") describes the needed steps in detail, but after making the right preparations, you'll be able to patch an IPA by calling the objection command: ```bash -$ objection patchipa --source my-app.ipa --codesign-signature 0C2E8200Dxxxx +objection patchipa --source my-app.ipa --codesign-signature 0C2E8200Dxxxx ``` Finally, the application needs to be sideloaded and run with debugging communication enabled. Detailed steps can be found on the [Objection Wiki](https://github.com/sensepost/objection/wiki/Running-Patched-iOS-Applications "Running Patched iOS Applications"), but for macOS users it can easily be done by using ios-deploy: ```bash -$ ios-deploy --bundle Payload/my-app.app -W -d +ios-deploy --bundle Payload/my-app.app -W -d ``` ##### Using Objection on iOS @@ -676,7 +676,7 @@ Please refer to [r2frida's official installation instructions](https://github.co With frida-server running, you should now be able to attach to it using the pid, spawn path, host and port, or device-id. For example, to attach to PID 1234: ```bash -$ r2 frida://1234 +r2 frida://1234 ``` For more examples on how to connect to frida-server, [see the usage section in the r2frida's README page](https://github.com/nowsecure/r2frida/blob/master/README.md#usage "r2frida usage"). @@ -864,7 +864,7 @@ Usage: rabin2 [-AcdeEghHiIjlLMqrRsSUvVxzZ] [-@ at] [-a arch] [-b bits] [-B addr] Use the main `r2` utility to access the **r2 shell**. You can load DEX binaries just like any other binary: ```bash -$ r2 classes.dex +r2 classes.dex ``` Enter `r2 -h` to see all available options. A very commonly used flag is `-A`, which triggers an analysis after loading the target binary. However, this should be used sparingly and with small binaries as it is very time and resource consuming. You can learn more about this in the chapter "[Tampering and Reverse Engineering on Android](0x05c-Reverse-Engineering-and-Tampering.md)". @@ -1032,7 +1032,7 @@ emulator-5554 device product:sdk_google_phone_x86 model:Android_SDK_built_for adb provides other useful commands such as `adb shell` to start an interactive shell on a target and `adb forward` to forward traffic on a specific host port to a different port on a connect device. ```bash -$ adb forward tcp: tcp: +adb forward tcp: tcp: ``` ```bash @@ -1067,13 +1067,13 @@ One possibility for setting up the build system is exporting the compiler path a To set up a standalone toolchain, download the [latest stable version of the NDK](https://developer.android.com/ndk/downloads/index.html#stable-downloads "Android NDK Downloads"). Extract the ZIP file, change into the NDK root directory, and run the following command: ```bash -$ ./build/tools/make_standalone_toolchain.py --arch arm --api 24 --install-dir /tmp/android-7-toolchain +./build/tools/make_standalone_toolchain.py --arch arm --api 24 --install-dir /tmp/android-7-toolchain ``` This creates a standalone toolchain for Android 7.0 (API level 24) in the directory `/tmp/android-7-toolchain`. For convenience, you can export an environment variable that points to your toolchain directory, (we'll be using this in the examples). Run the following command or add it to your `.bash_profile` or other startup script: ```bash -$ export TOOLCHAIN=/tmp/android-7-toolchain +export TOOLCHAIN=/tmp/android-7-toolchain ``` ### Android SDK @@ -1135,9 +1135,9 @@ You can also use apktool to repackage decoded resources back to binary APK/JAR. apkx is a Python wrapper to popular free DEX converters and Java decompilers. It automates the extraction, conversion, and decompilation of APKs. Install it as follows: ```bash -$ git clone https://github.com/b-mueller/apkx -$ cd apkx -$ sudo ./install.sh +git clone https://github.com/muellerberndt/apkx +cd apkx +sudo ./install.sh ``` This should copy apkx to `/usr/local/bin`. See section "[Decompiling Java Code](0x05c-Reverse-Engineering-and-Tampering.md#decompiling-java-code "Decompiling Java Code")" of the "Reverse Engineering and Tampering" chapter for more information about usage. @@ -1164,12 +1164,12 @@ You can refer to [drozer GitHub page](https://github.com/FSecureLABS/drozer "Dro Before you can start using drozer, you'll also need the drozer agent that runs on the Android device itself. Download the latest drozer agent [from the GitHub releases page](https://github.com/FSecureLABS/drozer/releases/ "drozer GitHub releases") and install it with `adb install drozer.apk`. -Once the setup is completed you can start a session to an emulator or a device connected per USB by running `adb forward tcp:31415 tcp:31415` and `drozer console connect`. This is called direct mode and you can see the full instructions in the [User Guide in section "Starting a Session"](https://labs.f-secure.com/assets/BlogFiles/mwri-drozer-user-guide-2015-03-23.pdf "Starting a Session"). An alternative is to run Drozer in infrastructure mode, where, you are running a drozer server that can handle multiple consoles and agents, and routes sessions between them. You can find the details of how to setup drozer in this mode in the ["Infrastructure Mode"](https://labs.f-secure.com/assets/BlogFiles/mwri-drozer-user-guide-2015-03-23.pdf "Infrastructure Mode") section of the User Guide. +Once the setup is completed you can start a session to an emulator or a device connected per USB by running `adb forward tcp:31415 tcp:31415` and `drozer console connect`. This is called direct mode and you can see the full instructions in the [User Guide in section "Starting a Session"](https://labs.withsecure.com/assets/BlogFiles/mwri-drozer-user-guide-2015-03-23.pdf "Starting a Session"). An alternative is to run Drozer in infrastructure mode, where, you are running a drozer server that can handle multiple consoles and agents, and routes sessions between them. You can find the details of how to setup drozer in this mode in the ["Infrastructure Mode"](https://labs.withsecure.com/assets/BlogFiles/mwri-drozer-user-guide-2015-03-23.pdf "Infrastructure Mode") section of the User Guide. Now you are ready to begin analyzing apps. A good first step is to enumerate the attack surface of an app which can be done easily with the following command: ```bash -$ dz> run app.package.attacksurface +dz> run app.package.attacksurface ``` Again, without drozer this would have required several steps. The module `app.package.attacksurface` lists activities, broadcast receivers, content providers and services that are exported, hence, they are public and can be accessed through other apps. Once we have identified our attack surface, we can interact with the IPC endpoints through drozer without having to write a separate standalone app as it would be required for certain tasks such as communicating with a content provider. @@ -1177,7 +1177,7 @@ Again, without drozer this would have required several steps. The module `app.pa For example, if the app has an exported Activity that leaks sensitive information we can invoke it with the Drozer module `app.activity.start`: ```bash -$ dz> run app.activity.start --component +dz> run app.activity.start --component ``` This previous command will start the activity, hopefully leaking some sensitive information. Drozer has modules for every type of IPC mechanism. Download [InsecureBankv2](https://github.com/dineshshetty/Android-InsecureBankv2 "InsecureBankv2 APK") if you would like to try the modules with an intentionally vulnerable application that illustrates common problems related to IPC endpoints. Pay close attention to the modules in the scanner category as they are very helpful automatically detecting vulnerabilities even in system packages, specially if you are using a ROM provided by your cellphone company. Even [SQL injection vulnerabilities in system packages by Google](https://issuetracker.google.com/u/0/issues/36965126 "SQL injection in Android") have been identified in the past with drozer. @@ -1219,7 +1219,7 @@ $ dz> run scanner.provider.injection -a (package name) Other resources where you might find useful information are: -- [Official drozer User Guide](https://labs.f-secure.com/assets/BlogFiles/mwri-drozer-user-guide-2015-03-23.pdf "Drozer User Guide"). +- [Official drozer User Guide](https://labs.withsecure.com/assets/BlogFiles/mwri-drozer-user-guide-2015-03-23.pdf "Drozer User Guide"). - [drozer GitHub page](https://github.com/FSecureLABS/drozer "GitHub repo") - [drozer Wiki](https://github.com/FSecureLABS/drozer/wiki "drozer Wiki") @@ -1494,8 +1494,8 @@ Besides Cydia there are several other open source tools available and should be Besides Cydia you can also ssh into your iOS device and you can install the packages directly via apt-get, like for example adv-cmds. ```bash -$ apt-get update -$ apt-get install adv-cmds +apt-get update +apt-get install adv-cmds ``` ### dsdump @@ -1573,18 +1573,18 @@ Blackbox tool to help understand what an iOS application is doing at runtime and With [ios-deploy](https://github.com/ios-control/ios-deploy "ios-deploy") you can install and debug iOS apps from the command line, without using Xcode. It can be installed via brew on macOS: ```bash -$ brew install ios-deploy +brew install ios-deploy ``` Alternatively: ```bash -$ git clone https://github.com/ios-control/ios-deploy.git -$ cd ios-deploy/ -$ xcodebuild -$ cd build/Release -$ ./ios-deploy -$ ln -s /build/Release/ios-deploy /usr/local/bin/ios-deploy +git clone https://github.com/ios-control/ios-deploy.git +cd ios-deploy/ +xcodebuild +cd build/Release +./ios-deploy +ln -s /build/Release/ios-deploy /usr/local/bin/ios-deploy ``` The last line creates a symbolic link and makes the executable available system-wide. Reload your shell to make the new commands available: @@ -1631,11 +1631,11 @@ A debugger by Apple’s Xcode used for debugging iOS applications - /build/Release/optool /usr/local/bin/optool +git clone https://github.com/alexzielenski/optool.git +cd optool/ +git submodule update --init --recursive +xcodebuild +ln -s /build/Release/optool /usr/local/bin/optool ``` The last line creates a symbolic link and makes the executable available system-wide. Reload your shell to make the new commands available: @@ -1678,6 +1678,10 @@ With Passionfruit it's possible to explore different kinds of information concer A program that can convert .plist files between a binary version and an XML version - +### security + +[`security`](https://ss64.com/osx/security.html) is a macOS command to administer Keychains, keys, certificates and the Security framework. + ### Sileo Since iOS 11 jailbreaks are introducing [Sileo](https://cydia-app.com/sileo/ "Sileo"), which is a new jailbreak app-store for iOS devices. The jailbreak [Chimera](https://chimera.sh/ "Chimera") for iOS 12 is also relying on Sileo as a package manager. @@ -1715,7 +1719,7 @@ Xcode is an Integrated Development Environment (IDE) for macOS that contains a s After installing [Xcode](#xcode), in order to make all development tools available systemwide, it is recommended to install the Xcode Command Line Tools package. This will be handy during testing of iOS apps as some of the tools (e.g. objection) are also relying on the availability of this package. You can [download it from the official Apple website](https://developer.apple.com/download/more/ "Apple iOS SDK") or install it straight away from your terminal: ```bash -$ xcode-select --install +xcode-select --install ``` ### xcrun @@ -1737,14 +1741,14 @@ A powerful framework which aims to offer to security researchers and reverse eng bettercap is available for all major Linux and Unix operating systems and should be part of their respective package installation mechanisms. You need to install it on your host computer that will act as the MITM. On macOS it can be installed by using brew. ```bash -$ brew install bettercap +brew install bettercap ``` For Kali Linux you can install bettercap with `apt-get`: ```bash -$ apt-get update -$ apt-get install bettercap +apt-get update +apt-get install bettercap ``` There are installation instructions as well for Ubuntu Linux 18.04 on [LinuxHint](https://linuxhint.com/install-bettercap-on-ubuntu-18-04-and-use-the-events-stream/ "Install Bettercap on Ubuntu 18.04"). diff --git a/Document/0x09-Suggested-Reading.md b/Document/0x09-Suggested-Reading.md index 2696521d16..acda6d982f 100644 --- a/Document/0x09-Suggested-Reading.md +++ b/Document/0x09-Suggested-Reading.md @@ -4,23 +4,23 @@ ### Android -- Dominic Chell, Tyrone Erasmus, Shaun Colley, Ollie Whitehous (2015) *Mobile Application Hacker's Handbook*. Wiley. Available at: -- Joshua J. Drake, Zach Lanier, Collin Mulliner, Pau Oliva, Stephen A. Ridley, Georg Wicherski (2014) *Android Hacker's Handbook*. Wiley. Available at: -- Godfrey Nolan (2014) *Bulletproof Android*. Addison-Wesley Professional. Available at: -- Nikolay Elenkov (2014) *Android Security Internals: An In-Depth Guide to Android's Security Architecture*. No Starch Press. Available at: -- Jonathan Levin (2015) *Android Internals :: A confectioners cookbook - Volume I: The power user's view*. Technologeeks.com. Available at: +- Dominic Chell, Tyrone Erasmus, Shaun Colley, Ollie Whitehous (2015) _Mobile Application Hacker's Handbook_. Wiley. Available at: +- Joshua J. Drake, Zach Lanier, Collin Mulliner, Pau Oliva, Stephen A. Ridley, Georg Wicherski (2014) _Android Hacker's Handbook_. Wiley. Available at: +- Godfrey Nolan (2014) _Bulletproof Android_. Addison-Wesley Professional. Available at: +- Nikolay Elenkov (2014) _Android Security Internals: An In-Depth Guide to Android's Security Architecture_. No Starch Press. Available at: +- Jonathan Levin (2015) _Android Internals :: A confectioners cookbook - Volume I: The power user's view_. Technologeeks.com. Available at: ### iOS -- Charlie Miller, Dionysus Blazakis, Dino Dai Zovi, Stefan Esser, Vincenzo Iozzo, Ralf-Philipp Weinmann (2012) *iOS Hacker's Handbook*. Wiley. Available at: -- David Thiel (2016) *iOS Application Security, The Definitive Guide for Hackers and Developers*. no starch press. Available at: -- Jonathan Levin (2017), *Mac OS X and iOS Internals*, Wiley. Available at: +- Charlie Miller, Dionysus Blazakis, Dino Dai Zovi, Stefan Esser, Vincenzo Iozzo, Ralf-Philipp Weinmann (2012) _iOS Hacker's Handbook_. Wiley. Available at: +- David Thiel (2016) _iOS Application Security, The Definitive Guide for Hackers and Developers_. no starch press. Available at: +- Jonathan Levin (2017), _Mac OS X and iOS Internals_, Wiley. Available at: ## Reverse Engineering -- Bruce Dang, Alexandre Gazet, Elias Backaalany (2014) *Practical Reverse Engineering*. Wiley. Available at: -- Skakenunny, Hangcom *iOS App Reverse Engineering*. Online. Available at: -- Bernhard Mueller (2016) *Hacking Soft Tokens - Advanced Reverse Engineering on Android*. HITB GSEC Singapore. Available at: -- Dennis Yurichev (2016) *Reverse Engineering for Beginners*. Online. Available at: -- Michael Hale Ligh, Andrew Case, Jamie Levy, Aaron Walters (2014) *The Art of Memory Forensics.* Wiley. Available at: -- Jacob Baines (2016) *Programming Linux Anti-Reversing Techniques*. Leanpub. Available at: +- Bruce Dang, Alexandre Gazet, Elias Backaalany (2014) _Practical Reverse Engineering_. Wiley. Available at: +- Skakenunny, Hangcom _iOS App Reverse Engineering_. Online. Available at: +- Bernhard Mueller (2016) _Hacking Soft Tokens - Advanced Reverse Engineering on Android_. HITB GSEC Singapore. Available at: +- Dennis Yurichev (2016) _Reverse Engineering for Beginners_. Online. Available at: +- Michael Hale Ligh, Andrew Case, Jamie Levy, Aaron Walters (2014) _The Art of Memory Forensics._ Wiley. Available at: +- Jacob Baines (2016) _Programming Linux Anti-Reversing Techniques_. Leanpub. Available at: diff --git a/README.md b/README.md index e2904215f1..499d625fff 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ Before you start contributing, please check our pages ["How Can You Contribute?" ### Contribution Credit / Acknowledgments -Contributors are added to the acknowledgments section based on their contributions logged by GitHub and/or by applying to a certain role and consistently demonstrating their commitment. Acknowledgements are visible in the [official owasp.org Project Page](https://owasp.org/www-project-mobile-security-testing-guide/#div-acknowledgements), in [GitHub](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x02-Frontispiece.md#acknowledgments), [GitBook](https://mobile-security.gitbook.io/mobile-security-testing-guide/0x02-frontispiece#acknowledgments) and in the [printed versions](https://www.lulu.com/shop/sven-schleier-and-jeroen-willemsen-and-bernhard-m%C3%BCller/owasp-mobile-security-testing-guide/paperback/product-24198359.html). +Contributors are added to the acknowledgments section based on their contributions logged by GitHub and/or by applying to a certain role and consistently demonstrating their commitment. Acknowledgements are visible in the [official owasp.org Project Page](https://owasp.org/www-project-mobile-security-testing-guide/#div-acknowledgements), in [GitHub](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x02c-Acknowledgements.md), [GitBook](https://mobile-security.gitbook.io/mobile-security-testing-guide/0x02-frontispiece#acknowledgments) and in the [printed versions](https://www.lulu.com/shop/sven-schleier-and-jeroen-willemsen-and-bernhard-m%C3%BCller/owasp-mobile-security-testing-guide/paperback/product-24198359.html). Contributors are categorized as follows: diff --git a/docs/contributing/1_How_Can_You_Contribute.md b/docs/contributing/1_How_Can_You_Contribute.md index c13da1c37d..84a43d5bfe 100644 --- a/docs/contributing/1_How_Can_You_Contribute.md +++ b/docs/contributing/1_How_Can_You_Contribute.md @@ -1,6 +1,6 @@ # How Can You Contribute? -A direct contribution to the MASVS can be done in many different ways. First of all **Create a GitHub account** (a free one is enough) by following [these steps](https://help.github.com/en/articles/signing-up-for-a-new-github-account "Signing up for a new GitHub account"). +A direct contribution to the MASVS can be done in many different ways. First of all **Create a GitHub account** (a free one is enough) by following [these steps](https://docs.github.com/en/get-started/signing-up-for-github/signing-up-for-a-new-github-account "Signing up for a new GitHub account"). ## ⭐ Give us a Star diff --git a/docs/contributing/5_Style_Guide.md b/docs/contributing/5_Style_Guide.md index c4413fa265..cd19e5a4e0 100644 --- a/docs/contributing/5_Style_Guide.md +++ b/docs/contributing/5_Style_Guide.md @@ -206,7 +206,7 @@ Use markdown's in-line link format (A) `[TEXT](URL "TITLE")` or (B) `[TEXT](URL) For example: ```markdown -The [threat modeling guidelines defined by OWASP](https://www.owasp.org/index.php/Application_Threat_Modeling "OWASP Application Threat Modeling") are generally applicable to mobile apps. +The [threat modeling guidelines defined by OWASP](https://owasp.org/www-community/Threat_Modeling "OWASP Threat Modeling") are generally applicable to mobile apps. ``` When using (A), be sure to escape special characters such as apostrophe (\') or single quote (\`), as otherwise the link will be broken in Gitbook. diff --git a/docs/index.md b/docs/index.md index 25814a221f..b5022d71a1 100644 --- a/docs/index.md +++ b/docs/index.md @@ -73,8 +73,3 @@ Its features include: - Multi language

- -## Docs - -- ["Contribute to the OWASP Mobile Security Project"](contributing/1_How_Can_You_Contribute.md) -- ["Learn about the MASVS and MSTG Releases"](releasing/1_How_to_Release.md) diff --git a/docs/news.md b/docs/news.md index 1cfbc5dcb9..41e83b71e7 100644 --- a/docs/news.md +++ b/docs/news.md @@ -50,7 +50,7 @@ Thanks to the great support of our community we have now 9 different languages a - Russian - Eugen Martynov, Gall Maxim, Chelnokov Vladislav (Review), Oprya Egor (Review) and Tereshin Dmitry (Review) - Spanish - Martin Marsicano and Carlos Holguera -The MASVS and its translations are available in PDF, Mobile, ePub, docx and you can also read it via Gitbook. See here for details: +The MASVS and its translations are available in PDF, Mobile, ePub, docx and you can also read it via Gitbook. See here for details: The project team (Sven Schleier, Jeroen Willemsen and Carlos Holguera) would like to thank all the contributors, translators and those who build the improved automation around it and all their hard work and support in the last few months! New releases will be much faster thanks to our GitHub actions and Docker containers. Next to that, we are happy to add Korean and Chinese Simplified to our ever growing list of translations! We will finalize the document generation system and then apply the same build system to the Mobile Security Testing Guide (MSTG) in order to speed up the release process and release more frequently. @@ -104,7 +104,7 @@ After many changes, we decided it was time to create a new release in order to i ## April 15th, 2019: Book version, project promotion & preparation for the summit -Given that most news is already shared via OWASP Slack over the last quarter, we still see that it is good to share a summary of all of the good things outside of Slack using this news section. In this update we have a lot to share! While we started off this year with an improved version of the MASVS and MSTG, things have not been quiet: there has been a huge development in master of the MSTG and many issues have been raised and fixed. In the meantime, we have worked on an actual print of the book! While an early version is available through Hulu (no link supplied, google and buy at your own risk), we are working on making a better version of that book. In the mean time we have filed for a project promotion to Flagship! Next a lot more cool things happened: with the now official publication of [NIST Special Publication (SP) 800-163 Revision 1](https://csrc.nist.gov/news/2019/nist-publishes-sp-800-163-rev-1), the MASVS and MSTG are getting more mainstream ;-). The MASVS & MSTG are mentioned in various other upcoming programs/standards/recommendations as well, which is really a recognition of the hard work put in by the community. We are proud to be part of such a great project! Next, we are preparing to join the [Open Security Summit](https://opensecsummit.org/tracks/mobile/) again! Already three people will be on site, and at least one remote, but we would love to work with more people at the project again! Want to know more? Please get in touch via Slack and join the #project-mobile_omtg channel or follow us on [Twitter](https://twitter.com/OWASP_MSTG). +Given that most news is already shared via OWASP Slack over the last quarter, we still see that it is good to share a summary of all of the good things outside of Slack using this news section. In this update we have a lot to share! While we started off this year with an improved version of the MASVS and MSTG, things have not been quiet: there has been a huge development in master of the MSTG and many issues have been raised and fixed. In the meantime, we have worked on an actual print of the book! While an early version is available through Hulu (no link supplied, google and buy at your own risk), we are working on making a better version of that book. In the mean time we have filed for a project promotion to Flagship! Next a lot more cool things happened: with the now official publication of [NIST Special Publication (SP) 800-163 Revision 1](https://csrc.nist.gov/news/2019/nist-publishes-sp-800-163-rev-1), the MASVS and MSTG are getting more mainstream ;-). The MASVS & MSTG are mentioned in various other upcoming programs/standards/recommendations as well, which is really a recognition of the hard work put in by the community. We are proud to be part of such a great project! Next, we are preparing to join the Open Security Summit again! Already three people will be on site, and at least one remote, but we would love to work with more people at the project again! Want to know more? Please get in touch via Slack and join the #project-mobile_omtg channel or follow us on [Twitter](https://twitter.com/OWASP_MSTG). ## January 15th, 2019: Release of improved checklist @@ -146,7 +146,7 @@ The Mobile Security Testing Guide version 1.0.1 has been released using our auto ## September 1st, 2018: Mobile Security Testing Guide mentioned in NIST SP-163r1 -The Mobile Security Testing Guide is now reference in [NIST SP 800-163 Revision 1](https://csrc.nist.gov/CSRC/media/Publications/sp/800-163/rev-1/error/documents/sp800-163r1-draft.pdf) . +The Mobile Security Testing Guide is now reference in [NIST SP 800-163 Revision 1](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-163r1.pdf). ## Augustus 2nd, 2018: Mobile App Security Verification Standard Releases @@ -175,7 +175,6 @@ We are happy to announce that a limited amount of sponsorship packages will be m ## June 17th, 2017: The OWASP Mobile Security Testing Guide - Summit Preview The MSTG Summit Preview is an experimental proof-of-concept book created on the OWASP Summit 2017 in London. The goal was to improve the authoring process and book deployment pipeline, as well as to demonstrate the viability of the project. Note that the content is not final and will likely change significantly in subsequent releases. -Download the ebook [here](https://github.com/OWASP/owasp-mstg/releases/download/1.0/owasp-mstg-summit-edition.epub). ## Mobile Security Testing Workshop on the OWASP Summit 2017 @@ -216,42 +215,41 @@ The MASVS is a community effort to establish security requirements for designing ## January 28th, 2017: Mobile Crackmes and Reversing Tutorials -![Uncrackable](/assets/immages/uncrackable250.png) A key goal of the OWASP Mobile Testing Project is to build the ultimate learning resource and reference guide for mobile app reversers. As hands-on hacking is by far the best way to learn, we'd like to link most of the content to practical examples. Starting now, we'll be adding [crackmes for Android and iOS](https://github.com/OWASP/owasp-mstg/tree/master/Crackmes) to the [GitHub repo](https://github.com/OWASP/owasp-mstg) that will then be used as examples throughout the guide. The goal is to collect enough resources for demonstrating the most important tools and techniques in our guide, plus additional crackmes for practicing. For starters there are three challenges: -- [Android License Validator](https://github.com/OWASP/owasp-mstg/tree/master/OMTG-Files/02_Crackmes/01_Android/01_License_Validation) +- [Android License Validator](https://github.com/OWASP/owasp-mstg/tree/master/Crackmes/Android/License_01) - [Uncrackable App for iOS Level 1](https://github.com/OWASP/owasp-mstg/tree/master/Crackmes/iOS/Level_01/) - [Uncrackable App for iOS Level 2](https://github.com/OWASP/owasp-mstg/tree/master/Crackmes/iOS/Level_02/) -One of these three already has a [documented solution](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05b-Reverse-Engineering-and-Tampering-Android.md#symbolicexec) in the guide. Tutorials for solving the other two [still need to be added](https://github.com/OWASP/owasp-mstg/blob/master/OMTG-Files/02_Crackmes/List_of_Crackmes.md). +One of these three already has a [documented solution](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05c-Reverse-Engineering-and-Tampering.md#symbolic-execution) in the guide. Tutorials for solving the other two [still need to be added](https://github.com/OWASP/owasp-mstg/blob/master/Crackmes/README.md). ### We Need More Authors and Contributors! -Maybe you have noticed that [the reverse engineering sections in the Mobile Testing Guide are incomplete](https://rawgit.com/OWASP/owasp-mstg/master/Generated/OWASP-MSTG-Table-of-Contents.html). The reason: We're still in the starting stages and don't have a lot of authors and contributors (in fact, 99% of the reversing content was produced by one guy). We'd love to welcome *you* as a contributor of crackmes, tutorials, writeups, or simply new ideas for this project. +Maybe you have noticed that the reverse engineering sections in the Mobile Testing Guide are incomplete. The reason: We're still in the starting stages and don't have a lot of authors and contributors (in fact, 99% of the reversing content was produced by one guy). We'd love to welcome _you_ as a contributor of crackmes, tutorials, writeups, or simply new ideas for this project. #### What You Can Do The OWASP MSTG is an open project and there's a lot of flexibility - it mostly depends on your skill set and willingness to commit your time. That said, the some areas that need help are: -- Solving crackmes and contributing a tutorial to the guide (preferable a technique that's not already documented. Check the [TOC](https://rawgit.com/OWASP/owasp-mstg/master/Generated/OWASP-MSTG-Table-of-Contents.html) first). +- Solving crackmes and contributing a tutorial to the guide (preferable a technique that's not already documented). - Writing and adding new crackmes along with solutions (should also describe something not already in the guide. Cracking white-boxes, dynamic analysis using an emulator / introspection, etc. etc.). - General reversing write-ups to describe specific processes and techniques -- Help us figure out r[esiliency testing processes](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x07b-Assessing_Software_Protections.md) and [obfuscation metrics](https://github.com/b-mueller/obfuscation-metrics) +- Help us figure out resiliency testing processes and [obfuscation metrics](https://github.com/muellerberndt/obfuscation-metrics) The reversing part of the guide consists of the following chapters: -- [Tampering and Reverse Engineering - General Overview](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05-Testing-Processes-and-Techniques.md#tampering-and-reverse-engineering) -- [Tampering and Reverse Engineering on Android](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05b-Reverse-Engineering-and-Tampering-Android.md#tampering-and-reverse-engineering-on-android) -- [Tampering and Reverse Engineering on iOS](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05d-Reverse-Engineering-and-Tampering-iOS.md#tampering-and-reverse-engineering-on-ios) +- Tampering and Reverse Engineering - General Overview +- Tampering and Reverse Engineering on Android +- Tampering and Reverse Engineering on iOS #### How To Join -Read the [author's guide](https://github.com/OWASP/owasp-mstg/blob/master/authors_guide.md) first, and join the [OWASP Mobile Security Project Slack Channel](https://owasp.slack.com/messages/project-mobile_omtg/details/), where you'll find all the other project members. +Read the [Contribution Guide](https://github.com/OWASP/owasp-mstg/blob/master/CONTRIBUTING.md) first, and join the [OWASP Mobile Security Project Slack Channel](https://owasp.slack.com/messages/project-mobile_omtg/details/), where you'll find all the other project members. ## January 22nd, 2017: Mobile Testing Guide TOC Available -As of now, we'll be auto-generating a [table of contents](https://rawgit.com/OWASP/owasp-mstg/master/Generated/OWASP-MSTG-Table-of-Contents.html) out of the current MSTG master branch. This reflects the current state of the guide, and should make it easier to coordinate work between authors. A short-term goal is to finalize the structure of the guide so we get a clearer picture of what will be included in the final document. Lead authors are encouraged to complete the outline of their respective chapters. +As of now, we'll be auto-generating a table of contents out of the current MSTG master branch. This reflects the current state of the guide, and should make it easier to coordinate work between authors. A short-term goal is to finalize the structure of the guide so we get a clearer picture of what will be included in the final document. Lead authors are encouraged to complete the outline of their respective chapters. **On another note, we still need additional authors to help with all sections of the guide, including mobile operating system overviews, testing processes and techniques, and reverse engineering.** Especially iOS authors are in short supply! As usual, ping us on the Slack Channel if you want to contribute. @@ -276,12 +274,6 @@ All of this is unpaid, volunteer work. However, depending on your contribution, ### Where do I sign up? -First of all, have a look at the existing RE chapters outline: +First of all, have a look at the existing RE chapters outline. You'll probably immediately have ideas on how you can contribute. If that's the case, read the [Contribution Guide](https://github.com/OWASP/owasp-mstg/blob/master/CONTRIBUTING.md) first. -- [Generic / Introduction](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05-Testing-Processes-and-Techniques.md#tampering-and-reverse-engineering) -- [Android](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05b-Reverse-Engineering-and-Tampering-Android.md) -- [iOS](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05d-Reverse-Engineering-and-Tampering-iOS.md#tampering-and-reverse-engineering-on-ios) - -You'll probably immediately have ideas on how you can contribute. If that's the case, read the [author's guide](https://github.com/OWASP/owasp-mstg/blob/master/authors_guide.md) first. - -Then contact [Bernhard Mueller](https://github.com/b-mueller) - ideally directly on the OWASP Mobile Security Project Slack Channel, where you'll find all the other project members. You can sign up for an account here. +Then contact [Bernhard Mueller](https://github.com/muellerberndt) - ideally directly on the OWASP Mobile Security Project Slack Channel, where you'll find all the other project members. You can sign up for an account here. diff --git a/docs/talks.md b/docs/talks.md index 3c8082377c..0ecf12f624 100644 --- a/docs/talks.md +++ b/docs/talks.md @@ -17,9 +17,9 @@ Below you can find a list of upcoming and previous talks: | September 2021 | OWASP 20th Anniversary | MASVS & MSTG Refactoring | [Recording](https://youtu.be/DFkCiNE2-MY) | [Slides](https://drive.google.com/file/d/1UAloD0oGn9sVcMc5qPkjfKDtyUlH46tp/view?usp=sharing) | | September 2020 | Ekoparty Security Conference | (Spanish) OWASP Mobile Project and how to use it for white hat hacking | [Recording](https://www.youtube.com/watch?v=Son1elZ_0bw) | [Slides](https://docs.google.com/presentation/d/1DLN5osuMjTi4hpanipCglUxYkH_gvitNyJjuv6s7SRk/edit?usp=sharing) | | May 2020 | OWASP Dutch Virtual chapter meetup | MSTG Update | [Recording](https://youtu.be/cuB8TNT0rMw?t=1999) | N/A | -| February 2020 | OWASP New Zealand Day | [Building Secure Mobile Apps (you don’t have to learn it the hard way!)](https://www.owasp.org/index.php/OWASP_New_Zealand_Day_2020#tab=Conference_-_21_February) | N/A | N/A | +| February 2020 | OWASP New Zealand Day | [Building Secure Mobile Apps (you don’t have to learn it the hard way!)](https://owasp.org/www-event-2020-NewZealandDay/) | N/A | N/A | | January 2020 | iOS Conf Singapore | Building Secure iOS Apps (you don’t have to learn it the hard way!) | [Recording](https://engineers.sg/video/building-secure-ios-apps-you-don-t-have-to-learn-it-the-hard-way-ios-conf-sg-2020--3932) | [Slides](http://bit.ly/2QRrSZ2) | -| October 2019 | OWASP AppSec Day Melbourne | [Fixing Mobile AppSec](https://appsecday.io/schedule/#session-7) | [Recording](https://youtu.be/Jm_i6I5B1HM) | N/A | +| October 2019 | OWASP AppSec Day Melbourne | Fixing Mobile AppSec | [Recording](https://youtu.be/Jm_i6I5B1HM) | N/A | | September 2019 | OWASP Global AppSec Amsterdam | [Fast Forwarding mobile security with the OWASP Mobile Security Testing Guide](https://sched.co/TepC) | N/A | N/A | | September 2019 | r2con in Barcelona | radare2 and Frida in the OWASP Mobile Security Testing Guide | [Recording](https://www.youtube.com/watch?v=BXwWBoRmh_4) | [Slides](https://github.com/radareorg/r2con2019/tree/master/talks/r2_and_frida_owasp_mstg) | | Summer 2019 | Open Security summit 2019 | [Open Security summit 2019](https://drive.google.com/file/d/1IS610Y-M8kVC4bTgE2qrB2ikl_A85k-M/view?usp=sharing) | N/A | [Outcomes](https://drive.google.com/file/d/1NNK5iLXX3taRjRd6HhNzyUMomO3g8WmC/view?usp=sharing) | diff --git a/tools/README.md b/tools/README.md index 2da1a9e765..f63f946b11 100644 --- a/tools/README.md +++ b/tools/README.md @@ -6,7 +6,7 @@ This directory is for tools that are used to generate the necessary files for ou Channels: -- Gitbook: currently using @sushi2k's repository () which is synced automatically via . +- Gitbook: currently using @sushi2k's repository () which is synced automatically via . - Github actions & Github releases: We use Github actions to build and verify the documents in an automated fashion as well as build releases. - Leanpub: The book can be bought via Leanpub as PDF to support OWASP and the MSTG project financially. - Lulu: The book can be bought via Lulu as hard-copy to support OWASP and the MSTG project financially.