C#不为人知的秘密-缓冲区溢出

  开场白

  各位朋友们,当你们看到网上传播关于微软windows、IE对黑客利用“缓冲区溢出”、0day漏洞攻击的新闻,是否有过自己也想试试身手,可惜无从下手的感慨?本文将完全使用C#语言,探索那些不为人知的秘密。

  1.本文讲述在C#中利用堆栈缓冲区溢出动态修改内存,达到改变应用程序执行流程的目的。

  2.如果你是高手,请指出本文的不足。

  3.为了让本文通俗易懂,代码将极尽精简。

  现在开始

  我们知道,当数组下标越界时,.NET会自动抛出StackOverflowException,这样便让我们可以安全的读写内存,那么我们有没有逾越这个自动检测的屏障,达到我们非常操作的目的呢?答案是有的,而且我们可以修改一些关键变量如if、switch的判断值,for循环变量i值,甚至方法返回值,当然理论上还可以注入代码、转移代码执行区块,前提是必须在unsafe代码里。

  方法在被调用时,系统会进行以下几项操作:将该方法入栈、参数入栈、返回地址入栈、控制代码区入栈(EIP入栈)。我们想要访问方法的栈内地址,常规的托管代码是不行的,只能使用unsafe代码,但也并不是说你非要精通C/C++语言和指针操作,本文的例子都非常简单,完全可以将指针就认为是简版C#数组。

  改变临时变量的值

  先给出一段代码,然后再详细解释原理。

代码

static  unsafe void Main(string[] args)

        {

            //在栈上申请一个只能保存一个int32的内存段

            int* p = stackalloc int[1];

for (var i = 0; i < 30; i++)

            {

                System.Threading.Thread.Sleep(200);

Console.WriteLine("{0}\n", i);

                p[i] = 0;

            }

           

            Console.ReadLine();

        }

  这是一个既简单,但是对于从没有尝试这样写过代码的开发者来说,又颇耐人寻味,C#(包括C/C++)不会去检查指针p的偏移量是否越界,那么这段代码将会顺利编译并运行,那么for循环会顺利执行30次吗?还是......

  结论是,这将是一个死循环,因为p不断的递增1偏移,并将附近的内存的值全改为0,而局部变量i是靠p最近的变量,所有当p[i]的偏移地址等于i的地址时,代码p[i]=0就等价于i=0,实际上我在测试中i=6的时候i的值就被覆盖为0了,我在代码中添加了Thread.Sleep(200)和Console.WriteLine("{0}\n", i)就是让大家能更直观的看到程序的执行过程,当然这里也可以改为p[i]=1,p[i]=2等数字

  搜索内存值并修改

  还是先给出代码

代码static  unsafe void Main(string[] args)

        {

            Console.WriteLine(Change_Result());

            Console.ReadLine();

        }

static unsafe int Change_Result()

        {

           

            int i = 0;

            //变量result,默认的返回值

            int result = 123;

            //申请一段栈内存,
大小可随意设置

            int* p = stackalloc int[1];

            //从当前栈地址开始向下
查找与函数返回值相匹配的地址,一旦匹配则修改为10000

            while (true)

            {

                if (p[++i] == 123)

                {

                    p[i] = 10000;

                    break;

                }

            };

            return result;

        }

  变量result作为方法的返回值默认为123,并且没有任何显式修改其值的代码,关键在这里

while (true)

{

if (p[++i] == 123)

{

p[i] = 10000;

break;

}

}

  这段代码找到值为123的内存地址(也就可能是变量result的地址),然后将其值修改为10000,当然,函数返回值就肯定不会再是原先的123咯

  这就是经典的StackOverFlow的两个例子,希望通俗易懂能让大家所接受,另外缓冲区溢出并不只是改变内存的值,在高手的手里,他还可以执行任意代码,因为方法执行的时候总会有一个指针指向方法即将执行的下一条指令,如果控制了这个指针,就控制了进程。

时间: 2024-08-02 09:55:30

C#不为人知的秘密-缓冲区溢出的相关文章

一起谈.NET技术,C#不为人知的秘密-缓冲区溢出

开场白 各位朋友们,当你们看到网上传播关于微软windows.IE对黑客利用"缓冲区溢出".0day漏洞攻击的新闻,是否有过自己也想试试身手,可惜无从下手的感慨?本文将完全使用C#语言,探索那些不为人知的秘密. 1.本文讲述在C#中利用堆栈缓冲区溢出动态修改内存,达到改变应用程序执行流程的目的. 2.如果你是高手,请指出本文的不足. 3.为了让本文通俗易懂,代码将极尽精简. 现在开始 我们知道,当数组下标越界时,.NET会自动抛出StackOverflowException,这样便让我

Oracle 8i TNS Listener 缓冲区溢出漏洞

