首页
社区
课程
招聘
[原创]签到题
2021-11-22 14:44 2162

[原创]签到题

2021-11-22 14:44
2162

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

这个就是序列号了


[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

收藏
点赞0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回