首页 > 其他分享 >2023 巅峰极客 m1_read 详细复现

2023 巅峰极客 m1_read 详细复现

时间:2023-10-14 21:11:07浏览次数:47  
标签:AES 极客 16 read m1 密钥 数据 Math

定位逻辑

本题给出了bin文件,即out.bin,故可以猜测其内部包含了加密结果或者密钥等
m1_read文件打开后,函数数量不多,并且静态分析WinMain不可行
于是翻找函数,可以找到形如AES的函数(sub_4BF0)


利用Findcrypt也出现了AES的特征码,于是假定是AES,并且没有魔改
函数接近结尾部分可以看出这是AES-128,一共有16B参与

观察调用AES函数的附近,还有一个异或就没了
寻找AES密钥,未能找到。。。
通过搜索查找,我们发现AES的密钥可以利用DFA进行攻击从而得到

AES加密一共十轮,其中第十轮不进行列混合
DFA需要的数据是,第九轮列混合之前,通过修改一位中间结果,导致加密结果与正确结果有4B不同

获得DFA数据

利用Frida框架,我们可以对AES函数进行hook,从而得到DFS攻击所需的数据

var baseAddr = Module.findBaseAddress("m1_read.exe")
// AES函数偏移:0x4BF0
var whiteAES = new NativeFunction(baseAddr.add(0x4BF0), 'pointer', ['pointer','pointer'])
// count = 9,这样第一轮数据恰好对应正确的数据
var count = 9

Interceptor.attach(baseAddr.add(0x4C2C),{
  // 列混合处的偏移:0x4C2C
  // 若不确定,可以通过测试来看:
  // 		1. 若正确数据与异常数据全部不同,则修改太早
  // 		2. 若正确数据与异常数据仅一个不同,则修改太晚
  onEnter: function(args){
    count++;
    // 第九轮修改中间结果
    if(count == 9){
      // 参考汇编代码可以发现rdi记录第九轮中间数据的地址
      // "add(Math.floor(Math.random()*16))":
      // 		表示对操作的地址进行偏移,值属于{1,2,3}
      // 		(0,4的可能性基本为0)
      //
      // "writeU8(Math.floor(Math.random()*256))":
      // 		表示对写入的值进行修改,值属于{1,2,3,...,E,F}
      // 		(0,16的可能性基本为0)
      // 综上,这实现了对中间数据的单个Byte修改,取消注释下述代码即可看出
      var p = ptr(this.context.rdi)
      // console.log("ori: ", p.readByteArray(16), "\n")
      p.add(Math.floor(Math.random()*16)).writeU8(Math.floor(Math.random()*256))
      // console.log("out: ", p.readByteArray(16), "\n")
    }
  },
  onLeave:(retval) =>{

  }
})

for (let index = 0; index < 33; index++){
  // 取消注释下述代码即可得到每一轮的数据
  var l = Memory.allocAnsiString("0123456789abcdef");
  var b = Memory.alloc(16);
  whiteAES(l, b);
  // console.log(b.readByteArray(16));
  count = 0;
}
import frida
import sys
import subprocess

# Things needed to be changed
currentDir = R"m1_read"
proName = R"m1_read.exe"
dir = R"************CENSORED************\m1_read"

def getJsScript(fileName="t1.ts", fileDir=currentDir) -> str:
  with open(fileDir + "/" +fileName, encoding='utf-8') as jsScript:
    return jsScript.read().rstrip()
def on_message(message, data):
  print(message)

jsScript = getJsScript()
program = dir + "/" + proName
subprocess.Popen(program)

session = frida.attach(proName)
script = session.create_script(jsScript)
script.on('message', on_message)
script.load()
sys.stdin.read()

于是可以得到33轮的数据:首轮是原始结果,之后各轮是经过替换的结果
程序实现还有一步异或加密,异或值为0x66,还原后可以得到

