[Writeup] badblock writeup

[复制链接]
查看7025 | 回复0 | 2019-5-22 22:41:42 | 显示全部楼层 |阅读模式
题目地址:https://www.bugku.com/ctfexercise-competition-163.html

main函数打开发现是C++写的,充斥大量无用代码
于是转头执行,发现接收输入后回弹err...
搜索字符串发现有三处引用
分别是两个anti_debug和一个puts_wrong
anti_debug分别通过ptrace和getpid()的方法,不必多说,调试的时候直接绕过即可

puts_wrong则是在一个vtable中,很明显是一个类的成员函数
于是根据vt指针找到sub_5607AA5F4DD0
做了一些初始化以后、包括对input和data的赋值
调用了这个函数
  1. return (*((unsigned int (__fastcall **)(Class *))obj->this + 13))(obj) == 1;
复制代码
this+13即vt[12],点进去看一下即可发现是main_loop

循环处理code,显然是个VM
此处一共有2个类,根据代码逐步复原结构即可然后处理VM的各个handler

  1. .data.rel.ro:00005607AA7F7A10 vt              dq offset plus          ; DATA XREF: Imp+16↑o
  2. .data.rel.ro:00005607AA7F7A18                 dq offset sub
  3. .data.rel.ro:00005607AA7F7A20                 dq offset cmp
  4. .data.rel.ro:00005607AA7F7A28                 dq offset jmp_2
  5. .data.rel.ro:00005607AA7F7A30                 dq offset mov
  6. .data.rel.ro:00005607AA7F7A38                 dq offset save_ip
  7. .data.rel.ro:00005607AA7F7A40                 dq offset load_ip
  8. .data.rel.ro:00005607AA7F7A48                 dq offset load_short
  9. .data.rel.ro:00005607AA7F7A50                 dq offset wrong
  10. .data.rel.ro:00005607AA7F7A58                 dq offset load_input
  11. .data.rel.ro:00005607AA7F7A60                 dq offset load_data
  12. .data.rel.ro:00005607AA7F7A68                 dq offset xor
  13. .data.rel.ro:00005607AA7F7A70                 dq offset get_final_flag
  14. .data.rel.ro:00005607AA7F7A78                 dq offset main_loop
复制代码

跑一下log可以发现是将输入和一个数异或后与另一个数比较的算法,dump出来发现不可见,于是回头调试发现在接受输入后的几行指令后的sub_5607AA5F4D50中对输入进行了一个前后字符异或的处理


我对模拟器进行了Patch功能-即输入不对时也会继续向后执行,和Dump功能的添加–计算并保存flag

  1. code = [8, 0, 20, 8, 1, 0, 8, 2, 1, 8, 7, 9, 8, 8, 0, 8, 9, 0, 1, 9, 8, 1, 8, 2, 3, 7, 8, 516, 65532, 0, 5, 3, 9, 3, 1, 0, 260, 10, 0, 5, 4, 1, 1, 4, 3, 1, 4, 4, 10, 5, 1, 12, 5, 4, 11, 6, 1, 1, 1, 2, 3, 6, 5, 260, 65525, 0, 516, 1, 0, 255, 0, 0, 9, 0, 0, 255, 0, 0, 0, 0, ]
  2. # data = [46, 0, 38, 0, 45, 0, 41, 0, 77,0,103, 0, 5, 0, 68, 0, 26, 0, 14,0,127, 0, 127, 0, 125, 0, 101, 0, 119,0,36, 0, 26, 0, 93, 0, 51, 0, 81, 0]
  3. mem = [0 for i in range(50)]
  4. input = [0 for i in range(50)]
  5. dump = ""
  6. n = 0
  7. flag = 0
  8. while (n < 100):
  9.     # patch check
  10.     if (n == 21):
  11.         flag = 1
  12.         # print("Patched:%d"%flag)
  13.     c = code[3 * n] & 0xff
  14.     f = code[3 * n] >> 8
  15.     h1 = code[3 * n + 1]
  16.     h2 = code[3 * n + 2]
  17.     if (f != 0 and f != flag):
  18.         n += 1
  19.         print("pass")
  20.         continue
  21.     if (False):
  22.         pass
  23.     elif (c == 1):
  24.         mem[h1] += mem[h2]
  25.     elif (c == 2):
  26.         mem[h1] -= mem[h2]
  27.     elif (c == 3):
  28.         # dump flag
  29.         if (n == 20):
  30.             dump += chr(mem[4] ^ mem[6])

  31.         print("cmp:%d-%d" % (mem[h1], mem[h2]), end='\t')
  32.         if (mem[h1] != mem[h2]):
  33.             flag = 2
  34.         else:
  35.             flag = 1
  36.         print(flag)
  37.     elif (c == 4):
  38.         n += h1
  39.         n &= 0xff
  40.         print("jmp")
  41.     elif (c == 5):
  42.         mem[h1] = mem[h2]
  43.     elif (c == 6):
  44.         mem[h1] = n
  45.     elif (c == 7):
  46.         n = mem[h1]
  47.     elif (c == 8):
  48.         mem[h1] = h2
  49.     elif (c == 9):
  50.         print("failed")
  51.         break
  52.     elif (c == 10):
  53.         print("Load input[%d] to %d" % (mem[h2], h1))
  54.         mem[h1] = input[mem[h2]]
  55.     elif (c == 11):
  56.         mem[h1] = data[mem[h2] * 2]
  57.     elif (c == 12):
  58.         mem[h1] ^= mem[h2]
  59.     elif (c == 255):
  60.         pass
  61.     else:
  62.         print("Error:%d" % c)
  63.         break
  64.     print("[%d]: %d-%d-%d" % (n, c, h1, h2), end=' ')
  65.     print(mem)
  66.     n += 1
  67. print(dump)
  68. input = [(ord(i)) for i in dump]
  69. for i in range(4):
  70.     for j in range(len(input) - 2, -1, -1):
  71.         input[j + 1] ^= input[j]
  72. print(input)
  73. print("".join([chr(i) for i in input]))

复制代码

最后flag

flag{Y0u_ar3_S0co0L}


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

5

主题

6

帖子

87

积分

版主

Rank: 7Rank: 7Rank: 7

积分
87