Jump to content
Tuts 4 You

A crackme with math problem


wwh1004

Recommended Posts

wwh1004

A crackme with math problem


Just run it. It is an interesting math problem. No vm, no obfuscation. You can debug it with dnSpy even Visual Studio. You should use public method inside this crackme to generate a valid hex string and make program output correct string.


 

Link to post
Washi

Either I am missing something (which is very likely, there is so much trash CIL in the methods that it is easy to miss something), or the crackme is kind of broken. I managed to construct a key that gets passed the entire verification process, yet the decryption of the flag fails with a padding error. It looks to me like some floating point precision error, but I am not sure.

Spoiler
  • Input string is a hex string of a serialized mathematical expression in AST form, which from now on will be referred to as g(x) (nodes are represented using GClass1).
  • Nice iterative bottom-up AST evaluator for mathematical expressions in smethod_6 (why use Tuple instead of ValueTuple though :c)
  • Nice hardcoded function f(x) = (2x+3)e^x+0 in Main (Fun fact, the hardcoded string is 66 chars long, resulting in 33 bytes. This is actually 5 hex bytes (=10 chars) too short. The deserializer reads from an unmanaged memory pointer that goes out of bounds, reading arbitrary memory. For me it always seemed to read 0 bytes, which results in the +0 added to the formula. This can be verified by serializing the read data back to a hex string and observing the 10 extra chars. Maybe there is an issue here?)
  • Crackme evaluates g(0) and verifies the result is 1 (with a particular margin of error), then computes the following for all x between 0 and 100 with step size 0.01
  • Screenshot_20200812_174350.png.d1385f33f9a59b53d0d67185a94fdeea.png
  • This is a numerical way to approximate the derivative of any function: In our case, the input function.
  • All computed values are compared with the value of f(x)+g(x).
  • Therefore, to solve this crackme, we need to find a function that is the solution to the first order differential equation g'(x) = f(x) + g(x) = (2x+3)e^x + g(x).
  • Solution to this is the formula below. If you plot the graphs using e.g. desmos.com, you can see g'(x) is exactly the function that the formula in the above attempts to approximate.
  • Screenshot_20200812_173424.png.b6dd5589937a5deeca08594490384d2d.png
  • To solve for c1, we come back to the fact that the program also verifies that g(0) = 1. Basic algebra tells us that this is only true if c1 = 1.
  • Now we need to write this function in hex format. For this, just reverse the reading process, or use the serializer in the binary itself.
  • I wrote my solution in Python first, which spits out the following as a hex representation of the formula above, with c1 set to 1.0.
  • Quote

    10041203000000000000f03f04140407000000000004100412041404070000000000041504070000000000000200000004120003000000041204140407000000000004070000000000

  • This passes all the tests, and the code continues into the decryption routine, but fails on the TransformFinalBlock call regardless. Note how obj5 and num7 (the results of both approximation and augmented input formula) are equal (within a certain margin of error).
  • wwh.gif.cde22b6c49427914ad4a00d657ed4bc8.gif
  • Using C# instead and the public serializer methods that were provided by the binary produces the same kind of result.
  • The differential equation to my knowledge only has one solution for g(0) = 1, and the derivative tests all succeed, so this should not be the issue, unless I missed something completely obvious 😀

Let me know if you want to see either my python script or C# program that produces an answer :)

 

Edited by Washi
Grammar (see edit history)
Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...