PDA

Bekijk Volledige Versie : ASP.NET __VIEWSTATE crypto validation prone to replay attacks



Michal Zalewski
03/05/05, 16:45
Good morning,

ASP.NET's extremely popular __VIEWSTATE functionality provides an automatic=
,=20
uniform method for storing current state of all webpage "controls" (includi=
ng=20
form fields, database views, etc), so that user-entered data automagically=
=20
persists and is populated across newly rendered HTML, and so that current=
=20
selections of displayed database records are cached and do not need to be=
=20
looked up again after every operation.

The data is by *typically* stored on client side as base64-encoded, hidden=
=20
POST form field. By default, the field is protected from tampering by being
"signed" using SHA1 with machine-specific key and - although not discussed =
by
Microsoft - presumably either target .aspx filename or other file ID parame=
ter.=20

Because information from controls such as DataGrid is by default "cached" i=
n=20
__VIEWSTATE, enabling the user to tamper with this data would allow for=20
modifying item ID and price data in ASP.NET online shops, for example. This=
=20
possibility is discussed by Microsoft and others, with the conclusion that=
=20
SHA1/MD5 signing prevents it, and hence it is safe to rely on __VIEWSTATE=
=20
cached data in that regard:

http://msdn.microsoft.com/library/en-us/dnaspp/html/viewstate.asp

Storing and then trusting database fields retrieved from user, even with
SHA1 validation, may send shivers down any infosec guy's or gal's spine,=20
but that's the way it'd seem to be done:

"DataGrid stores its contents in the view state so the page developer
doesn't need to rebind the database data to the DataGrid on each and
every page load, but only on the first one. The benefit is that the
database doesn't need to be accessed as often. "

Lacking proper documentation of __VIEWSTATE validation, and based=20
on my limited testing, I see two major problems with how the mechanism=20
is designed:

1) Injection-through-replay scenarios are still available.

"Signed" __VIEWSTATE is replayable for the system or cluster that
generated it, for that specific .aspx script:

a) The attacker may submit __VIEWSTATE acquired from one view, to a
wholly different view with a reasonably compatible layout of cached
controls.
=20
For example, if a provider of online shopping solutions hosts two
distinct shops on a shared scripting platform - one shop with pet=
=20
supplies, and one with expensive watches - and both (within their=
=20
distinct databases or tables) happen to have item ID 123 - one for=
=20
$19.99 (Acme brand cat food), another for $1999.00 (Rolex), the=20
attacker may move __VIEWSTATE from buystuff.aspx?shop=3Dcatfood to=
=20
buystuff.aspx?shop=3Dwatches, and place an order item ID 123 for=20
$19.99.

b) Since there appears to be no expiration mechanism, user may keep
__VIEWSTATE data and reuse it after availability, pricing, or other
parameters of items or settings has changed, or ability to access
certain information has been restricted, effectively obtaining
a "backdoor" of sorts.

c) The attacker may obtain __VIEWSTATE after entering dangerous or
offensive contents or view settings within his session (some of whi=
ch=20
may be not immediately visible), then redirect third parties throug=
h
a webpage with a specific __VIEWSTATE parameter to expose them to t=
hat=20
contents, or to impose these settings upon that viewer.
=20
2) When NOT signed, resource starvation due to __VIEWSTATE complexity is =
=20
possible.

The format of the base64-encoded data is often summarised as "compress=
ed=20
XML"; __VIEWSTATE uses a simplistic, hierarchical markup scheme: first=
=20
letter decides record type (triplet, pair, one of primitive types such
as strings or integers); values for that record are enclosed in <...>
that immediately follows that letter; fields of a record are separated=
by=20
';'; records can be nested with no limits.

The problem: __VIEWSTATE is sometimes used with no integrity protectio=
n
for valid reasons. If only user input fields are going to be cached,=
=20
there is no immediate problem with effects of __VIEWSTATE tampering=20
(with the possible exception of 1c), and performance benefits of avoid=
ing=20
SHA1 are noticable.

