swiss hacking challenge 2024 - license-check

Posted on May 1, 2024

Difficulty: medium

Category: re

Author: tttttx2

Have you heard? Phishing is on the rise, evil people are hacking things, and this hurts our sales. Management held an all-hands-on-deck meeting yesterday, and posed an important question:

What if some evil hacker group simply cracks the license code to our new Cyber Gateway?

Well, finally it’s Steve’s time to shine, as he came up with a fancy new license checker - surely it must be unbreakable, it’s Steve down in accounting we’re talking about!

Files

We get four verilog files:

license-check
├── flagchecker_encoder.v
├── flagchecker_keygen.v
├── flagchecker_tb.v
└── flagchecker_validator.v

They do the following:

  • flagchecker_encoder.v: XOR the provided flag when posedge clk or posedge reset
  • flagchecker_keygen.v: Gerates a key when negedge clk or posedge reset, on reset start with b11011001 and cnt = 0, otherwise key = key + 2*cnt and cnt += 1
  • flagchecker_validator.v: Validates the flag based on a lot of bit shifts and a hardcoded encoded flag value
  • flagchecker_tb.v: Contains an example flag and runs all the other files to validate that flag

Exploitation

We can just print out the XOR key at the right interval by adding the following to the flagchecker_tb.v:

  always @(negedge clk or posedge reset) begin
    $display("%d", key);
  end

Then, I used verilator to compile and run the verilog:

$ verilator --binary  *.v --timing  -Wno-lint
$ ./obj_dir/Vflagchecker_encoder
  0
  0
217
217
219
223
217
217
217
219
223
229
229
231
235
241
241
243
247
253
253
255
  3
  9
  9
 11
 15
 21
 21
 23
 27
 33

We can now use the hex string from the validator (52737427253d3f7279669699ccb29a96998481808ce7b8a400) and XOR it with the keys in reverse order to get the flag:

from pwn import *
key = [0, 0, 217, 217, 219, 223, 217, 217, 217, 219, 223, 229, 22, 9, 231, 235, 241, 241, 243, 247, 253, 253, 255, 3, 9, 9, 11, 15, 21, 21, 23, 27, 33]
enc = unhex("52737427253d3f7279669699ccb29a96998481808ce7b8a400")
xor(key[::-1], enc)

Flag

shc2024{peid1Eighofei8c}

Conclusion

Cool challenge :D I feel like I could’ve gone down quite a rabbithole by trying to reverse the checker myself.