6.858 Fall 2014 Lab 1: Buffer overflows

Exercise1 找漏洞

1.[http.c:165] <sprintf(envvar, "HTTP_%s", buf);>

在http_request_headers()函数调用了不安全的sprintf()函数。sprintf()函数有三个参数:envvar, “HTTP_%s” 和 buf。这个函数的作用是先将“HTTP__”和buf拼接,然后复制到envvar中,这里buf的最大长度是8192,而envvar长度是512,我们可以将buf溢出到返回地址中,这里buf为http头部的key,我们可以选择将2000个‘A’填充在buf中。

2. [http.c:105] <url_decode(reqpath, sp1);>

在http_request_line中调用了url_decode函数,这里传入了参数reqpath和sp1,作用是将sp1处的字符串拷贝到reqpath地址处,但url_decode此处并不做长度的检查。reqpath的长度为4096,而sp1这里最长可以达到8192,因此我们可以考虑将sp1指向的内容设置为5000,这里溢出的内容可以覆盖到返回地址,最终使得程序崩溃。

3.[http.c:159] <url_decode(value, sp);>

在http_request_header中同样调用了url_decode,这里传入的参数是value和sp,这里value的长度是512,而sp的长度是8192,这里需要修改的内容是http报文头部。

4.[zookd.c:70] <http_request_line(fd, reqpath, env, &env_len)>

reqpath缓冲区的大小应小于2048字节。发送长度超过2048字节的请求路径将导致缓冲区溢出。

5.[http.c:282] <strcat(pn, name);>

http_server中的pn缓冲区只有1024字节。如果传递足够长的URI值,将导致缓冲区溢出。

6.[http.c:344] <strcpy(dst, dirname);>

dst是大小为1024的名称缓冲区。如果reqpath大于1024,则可能导致缓冲区溢出。

Exercise2 测试漏洞

exploit-2a.py

[http.c:105]在http_request_line中调用了url_decode函数,这里传入了参数reqpath和sp1,作用是将sp1处的字符串拷贝到reqpath地址处,但url_decode此处并不做长度的检查。reqpath的长度为4096,而sp1这里最长可以达到8192,因此可以考虑将sp1指向的内容设置为2000,这里溢出的内容可以覆盖到返回地址,最终使得程序崩溃。

代码:

def build_exploit(shellcode):
    req = b"GET /"
    for i in range(2000):
        req = req + b"A"
    req = req + b" HTTP/1.0\r\n"
    req = req + b"\r\n"
    return req

执行效果:

exploit-2b.py

[http.c:159] 在http_request_header中调用了url_decode,这里传入的参数是value和sp,这里value的长度是512,而sp的长度是8192,这里我们修改http报文头部。

代码:

def build_exploit(shellcode):
    req = b"GET / HTTP/1.0\r\n"
    req = req + b"HOST"
    for i in range(777):
        req = req + b"7"
    req = req + b"\r\n"
    return req

执行效果:

检查攻击是否有效:make check-crash

Exercise3 可执行栈注入shellcode攻击

首先获得shellcode在内存中的地址,先使用gdb -p $(pgrep zookfs-extack)进入gdb调试模式,然后使用break http_serve设置断点,然后使用continue继续运行。

再打开一个新的cmd调用./exploit-3.py locahost 8080请求网站,此时,该请求被阻塞。

再回到gdb调试界面,print &pn即可获得其在内存中的地址。

可以看出需要的地址是0xbfffd9fc

接下来编写需要注入的汇编代码,写入shellcode.S文件,其功能是调用unlink删除/home/httpd/grades.txt文件。汇编代码如下:

编写完毕后,将S文件编译成bin文件,需要两条指令,为了方便使用,可以将这两条指令写成一个sTobin.sh文件,方便调用。该文件内容如下:

最后编写exploit-3.py进行攻击,根据exploit-template.py进行修改即可,需要修改的内容如下:

然后,使用touch /home/httpd/grades.txt创建文件,使用make check-exstack测试,测试结果如下:

可以看见,grades.txt也确实被删除了

Exercise4 不可执行栈上return-to-libc攻击

这一步首先改变zoobar网站的启动指令为

./clean-env.sh ./zookld zook-nxstack.conf

采用这条指令启动的zoobar网站,上一个实验的汇编代码无法注入内存栈,所以采用return-to-libc攻击,将程序的控制权跳转到系统自己的可执行代码,实验目标也是为了删除grades.txt文件。

攻击代码如下:

exploit-4a.py:

exploit-4b.py

然后,使用touch /home/httpd/grades.txt创建文件,使用make check-libc测试,测试结果如下:

可以看见,grades.txt也确实被删除了

Exercise5 再找出两个漏洞

(1)在http.c第129行,有一个缓冲区溢出bug。我们能够通过发送超过8192长度的请求攻击这个漏洞。但是,这个缓冲区中所有的字符都会转换为大写,使它很难像实验4一样进行攻击。

(2)在http_serve_directory()函数中,允许所有攻击者通过。

Exercise6 修复漏洞

1.将sprintf()替换为snprintf();

2.将strcat()替换为strncat();

3.对于由url_decode引起的缓冲区溢出,将dst变量设置为静态变量。

4.将http.c中http_request_headers()函数中value数字的大小修改为大于8192.

5.将zookd.c中process_client()函数的reqpath数组修改为8192大小

猜你喜欢

转载自blog.csdn.net/qq_43536827/article/details/128362173