Properly Sciolistic Security Turing Complete, Mostly

Properly Sciolistic Security

While consolidating the many many MySQL and MSSQL servers I inherited I was tasked with migrating a home grown application that supported processing and chargeback of returned mail. What it was used for is immaterial. But when I say that it was bespoke, it was bespoke. Very Bespoke VB. No documentation ofcourse. That's a given.

First step would be to figure out which of the 24 different SQL servers are implicated and find out how the application is configured on which server to use. When reviewing the file structure Application\ConfigSQL.ini seemed like a natural place to look. Oh good, a .ini. This should be straight forward.

After opening the file I'm confronted with this;

[server]JanetSQL[Cnn_Server]ïîòø¡íèõõíä¡ãôææäó­¡àóäï¦õ¡øà¾ïîòø¡íèõõíä¡ãôææäó­¡àóäï¦õ¡øà¾ïîòø¡íèõõíä¡ãôææäó­¡àóäï¦õ¡øà¾°
*[server]JanetSQL[Cnn_Server]ïîòø¡íèõõíä¡ãôææäó­¡àóäï¦õ¡øà¾ïîòø¡íèõõíä¡ãôææäó­¡àóäï¦õ¡øà¾ïîòø¡íèõõíä¡ãôææäó­¡àóäï¦õ¡øà¾° 

What the hell is that? Do I need Some obscure Windows process/tool? A hexeditor? A drink? A new job? This is unlike any .ini i've ever seen. Why is there an asterisk? Maybe I missed something in my 30 years of doing this. And does Janet have her own SQL server? When you have SQL servers provisioned and named after employees, you're in a special place.

I managed to find a copy of the application source on a NAS drive, because why would it be in Git when you can zip it onto a locally administered (administered by no one) NAS drive with no backups.

After grep-ing the code base for a few things and clutching at straws this turns up.

Public Sub LoadSQLServerSettings()
    Dim oRead As New StreamReader(Application.StartupPath 
        & "\ConfigSQL.ini", System.Text.Encoding.UTF7)
    ...
    utConfig.sCnnCurrent = EncryptDecryptString(sLine.Substring(sLine.IndexOf("Cnn_Server]") + 11))
    ...

What the hell is UTF-7? And why on earth would anyone want to use that? I haven't heard of this encoding before. According to Wikipedia; a dead format. Much like the rest of the technology used in this company. But half of the .ini was legible. So was half of the file UTF-8 and the other half UTF-7?

This gets even better because it's an even more (ob)secure-ified .ini. Obviously we need to EncryptDecryptString() this "UTF-7".

Public Function EncryptDecryptString(ByVal sTXT As String) As String
    ...
    For iCount = 0 To sTXT.Length - 1
        sTmp = sTmp & Chr(Asc(sTXT.Substring(iCount, 1)) Xor 129)
    Next
    EncryptDecryptString = sTmp
End Function

And then I laughed and I laughed. If anything work should be fun.

Thankfully the configuration details are kept secured using XOR "encryption". Phew. Good thing. Evidently the data is sensitive enough to protect, but not sensitive enough to implement any actual protection. We're just making things up as we go here.

So is there a tool to decode"crypt" and edit the configuration file?

While scouring the various databases to which I only happen to have access to thanks to a saved password in Microsoft SQL Management Studio almost a dozen stored procedures turn up. One function stands out: fn_EncryptDecryptString().

The tool used to modify the VB application configuration file (using XOR) is an MSSQL stored procedure. You need an SQL server to XOR a string.

CREATE FUNCTION [dbo].[fn_EncryptDecryptString] ( @pClearString VARCHAR(1000) )
    --RETURNS NVARCHAR(1000) WITH ENCRYPTION AS --(use this line to hide the code)
    RETURNS NVARCHAR(1000)  AS
    BEGIN

    DECLARE @vEncryptedString NVARCHAR(1000)
    DECLARE @vIdx INT
    DECLARE @vBaseIncrement INT

    SET @vIdx = 1
    SET @vBaseIncrement = 128
    SET @vEncryptedString = ''

    WHILE @vIdx <= LEN(@pClearString) 
    BEGIN 
        SET @vEncryptedString = @vEncryptedString 
            + NCHAR(ASCII( SUBSTRING(@pClearString, @vIdx, 1)) ^129) 
        SET @vIdx = @vIdx + 1 
    END 

    RETURN @vEncryptedString 
END 

So what configuration secrets does the XOR hide? Copy and paste the illegible encoded portion into the SQL function.

Data Source=DarthVador\SQLFJ;Initial Catalog=DataProcessingV2;Persist Security Info=True;User ID=USERNAME;Password=USERPASSWORD

Ofcourse a Star Wars reference. In a .ini semicolons are comments right? No no, not here, not now. We're in a galaxy far far away. Currently semicolons are used as field delimiters. Asterisks are used to denote the presently active configuration line. UTF-7 is meaningless, XOR is encryption and editing .inis passes for entertainment.

    While oRead.Peek <> -1
        sLine = oRead.ReadLine()
        If sLine.Substring(0, 1) = "*" Then Exit While
    End While

Oh, and the referenced MSSQL server turned out to be running on a laptop. Of a user (Janet ofcourse) that had long left the company. But I'm still here.


More Posts

Properly Sciolistic Security

Trilemmic Paradigms as Applied to Forced Induction

The Path to Solder Reflow

What the Tic Tac?

Timing belt maintenance

How to save 13¢ per day