rust实现模糊测试器挖掘漏洞之旅(上)

admin 2022年7月5日14:18:09评论158 views字数 2970阅读9分54秒阅读模式

前言

1、模糊测试器是什么?
模糊测试器是一段代码,这段代码是用来挖掘某些特定应用的漏洞。
2、rust是什么?

rust是一门编程语言。
3、dumb fuzzer、smart fuzzer是什么?
dumb-蠢一点的模糊测试器
smart-高级版的模糊测试器


下面我们就从零编写一个模糊测试器来挖掘win32计算器的漏洞。


分析win32calc.exe

rust实现模糊测试器挖掘漏洞之旅(上)

       编写代码之前首先需要分析win32计算器的功能,作为一个dumb fuzzer,我们要实现的仅仅是枚举计算器的各种操作,并期待它crash,不需要code coverage也不需要优化mutator。crash我们可以通过设置windbg为默认调试器来捕获


熟悉win32calc.exe的功能

       这里带大家来熟悉一下win32calc的功能

rust实现模糊测试器挖掘漏洞之旅(上)

       常见的计算功能

rust实现模糊测试器挖掘漏洞之旅(上)

       Alt+V快捷键可以打开查看这个菜单,在此状态下Alt加上数字1,2,3,4可以切换到不同的模式,同时Ctrl加上F4,U,E会为计算器添加额外的功能

rust实现模糊测试器挖掘漏洞之旅(上)

       Alt+3进入程序员模式

rust实现模糊测试器挖掘漏洞之旅(上)

       Ctrl+E计算日期差

rust实现模糊测试器挖掘漏洞之旅(上)

       Ctrl+U单位换算

rust实现模糊测试器挖掘漏洞之旅(上)

       Ctrl+H  历史记录


实现思路

       一个朴素的想法就是在聚焦于win32calc的情况下给窗口发送键盘事件,这其中会有很多事件并没有实际的意义,我们可以通过黑名单来减少这些噪声


代码实现

       首先我们通过FindWindowW拿到窗口的句柄

struct Window{    hwnd : isize,    seed : Cell<u64>,}
impl Window{ fn attach(title: &str) -> Result<Self, Error>{ let ret = unsafe{ FindWindowW(None, title) }; ...

'reconnect: loop{ let window = Window::attach(&args[1]); if window.is_err() { println!("Couldn't 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实现模糊测试器挖掘漏洞之旅(上)

► 狼蛛安全实验室

欢迎合作交流~

原文始发于微信公众号(狼蛛安全实验室):rust实现模糊测试器挖掘漏洞之旅(上)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年7月5日14:18:09
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   rust实现模糊测试器挖掘漏洞之旅(上)https://cn-sec.com/archives/1158509.html

发表评论

匿名网友 填写信息