14f5fe746966f292651c2288bbff4609
14f5fe746966f292651c2288bbff4609
14f5fe176966209265e32288c3ff4609
14f5c27469e9f292de1c2288bbff4662
14cafe741066f292651c22d6bbff8409
14f5fe746966f292651c2288bbff4609
14f5fe746966f292651c2288bbff4609
14f5fe746966f292651c2288bbff4609
14f5fe746966f292651c2288bbff4609
14ecfe74fc66f292651c228cbbffae09
144cfe74a566f292651c228fbbff0709
14f58674692cf292391c2288bbff46b0
14c1fe744666f292651c2292bbffbc09
14f5087469bcf292211c2288bbff4661
14f5fe4e69663d92653f2288c6ff4609
14f5fe2669664792657e2288c1ff4609
14f58e746965f292c91c2288bbff4672
cef5fe746966f2f5651ce988bb6a4609
14f5e57469d8f292f41c2288bbff4660
14f5fe746966f292651c2288bbff4609
14f5fe606966a69265af228891ff4609
4af5fe746966f21f651c5188bb9b4609
144bfe740d66f292651c2270bbff3609
14f5687469a4f292181c2288bbff4688
1483fe740066f292651c2241bbff2409
1af5fe746966f27d651c6288bb354609
16f5fe746966f21e651c1488bbd24609
14f5fe4569667d92650422887aff4609
14f542746936f2929e1c2288bbff4623
14f5fe746966f292651c2288bbff4609
14f5ec746950f292cf1c2288bbff469f
140bfe749166f292651c224fbbff4909
14f5197469dff292041c2288bbff46ee
(上述脚本下,每个人的结果只能保证第一个相同)

得到原始密钥

利用phoenixAES可以实现DFA

# s1是前文中的33轮数据,以字符串形式存储(包含换行,否则无法识别)
import phoenixAES
with open("testfile", "wb") as t:
    t.write(s1.encode())

phoenixAES.crack_file("testfile")
# 自动打印出来第10轮的密钥
# B4EF5BCB3E92E21123E951CF6F8F188E

接着,得到首轮密钥,参考https://github.com/SideChannelMarvels/Stark
自行编译项目,可以得到一系列文件,其中我们需要aes_keyschedule.exe

./aes_keyschedule.exe B4EF5BCB3E92E21123E951CF6F8F188E 10

通过指定密钥和它对应的轮数,程序得到了其他每一轮的密钥,我们需要首轮密钥

取得加密数据

知道程序密钥过后,本题只需要先解决最终的异或,然后把AES解密即可
程序的加密数据在out.bin,010editor可以看到一大串数据,然而文件的后面部分都是重复的
于是猜测加密数据在前面,并且由于offset在0x10到0x1F的数据是0x0,我们猜测第一行或者第三行是加密数据

解密脚本

from Crypto.Cipher import AES

// 经过测试,第一行数据得到的不符合题意
# s = "ADB6A0F04B08040001FC08773BB0DB16"
s = "0B987EF5D94DD679592C4D2FADD4EB89"
# key长度注意要写为16B的长度,否则AES识别不正确
key = bytes.fromhex("00000000000000000000000000000000")
enc = bytearray(bytes.fromhex(s))
cipher = AES.new(key, AES.MODE_ECB)

for i in range(16):
  enc[i] ^= 0x66

flag = cipher.decrypt(enc)
print(flag)
# flag => cddc8d28dabb4ea9

标签:AES,极客,16,read,m1,密钥,数据,Math
From: https://www.cnblogs.com/Carykd/p/17764740.html

