TJUT-8INF135课程全攻略 实验一

591 阅读5分钟

前言

这节实验没有什么核心内容,主要分为A和B两小节。

A是分别通过C和Java的数组的数组越界来告诉大家C和Java在数组越界上的处理的不同。从而引出了缓冲区溢出这个概念,告诉大家什么是缓冲与溢出以及缓冲区溢出可能会导致的问题。

B则是通过setuid命令,引出了linux下的权限

下面就按照步骤进行讲解。

Lab01-A

Task2

step1

这一步没有什么实际的意义,大概就是用自己的编辑器打开看一下Java的代码是怎么样的,了解一下这段代码。 image-20191217123659809

step2&step3

这一步是创建一个共享文件夹,然后把主机上的共享文件夹和这个虚拟机中创建的文件夹进行共享,其实挺麻烦的,也可以自己把这一个实验里边用到的文件都直接复制进虚拟机里。 image-20191217124023454

step4

这一步是把共享文件夹里的内容再复制到虚拟机的一个文件夹里做一个自己备份。所以真的很麻烦,不如直接复制进虚拟机算了。 image-20191217124904674

step5

确认了一下文件被复制进来了。 image-20191217124943706

step6

javac命令对ArrayCopy.java进行编译,然后有ArrayCopy.class的话就代表编译成功了。 image-20191217125019148

step7

java ArrayCopy命令运行刚才编译好的ArrayCopy.classimage-20191217125121389

因为array02的长度大于array01的长度,当试图访问array01[10]时,程序会发生数组下标越界错误,这个错误在Java中被称为ArrayIndexOutOfBoundsException,所以有以上输出。

Task3

step1

和上面一样,大概看一下arraycopy.c的代码了解一下这段代码干了什么。 image-20191217125356863

step2&step3

这一步在上边task2已经做过了,不需要再做一次了

step4

创建文件夹的操作上边已经进行过了,这里仅仅把arraycopy.c拷贝到labs文件夹里

image-20191217125635562

step5

切换到labs文件夹目录。 image-20191217125803852

step6

gcc arraycopy.c -o arraycopy命令编译arraycopy.c。有arraycopy文件就表示编译成功了。 image-20191217125839024

step7

运行arraycopy,可以发现程序被终止了。 image-20191217125912684

这是因为arraycopy.c中的strcpy(buffer, str);这一段代码在进行字符串拷贝时发生了缓冲区溢出,具体是什么原理我们会在后边的实验中细讲,因为在系统中存在默认的防护措施,当出现缓冲区溢出时,自动中断程序的运行,所以有以上输出。

step8

  1. 运行sudo sysctl -w kernel.randomize_va_space=0命令,这个命令的含义是关闭地址空间随机化,1代表开启,0代表关闭。关闭这个选项后你就可以认为我们一段代码在编译后被运行时不论运行多少次它的内存地址状态都是固定的,而在默认情况下它是随机的。 image-20191217130046813

2.&3.

运行gcc arraycopy.c -o arraycopy -z execstack -fno-stack-protector命令

-z execstack的含义是因为我们缓冲区溢出是把我们要执行的代码段溢出到栈上然后执行,而gcc默认是不允许在栈上的代码段被运行的,所以必须要把该选项带上,不然你的代码就是一堆没用的字符串。

-fno-stack-protector 的含义则是因为gcc默认对缓冲区溢出做了一定的防范措施,当出现缓冲区溢出时程序会被终止,所以要带上这一个参数把改防范措施关掉。

image-20191217130337776

step9

image-20191217130440001

当关掉地址空间随机化并以上述参数进行编译和运行时,由于缓冲区溢出,会报一个Segmentation fault的错误。

chang size and repeat

改变到22
  1. 使用vi改变buffer的大小

    1. image-20191217130750815

    2. image-20191217131430150

    3. 保存

      image-20191217131454163

  2. 重新编译运行查看结果

    1. image-20191217131529112

    2. image-20191217131601885

      由于缓冲区溢出依旧报了Segmentation fault的错误,但是此时缓冲区溢出篡改的返回地址恰好可以让程序继续运行,因此还运行了printf函数。

改变到32
  1. 使用vi改变buffer的大小

    1. image-20191217130750815

    2. image-20191217130854204

    3. 保存

      image-20191217130926208

  2. 重新编译运行查看结果

    1. image-20191217131009256

    2. image-20191217131028723

      更改到32以后,虽然字符串长度大于缓冲区大小,但是程序并不会产生缓冲区溢出,所以程序正常运行。

Lab01B

因为这一部分涉及到linux下权限的问题,就不在这里长篇大论了,具体的可以自己查资料和课程讲义。

你需要知道的就是通过chmod u+s 文件名可以让任何运行该文件的用户在运行时都拥有该文件的最高权限。

在C语言中调用setuid(0);可以达到一样的效果。

Task1&Task2&Task3

所以这个问题的答案就是应该选择更改cat的权限。

因为当给cat更改完权限之后,cat在运行时就会拥有最高权限,自然可以查看shadow中的内容。

下面这张图也给出了对比,在提权之前,访问shadow中的内容是权限不够的,而提权之后就可以显示shadow中的所有内容了。

image-20191217214442074

Task4

在这个地方,chmod不生效的原因是,sh在这里是一个链接,类似于在Windows中的快捷方式一样,实际上运行的是/bin/dash,而dash是有防范措施的,不能够通过chmod u+s的方式来进行提权拿到最高权限。

那么这个问题目前最好的解决方法是直接用sudo命令来运行shell就好了。sudo命令会以root权限执行程序。至于更好的解决方法后边的实验里有提及。