#######################################################################

                             Luigi Auriemma

Application:  Pro-face Pro-Server EX
              WinGP PC Runtime
              http://www.profaceamerica.com/cms/resource_library/products/9e3c2a7965a27592/index.html
Versions:     ProServr  <= 1.30.000
              PCRuntime <= 3.1.00
Platforms:    Windows
Bug:          A] "Find Node" invalid memory access
              B] memset integer overflow
              C] Unhandled exception
              D] Invalid memory read access and disclosure
              E] Possible limited memory corruptions
Exploitation: remote
Date:         13 May 2012
Author:       Luigi Auriemma
              e-mail: aluigi@autistici.org
              web:    aluigi.org


#######################################################################


1) Introduction
2) Bug
3) The Code
4) Fix


#######################################################################

===============
1) Introduction
===============


From vendor's homepage:
"Pro-Server EX is a powerful, yet cost effective data management server
that provides real-time reporting of automated manufacturing and
production environments at a fraction of the price of a full SCADA
system."


#######################################################################

=======
2) Bugs
=======


By default Pro-Server EX (ProServr.exe) runs as a stand-alone server
but it can be set as a Windows service during the installation, this
second mode is suggested by the vendor.


------------------------------------
A] "Find Node" invalid memory access
------------------------------------

The server trusts a 32bit "number of elements" value used locate the
subsequent string in the received packet.
If the packet contains a particular flag then the following function
will try to check the presence of the string "\x1c" "Find Node\0" "ASP"
at that arbitrary location:

  0033650C  |. 8D4486 04      LEA EAX,DWORD PTR DS:[ESI+EAX*4+4]    ; seek
  ...
  00336400  /$ A1 9C7A3A00    MOV EAX,DWORD PTR DS:[3A7A9C]         ; the function
  00336405  |. 8038 1C        CMP BYTE PTR DS:[EAX],1C
  00336408  |. 74 03          JE SHORT TDASforW.0033640D
  0033640A  |> 32C0           XOR AL,AL
  0033640C  |. C3             RETN

This bug works also if the server is protected by password (max 8 bytes
xored with 0xff) and the attacker doesn't know it.


--------------------------
B] memset integer overflow
--------------------------

Through the opcode 0x07 -> 0x5/0x6/0x7 it's possible to exploit an
integer overflow for allocating a buffer of 0 bytes but a memset()
after it allows only to exploit this bug for crashing the server due to
a buffer-overflow of zeroes (unfortunately memcpy can't be reached):

  0033660C  |. 8B7D 18        MOV EDI,DWORD PTR SS:[EBP+18]     ; our 32bit value
  0033660F  |. 83C7 18        ADD EDI,18                        ; + 0x18
  00336612  |. B9 988C3A00    MOV ECX,TDASforW.003A8C98
  00336617  |. 8D1C07         LEA EBX,DWORD PTR DS:[EDI+EAX]
  0033661A  |. E8 C14CFFFF    CALL TDASforW.?Lock@GaMutex@@QAEXXZ
  0033661F  |. 8B35 3C8C3A00  MOV ESI,DWORD PTR DS:[3A8C3C]
  00336625  |. 03F3           ADD ESI,EBX
  00336627  |. B9 988C3A00    MOV ECX,TDASforW.003A8C98
  0033662C  |. 8935 3C8C3A00  MOV DWORD PTR DS:[3A8C3C],ESI
  00336632  |. E8 A921FFFF    CALL TDASforW.?Unlock@GaMutex@@QAEXXZ
  00336637  |. 8D4B 04        LEA ECX,DWORD PTR DS:[EBX+4]
  0033663A  |. 51             PUSH ECX
  0033663B  |. E8 045F0300    CALL <JMP.&MFC71.#265>            ; malloc + 4
  00336640  |. 53             PUSH EBX
  00336641  |. 8D70 04        LEA ESI,DWORD PTR DS:[EAX+4]
  00336644  |. 6A 00          PUSH 0
  00336646  |. 56             PUSH ESI
  00336647  |. 8918           MOV DWORD PTR DS:[EAX],EBX        ; memset crash
  00336649  |. FF15 28803800  CALL DWORD PTR DS:[<&GAOS.?osUTmemset@>
  0033664F  |. 57             PUSH EDI
  00336650  |. 55             PUSH EBP
  00336651  |. 56             PUSH ESI
  00336652  |. FF15 24803800  CALL DWORD PTR DS:[<&GAOS.?osUTmemcpy@>


----------------------
C] Unhandled exception
----------------------

Through the opcode 0x07 -> 0x5/0x6/0x7 it's possible to terminate the
server due to an unhandled exception ("Runtime Error") caused by a too
big amount of data to allocate.


--------------------------------------------
D] Invalid memory read access and disclosure
--------------------------------------------

Through the opcode 0x07 -> 0x5/0x6/0x7/0x14 it's possible to crash the
server specifying a big size value so that it's impossible to copy the
data from the source packet using the osUTmemcpy function.
The opcode 0x7 -> 0x14 is a bit more interesting because it returns a
desired amount of memory back to the client and so it's possible to see
all the memory till the end of the buffer.


--------------------------------------
E] Possible limited memory corruptions
--------------------------------------

Often the server reuses the same memory used for the input packet for
modifying it and then sending it back to the client.
The lack of checks on the size of the received packet allows an
attacker to send a small packet and then forcing the server to write
its fields at those positions higher than the allocated packet size
corrupting the heap.
An example of these memory corruptions happen with the opcode
0x7->0x14:

  0033CE2F   . 33C9                XOR ECX,ECX
  0033CE31   . 3BD1                CMP EDX,ECX
  0033CE33   . 66:8948 04          MOV WORD PTR DS:[EAX+4],CX
  0033CE37   . C740 1C 16260000    MOV DWORD PTR DS:[EAX+1C],2616
  0033CE3E   . 8948 24             MOV DWORD PTR DS:[EAX+24],ECX
  0033CE41   . 8948 28             MOV DWORD PTR DS:[EAX+28],ECX
  0033CE44   . 8948 2C             MOV DWORD PTR DS:[EAX+2C],ECX
  0033CE47   . 8948 30             MOV DWORD PTR DS:[EAX+30],ECX
  0033CE4A   . 8948 34             MOV DWORD PTR DS:[EAX+34],ECX
  0033CE4D   . 8948 38             MOV DWORD PTR DS:[EAX+38],ECX
  0033CE50   . 8948 3C             MOV DWORD PTR DS:[EAX+3C],ECX
  0033CE53   . 8948 40             MOV DWORD PTR DS:[EAX+40],ECX

Anyway in this example ECX is just zero so not much useful but it's
only to demonstrate a big chunk of code since there are some other
places where are performed no checks on the received packet size.
Note that this attack is possible only if no bigger packets have been
received previously because the memory buffer is one and fits the
latest biggest packet.


PCRuntime.exe uses also the TCP port 8000 which is fully compatible
with the protocol running on the UDP one (type, flags, size, data).


#######################################################################

===========
3) The Code
===========


http://aluigi.org/poc/proservrex_1.zip
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/18878.zip


#######################################################################

======
4) Fix
======


No fix.


#######################################################################