Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hash table vulnerability (property overwrite)?

I was playing around with hash tables in PowerShell, and I noticed some odd behavior related to accessing items. As we know, PowerShell allows at least three different ways of assigning values to hash table entries:

$hashtable["foo"] = "bar"        #1
$hashtable.Item("foo") = "bar"   #2
$hashtable.foo = "bar"           #3

Meanwhile, we use the #3 syntax to access the properties of the Hashtable object itself, such as Count, Keys, Values, etc. And if we add an item with the key that conflicts with the name of an internal property, PowerShell allows us to do so, and we effectively are no longer able to read the value of the property (except using Reflection).

I guess that in a situation where the keys come from an untrustworthy source (e.g. from external file or network), this might have an undesired impact on flow control, and could probably be exploited by a malicious user.

This snippet demonstrates the issue:

function Get-HashtableProperties($hashTable, $header)
{
    "{0} {1} {0}" -f ("-" * 10), $header

    "Count                      : {0}" -f $hashtable.Count
    "Keys.Count                 : {0}" -f $hashtable.Keys.Count
    "Values.Count               : {0}" -f $hashtable.Values.Count
    "Actual Count (Reflection)  : {0}" -f $hashtable.GetType().GetProperty("Count").GetValue($hashtable)

    "`nItems (Keys iteration):"
    $hashtable.Keys | ForEach-Object { "  [ {0} = {1} ]" -f $_, $hashtable.Item($_) }

    "`nItems (Enumerator iteration):"
    $enumerator = $hashTable.GetEnumerator()
    while ($enumerator.MoveNext())
    {
        "  [ {0} = {1} ]" -f $enumerator.Current.Key, $enumerator.Current.Value
    }
}

$fileContent = @"
    Foo = a
    Bar = b
"@

$maliciousFileContent = @"
    Foo = a
    Bar = b
    Count = 0
    Keys =
    Values =
"@

$hashtable = ConvertFrom-StringData $fileContent
$damagedHashtable = ConvertFrom-StringData $maliciousFileContent

Get-HashtableProperties $hashtable "Normal Hash Table"
Get-HashtableProperties $damagedHashtable "Damaged Hash Table"

Output:

---------- Normal Hash Table ----------
Count                      : 2
Keys.Count                 : 2
Values.Count               : 2
Actual Count (Reflection)  : 2

Items (Keys iteration):
  [ Bar = b ]
  [ Foo = a ]

Items (Enumerator iteration):
  [ Bar = b ]
  [ Foo = a ]
---------- Damaged Hash Table ----------
Count                      : 0
Keys.Count                 : 1
Values.Count               : 1
Actual Count (Reflection)  : 5

Items (Keys iteration):
  [  =  ]

Items (Enumerator iteration):
  [ Count = 0 ]
  [ Bar = b ]
  [ Foo = a ]
  [ Values =  ]
  [ Keys =  ]

Question: is there a way to protect against this issue, except manually checking every key before assignment and/or using Reflection everywhere in the code when we need to access the value of some Hashtable property?

like image 602
Yuriy Guts Avatar asked Feb 27 '13 21:02

Yuriy Guts


1 Answers

In this sort of a scenario you can access the Hashtable's count property like so:

C:\PS> $ht = @{Count = 99}
$ht.psbase.Count
1

The extended type system in PowerShell offers several different views on an object via these PS* properties. See the PowerShell team blog post for details.

like image 156
Keith Hill Avatar answered Oct 19 '22 18:10

Keith Hill