-1

I'm trying to solve this exercise for university. We have to "crack" a program, which is missing a license file that is required to start the program. We are only working with a Linux shell.

So what I've already done is creating this missing license file. It is an .ini that includes a license-holder and a license key. The only thing i'm looking for now is the correct license key. The task says we should use "strace" and "ltrace" to solve this problem. This is what i get as an output:

fopen("license.ini", "r")                                   =0x55c088307380

fgets("LicenseHolder=annabell.krause@ex"..., 4096, 0x55c088307380)  = 0x7ffe72450860

strncmp("LicenseKey=", "LicenseHolder=annabell.krause@ex"..., 11)   = 3

strncmp("LicenseHolder=", "LicenseHolder=annabell.krause@ex"..., 14)    = 0

sscanf(0x7ffe72450860, 0x55c08753c16b, 0x7ffe72450800, 0xffffc000)  = 1

fgets("LicenseKey=aoeklycf", 4096, 0x55c088307380) = 0x7ffe72450860

strncmp("LicenseKey=", "LicenseKey=aoeklycf", 11)           = 0

sscanf(0x7ffe72450860, 0x55c08753c121, 0x7ffe72450840, 0xfffff800)  = 1

fgets("LicenseKey=aoeklycf", 4096, 0x55c088307380)          = 0

memfrob(0x7ffe72450840, 8, 0, 0xfbad2498)                   = 0x7ffe72450840

strncmp("KEOAFSIL", "aoeklycf", 8)                          = -22

fwrite("ERROR: License key is invalid.\n", 1, 31, 0x7faeabe60680
ERROR: License key is invalid.
)                                   = 31

+++ exited (status 1) +++

So I guess the answer lies somewhere within the memfrob and strncmp function at the end. But i don't know what's the next step.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Kroonox
  • 21
  • 3

1 Answers1

4

Let's look at the library trace call by call. The important part is in step 5.

Analysis

  1. Open the file

    fopen("license.ini", "r")                                   =0x55c088307380
    

    Opens the license file.

  2. Parse the license holder

    fgets("LicenseHolder=annabell.krause@ex"..., 4096, 0x55c088307380)  = 0x7ffe72450860
    

    Reads a line from the file: LicenseHolder=annabell.krause@ex….

    strncmp("LicenseKey=", "LicenseHolder=annabell.krause@ex"..., 11)   = 3
    

    Does the line start with LicenseKey=? The return value of 3 means no, it does not.

    strncmp("LicenseHolder=", "LicenseHolder=annabell.krause@ex"..., 14)    = 0
    

    Does the line start with LicenseHolder=? Yes, it does.

    sscanf(0x7ffe72450860, 0x55c08753c16b, 0x7ffe72450800, 0xffffc000)  = 1
    

    Unfortunately, ltrace has not dereferenced any of the addresses to show us the contents. We know that 0x7ffe72450860 is the current line, so it's presumably pulling out the e-mail address from the current line.

  3. Parse the license key

    fgets("LicenseKey=aoeklycf", 4096, 0x55c088307380) = 0x7ffe72450860
    

    It reads another line: LicenseKey=aoeklycf.

    strncmp("LicenseKey=", "LicenseKey=aoeklycf", 11)           = 0
    

    Does the line start with LicenseKey=? Yes, it does.

    sscanf(0x7ffe72450860, 0x55c08753c121, 0x7ffe72450840, 0xfffff800)  = 1
    

    It's parsing the current line. Presumably, it's extracting the license key you entered, aoeklycf, and saving it in a variable for later comparison against the expected license key. Something like sscanf(line, "LicenseKey=%s", licenseKey);.

  4. End-of-file

    fgets("LicenseKey=aoeklycf", 4096, 0x55c088307380)          = 0
    

    It tries to read another line and hits EOF. Ignore the first argument, it's just showing what was left in the buffer from the last call.

  5. License key comparison

    memfrob(0x7ffe72450840, 8, 0, 0xfbad2498)                   = 0x7ffe72450840
    

    "Encrypts" 8 bytes of some memory area by XORing each byte with 42. This can be reversed by running memfrob() again. I put "encrypts" in air quotes because this can barely be called encryption. It's just a little bit of obfuscation.

    Notice that 0x7ffe72450840 is the address from the sscanf() above. It's frobbing the variable I called licenseKey above, the LicenseKey= string it extracted from the input file.

    strncmp("KEOAFSIL", "aoeklycf", 8)                          = -22
    

    This is the money line. It compares actual and expected values and fails.

  6. Error message

    fwrite("ERROR: License key is invalid.\n", 1, 31, 0x7faeabe60680)                                   = 31
    

    An error is printed.

Synthesis

But the author doesn't want you to be able to run a simple string search like strings ./program to pull the license key out of the executable. To prevent that you have to enter the frobbed version of the license key in license.ini, not the raw string strings finds.

The code might look something like:

char *expected = "aoeklycf";
char actual[BUFSIZE];

sscanf(line, "LicenseKey=%s", actual);
memfrob(actual);
if (strncmp(actual, expected, strlen(expected)) != 0) {
    error("ERROR: License key is invalid.\n");
}

Did you extract aoeklycf from the program? If so, you missed the memfrob() step. license.ini needs to list the "encrypted" version of the license key: KEOAFSIL.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • Thank you so much! But could you explain to me how this works in detail? Because when i enter a license key different to "aoeklycf", the first output "KEOAFSIL" changes too. Is "aoeklycf" the encrypted form of "KEOAFSIL" due to the memfrob function? – Kroonox Jun 30 '19 at 15:44
  • Ah yes i extracted `aoeklycf` from the programm. Ok, now i understand. Thanks again for the explanation. – Kroonox Jun 30 '19 at 15:52