-
-
[原创]签到题
-
发表于: 2021-11-22 14:44 2692
-
main函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | int __cdecl sub_141340(HWND hDlg) { int name_len; / / ebx@ 1 unsigned int v2; / / ebx@ 2 int v3; / / eax@ 4 int result; / / eax@ 6 signed int serial_len; / / [sp + Ch] [bp - 260h ]@ 2 char rst; / / [sp + 10h ] [bp - 25Ch ]@ 1 CHAR name; / / [sp + D8h] [bp - 194h ]@ 1 CHAR serial; / / [sp + 1A0h ] [bp - CCh]@ 1 sub_1420A0(&name, 0 , 200 ); sub_1420A0(&rst, 0 , 200 ); sub_1420A0(&serial, 0 , 200 ); name_len = GetDlgItemTextA(hDlg, 1000 , &name, 201 ); if ( name_len && (serial_len = GetDlgItemTextA(hDlg, 1001 , &serial, 201 ), v2 = sub_141260(&name, name_len), sub_142CA0(&serial, "0123456789" ) = = strlen(&serial)) && serial_len < = 10 && (v3 = calc_serial(&serial)) ! = 0 && (sub_1442B3(v2 ^ v3, &rst, 16 ), sub_141260(&rst, 8 ) = = 0x13B88C77 ) ) { SetDlgItemTextA(hDlg, 1001 , "Success!" ); result = 1 ; } else { SetDlgItemTextA(hDlg, 1001 , "Wrong Serial!" ); result = 0 ; } return result; } |
重点是:
1 2 3 4 5 6 7 8 | if ( name_len && (serial_len = GetDlgItemTextA(hDlg, 1001 , &serial, 201 ), v2 = sub_141260(&name, name_len), sub_142CA0(&serial, "0123456789" ) = = strlen(&serial)) && serial_len < = 10 && (v3 = calc_serial(&serial)) ! = 0 && (sub_1442B3(v2 ^ v3, &rst, 16 ), sub_141260(&rst, 8 ) = = 0x13B88C77 ) ) { |
满足以上条件才能success。 从右往左分析,
sub_141260依赖于 参数rst,rst从sub_1442B3传递过来。
sub_1442B3的功能是将 v2 ^ v3的结果转化为字符串。
关键在于v2 ^ v3的值,其中 v2由用户名计算而来,v3由序列哈计算而来。
规则二给出了一个组正确的用户名、密码。
ida调试,发现 rst="52a1ed5a",
v2^v3 = 0x52a1ed5a1
输入用户名KCTF,动态调试得到V2 =0x5ee54f4c
1 2 3 4 | 得到: name = > KCTF = 0xfeef4f4c name ^ serial = 0x52a1ed5a 固 serial = 0x0c44a216 |
v3由serial计算而来,计算函数是calc_serial
1 2 3 4 5 6 | .text: 0014141A lea eax, [ebp + serial] .text: 00141420 push eax ; p_serial .text: 00141421 call calc_serial .text: 00141426 add esp, 4 .text: 00141429 test eax, eax .text: 0014142B jz short loc_14 |
函数入参已有一个就是注册码,返回值为v3,使用angr模拟计算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | import angr import claripy import sys def main(argv): path_to_binary = argv[ 1 ] project = angr.Project(path_to_binary) start_address = 0x00401420 win_addr = 0x00401456 serial_buf = 0x12ff600 initial_state = project.factory.blank_state(addr = start_address, load_options = { "auto_load_libs" : False }) flag_chars = [claripy.BVS( 'flag_%d' % i, 8 ) for i in range ( 9 )] for flag in flag_chars: initial_state.solver.add(flag> = 48 ) initial_state.solver.add(flag< = 57 ) password0 = claripy.Concat( * flag_chars + [claripy.BVV (b '\0' )]) initial_state.memory.store(serial_buf,password0) initial_state.regs.eax = serial_buf simulation = project.factory.simgr(initial_state) #0x52a1ed5a # name: KCTF = 0x5EE5 4F4C # name ^ serial = 0x52a1ed5a #serial = 0x 0C44A216 check_addr = 0x00401426 def is_successful(state): return state.solver.is_true(state.regs.eax = = 0x26eff19d ) print ( ">>>>>>>>>>>>>> init" ) simulation.explore(find = check_addr) print ( ">>>>>>>>>>>>>> run end" ) if simulation.found: check_state = simulation.found[ 0 ] check_state.solver.add(check_state.regs.eax = = 0x0C44A216 ) solution0 = check_state.solver. eval (password0, cast_to = bytes) print ( "Solution : {}" . format (solution0)) print ( "Solution : {}" . format (solution0.decode( "utf-8" ))) else : raise Exception( 'Could not find the solution' ) if __name__ = = '__main__' : main(sys.argv) |
结果如下
1 2 3 | >>>>>>>>>>run end Solution:b '205824534\x00' Solution: 205824534 |
这个就是序列号了
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
看原图
赞赏
雪币:
留言: