前言
1、模糊测试器是什么?
模糊测试器是一段代码,这段代码是用来挖掘某些特定应用的漏洞。
2、rust是什么?
rust是一门编程语言。
3、dumb fuzzer、smart fuzzer是什么?
dumb-蠢一点的模糊测试器
smart-高级版的模糊测试器
下面我们就从零编写一个模糊测试器来挖掘win32计算器的漏洞。
分析win32calc.exe
编写代码之前首先需要分析win32计算器的功能,作为一个dumb fuzzer,我们要实现的仅仅是枚举计算器的各种操作,并期待它crash,不需要code coverage也不需要优化mutator。crash我们可以通过设置windbg为默认调试器来捕获
熟悉win32calc.exe的功能
这里带大家来熟悉一下win32calc的功能
常见的计算功能
Alt+V快捷键可以打开查看这个菜单,在此状态下Alt加上数字1,2,3,4可以切换到不同的模式,同时Ctrl加上F4,U,E会为计算器添加额外的功能
Alt+3进入程序员模式
Ctrl+E计算日期差
Ctrl+U单位换算
Ctrl+H 历史记录
实现思路
一个朴素的想法就是在聚焦于win32calc的情况下给窗口发送键盘事件,这其中会有很多事件并没有实际的意义,我们可以通过黑名单来减少这些噪声
代码实现
首先我们通过FindWindowW拿到窗口的句柄
struct Window{
hwnd : isize,
seed : Cell<u64>,
}
impl Window{
fn attach(title: &str) -> Result<Self, Error>{
let ret = unsafe{
title)
};
...
loop{ :
let window = Window::attach(&args[1]);
if window.is_err() {
attach to window");
continue
}
...
之后SetForegroundWindow,并生成随机的信号,其中有些是Ctrl操作有些是Alt操作,还有些常规的按键操作
if unsafe { SetForegroundWindow(window.hwnd) } == false {
println!("Couldn't set foreground");
continue 'reconnect;
}
...
let key = window.rand() as u8;
if black_list.contains(&key) {
continue;
}
let sel = window.rand() % 3;
match sel {
0 => { window.alt_press(key as _); }
1 => { window.ctrl_press(key as _); }
_ => { window.press(key as _); }
}
按键操作实现如下
fn rand(&self) ->usize{
let mut seed = self.seed.get();
seed ^= seed << 13;
seed ^= seed >> 17;
seed ^= seed << 43;
self.seed.set(seed);
seed as usize
}
fn key_down(&self, key: u8){
unsafe{
keybd_event(key, 0, 0, 0);
}
}
fn key_up(&self, key: u8){
unsafe{
keybd_event(key, 0, KEYEVENTF_KEYUP, 0);
}
}
fn alt_press(&self, key: u8) {
if key == KeyCode::Tab as _ ||
key == KeyCode::Space as _ ||
key == KeyCode::Esc as _ ||
key == KeyCode::Shift as _ {
return;
}
self.key_down(KeyCode::Alt as u8);
self.key_down(key);
self.key_up(key);
self.key_up(KeyCode::Alt as u8);
}
fn ctrl_press(&self, key: u8) {
if key == KeyCode::Esc as _ ||
key == KeyCode::Space as _ ||
key == KeyCode::Shift as _ {
return;
}
self.key_down(KeyCode::Ctrl as u8);
self.key_down(key);
self.key_up(key);
self.key_up(KeyCode::Ctrl as u8);
}
fn press(&self, key: u8){
self.key_down(key);
self.key_up(key);
}
...
通过黑名单来减少无效的信号
let mut black_list = HashSet::new();
black_list.insert(0x5b); // left windows key
black_list.insert(0x5c); // right windows key
black_list.insert(0x5d); // Application key
black_list.insert(0x5f); // Sleep key
black_list.insert(0x70); // F1
black_list.insert(0x73); // F4
black_list.insert(0x2f); // Help key
black_list.insert(0x2c); // Print screen
black_list.insert(0x2a); // Print
black_list.insert(0x2b); // Execute
black_list.insert(0x12); // Alt
black_list.insert(0x11); // Control
black_list.insert(0x1b); // Escape
至此我们就实现了一个dumb fuzzer,来看看效果
结果
很遗憾,经过了一晚上的fuzz,这个dumb fuzzer一个crash都没产生,不过没关系,下一篇文章中我们将在这个fuzzer的基础上优化我们的输入,去掉多余的噪音,让我们产生的输入更加高效。我们会收集code coverage,利用code coverage去评估和优化我们的mutation。另外我们还会添加多线程来并发的fuzz,从而让我们的fuzzer在20秒内就能挖到win32calc的crash
关于我们
招贤纳士:
实验室介绍:狼蛛安全实验室以”情报驱动的威胁猎手”为核心,构建了面向威胁狩猎的全流程解决方案,可为客户解决网络攻击发现、线索扩线、落地核查、追踪溯源全流程业务需求。
公众号介绍:
公众号将每周更新当周较为重要的安全事件以供读者参考和发现新线索,不定期更新实用小工具、网络安全各方向(逆向、渗透、情报等)干货分享、重大安全事件梳理跟进情况等内容……
请发简历到 [email protected] 每一份简历我们都会认真对待。
► 狼蛛安全实验室
欢迎合作交流~
原文始发于微信公众号(狼蛛安全实验室):rust实现模糊测试器挖掘漏洞之旅(上)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论