DevDisasters

Tale of the Cryptic Encoding

Lee S. nodded gently as she re-read the message-board post.

Someone named Robbie had created a posting asking for assistance in resolving a problem with a simple Visual Basic .NET console application. It was used to retrieve and process product registrations and credit card transactions via the Internet for a piece of niche shareware.

"Bottom line, I do FORTRAN and C++, I don't know or want to know Visual Basic .NET," the post explained. "All I know is that I have an app with the 2KB source file for it that I need fixed so I can earn money. I will happily send $100 to the person who can fix this."

Naturally, Lee felt a little bit cautious dealing with some guy (or gal) from the Internet, but the promise of an easy $100 tempted her to take a chance.

Processing over the Internet ... Kind Of
Within minutes of crafting and sending out a professionally worded missive, Lee received a reply.

After graciously thanking Lee for her e-mail, Robbie explained that the attached .exe file normally would run on a daily basis with the output directed to a text file that would, in turn, get loaded into a spreadsheet. Written years ago, it had worked perfectly until the other day when it started choking.

A quick run of the executable revealed the error: Invalid length for a Base-64 char array.

Drawing on her professional experience with troubleshooting Base-64 encoding issues, Lee was positive that the problem would be a cinch to solve. Eager to test her mettle, Lee jumped straight into the attached .vb source file. She was quickly caught off guard:

Imports System.Net.Sockets
Imports System.IO
Imports Confidential

Module EmailApp

  Sub Main()

    Dim ProcessPayment As New Secret
    Dim Server As TcpClient
    Dim ns As NetworkStream
    Dim sr As StreamReader

    Dim s1 As String = "pop3.initech.com"
    Dim user As String = "secret@initech.com"
    Dim pass As String = "l&28a%"

    Server = New TcpClient(s1, 110)
    ns = Server.GetStream
    sr = New StreamReader(Server.GetStream)
    Dim data As String = "USER " + user + vbCrLf + "PASS " + pass + _
               vbCrLf + "STAT" + vbCrLf + "STAT" + vbCrLf
    Dim enc1() As Byte = _
          System.Text.Encoding.ASCII.GetBytes(data.ToCharArray())
    ns.Write(enc1, 0, enc1.Length)

    Dim x As Integer = CInt(String.Concat(sr.ReadLine + sr.ReadLine + _
               sr.ReadLine + sr.ReadLine).Split(" ")(6))
    Dim tmp As String
    
    For i As Integer = x To x
      data = "RETR " & i.ToString & vbCrLf
      enc1 = System.Text.Encoding.ASCII.GetBytes(data.ToCharArray())
      ns.Write(enc1, 0, enc1.Length)
      tmp = sr.ReadLine

      While (tmp <> ".")
        If tmp.StartsWith("Subject") Then
          data = tmp.Substring(9, tmp.Length - 9)
        End If
        tmp = sr.ReadLine
      End While

      Console.WriteLine(i.ToString + "," + ProcessPayment.DeCrypt(data))

      data = "DELE " & i.ToString & vbCrLf
      enc1 = System.Text.Encoding.ASCII.GetBytes(data.ToCharArray())
      ns.Write(enc1, 0, enc1.Length)

    Next
    data = "QUIT " + vbCrLf
    enc1 = System.Text.Encoding.ASCII.GetBytes(data.ToCharArray())
    ns.Write(enc1, 0, enc1.Length)

  End Sub

End Module
Lee's mind was reeling. The way the program "worked" was almost unthinkable. Processing payments over e-mail in the 21st century ... and in the subject field?! Exactly what kind of madness had she walked into?

Reality Sets In
After Lee calmed down, she thought back to what Robbie had said before realizing, "Ah ha! This must be a data problem!" She proceeded to take a peek at the e-mail messages backed up in the account listed in the source code.

The majority of the messages, at least five per day, had subjects that looked like this: H4sIAJ4qnU0AA4vML1VIyy/NS1EoyUhVCE5NLkotUQgN8lFUyCgpKbDS10/KLNHLqdRPyw3LcXLjAgDGBcb9LwAA

However, a Web marketer had apparently discovered the "hidden" account, poisoning it with amazing deals for quasi-legal mail-order pharmaceuticals, which caused the program to choke. Lee figured that she would've choked too.

