Following my previous discoveries of security flaws in (then) Saudi Arabia’s popular Cyber Cafe management program, I thought I’d try to make my own Cyber Cafe management program without the flaws that I observed.
A little background:
During my visits to Cyber Cafes in Saudi, I noticed flaws in software on client machines that were supposed to guard against users being to use the machine without logging in. Simple ways like freezing the process, releasing its keyboard hooks etc could easily enable anyone to cheat the system. (see Project SILENCER. I made a simple suite for doing just this). Also, using port sniffing, I noticed that all the client/server communications were unencrypted and visibly simple and easy to emulate. Meaning, I could now disable the client, and build a fake client claiming to the server that this particular machine was actually online and also fully functional! Simply freezing the process would cause the server to mark the client machine as offline or shutdown. I also learnt that I could easily decrypt communication in later version that incorporated encryption. The EXE files weren’t obfuscated. I could simply disassemble the EXE and perform a string search looking for the encryption key used. The encryption algorithm was easily visible as they were using an external library and I could see the function call to that particular entry. (I recall it being Blowfish or Twofish, I don’t recall which one). I also theorized that in case later version didn’t have static encryption keys, I could simply attach a memory analyzer to the EXE when restarting the program after termination. I could then easily perform a simple string search, again, and find the generated encryption key.
With all these weakness in mind, I went on to attempt to program my own Cyber Cafe management system.
Also, one of my incentives to working on this was to earn money. Someone had stolen my PlaystationPortable and I was determined to sell this software and earn enough money to buy it back without having to tell my parents. I was terrified of that thought. 😉
I didn’t have any idea of network programming prior to this. I most certainly did not know how to perform multi-threading and things like that. I didn’t even know the most basic concept of time-outs! I had an amazing journey of having to deal with all of these problems first hand, discovering each of them, one by one, and attempted to deal with each of them with my own creativity and technical capability.
Again, like other school programs. This was made a long time back. I just happened to have 3 screen shots of the program that I took back then. I used Codejock utilities for UI components. Even setting up VB6 on a modern machine is tedious. Factoring in old obsolete versions of UI tools in an already nearly impossible-to-setup development environment, is virtually impossible. So, I’ll provide the only screen shots I have and show code snippets where things get interesting.
“Inventing” semaphores !
As I worked on the program, I realized that possibility of the the server receiving a request when already processing another request, was quite very possible! I had only heard about multithreading and knew nothing more about it. I tried to look into it, but, I was completely stumped at how complex I found it. I retreated and tried to find other ways to deal with the problem. I experimented by simulating “request collisions” and discovered this: If the program received a request while processing another request, flow of execution would just STOP the moment the collision occurs, and the request processing function would be called again with the new arguments!
After a lot of experimenting, I realized that what I needed was something which could “save” requests as they came in, and then something that could then process the requests one by one. Saving the data in a memory space in a literal manner still posed the save threat: what if a request came in just when the older request was being save? This frustrated me a lot. But, after a long time and lot of experimenting, I discovered that there was a way I could detect whether logic was currently within a code block or not, before even entering it! I used simple Boolean variables to get this done. I then simulated a request collision again, but this time, with this “magic” variable set in place before the critical section code. The program sensed that there was another request being processed! I then thought that I could build a sort of “nested” magic variable code in which, each code section would be “guarded” with a variable initially set to true. Upon entry into that code section, the variable would then be set to false. If another request came through at that time, it would notice that the “magic” variable was set to false, and would then jump to the subsequent copy of the critical code section, which would be completely the same except for a different set of temporary variables. I made 30 such nested sections, meaning, the program could handle upto 30 requests simultaneously. This may not seem much compared to the power of an actual fully multithreaded solution, but, looking back on how I had somehow managed to work out an alternate solution using what I later learnt in college as Semaphores… is something very satisfying.
Screenshot of its implementation!
Here’s a screenshot of how I implemented this system with “magic variables” (Essentially, semaphores). Please overlook the poor coding discipline. I was 15 years old and I didn’t know the advantages of properly indented code and variable naming convention.