Buffer Overflow Attack(Server Version)
task 1:Get familiar with the shellcode
就是按照步骤来实现shell命令的修改,为了测试,在shellcode文件夹下面创建了temp文件
首先是在shellcode_32.py
文件当中,将原来的line 2的命令修改为"rm /home/seed/Desktop/lab1/Labsetup/shellcode/temp *"
,之后运行py文件并且编译call_shellcode.c文件,运行后可以看到temp文件被删除
64位的和32位的命令是一样的,下面只展示成功时候的截图
task 2:Level 1 Attack
此时相当于是已经建立好了attacker和server之间的连接,当执行下面命令后
会在server端出现
之后,我们要通过构造badfile
文件,让badfile来覆盖掉返回地址,使得之后返回的地址是shellcode在栈上的位置,或者指向shellcode前面的nop指令。
思路:进行代码分析,首先来看stack.c
,也就是buffer overflow vulnerability
的代码,它的基本思路是这样的:首先,main()
函数会开一个517个byte的局部变量str[]
,用来存储我们所需要写入的字节,之后将str的首字节压入栈中,作为dummy_function()
的参数,而dummy_function()
最主要的作用就是将str首地址并调用了bof()函数,该函数的作用是开一个buffer[]
,并且将str
里面的内容写入到buffer
里面。而exploit.py
的文件内容实际上就是构造badfile
里面的内容(将content
写入到badfile
),而badfile
就是输入的东西,写入到str,之后就是strcpy
到buffer
并且覆盖return address
我们已经知道了ebp的地址是0xffffd318
,而返回地址的起始地址就是ebp + 4,就是0xffffd31c
,距离buffer首地址0x74,就是116个byte,而shellcode随便放在返回地址上面,这里放在ebp + 12
处,也就是0xffffd324,距离buffer首地址0x7c
)
之后在主机上开一个监听端口,nc -nv -l 9090
,然后运行exploit.py文件./exploit.py
以及cat badfile | nc 10.9.0.5 9090
reverse shell成功
task 3:Level-2 Attack
在这个task里面,给我们的hint会变少,运行echo hello,会发现只给了Buffer的起始位置是0xffffd258,我们不知道buffer具体的大小,但是可以得知范围是在[100,300]之间,同时需要之构造一个就能够解决这个范围内所有的变化
- 针对于buffer的范围,我们选择直接将300byte来作为buffer的区域,同时,shellcode的起始位置也是可以找到的,我们选择将从buffer首地址开始到300+8都填充为我们shellcode的起始位置,偏移量308 = 0x134
- 针对于如何设置返回地址/shellcode的起始位置,返回地址要指向偏移量308以及之后的位置,在这里设置为了312 = 0x138,所以返回的地址就是0xffffd258 + 0x138 = 0xffffd390
shellcode无需修改,仍然是这个命令,修改后的部分code如下
之后按照上面的命令顺序在运行一遍,能够reverse shell,成功!
task 4: Level-3 Attack
在这个task里面,我们的目标服务器运行的是64位的程序,首先先echo hello来看一下打印出来的信息
可以看到我们能够知道buffer的起始地址以及rbp的地址,同时问题是不能出现1byte的0,否则strcpy函数就会停止复制,解决方法是既然要跳转的shellcode一定会是含有0x00,那么就直接把shellcode放在buffer里面,这样在最后strcpy的时候,会将要跳转的位置进行修改后才停止(要注意buffer的大小),在这里buffer的大小位0xd0 = 208bytes,而shellcode在这里是能够放下的
把shellcode放在buffer起始位置,然后返回地址的偏移量是0xd0 + 8 = 0xd8
之后将相应的code进行修改
然后再按照之前命令进行运行,reverse shell成功!
task 5:Level-4 Attack
思路:在这里,buffer是空间较小的,不足以放下我们的shellcode,但是需要注意的是,每次都是先将badfile作为输入写入到main里面的str的位置,然后才会去strcpy到我们的buffer里来进行覆盖返回地址,所以在这里的解决方法就是将shellcode写入到str里面,但是不strcpy到下面,而是将返回地址修改位shellcode在str里面的地址
首先,还是先echo hello
我们能够知道rbp的地址是0x00007fffffffe1a0,而buffer的首地址是0x00007fffffffe140,此时相距0x60 = 96bytes
之后需要用到gdb来调试,在这里需要修改makefile,并且重新编译并且启动容器
分别运行gdb stack-L4,b main,r,p /x &str
命令来获取str的地址
之后我们需要找到rbp的位置来确定相对偏移量,将断点设在bof函数,然后查看rbp寄存器的值就好
所以,str和rbp之间的相对的偏移量是0x430
之后结合运行时候rbp的地址是0x00007fffffffe1a0,可以计算出str的地址是0x00007fffffffe5d0,同时将shellcode存放在相对str起始位置256偏移量的地方,所以shellcode的地址就是0x00007fffffffe6d0,而return address相对于buffer的偏移量是0x68
成功!
task 6:Experimenting with the Address Randomization
打开栈地址随机化并且发送echo hello命令
可以看到每次栈的栈帧指针和buffer起始位置都变化了,但是buffer分配的缓冲区大小不变。
采用暴力破解来击败随机化策略:原理是任意猜一组当前栈帧指针位置和buffer首地址,只要保证buffer size为0x70即可,然后不停给server发送badfile,由于server栈地址一直在变化,总有一次可以正好变成你猜的这组地址,然后就能获取reverse shell了。
好吧,是我脸黑
task 7:Experimenting with Other Countermeasures
在makefile中把 -fno-stack-protector注释掉。然后make,并且单独运行stack-L1
可以看到stack smashing detected,保护机制丢弃了这个输入
下面是使得堆栈不可执行,修改makefile文件,并重新编译运行
完成!
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!