How man-in-the-middle saved the day

True software development horror experience

--

Innocent beginning

Many, many years ago I worked with Windows desktop C♯ and C++ apps. The app was accessible through public interfaces, which we internally called Terminals. Terminals were very similar to the ATMs. Each Terminal was nothing more than a PC packaged into shiny armor and touch screen.

One day, the company decided to use smart cards to track users. I had to write a new smart-card-feature for the app. We were not beginners; we had some experience. On a daily basis, we worked with usb, rs232, rfid, nfc, ccTalk, SAS, AT, ICT, custom-made in-house PCBs, and all other kinds of hardware devices. Working on a smart card device feature looked like a task that you assign to yourself when you want to take a rest from the real tasks.

To accomplish the task, we received a low-budget, no-name, plug-n-play card reader, a few blank PVC smart cards, and SDK. There was no manual, or how-to-guide, or set of instructions, to tell us where to start, what to expect, to warn us about any danger (!), to tell us what type of smart cards are required (there are tons of different card types on the market), to provide any useful information — nothing.

Communication with the supplier was poor, practically useless. For unknown reasons, the company insisted that we should proceed with that specific supplier.

Wrong turn

Soon, we realized SDK is not the real SDK. SDK contained two files only. One file was executable (.exe) file, and it was a demo app with one purpose only — to show us that the device and card work as expected.

The other file was dynamic-link library (.dll) file. We were supposed that the magic was taking place inside .dll file, and that we were supposed to import and use .dll file inside our app.

Although there were so many questions, it seemed like Demo App and the card reader device could communicate. With utilities like dumpbin and Dependency Walker, we figured out the definitions of exported .dll functions. The names of the functions were almost identical to the labels on the buttons inside Demo App. It was a good sign — we could associate .dll function with a specific part of demo app.

When we tried to import .dll into our source code — nothing worked as expected. Actually, we could not establish any communication between our code and .dll. No matter what approach we tried, and we tried a lot of them, the result was always bad. We even tried to decompile both Demo App and .dll, hoping that we could reuse the decompiled code, but both files were obfusacted, so the decompiled version was not very useful.

Doom

Accidentally, we found out that cards were Siemens SLE4442 EEPROM cards. SLE4442 has a security mechanism (PSC Verification), and improper use of the card can block the card for further usage. Later on, we would found out that we blocked some cards.

Also, we found out and that Demo App doesn’t work if Smart Cards for Windows Service (SCWS) is enabled. This fact was a huge surprise. SCWS is the core part of the OS. It manages all interactions between smart card devices and OS. Just by using common sense one would expect that Smart Card Service has to be enabled when interacting with a smart card reader. Anyway, we concluded that this illogical fact means that our card reader probably does not run on top of PC/SC Workgroup Specifications.

Days passed by. Frustration was at its peak. We were almost beaten, without ideas on how to proceed. Only thing that kept us trying was the fact that Demo App could interact with the card reader device.

Insidious App

In the end, we tried to eavesdrop on communication between Demo App and .dll file. The idea was to record data sent from Demo App, and then to sent the same data from our source code.

The technique for eavesdropping is called API Hooking. The concept is comparable to man-in-the-middle attack concept. API Hooking is often used by antivirus softwares, gaming cheaters, malicious softwares, etc. It’s a close relative to dll hijacking technique.

Eavesdropping created even more question marks above our heads. There was no communication between Demo App and .dll file. The magic was happening inside Demo App. DLL file was purposeless. The whole time we were trying to do the impossible.

Revelation

In the end, we discovered that Demo App communicated with some of the core OS system files (it was a long time ago, cannot recall exactly). Although it was a long and painful process, we recorded and reconstructed all data packets sent from Demo App. We put those reconstructed messages to our source code and everything worked fine.

Happy ending

It took a few weeks just to establish communication between our source code and the card reader device, but eventually the feature went to the production environment. Many, many years later, it still runs on Terminals all across the globe.

Part 2

Two-three years later, the company created a new terminal, aka Terminal 2. Terminal 2 use SLE5542 cards instead of SLE4442. A small software upgrade was required to run SLE5542 cards. We received the same package as before: a card reader, blank PVCs cards and SDK (Demo App + dll). Version of the .dll was incremented from 1.0 to 1.1 — it was not the same file as before.

Out of curiosity I tried to import new .dll to source code and to try it. It took me less than a 3 minutes to prepare everything. New .dll worked like a charm.

Final word

This is an example of HOW NOT TO APPROACH THE TASK.

Although this journey was unique, although some hardcore approaches were taken, it shows how poor communication, low-budget, personal interests can and will lead to overcomplicated solutions, enormous waste of time and resources, immense frustrations, and, in most cases, poor results.

Instead of engineering, we were reverse-engineering. There are use cases where reverse-engineering applies. However, if you need to add a simple new feature to the existing codebase, in most cases, that is not a place for reverse-engineering.

Ministry of Programming is a supercharged startup studio specialized in building startups and new products💡 We were voted in the top 1000 fastest growing companies in Europe by Financial Times. Twice.

We offer product management, design, development, and investment services to support entrepreneurs and startups towards product success.

Building your next startup? We would love to hear more. If you want to work with us on your startup feel free to reach out at — https://ministryofprogramming.com/contact/

--

--