Oracle 8i TNS Listener 缓冲区溢出漏洞 (Other,缺陷)     Oracle 8i 发现重大漏洞,允许攻击者执行任意代码 详细: Oracle 8i TNS (Transparent Network Substrate) Listener 负责建立和维系客户机同 ORACLE 数据库服务的远程连接.发现该 Listener 存在缓冲区溢出漏洞.攻击者成功利用此漏洞,将能在数据库服务器上执行任意代码. 更为糟糕的是,缓冲溢出发生在验证之前,这意味着激活了口令保护机制的

iPlanet Web Server 缓冲区溢出漏洞

server|web 涉及程序: iPlanet 描述: iPlanet Web Server 缓冲区溢出漏洞 详细: iPlanet Web Server 4.x存在一个缓冲区溢出漏洞.该漏洞允许恶意的用户远程执行任意代码或产生拒绝服务攻击. 通过发送一个长度大约为 198-240 字符并以.shtml 作后缀的HTTP请求,将产生缓冲区溢出. 该漏洞只有在服务器端打开'parsing' 选项时才被利用.成功地利用这个漏洞恶意的攻击者可以完全控制目标主机. 受影响的系统:Sun Solaris

缓冲区溢出还是问题吗?C++/CLI安全编码

C++/CLI是对C++的一个扩展,其对所有类型,包括标准C++类,都添加了对属性.事件.垃圾回收.及泛型的支持. Visual C++ 2005扩展了对使用C++/CLI(通用语言基础结构)开发运行于带有垃圾回收的虚拟机上的控件及应用程序的支持,而C++/CLI是对C++编程语言的一个扩展,其对所有类型,包括标准C++类,都添加了如属性.事件.垃圾回收.及泛型等特性. Visual C++ 2005支持.NET Framework通用语言运行时库(CLR),其是垃圾回收虚拟机Microsoft

缓冲区溢出攻防

很久以来,在人们心目中,"黑客"和病毒作者的身上总是笼罩着一层神秘的光环,他们被各种媒体描述成技术高手甚至技术天才,以至于有些人为了证明自己的"天才"身份而走上歧途,甚至违法犯罪.记得不久前就看到过这样一个案例:一位计算机专业研究生入侵了一家商业网站并删除了所有数据.当他在狱中接受记者的采访时,他非常自豪地说这样做只是为了证明自己和获得那种成就感. 本文讨论的缓冲区溢出攻击实际上是一项非常"古老"的技术,但它的破坏力依然不可小视--相信大家都还没

VC++中利用/GS开关防止缓冲区溢出

缓冲区溢出通常表现为一个最为常见的漏洞而存在于今天的各种软件之中,黑客可以用恶意的输入,从而更改程序的执行流程,由此入侵相应的进程.电脑.或整个域.如果进程运行于一个高度受信的账户之下,如管理员或本地系统账户,那么黑客带来的破坏将是极其严重,并有潜在广泛传播的危险.近几年来爆发的一些"知名"病毒,如红色代码.冲击波.震荡波等等,都源于C/C++代码缓冲区溢出的结果. 从程序的角度来看,缓冲区溢出只是一个再简单不过的编程错误--都是关于复制一个内存区域的内容到另一个内存区域,而目标内存区

浅谈缓冲区溢出之栈溢出&lt;上&gt;

有段时间没有用windows了,刚一开机又是系统补丁更新.匆匆瞥了一眼看到了"内核缓冲区溢出漏洞补丁"几个字眼.靠,又是内核补丁.打完这个补丁后MD的内核符号文件又得更新了.于是抱怨了几句,一旁的兄弟问什么是缓冲区溢出.这个-三两句话还真说不清楚.解释这个问题用C语言比较方便,但是单从C代码是看不出来什么的,具体原理要分析机器级代码才能说清楚.既然是浅谈原理,那就从最基本的开始吧. 本文的定位是对此方面一无所知的读者,所以大牛们可以直接飘过- 缓冲区溢出这个名词想必大家并不陌生吧,在微

浅谈缓冲区溢出之栈溢出&lt;下&gt;

上回我们简单的介绍了缓冲区溢出的基本原理和机器级代码的解释,对此类问题的分析和研究都必须建立在对程序的机器级表示有一定的了解的基础上.记得有句话是这样说的,"真正了不起的程序员是对自己代码的每一个字节都了如指掌的程序员."我们也许做不到每一字节,但至少得明晰机器级程序的组成结构和执行流程. 言归正传,我们今天在上回的基础上继续探索缓冲区溢出.之前的例子都是简单的通过越界访问来实现对程序执行流程的变动,而且执行的函数都是编译前写入的,那么如何对一个发行版的可执行程序进行缓冲区溢出呢? 首

在linux下进行缓冲区溢出实验 出现illegal instruction

问题描述 在linux下进行缓冲区溢出实验 出现illegal instruction int main(int argc, int *argv[]) { char buf[10]; if(argc>1) strcpy(buf,argv[1]); return 0; } 编译时带有-fno-stack-protector,在第一参数为21字符时正常,22字符时出现illegal instruction,23字符时出点段错误. 请问22字符时的illegal instruction是怎么回事? 解