0

In short, I have a code that gets an input via stdin. Once it has the input string in memory, it verifies its integrity by calling a function for every condition, and exiting the program if those conditions are not met.

There are 20 of those verifications, and I do not think it is efficient to reverse it manually considering the first is (according to Ghidra disassemblying), being param1 = (long) input; and input = the 32-byte array in which the input is stored,

void verify1(long param_1){
    if ((int)*(char *)(param_1 + 4) * (int)*(char *)(param_1 + 0xf) - (int)*(char *)(param_1 + 0xd) !=
      0x349f) {
        exit(-1);
      }
    return;
}

I think a program or plugin to automate this would be useful. However, I could not find anything useful at all.

4
  • 2
    You could try angr or z3 to get what input would be needed for passing all the checks. May 17, 2021 at 12:49
  • Roger that, and thank you for the answer. Gonna try them out May 17, 2021 at 13:42
  • There's an example of using angr to solve a crackme employing many checks here (I'm the author of the article)
    – julian
    May 17, 2021 at 13:48
  • Okay, @julian, I am reading it. I'm sure it'll be interesting! May 17, 2021 at 17:04

1 Answer 1

0

trying to tackle it with pencil and paper

a common pattern pattern noticeable is
(int)*(char *)(param_1 + x) which is equivalent to param_1[x] (unsigned char Array access)

so if you pass an array like

char param_1[] ={ 0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf}; 

then the function will multiply param_1[4] * param_1[0xf] and subtract param_1[0xd] or actually 4*0xf-0xd = 0x2f

since we know it is a char so any of these values can be only with 0 to 255

so the equation is a * b = 0x349f+c where a,b,c can only be between 0 and 255 or rather 1 and 255 as multiplication by 0 is 0

simply brute forcing you have a possible 215 key space for next round

def brute1(x):    
    for divisor in range(1, x + 1):
        rem = (x % divisor)
        quo = (x / divisor)
        if ( (rem == 0) and (quo < 128) and (divisor<255) ):
            print("a = %3d        b = %3d          c = %3d\t" % 
            (divisor,quo,((divisor*quo)-0x349f)))
            
print ("a = param_1[4] b = param_1[0xf] c = param_1[0xd]")            
for i in range(0x349f,(0x349f+0xff),1):    
    brute1(i)

some possible chars

python verify.py | wc -l
216
python verify.py | head -n 5
a = param_1[4] b = param_1[0xf] c = param_1[0xd]
a = 175        b =  77          c =   4
a = 245        b =  55          c =   4
a = 221        b =  61          c =  10
a = 107        b = 126          c =  11

with this in hand you can possibly lift the function and dump it into a c maybe for testing a set of key lets say (55,245,4)

#include <stdio.h>
#include <stdlib.h>

void verify1(unsigned char *param_1)
{
    if (
        (int)*(unsigned char *)(param_1 + 4) *
                (int)*(unsigned char *)(param_1 + 0xf) -
            (int)*(unsigned char *)(param_1 + 0xd) !=
        0x349f)
    {
        exit(-1);
    }
    return;
}

int main(void)
{
    unsigned char param_1[] = {0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 245};
    verify1(param_1);
    printf("we passed verify1\n");
}

compiling and executing

cl /Zi /W4 /analyze /Od /nologo verify.cpp /link /release
verify.cpp

verify.exe
we passed verify1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.