ToB企服应用市场:ToB评测及商务社交产业平台

标题: 矩阵爆破逆向之条件断点的妙用 [打印本页]

作者: 雁过留声    时间: 2024-5-12 18:07
标题: 矩阵爆破逆向之条件断点的妙用
不知道你是否利用过IDA的条件断点呢?在IDA进阶利用中,它的很多功能都有大作用,比如:ida-trace来跟踪调用流程。同时IDA的断点功能也十分强大,配合IDA-python的输出语句能够大杀特杀!
那么本文就介绍一下这个功能点,利用z3来秒解标题。
条件断点
什么是条件断点呢?
条件断点(ConditionalBreakpoint)是一种在代码调试过程中设置的断点,它可以根据特定的条件暂停步伐的执行。当步伐执行到设置了条件断点的代码行时,如果该条件为真,则步伐会暂停执行;如果该条件为假,则步伐会继续执行。这种调试技术常用于复杂的步伐调试,能够资助步伐员更快地发现步伐中的错误,并提高调试的效率。条件断点可以应用于多种编程语言和开发情况中,如C++、Java、Python等。
与普通的断点大差不差,不同点在于,步伐运行到条件断点处时,不会让步伐暂停,而是继续执行,并执行我们设置好的脚本。
OK,接下来让我们分析这道标题
初次分析
main函数
flag的格式

打开main函数,发现利用了SIMD指令赋值了一些关键数据
[img=720,200.21688613477923]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202403011500610.png[/img]

继续分析
[img=720,274.64516129032256]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202403011500611.png[/img]

看来cry1和cry2是很关键的函数
密文:

cry1
发现对我们的输入flag,举行一些转换:
比如:位置顺序和对我们的flag异或一个固定的值。
异或的值是由上下文决定的,但是总是单字节固定
[img=720,282.4937655860349]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202403011500613.png[/img]

将输入的flag运算完后,转换为 一个int类型的矩阵
[img=720,309.7132284921369]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202403011500614.png[/img]

初次分析到此结束
【----资助网安学习,以下所有学习资料免费领!加vx:dctintin,备注 “博客园” 获取!】
 ① 网安学习成长路径思维导图
 ② 60+网安经典常用工具包
 ③ 100+SRC漏洞分析报告
 ④ 150+网安攻防实战技术电子书
 ⑤ 最权威CISSP 认证考试指南+题库
 ⑥ 超1800页CTF实战本领手册
 ⑦ 最新网安大厂面试题合集(含答案)
 ⑧ APP客户端安全检测指南(安卓+IOS)
cry2
[img=720,493.65269461077844]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202403011500615.png[/img]

[img=720,144.9418604651163]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202403011500616.png[/img]

条件断点妙用
经过动调,我发现关键的加密就这三个汇编指令。
意思:取flag->与一个固定的矩阵相乘->输出加密之后的矩阵
如果我们能够打印,加密前的flag和相乘的矩阵元素,就可以逆推明文啦
主要是不清楚,矩阵相乘的顺序,可能是打乱的,那样只能这样来做。
利用了:条件断点
[img=720,266.9178082191781]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202403011500617.png[/img]

