题目越做越多(g🔫
BabyDriver
一道驱动逆向题
驱动
本质上也是一个程序,它是用户层和内核层通信的桥梁。
我们的操作都只能在3环用户层上,想要影响到0环内核的操作就需要通过驱动。
浅析
通过查找字符串"flag",然后交叉引用到达关键函数 sub_140006810()
重点是打头的 sub_140006380() 函数
在 sub_1400036C0(FileName, v2) 函数中,将程序资源里名字叫 WMCTF 资源里的内容写进了 FileName 文件中。换句话说,驱动的代码一开始就在程序里面,保存在名字叫 WMCTF 的资源里
相关驱动前置操作完成之后,函数 sub_140006750(v3, (unsigned int)v2) 将我们所输入的字符串进行了一个异或操作
在函数 sub_1400062A0() 里,函数NtQueryInformationFile( ) 将加密后的字符串以及上图中的一些信息传给驱动,由驱动对我们所输入的字符串进行一些操作
后续就是对字符串进行一些比较,输出正确或错误信息
所以主要就是将驱动中的信息找出来。
- 通过动调,在驱动释放之前将驱动取出来
- 驱动的内容是通过资源写入的,使用工具获取程序资源
驱动浅析
找到关键函数
发现 AES 加密特征
所以驱动的功能就是将我们输入并且异或后的字符串进行 AES 加密,也可以推断出传入驱动时的字符串是加密使用的key
关键函数的后续操作就是将加密后的字符串和密文进行比较
小结
第一次遇到驱动,也第一次了解。
涉及到内核的一些内容,内核很复杂,可以干很多事情,这题让我对驱动有了点初步了解,里面有很多东西现在还没有办法深究。
seeee
main 很简单,就一个函数调用然后就 return
刚开始的时候思路错误,只关注运行完哪个函数之后运行框里会出现错误的信息提示,再加上混淆严重所以基本上动调就没用过f5,纯纯汇编在那里傻看。
把断点下在了这个位置,之后就一直跟
结果就是:压根就没有进入到关键函数里面去,上面的那个函数可能已经是关键函数运行结束后用于收尾的函数。
浅析
通过查找字符串和交叉引用找到关键函数 sub_7FF60F111410 ,f5 发现混淆严重基本上看不到有用的信息,故转动调
在动调的过程中,运行到此处,如果走了绿色的那条分支那函数就很快结束了,并且返回 error
关注这里上方所调用的函数,并通过动调发现,下方函数里的 sub_7FF60F11B4A0 用于获取我们的输入
猜测需要两个输入的前置条件
继续运行调试发现对我们的输入进行了一个复制,r14 储存我们所输入的第一个字符串的长度,memcpy 之后将长度和 18h 进行了一个比较
在长度正确的情况下,就会进入下图中黄色框框中的分支,结合动调以及f5的分析,感觉是在对我们所输入的字符串进行某种排序
先是将输入的字符串的这几位放入局部变量中
接着又字符串中的几位进行了用于排序的相同的某种操作(猜的,不知道对不对,因为结构很类似)
再运行之后会发现字符会被取出来和一段字符串逐一进行比较,错误的话就g了
这里和我遇到的不太一样的地方在于,我们所输入的经过二叉树排序的字符串并不会被连续储存在一起。这就意味着我们是无法一次性能够得到二叉树的每个字母对应位置关系。
通过动态调试发现,用于每次用于对比的字母会被取出并放入下图的寄存器所指向的位置当中
所以我们可以通过修改下面的跳转条件,将每个字母对比的顺序记录下来
1 | 例如: |
最后根据上面所找到的目标字符串还原出正确的输入
1 | 输出 uy7sY6CTJnQpXVxUhOBFoEqA |
之后就是一个 chacha20 的流加密算法,可以通过插件 Findcrypt 直接找到它 (放图)
也可以通过动调发现,像这种传进去的参数特别明显的就可以跟进去看一看
进去之后可以发现对传进的字符串进行了10轮次的迭代
以及迭代函数中明显的 chacha20 特征
之后再运行发现我们所输入的第二串字符串和前面被加密后的输出传入了一个函数中,之后出来和 3fh 比较了一下我们所输入的字符串的长度
再走下去就是字符串对比的一个操作了
从 buf2 中 dump 出所要对比的目标数据,buf1 中 dump 出自己输入的经过异或后的数据,将异或后的数据和原始数据进行异或再和目标数据进行异或就可以得出正确输入
Exp:
1 | a=[0x91,0x2C,0xBB,0xB3,0xC1,0xEB,0x9A,0x16,0x60,0xAD,0xC9,0x5E,0x6D,0x4E,0x15,0xF2,0x0,0x1A,0x58,0xB2,0x31,0x7B,0x74,0x24,0x7E,0x74,0x7A,0xC,0xBC,0x50,0xBB,0xAC,0x5E,0x18,0x25,0xE1,0x24,0x74,0xC3,0x22,0x5A,0xE,0x4F,0x96,0x58,0x7F,0x9F,0xB3,0xAF,0xCA,0xAF,0x17,0x7E,0xAD,0x2,0x44,0xAC,0xFD,0x2F,0xAF,0x63,0x88,0x1D] |
小结
很感谢 ret 师傅,我真的为了seeee这题缠了他好久
-
了解了驱动的大致过程:
- 驱动的内容开始的时候就储存在程序中
- 在磁盘的指定位置中将程序中驱动的内容写进去
- 注册、加载驱动
- 通过函数 (?猜的 与驱动进行通信
- 释放驱动
-
seeee这题混淆非常严重导致,f5 基本上看不出什么东西
在上图红色方框位置按 tab 键,然后手动将 data 改为 code,再 f5 编译即可修补
-
在 seeee 中意识到动调的时候多看cfg,f5也要多用,即使没有手动修补过,但是通过动调再多次f5也可以将逻辑理清
-
在调试的时候可以尝试修改跳转
-
chacha20 加密特征:
-
有一个10轮次的迭代
-
在进行轮函数变换时左移的位数:16,12,8,7
-
emmmmm,这个不知道是什么东西,但是 findcrypt 是靠这个找出来的
-
多多努力吧🙂
本文作者:GhDemi
本文链接: https://ghdemi.github.io/2022/09/18/WMCTF-Re/
文章默认使用 CC BY-NC-SA 4.0 协议进行许可,使用时请注意遵守协议。