矩陣爆破逆向之條件斷點的妙用

合天网安实验室發表於2024-03-01

不知道你是否使用過IDA的條件斷點呢?在IDA進階使用中,它的很多功能都有大作用,比如:ida-trace來跟蹤呼叫流程。同時IDA的斷點功能也十分強大,配合IDA-python的輸出語句能夠大殺特殺!

那麼本文就介紹一下這個功能點,使用z3來秒解題目。

條件斷點

什麼是條件斷點呢?

條件斷點(ConditionalBreakpoint)是一種在程式碼除錯過程中設定的斷點,它可以根據特定的條件暫停程式的執行。當程式執行到設定了條件斷點的程式碼行時,如果該條件為真,則程式會暫停執行;如果該條件為假,則程式會繼續執行。這種除錯技術常用於複雜的程式除錯,能夠幫助程式設計師更快地發現程式中的錯誤,並提高除錯的效率。條件斷點可以應用於多種程式語言和開發環境中,如C++、Java、Python等。

與普通的斷點大差不差,不同點在於,程式執行到條件斷點處時,不會讓程式暫停,而是繼續執行,並執行我們設定好的指令碼。

OK,接下來讓我們分析這道題目

初次分析

main函式

flag的格式

矩陣爆破逆向之條件斷點的妙用

開啟main函式,發現使用了SIMD指令賦值了一些關鍵資料

矩陣爆破逆向之條件斷點的妙用

繼續分析

矩陣爆破逆向之條件斷點的妙用

看來cry1和cry2是很關鍵的函式

密文:

矩陣爆破逆向之條件斷點的妙用

cry1

發現對我們的輸入flag,進行一些轉換:

比如:位置順序和對我們的flag異或一個固定的值。

異或的值是由上下文決定的,但是總是單位元組固定

矩陣爆破逆向之條件斷點的妙用

將輸入的flag運算完後,轉換為 一個int型別的矩陣

矩陣爆破逆向之條件斷點的妙用

初次分析到此結束

【----幫助網安學習,以下所有學習資料免費領!加vx:dctintin,備註 “部落格園” 獲取!】

 ① 網安學習成長路徑思維導圖
 ② 60+網安經典常用工具包
 ③ 100+SRC漏洞分析報告
 ④ 150+網安攻防實戰技術電子書
 ⑤ 最權威CISSP 認證考試指南+題庫
 ⑥ 超1800頁CTF實戰技巧手冊
 ⑦ 最新網安大廠面試題合集(含答案)
 ⑧ APP客戶端安全檢測指南(安卓+IOS)

cry2

矩陣爆破逆向之條件斷點的妙用

矩陣爆破逆向之條件斷點的妙用

條件斷點妙用

經過動調,我發現關鍵的加密就這三個彙編指令。

意思:取flag->與一個固定的矩陣相乘->輸出加密之後的矩陣

如果我們能夠列印,加密前的flag和相乘的矩陣元素,就可以逆推明文啦

主要是不清楚,矩陣相乘的順序,可能是打亂的,那樣只能這樣來做。

使用了:條件斷點

矩陣爆破逆向之條件斷點的妙用

這三個斷點依次使用下面3個條件輸出

主要是這兩個命令:

get_reg_value("rbx") 獲取rbx暫存器的值

