用过C#的朋友可能认为它是一种十分安全的语言,其实C#也可以做到经典的缓冲区溢出。
本文章将用一个实例来描述C#究竟是如何发生缓冲区溢出的!
首先建立一个C# Console工程,并开启工程的“允许不安全代码”选项
键入代码:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
-
- namespace ConsoleTest
- {
- class Program
- {
- static void Main(string[] args)
- {
- char ori = 'A';
- StackOverflow();
-
- Console.WriteLine(ori);
- Console.ReadLine();
- }
-
- static unsafe void StackOverflow()
- {
- int* p = stackalloc int[1];
- int i = sizeof(int);
-
- while (*p != (int)'A')
- {
- p += i;
- Console.ForegroundColor = ConsoleColor.Yellow;
- Console.WriteLine("Address: {0}", (int)p);
- Console.ForegroundColor = ConsoleColor.Gray;
- try
- {
- Console.WriteLine("Value: {0}", *p);
- }
- catch
- {
- Console.WriteLine("We can't reach the system area");
- break;
- }
- Console.WriteLine();
- };
- }
- }
- }
大家可以先运行一下:
程序在找到‘A’的ASCII码后跳出循环。
其实程序的原理是:
p指针指向int数组的第一个元素,指针每次增加一个int的内存空间,由于数组的大小为1,所以两次循环后就溢出并指向在其前面的内存变量。最终找到ori所在的内存地址。
下面我们尝试修改ori的值,将其从‘A’修改为‘!’,there we Go:
这样修改代码:
经过这样的修改,再次运行:
可以看到ori被彻底修改为‘!’了。如果用这种方式将函数的地址进行修改就可以达到执行远程代码的目的了。