# Password evaluated from the sum of ASCII letters

After analyzing the code, I have been able to understand and recreate the algorithm used to check if the password the binary takes is correct, but don't know how to solve it (or at least can't think of any approach that would be performant enough to finish within feasible time).

The first three letters of the expected password can be easily seen in the disassembly, as well as the length of the password being 16 letters.

Then it gets a little tricky, as the program enters a loop summing up the ASCII values of different letters of the password into 4 variables, which are afterwards checked against a value each after being taken modulo 100, which have to be met for the password to be regarded as "correct"

To be more exact, the letters are summed up as follows (indices in the password starting from 1: Var1: 1, 3, 4, 6, 7, 11, 12, 14, 15 Var2: 1, 3, 5, 7, 9, 11, 13, 15 Var3: 2, 5, 8, 11, 14 Var4: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15

This also tells me, that given I didn't understand the code completely wrong, the last letter of the password is not relevant as well.

Anyways, my question would be, if with the information present this problem is even solvable, and if yes, what approach would make sense, as brute-forcing obviously doesn't.

You may be able to set up a system of equations and try and narrow this down with linear algebra. Because you have more unknowns than knowns, you will not be able to know the original password, but you can still get one the passes the validation routine. You already know some of the letters due to seeing them in the disassembly.

As a smaller example, say we know the first letter of a password is `G` and the that there are 6 letters. The program then sums up the letters into three variables as follows:

``````var1 = password[0] + password[1] + password[5]
``````

Then later we see that it checks:

``````var1 == 225
var2 == 160
var3 == 392
``````

We can set up a matrix for this:

``````[1 1 0 0 0 1 | 225]
[1 0 0 0 1 0 | 160]
[1 1 1 1 1 0 | 392]
``````

Using `SymPy` or something similar, we can reduce this matrix down:

``````from sypy import *
A = Matrix([[1,1,0,0,0,1,225],[1,0,0,0,1,0,160],[1,1,1,1,1,0,392]])
A.rref()

(Matrix([
[1, 0, 0, 0,  1,  0, 160],
[0, 1, 0, 0, -1,  1,  65],
[0, 0, 1, 1,  1, -1, 167]]), (0, 1, 2))
``````

Our pivots are `password[0]`, `password[1]` and `password[2]`. We already know `password[0] == 71`, we will select whatever we want for `password[1]` & `password[2]` and will try to get everything else in terms of these.

Since we know that the first letter is `'G'` and has a value of `71`, the first equation is `72 + password[4] = 160`. We now know `password[4]` is `89` or `Y`.

Knowing this, we can look at our next equation. `password[1] - 89 + password[5] = 65.` Rewriting: `password[5] = 154 - password[1]`.

We can now look at the last equation: `password[2] + password[3] + 89 - password[5] = 167` Rewriting: `password[3] = password[5] - password[2] + 78`

Putting it all together:

``````password[0] = 'G'
``````

Now we just assign whatever we want for `password[1]` and `password[2]` and we will get a valid password.

``````password[1] = 'A'
``````
``````# Find password[5]
chr(154 - ord('A'))
'Y'

chr(ord('Y') - ord('A') + 78)
'f'

It will be harder for your specific one because you the numbers are being taken `% 100`, but you know how many characters there are and what value range ASCII falls in so it shouldn't be too hard to set a limited range for the possible values.