cscg24-license

CSCG 2024 Challenge 'Most unique license checker'
git clone https://git.sinitax.com/sinitax/cscg24-license
Log | Files | Refs | sfeed.txt

commit f73a986ae16975455d86ebd440d86d90d270af6b
parent c4cc7c6341e6326c1a2a5a42768ce27bd3535380
Author: Louis Burda <quent.burda@gmail.com>
Date:   Fri,  5 Apr 2024 20:23:39 +0200

Add solution

Diffstat:
Achall/description | 3+++
Achall/single-license.zip | 0
Asolve/all.o | 0
Asolve/all.o.sig | 0
Asolve/bvscript | 11+++++++++++
Asolve/got.plt | 0
Asolve/libc.a.sig | 0
Asolve/libc6-dev_2.35-0ubuntu3.6_amd64.deb | 0
Asolve/licensecheck | 0
Asolve/licensecheck.bndb | 0
Asolve/notes | 9+++++++++
Msolve/solve | 19+++++++++++++++++++
12 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/chall/description b/chall/description @@ -0,0 +1,3 @@ +So you think you cracked some license checkers before? Try this unique license checker and see if you have the requirements to crack all software! + +The web-service is only used to verify the valid license and get the flag. You don't need to attack it or do any scanning against it! diff --git a/chall/single-license.zip b/chall/single-license.zip Binary files differ. diff --git a/solve/all.o b/solve/all.o Binary files differ. diff --git a/solve/all.o.sig b/solve/all.o.sig Binary files differ. diff --git a/solve/bvscript b/solve/bvscript @@ -0,0 +1,11 @@ +plt = bv.sections[".plt"] +for a in range(plt.start, plt.end, 8): + f = bv.get_function_at(a) + if f is None: continue + i = next(f.hlil.instructions) + assert(type(i) == binaryninja.highlevelil.HighLevelILJump) + dst = i.get_expr(1).value.value + src = bv.get_data_var_at(dst).value + f2 = bv.get_function_at(src) + f.name = "plt_" + f2.name + diff --git a/solve/got.plt b/solve/got.plt Binary files differ. diff --git a/solve/libc.a.sig b/solve/libc.a.sig Binary files differ. diff --git a/solve/libc6-dev_2.35-0ubuntu3.6_amd64.deb b/solve/libc6-dev_2.35-0ubuntu3.6_amd64.deb Binary files differ. diff --git a/solve/licensecheck b/solve/licensecheck Binary files differ. diff --git a/solve/licensecheck.bndb b/solve/licensecheck.bndb Binary files differ. diff --git a/solve/notes b/solve/notes @@ -0,0 +1,9 @@ +trying to symbolically solve, should be possible, angr as intransparent as ever + +problem is that the plt entries are not updated yet, which is why +just using call_state fails + +its only a few functions, could do it by hand.. but to actually learn +something i should try to automate it. + +basically want that angr can make it through the init process so the funcs are init. diff --git a/solve/solve b/solve/solve @@ -7,10 +7,17 @@ import signal def sigalarm(_a, _b): print("STATE", sim, sim.active) + if len(sim.active) > 0: + print(sim.active[0].callstack) signal.signal(signal.SIGALRM, sigalarm) signal.alarm(1) signal.signal(signal.SIGALRM, sigalarm) +def sigint(_a, _b): + from IPython import embed + embed() +signal.signal(signal.SIGINT, sigint) + key_addr = 0x1000 keylen = 29 key = [claripy.BVS(f"key_{i}", 8) for i in range(keylen)] @@ -29,6 +36,8 @@ state.memory.store(0x4cd000, open("got.plt", "rb").read()) state.regs.rbp = state.regs.rsp state.regs.fs = blank.regs.fs +#state.memory[0x401980].uint8_t = 0xc3 + binfile = angr.SimFile("licensecheck", open("licensecheck", "rb").read()) binfile.set_state(state) @@ -83,6 +92,16 @@ checkpoint(0x40205d, "after strlen") checkpoint(0x40207f, "after len check") assert(len(sim.active) == 1) +sim.active[0].regs.rip = 0x4020e4 + +signal.alarm(1) +sim.explore(find=0x402538, avoid=0x4020a4) +print("found!", sim) +state = sim.found[0] +state.solver.add(state.regs.rax != 1) +print_key() + +raise 0 signal.alarm(1) findall(0x4020d0, "before content check")