Unfortunately, because of its hierarchical structure, and parsing base=
d
on recursive function calls, it is trivial to consume excessive amount=
s
of resources by constructing a very deeply nested structure. Consider
this unix shell example:

perl -e '{print "t<" x 8000, ";;>" x 8000}' | \
mimencode | awk '{printf "%s", $0}'
=20
Inserting the output of that sequence in place of __VIEWSTATE form fie=
ld=20
value in a page then submitted to a webserver that has SHA1 integrity=
=20
checking disabled will consume excessive resources on the target machi=
ne
(in some cases, omitting the closing ";;>" sequence offers even better
effort-gain DoS ratio).

Possible mitigation method for problem #1: include secure session ID within=
=20
__VIEWSTATE data, correlate with existing session control data, or validate=
=20
and expire appropriately; or sacrifice storage and keep this data on server=
..

Mitigation method for problem #2: sacrifice CPU cycles to always validate
data; or store on server.

Cheers,
Michal Zalewski
SotW plug: http://lcamtuf.coredump.cx/silence/

Michal Zalewski
05/05/05, 23:45
> Microsoft has addressed your issues 1-a, 1-b and 1-c by adding a
> property "ViewStateUserKey" to the System.Web.UI.Page class in
> .NET Framework 1.1. The documentation for this property is here:

No, I think this statement is simply not true. The key is intended to
solve a wholly different class of problems, and has nothing to do with
replay attacks I reported.

Reported issue 1-a: same user moves __VIEWSTATE from one page to
another. Adding unique user identifier to __VIEWSTATE does not help,
because in both cases, it's precisely the same user within the same
system.

Reported issue 1-b: same user retains __VIEWSTATE and reuses it at a
later date. Again, it's precisely the same person and the same unique
ID.

Reported issue 1-c: this is the least relevant of all reported
problems, and indeed can be in some situations mitigated by binding
__VIEWSTATE data to a specific user.

/mz

Michal Zalewski
06/05/05, 17:55
I would also like to point all concerned to an excellent post about
replay attacks on __VIEWSTATE; the post is by Scott Mitchell, the guy
who authored the MSDN article I initially referred to [1]:

http://scottonwriting.net/sowblog/posts/3747.aspx

His article is aimed at developers; Scott explains the issue I
reported in a way that makes it perhaps more clear why putting user
ID, session ID, or other similar data in __VIEWSTATE is not a remedy
by itself, and why reposting __VIEWSTATE is dangerous despite target
script location checks.

[1] http://msdn.microsoft.com/library/en-us/dnaspp/html/viewstate.asp

Cheers,
/mz

Anton Ivanov
12/05/05, 20:05
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

One more example.

http://www.theregister.co.uk/2005/05/11/ms_gatekeeper_test_fiasco/

It looks like someone already used this to rig his scores in the
Microsoft Security Professional competition.

ROFL.

A.

Michal Zalewski wrote:

| I would also like to point all concerned to an excellent post about
| replay attacks on __VIEWSTATE; the post is by Scott Mitchell, the
| guy who authored the MSDN article I initially referred to [1]:
|
| http://scottonwriting.net/sowblog/posts/3747.aspx
|
| His article is aimed at developers; Scott explains the issue I
| reported in a way that makes it perhaps more clear why putting user
| ID, session ID, or other similar data in __VIEWSTATE is not a
| remedy by itself, and why reposting __VIEWSTATE is dangerous
| despite target script location checks.
|
| [1]
| http://msdn.microsoft.com/library/en-us/dnaspp/html/viewstate.asp
|
| Cheers, /mz
|


- --
La Châtelier's Law:

~ If some stress is brought to bear on a system in equilibrium,
the equilibrium is displaced in the direction which tends to undo the
effect of the stress.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFCgxKX/NpXLt3l5xURAoCRAKCST0nfsIav2YahTueJdgyl1sjfIQCgwRh m
L/0uD824ZveBMYbo9yi1ErI=
=0rM6
-----END PGP SIGNATURE-----