相关文章

  • 第9期ThreadX视频教程:自制个微秒分辨率任务调度实现方案(2023-10-11)
    视频教程汇总帖:https://www.armbbs.cn/forum.php?mod=viewthread&tid=110519 说明:1、一般应用,我们都会将任务RTOS系统时钟节拍(心跳)设置为1ms,但如果直接把RTOS的系统时钟节拍设置为1us,系统负担非常大,而且很多RTOS也做不到100MHz主频下,1us切换一次任务,导致RTOS没有时间处理应用......
  • InputStream类的read()方法返回的int值是如何计算的
    InputStream类有一个read()方法,它的返回类型是int。InputStream类本身是抽象类,它的一些子类的read()方法每次读取一个字节,也就是8个二进制位。比如读到如下二进制数据:111111111以上二进制数据如果按照byte类型来转换,是负数-1。而read()方法会把它先变成32位的二进制数据:000000000......
  • Exception in thread "main" java.security.InvalidKeyException: Wrong key size问题
    问题描述在Java里面使用DES加密算法,然后就爆出这个错误:问题解决换用了另外一种加密解密的函数:SecretKeySpec;即将原来的这种:换成了这种:我是觉得使用DES加密算法时,它一直显示key的字节长度不对,就想着换一种表述方式,又看到了别的友友的经验分享,就换成这样试了试(直接放进mai......
  • Gym100078F Formula
    非常好,竟然是有思维的模拟题。换句话讲就是有模拟的思维题题意:给定一个由与或非组成的逻辑表达式,你需要把他化简成一个变量不重复的与或非逻辑表达式或报告无解。发现如果允许变量重复了,这个逻辑表达式没有什么性质,任何一种真值表都可以通过合适的构造得来。所以题目相当于直接......
  • Hadoop-Operation category READ is not supported in state standby 故障解决
    在查询hdfs时或者执行程序向hdfs写入数据时遇到报错:OperationcategoryREADisnotsupportedinstatestandby 意思是:该主机状态为待机,不支持操作类别READ.你会发现最基本的hdfs命令都不能执行,例如:hadoopfs-ls/自定义的是nn1还是namenode1等自定义名可以在配置文件h......
  • matalab实验imread函数和FFT使用!【图像的傅立叶变换实验】
    解决的问题:Imread函数一般不要用动态的图,否则会如下的报错!步骤:随便搞一张.png图片—>新建一个文件夹—>存放你找的图片和你建的工程(matalab工程命名不可以使用空格)—>把当前文件夹设置成改你设置的文件【如图】:如果没有后缀出现(点击查看,打开显示后缀名,修改成.gif,如果实验要求是。p......
  • C语言 - 使用_beginthreadex()创建线程
    经过了解才知道,C++03之前,用的创建线程都是CreateThread与_beginthreadex。使用这个两个函数进行创建线程。然后C++11之后,就出现了新的线程函数thread,当然,这个创建线程比较方便!经过两三天的纠结,最终决定深入研究_beginthreadex此方式创建线程,具体为什么我也说不清楚,看到网上很多......
  • leaflet使用heatmap.js出现heatmap.js:527 Uncaught TypeError: Cannot assign to rea
    一、问题背景问题是这样发生的,因为项目中需要实现热力图的功能,所以使用了第三方的库heatmap.js。但是在一些浏览器中使用它时,会出现这个错误:>UncaughtTypeError:Cannotassigntoreadonlyproperty'data'ofobject'#<ImageData>'出现问题的原因是因为img.data=im......
  • 2023.10.9NOIPSIM1总结
    ##T1区分度先手算一下找下规律,发现数列呈现$1,2,2,3,3,4,4,4,5,5,5,6,6,6,6,7,7,7,7,8,8,8,8,8......$的规律。数据范围到$1e13$,考虑数论分块,每块的块长由前一块块长递推得到。在块内累$\Omicron$(1)累计答案,跳块时间复杂度$\Omicron$($\sqrtn$),总复杂度$\Omicron(t\sqr......
  • 【C#】【IO】【Threading】【实例】工作报表前的本地数据聚合操作
    <工作记录——Report>报表前的数据获取操作是高重复性的,今天差不多完成了脚本,下述是代码:1//Seehttps://aka.ms/new-console-templateformoreinformation2usingSystem.IO;3usingSystem.Threading;45stringSN=@"C0230U25";6stringsourcefold=......