Saturday, October 5, 2024

Wherein We Crack A Simple Program: level 1

 



I'll let you in on a little secret: I don't play chess.
Well... I can, and I have, but I don't anymore.
Not because I lack the ability, but because I get obsessed with it. I mean it.

Let me paint you a picture.

Years ago, I decided to rekindle my childhood passion for chess. As a kid, I was pretty good—not grandmaster level, mind you, but good enough to hold my own (and beat up quite a few adults in the process). 

Fast forward to adulthood, and I downloaded a chess app with daily challenges. You know the type—"Checkmate in X moves." Innocent enough, right? Wrong.

I was immediately hooked. Every spare moment became a chess moment. One day, I hopped on the subway, intending to get off 15 minutes later. When I finally looked up from my phone, I was at the end of the line, having totally missed my stop. "No big deal," you might think. Except I did it again. And again. Six or seven times that day, I rode back and forth, missing my stop each time, completely absorbed in the game.

That's why I can't play chess casually. It's all or nothing for me - books, constant practice, moves (and countermoves) consuming my every waking thought. So, I made a promise to myself: chess would only be for teaching my daughter the game. Nothing more.


Now, you might wonder where I'm going with this. Well, it's simple, really. Back when I was 12 or 13, if I couldn't find a partner, I'd play against myself. Hard to imagine in today's world of one-click online matches, but it wasn't half bad.

So, in that same spirit of playing against oneself (and a Woody Allen quote does come to mind...), I am starting a new series of blog posts where I'll be cracking simple programs. I'll create C programs that require a password to jump to the next level, then attempt to crack them by disassembling the binary and reading it with ASM. Each success will lead to a stronger, harder-to-crack program.

Feel free to spice things up by asking an LLM to create these for you, or better yet, challenge a friend to send you increasingly difficult C programs (remember? Real friends know C).

Here's the program (ignore it and move on if you want to just check the steps taken).



Simplicity itself. The program has a fixed password in plain text. If anything, this one is screaming FIND ME. Right?

Still, always remember that time, days, months, or years ago, when this simple password would be a deterrent enough to keep you from accessing the program.

Let's look at four different ways to find out this password. You might even be considering a fifth: some sort of brute force attack. But this would probably fail in this case. Notice that the password has 16 characters and, a priori, we have no present way to know how many characters it has. It's also not incredibly likely that the password will be in a popular wordlist.

So, assuming that, and assuming that you're only testing for some 60 total characters (uppercase + lowercase + a few favorite symbols), it could take up to 60 to the power of 16 attempts for our loop to capture the correct password. That's a lot. That's really a loooooooooot. So let's not do that.

Our four approaches (remember to man <tool>):

  • xxd


See the password?

xxd is a tool that converts binary files into their hexadecimal representation, which basically gives us a byte-by-byte view of the file.

If the program is storing the password in plain text, like in this case, then... it's Game Over for the program, and Game On for us.


  • strings


This nice tool quickly pulls out readable strings from a binary file. Nifty, no?

Our poor, exposed password is there again, for all to see.

Even if you don't see something as glaringly obvious as a password, taking a look at visible text can give you some good hints on what the program might be doing.


  • ltrace


After having played through the
Leviathan game in OTW, I became a fan of this tool. ltrace is a powerful tool that traces all the function calls made by a running program - allowing us to spy on what's happening under the hood as the program executes. More so, since there is absolutely no obfuscation in our original C program.


  • gdb



This one is starting to feel like an old friend, right?

I won't go into much detail on how to use it, since I've done so here and here.

After exploring we find something slightly odd:

A couple of movabs instructions (this is intel flavor right here. Is it also there if we don't use intel? Check it out)


Now, movabs is an instruction that moves a 64-bit (8-byte) immediate value directly into a 64-bit register. That's interesting, since we use movabs when we 
need to load a large constant value that won't fit in the 32-bit immediate field of a regular mov instruction.

Our registers will be loaded with those values in reverse-order (because of little-endian). And, just to make it plainly obvious (you could do this outside, through a program, etc) we can showcase what we mean:


There we go. Our hexadecimals converted into characters, in all their glory.


Alright. Program cracked with 4 different tools. But this is just our opening move. We're moving on to the next level. 

Whatever was your weapon of choice, we got this result:


Next up:

  • Basic Obfuscation of the Password
  • Environment Variables


Consider Phlebas, who was once handsome and tall as you.

No comments:

Post a Comment

Why Won’t You Power Off?

                                  "Beneath this mask there is more than flesh. Beneath this mask there is an idea, Mr. Creedy."   ...