idc.get_wide_dword() 獲取某地址的值(4位元組讀取)


  print("[rbx] = ",hex(idc.get_wide_dword(get_reg_value("rbx"))))
  
  print("rax = ",hex(get_reg_value("rax")),"[rdi]=
  ",hex(idc.get_wide_dword(get_reg_value("rdi"))))
  
  print("output,rax = ",hex(get_reg_value("rax")),"n")

矩陣爆破逆向之條件斷點的妙用

然後edit breakpoint

矩陣爆破逆向之條件斷點的妙用

矩陣爆破逆向之條件斷點的妙用

OK,見證奇蹟的時刻到了,執行程式,成功輸出:

矩陣爆破逆向之條件斷點的妙用

推導

因為密文說16位元組的,我們將真正的密文提取出來和我們輸入假flag產生的密文也提取出來,進行對比


Python

 密文
  unsigned int data[16] = {
  0x00000436, 0x000002B4, 0x000002AF, 0x00000312, 0x000002EA, 0x00000253,
  0x0000020A, 0x0000028E,
  0x000001C6, 0x0000015C, 0x0000017C, 0x0000017A, 0x0000069E, 0x000004AE,
  0x000004B1, 0x00000522
  };
  
  假flag輸出的結果密文
  unsigned int data[16] = {
  0x00000466, 0x000002F9, 0x00000329, 0x0000046E, 0x00000290, 0x00000184,
  0x000001E4, 0x0000023A,
  0x00000183, 0x000000C1, 0x0000011E, 0x00000122, 0x00000646, 0x00000467,
  0x000004F7, 0x000005EA
  };
  
  這是根據條件輸出得到的規律;
  
  x1*1+x2*5+x3*4+x4*3=0x436
  y1*1+y2*5+y3*4+y4*3=0x2B4
  z1*1+z2*5+z3*4+z4*3=0x2AF
  n1*1+n2*5+n3*4+n4*3=0x312
  
  x1*2+x2*1+x3*2+x4*3=0x2EA
  y1*2+y2*1+y3*2+y4*3=0x253
  z1*2+z2*1+z3*2+z4*3=0x20A
  n1*2+n2*1+n3*2+n4*3=0x28E
  
  x1*2+x2+x3+x4=0x1c6
  y1*2+y2+y3+y4=0x15c
  z1*2+z2+z3+z4=0x17c
  n1*2+n2+n3+n4=0x17a
  
  x1*3+x2*5+x3*4+x4*7=0x69e
  y1*3+y2*5+y3*4+y4*7=0x4ae
  z1*3+z2*5+z3*4+z4*7=0x4b1
  n1*3+n2*5+n3*4+n4*7=0x522

矩陣爆破逆向之條件斷點的妙用

z3解密

解密指令碼:


Python

 from z3 import *
  
  # 定義變數
  x = [Int(f'x{i}') for i in range(1, 5)]
  y = [Int(f'y{i}') for i in range(1, 5)]
  z = [Int(f'z{i}') for i in range(1, 5)]
  n = [Int(f'n{i}') for i in range(1, 5)]
  
  # 定義目標值
  goal = [
  0x466,
  0x2f9,
  0x329,
  0x46e,
  0x290,
  0x184,
  0x1e4,
  0x23a,
  0x183,
  0xc1,
  0x11e,
  0x122,
  0x646,
  0x467,
  0x4f7,
  0x5ea
  ]
  
  # 定義約束條件
  constraints = [
  x[0]*1 + x[1]*5 + x[2]*4 + x[3]*3 == goal[0],
  y[0]*1 + y[1]*5 + y[2]*4 + y[3]*3 == goal[1],
  z[0]*1 + z[1]*5 + z[2]*4 + z[3]*3 == goal[2],
  n[0]*1 + n[1]*5 + n[2]*4 + n[3]*3 == goal[3],
  x[0]*2 + x[1]*1 + x[2]*2 + x[3]*3 == goal[4],
  y[0]*2 + y[1]*1 + y[2]*2 + y[3]*3 == goal[5],
  z[0]*2 + z[1]*1 + z[2]*2 + z[3]*3 == goal[6],
  n[0]*2 + n[1]*1 + n[2]*2 + n[3]*3 == goal[7],
  x[0]*2 + x[1] + x[2] + x[3] == goal[8],
  y[0]*2 + y[1] + y[2] + y[3] == goal[9],
  z[0]*2 + z[1] + z[2] + z[3] == goal[10],
  n[0]*2 + n[1] + n[2] + n[3] == goal[11],
  x[0]*3 + x[1]*5 + x[2]*4 + x[3]*7 == goal[12],
  y[0]*3 + y[1]*5 + y[2]*4 + y[3]*7 == goal[13],
  z[0]*3 + z[1]*5 + z[2]*4 + z[3]*7 == goal[14],
  n[0]*3 + n[1]*5 + n[2]*4 + n[3]*7 == goal[15]
  ]
  
  # 建立求解器
  solver = Solver()
  
  # 新增約束條件
  solver.add(constraints)
  
  # 求解
  if solver.check() == sat:
  model = solver.model()
  for i in range(1, 5):
  print(f'x{i} = {model[x[i-1]]}')
  print(f'y{i} = {model[y[i-1]]}')
  print(f'z{i} = {model[z[i-1]]}')
  print(f'n{i} = {model[n[i-1]]}')
  else:
  print('無解')

得到的結果,將其按照陣列來填充

矩陣爆破逆向之條件斷點的妙用

得到


Python

這是真flag解密後的結果:
  x1 = 100
  y1 = 89
  z1 = 119
  n1 = 92
  
  x2 = 66
  y2 = 5
  z2 = 69
  n2 = 4
  
  x3 = 84
  y3 = 83
  z3 = 4
  n3 = 104
  
  x4 = 104
  y4 = 82
  z4 = 69
  n4 = 86
  
  100,89,119,92,66,5,69,4,84,83,4,104,104,82,69,86
  

這是假flag解密後的結果:

x1 = 60
  y1 = 1
  z1 = 47
  n1 = 4
  
  x2 = 88
  y2 = 87
  z2 = 86
  n2 = 95
  
  x3 = 89
  y3 = 13
  z3 = 14
  n3 = 94
  x4 = 90
  y4 = 91
  z4 = 92
  n4 = 93
  
  60,1,47,4,88,87,86,95,89,13,14,94,90,91,92,93

按照我的思路來填充結果陣列;

矩陣爆破逆向之條件斷點的妙用

因為剛才說了,異或的值不清楚,但是一直為單位元組固定值,所以使用Cybe的爆破功能。

根據程式的驗證功能可知,flag以Sn@K開頭,所以找到了真正的flag

但是順序發生了變化,下面是假flag生成密文解密之後的結果,發現密文變化了

+-----------------------------------------------------------------------+

| Sn@ku2r3cd3__era |

| Sn@k78906ba15432 |

| |

| Sn@k0123456789ab |

| |

| 經過交換後的結果: |

| |

| Sn@k78906ba15432 |

| |

| 按照我們構造的flag交換順序後的字串來恢復 |

| 恢復 |

| Sn@k3_are_cu2r3 |

+-----------------------------------------------------------------------+

矩陣爆破逆向之條件斷點的妙用

成功驗證!

矩陣爆破逆向之條件斷點的妙用

更多網安技能的線上實操練習,請點選這裡>>

相關文章