这三个断点依次利用下面3个条件输出
主要是这两个命令:
get_reg_value("rbx") 获取rbx寄存器的值
idc.get_wide_dword() 获取某地址的值(4字节读取)
  1.  print("[rbx] = ",hex(idc.get_wide_dword(get_reg_value("rbx"))))
  2.  
  3.  print("rax = ",hex(get_reg_value("rax")),"[rdi]=
  4.  ",hex(idc.get_wide_dword(get_reg_value("rdi"))))
  5.  
  6.  print("output,rax = ",hex(get_reg_value("rax")),"n")
复制代码
[img=720,217.32441471571906]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202403011500619.png[/img]

然后edit breakpoint
[img=720,200.04499437570303]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202403011500620.png[/img]

[img=720,392.5233644859813]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202403011500621.png[/img]

OK,见证古迹的时刻到了,运行步伐,乐成输出:
[img=720,372.0388349514563]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202403011500622.png[/img]

推导
因为密文说16字节的,我们将真正的密文提取出来和我们输入假flag产生的密文也提取出来,举行对比
Python
  1. 密文
  2.  unsigned int data[16] = {
  3.  0x00000436, 0x000002B4, 0x000002AF, 0x00000312, 0x000002EA, 0x00000253,
  4.  0x0000020A, 0x0000028E,
  5.  0x000001C6, 0x0000015C, 0x0000017C, 0x0000017A, 0x0000069E, 0x000004AE,
  6.  0x000004B1, 0x00000522
  7.   };
  8.  
  9.  假flag输出的结果密文
  10.  unsigned int data[16] = {
  11.  0x00000466, 0x000002F9, 0x00000329, 0x0000046E, 0x00000290, 0x00000184,
  12.  0x000001E4, 0x0000023A,
  13.  0x00000183, 0x000000C1, 0x0000011E, 0x00000122, 0x00000646, 0x00000467,
  14.  0x000004F7, 0x000005EA
  15.   };
  16.  
  17.  这是根据条件输出得到的规律;
  18.  
  19.  x1*1+x2*5+x3*4+x4*3=0x436
  20.  y1*1+y2*5+y3*4+y4*3=0x2B4
  21.  z1*1+z2*5+z3*4+z4*3=0x2AF
  22.  n1*1+n2*5+n3*4+n4*3=0x312
  23.  
  24.  x1*2+x2*1+x3*2+x4*3=0x2EA
  25.  y1*2+y2*1+y3*2+y4*3=0x253
  26.  z1*2+z2*1+z3*2+z4*3=0x20A
  27.  n1*2+n2*1+n3*2+n4*3=0x28E
  28.  
  29.  x1*2+x2+x3+x4=0x1c6
  30.  y1*2+y2+y3+y4=0x15c
  31.  z1*2+z2+z3+z4=0x17c
  32.  n1*2+n2+n3+n4=0x17a
  33.  
  34.  x1*3+x2*5+x3*4+x4*7=0x69e
  35.  y1*3+y2*5+y3*4+y4*7=0x4ae
  36.  z1*3+z2*5+z3*4+z4*7=0x4b1
  37.  n1*3+n2*5+n3*4+n4*7=0x522
复制代码

z3解密
解密脚本:
Python
  1. from z3 import *
  2.  
  3.  # 定义变量
  4.  x = [Int(f'x{i}') for i in range(1, 5)]
  5.  y = [Int(f'y{i}') for i in range(1, 5)]
  6.  z = [Int(f'z{i}') for i in range(1, 5)]
  7.  n = [Int(f'n{i}') for i in range(1, 5)]
  8.  
  9.  # 定义目标值
  10.  goal = [
  11.  0x466,
  12.  0x2f9,
  13.  0x329,
  14.  0x46e,
  15.  0x290,
  16.  0x184,
  17.  0x1e4,
  18.  0x23a,
  19.  0x183,
  20.  0xc1,
  21.  0x11e,
  22.  0x122,
  23.  0x646,
  24.  0x467,
  25.  0x4f7,
  26.  0x5ea
  27.   ]
  28.  
  29.  # 定义约束条件
  30.  constraints = [
  31.  x[0]*1 + x[1]*5 + x[2]*4 + x[3]*3 == goal[0],
  32.  y[0]*1 + y[1]*5 + y[2]*4 + y[3]*3 == goal[1],
  33.  z[0]*1 + z[1]*5 + z[2]*4 + z[3]*3 == goal[2],
  34.  n[0]*1 + n[1]*5 + n[2]*4 + n[3]*3 == goal[3],
  35.  x[0]*2 + x[1]*1 + x[2]*2 + x[3]*3 == goal[4],
  36.  y[0]*2 + y[1]*1 + y[2]*2 + y[3]*3 == goal[5],
  37.  z[0]*2 + z[1]*1 + z[2]*2 + z[3]*3 == goal[6],
  38.  n[0]*2 + n[1]*1 + n[2]*2 + n[3]*3 == goal[7],
  39.  x[0]*2 + x[1] + x[2] + x[3] == goal[8],
  40.  y[0]*2 + y[1] + y[2] + y[3] == goal[9],
  41.  z[0]*2 + z[1] + z[2] + z[3] == goal[10],
  42.  n[0]*2 + n[1] + n[2] + n[3] == goal[11],
  43.  x[0]*3 + x[1]*5 + x[2]*4 + x[3]*7 == goal[12],
  44.  y[0]*3 + y[1]*5 + y[2]*4 + y[3]*7 == goal[13],
  45.  z[0]*3 + z[1]*5 + z[2]*4 + z[3]*7 == goal[14],
  46.  n[0]*3 + n[1]*5 + n[2]*4 + n[3]*7 == goal[15]
  47.   ]
  48.  
  49.  # 创建求解器
  50.  solver = Solver()
  51.  
  52.  # 添加约束条件
  53.  solver.add(constraints)
  54.  
  55.  # 求解
  56.  if solver.check() == sat:
  57.  model = solver.model()
  58.  for i in range(1, 5):
  59.  print(f'x{i} = {model[x[i-1]]}')
  60.  print(f'y{i} = {model[y[i-1]]}')
  61.  print(f'z{i} = {model[z[i-1]]}')
  62.  print(f'n{i} = {model[n[i-1]]}')
  63.  else:
  64.  print('无解')
复制代码
得到的结果,将其按照数组来填充

得到
Python
  1. 这是真flag解密后的结果:
  2.  x1 = 100
  3.  y1 = 89
  4.  z1 = 119
  5.  n1 = 92
  6.  
  7.  x2 = 66
  8.  y2 = 5
  9.  z2 = 69
  10.  n2 = 4
  11.  
  12.  x3 = 84
  13.  y3 = 83
  14.  z3 = 4
  15.  n3 = 104
  16.  
  17.  x4 = 104
  18.  y4 = 82
  19.  z4 = 69
  20.  n4 = 86
  21.  
  22.  100,89,119,92,66,5,69,4,84,83,4,104,104,82,69,86
  23.  
复制代码
这是假flag解密后的结果:
  1. x1 = 60
  2.  y1 = 1
  3.  z1 = 47
  4.  n1 = 4
  5.  
  6.  x2 = 88
  7.  y2 = 87
  8.  z2 = 86
  9.  n2 = 95
  10.  
  11.  x3 = 89
  12.  y3 = 13
  13.  z3 = 14
  14.  n3 = 94
  15.  x4 = 90
  16.  y4 = 91
  17.  z4 = 92
  18.  n4 = 93
  19.  
  20.  60,1,47,4,88,87,86,95,89,13,14,94,90,91,92,93
复制代码
按照我的思绪来填充结果数组;
[img=720,309.375]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202403011500624.png[/img]

因为刚才说了,异或的值不清楚,但是一直为单字节固定值,以是利用Cybe的爆破功能。
根据步伐的验证功能可知,flag以Sn@K开头,以是找到了真正的flag
但是顺序发生了变化,下面是假flag生成密文解密之后的结果,发现密文变化了
+-----------------------------------------------------------------------+
| Sn@ku2r3cd3__era                                                      |
| Sn@k78906ba15432                                                     |
|                                                                                       |
| Sn@k0123456789ab                                                    |
|                                                                                       |
| 经过互换后的结果:                                                      |
|                                                                                       |
| Sn@k78906ba15432                                                    |
|                                                                                       |
| 按照我们构造的flag互换顺序后的字符串来规复            |
| 规复                                                                               |
| Sn@k3_are_cu2r3                                                        |
+-----------------------------------------------------------------------+

乐成验证!

更多网安技能的在线实操练习,请点击这里>>
  

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4