Kfence provides kernel protection against basic exploitation techniques, including stack and heap overflows and format string exploit, by patching /dev/kmem and redirecting system_call to test if the EIP of the caller is in the wrong memory region.
Tool code:
/*
* kfence 1.2
* added .bss exec protection
* modified extraction of struct distances
* you need to have a valid System.map on your box
* tested on 2.2.16 2.4.7 2.4.18 2.4.19 2.4.10
* Coded by ins1der
* 2003
* trixterjack@yahoo.com
*/
int kmemrw(void *rwbuf, ulong offset, size_t size, int type)
{
int f;
int ret;
f=open("/dev/kmem",O_RDWR);
if (f<0)
{
fprintf(stderr,"unable to open /dev/kmem in rw mode\n");
_exit(0);
}
lseek(f,offset,SEEK_SET);
if (type==0)
ret=read(f,rwbuf,size);
else
ret=write(f,rwbuf,size);
close(f);
return ret;
}
void usage(char *argv)
{
fprintf(stderr,"***\nkfence \nins1der 2003
(trixterjack@yahoo.com)\n***\n");
fprintf(stderr,"Usage : %s command [v]\n",argv);
fprintf(stderr,"Commands:\n");
fprintf(stderr," r remove the kernel patch\n");
fprintf(stderr," i install kfence \n");
_exit(0);
}
fprintf(stderr,"Something is wrong with system_call\n");
fprintf(stderr,"kfence probably installed\n");
fprintf(stderr,"Exiting.\n");
_exit(0);
}
if (verbose)
printf("# load_aout_interp at 0x%x\n",(int)load_aout);
/*get sys_call_table*/
kmemrw(shell,system_call,100,0);
p=(char*)memmem(shell,100,"\xff\x14\x85",3);
if (!p)
{
fprintf(stderr,"sys_call_table not found!\n");
return 0;
}
p+=3;
sct=*(ulong*)p;
if (verbose)
printf("# sys_call_table 0x%x\n",(int)sct);
/*get the address of sys_olduname*/
kmemrw(&olduname,sct+4*__NR_oldolduname,4,0);
if (verbose)
printf("# olduname at 0x%x\n",(int)olduname);
/*get the distances from load_aout_interp bling bling! :\*/
p=(char*)kmemrw(shell,load_aout,70,0);
p=(char*)memmem(shell,70,"\x00\xe0\xff\xff",4);
if (!p)
{
fprintf(stderr,"couldn't get needed structures!\n");
return 0;
}
p--;
{
unsigned char i,j,b,c;
i=*p;
i-=0xb8;
for (;;)
{
p=(char*)memchr(p,'\x8b',70-((ulong)p-(ulong)shell));
if (!p)
{
fprintf(stderr,"couldn't get needed structures!\n");
return 0;
}
p++;
b=*p;
b-=0x40;
if (b<=0x3f)
if (b%0x8==i)
{
p++;
mm_dist=*p;
for (;;)
{
j=b/0x8;
p=(char*)memchr(p,'\x89',70-((ulong)p-(ulong)shell));
if (!p)
{
fprintf(stderr,"couldn't get needed structures!\n");
return 0;
}