Full Trust CLR Verification issue: changing the return address order

De OWASP
Saltar a: navegación, buscar
This page has been recommended for deletion.
You can help OWASP by improving it or discussing it on its Talk page.
Please add a comment to '{{taggedDocument ... | comment=<comment> ... }}'. See
FixME

This is a similar issue to Full Trust CLR Verification issue: changing the Method Parameters order

The problem here is that the CLR doesn't check (when the verifier is disabled) if the parameters returned are correct (i.e. if the Type of the variable being allocated and the Type of methods's return parameter are the same)


Proof of Concept

using System;
using System.Text;
namespace Owasp
{
   class ClrVerification_returnParams
   {
       public static void Main()
       {
           Console.WriteLine("\n\nCLR Verification - Return Parameters\n\n");
           string strReturnedString = returnStringOrStringBuilder();
           object objReturnedString = returnStringOrStringBuilder();
           Console.WriteLine("strReturnedString: Contents = {0} | Type = {1}", strReturnedString, strReturnedString.GetType());
           Console.WriteLine("objReturnedString: Contents = {0} | Type = {1}", objReturnedString, objReturnedString.GetType());
       }
       private static string returnStringOrStringBuilder()
       {
           string strString = "This is a string";
           StringBuilder sbStringBuilder = new StringBuilder("This is a StringBuilder");
           return strString;
       }
   }
}

after csc typeSafety_returnParams.cs the execution of typeSafety_returnParams.exe returns

CLR Verification - Return Parameters
.
strReturnedString: Contents = This is a string | Type = System.String
objReturnedString: Contents = This is a string | Type = System.String

Now, manipulating the MSIL directly make the following changes (for this one I used a custom version of ILIDE which has a great GUI for editing MSIL)

From

.method private hidebysig static string 
         returnStringOrStringBuilder() cil managed
 {
   // Code size       24 (0x18)
   .maxstack  2
   .locals init (string V_0,
            class [mscorlib]System.Text.StringBuilder V_1,
            string V_2)
   IL_0000:  nop
   IL_0001:  ldstr      "This is a string"
   IL_0006:  stloc.0
   IL_0007:  ldstr      "This is a StringBuilder"
   IL_000c:  newobj     instance void [mscorlib]System.Text.StringBuilder::.ctor(string)
   IL_0011:  stloc.1
   IL_0012:  ldloc.0
    IL_0013:  stloc.2
   IL_0014:  br.s       IL_0016
   IL_0016:  ldloc.2
   IL_0017:  ret
 } // end of method ClrVerification_returnParams::returnStringOrStringBuilder


To (Changes are highlighted)

.method private hidebysig static string 
         returnStringOrStringBuilder() cil managed
 {
   // Code size       24 (0x18)
   .maxstack  2
   .locals init (string V_0,
            class [mscorlib]System.Text.StringBuilder V_1,
            string V_2)
   IL_0000:  nop
   IL_0001:  ldstr      "This is a string"
   IL_0006:  stloc.0
   IL_0007:  ldstr      "This is a StringBuilder"
   IL_000c:  newobj     instance void [mscorlib]System.Text.StringBuilder::.ctor(string)
   IL_0011:  stloc.1
   IL_0012:  ldloc.0
   IL_0013:  stloc.2
   IL_0014:  br.s       IL_0016
    IL_0016:  ldloc.1
   IL_0017:  ret
 } // end of method ClrVerification_returnParams::returnStringOrStringBuilder


and now executing typeSafety_returnParams.exe results in

CLR Verification - Return Parameters
.
strReturnedString: Contents = This is a StringBuilder | Type = System.Text.StringBuilder
objReturnedString: Contents = This is a StringBuilder | Type = System.Text.StringBuilder

which is breaking type safety since strReturnedString should be a string


Peverify Result

Microsoft (R) .NET Framework PE Verifier.  Version  2.0.50727.42
Copyright (c) Microsoft Corporation.  All rights reserved.
[IL]: Error: [F:\_Research\_typeSafety\TypeVerification - Return Parameters\typeSafety_returnParams.exe : 
Owasp.ClrVerification_returnParams::returnStringOrStringBuilder][offset 0x00000017][found ref 'System.Text.StringBuilder']
[expected  ref 'System.String'] Unexpected type on the stack.
1 Error Verifying typeSafety_returnParams.exe


Reflector Result

This one is actually interresting since Refector gets it wrong when convering the MSIL into C# (note the boxing into string (from buildee1) that doesn't exist

private static string returnStringOrStringBuilder()
{
      string text1 = "This is a string";
      StringBuilder builder1 = new StringBuilder("This is a StringBuilder");
      string text2 = text1;
      return (string) builder1;
}

The MSIL is equal to the one above

.method private hidebysig static string returnStringOrStringBuilder() cil managed
{
     .maxstack 2
     .locals init (
           [0] string text1,
           [1] [mscorlib]System.Text.StringBuilder builder1,
           [2] string text2)
     L_0000: nop 
     L_0001: ldstr "This is a string"
     L_0006: stloc.0 
     L_0007: ldstr "This is a StringBuilder"
     L_000c: newobj instance void [mscorlib]System.Text.StringBuilder::.ctor(string)
     L_0011: stloc.1 
     L_0012: ldloc.0 
     L_0013: stloc.2 
     L_0014: br.s L_0016
     L_0016: ldloc.1 
     L_0017: ret 
}


And, if you try to complile it an error will be thrown since you can't convert a StringBuilder into a String

csc typeSafety_returnParams.cs

Microsoft (R) Visual C# 2005 Compiler version 8.00.50727.42
for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727
Copyright (C) Microsoft Corporation 2001-2005. All rights reserved. 
.
typeSafety_returnParams.cs(29,20): error CS0030: Cannot convert type 'System.Text.StringBuilder' to 'string'