Because adding a heuristic spam filter to the program was not only out of scope, but also outside of the $100, Lee took the quick and easy route by wrapping the "DeCrypt" function within a Try...Catch block. A quick test revealed that the program could now download and export user registrations as it had before. User names, e-mail addresses, telephone numbers and credit card information all appeared, arranged in neat, comma-delimited fields. Lee sent her revision back to Robbie, who, in return, offered to meet up for coffee.

When they met, Lee did her best to explain why the process failed when it did and what she did to fix it. Robbie appeared to be receptive. Following some additional chit-chat, the payment was handed over and Lee asked one question that still gnawed at her.

"The third file you sent me -- the Confidential.DLL file -- what does that do? Is that ..."

"Sorry, no idea," Robbie cut in with palms opened in front of her. "Not my area of expertise, remember?"

"Besides," Lee chuckled, "everything works exactly as it did before if not better, and that's what counts, right?"

Lee held her breath for a second before extending a hand thanking Robbie for the opportunity. Her sense of developer responsibility was screaming in her head: "Are you crazy, lady?! Yeah, it works today, but what if something else changes? What if you get hacked?"

On the way home, Lee resolved to put off saving the world until another day. Meanwhile, she was going to find out what that DLL did.

Shrouded in Secrecy?
Two main obstacles prevented Lee from seeing how the DLL worked. The lack of program source and the file named "Confidential," which had a class named "Secret." Despite these obstacles, Lee was able to easily decompile the binary file to see the truth that lay therein:

Public Function DeCrypt(ByVal strInput As String) As String
  Dim ms As New MemoryStream(Convert.FromBase64String(strInput))
  Dim gz As Stream = New GZipStream(ms, CompressionMode.Decompress)
  Dim sr As New StreamReader(gz)
  Return sr.ReadLine
End Function

Because the initial shock of the calling application had subsided, all that Lee could muster was, "At least they didn't use ROT-13." Somehow, this implementation of decryption fit.

A few months passed before Lee heard from Robbie; payment processing was throwing another fit. The cause this time, though, was the small ISP that had kept the registration e-mail address afloat. It had finally been swallowed by a large telecom prompting them to rename their e-mail servers.

Robbie offered Lee another $100 to help figure out a potential fix. Lee replied that she didn't have the time to dedicate to such a task. "In the meantime," she said, "perhaps you'd like to investigate other options for handling secure online transactions," and forwarded a set of links.

About the Author

Mark Bowytz is a contributor to the popular Web site The Daily WTF. He has more than a decade of IT experience and is currently a systems analyst for PPG Industries.

comments powered by Disqus

Featured

  • Mastering Blazor Authentication and Authorization

    At the Visual Studio Live! @ Microsoft HQ developer conference set for August, Rockford Lhotka will explain the ins and outs of authentication across Blazor Server, WebAssembly, and .NET MAUI Hybrid apps, and show how to use identity and claims to customize application behavior through fine-grained authorization.

  • Linear Support Vector Regression from Scratch Using C# with Evolutionary Training

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the linear support vector regression (linear SVR) technique, where the goal is to predict a single numeric value. A linear SVR model uses an unusual error/loss function and cannot be trained using standard simple techniques, and so evolutionary optimization training is used.

  • Low-Code Report Says AI Will Enhance, Not Replace DIY Dev Tools

    Along with replacing software developers and possibly killing humanity, advanced AI is seen by many as a death knell for the do-it-yourself, low-code/no-code tooling industry, but a new report belies that notion.

  • Vibe Coding with Latest Visual Studio Preview

    Microsoft's latest Visual Studio preview facilitates "vibe coding," where developers mainly use GitHub Copilot AI to do all the programming in accordance with spoken or typed instructions.

  • Steve Sanderson Previews AI App Dev: Small Models, Agents and a Blazor Voice Assistant

    Blazor creator Steve Sanderson presented a keynote at the recent NDC London 2025 conference where he previewed the future of .NET application development with smaller AI models and autonomous agents, along with showcasing a new Blazor voice assistant project demonstrating cutting-edge functionality.

Subscribe on YouTube