信息安全从业者书单推荐(2020.6.28更新)

近来也读过不少书,推荐几本个人觉得不错的:

  1. 《Vue.js项目开发实战》张帆
  2. 《我的第一本算法书》【日】宫崎修一;石田保辉,入门书籍,无代码进行图解
  3. 《算法图解:像小说一样有趣的算法入门书》【美】Aditya Bhargava
  4. 《编译与反编译技术实战》庞建民
  5. 《重构:改善既有代码的设计》【美】Martin Fowler
  6. 《Docker技术入门与实战》杨保华;戴王剑;曹亚仑
  7. 《一本小小的蓝色逻辑书》【加】布兰登•罗伊尔
  8. 《精进:如何成为一个很厉害的人》采铜

最近也买了极客时间上的几门课程,有几门我觉得不错的,虽然没有实体书出版,但课程依然还是按照书籍写作方式来写,比较系统化,有兴趣的也可以看看:

  1. 《左耳听风》
  2. 《软件工程之美》
  3. 《项目管理实战20讲》

不过有一门课是不推荐的,就是《程序员进阶攻略》,后来作者也出了实体书,但总觉得作者对武侠小说过着迷,课程写得有点过于武侠风,技术与武侠关联得过于牵强。

书单均是个人看过或者业界认可的经典书籍,跟网上罗列的安全书单不同,并非把网店上的各安全书籍都罗列上的。如果你有何好书推荐可在Issues(https://github.com/riusksk/secbook/issues)上提交,或者提交合并,待我看过之后,如果觉得可以就会在此处更新,这里也会不定期更新书单。

文末附完整的思维导图,欢迎收藏。

计算机及系统原理

· 《编码:隐匿在计算机软硬件背后的语言》 【美】Charles Petzold

· 《深入理解计算机系统》【美】Randal E.Bryant

· 《深入理解Windows操作系统》【美】Russinovich,M.E.;Solomon,D.A.

· 《Linux内核设计与实现》【美】Robert Love

· 《深入理解Android内核设计思想》林学森

· 《Android系统源代码情景分析》罗升阳

· 《深入理解Mac OS X & iOS操作系统》【美】Jonathan Levin

· 《深入理解Linux内核》 【美】DanielP.Bovet

· 《代码揭秘:从C/C++的角度探秘计算机系统》左飞

· 《Android Dalvik虚拟机结构及机制剖析(第1、2卷)》吴艳霞;张国印

· 《Android Internals::Power User’s View》【美】Jonathan Levin,中译本《最强Android书:架构大剖析》

编程开发

系统平台

Windows

· 《Windows程序设计》【美】Charles Petzold

· 《Windows核心编程》【美】Jeffrey Richter

· 《Windows环境下32位汇编语言程序设计》罗云彬

· 《Windows驱动开发技术详解》张帆

Linux/Unix

· 《UNIX环境高级编程》【美】W.Richard Stevens;Stephen A.Rago

· 《Linux程序设计》【美】Neil Matthew;Richard Stones

· 《Linux设备驱动程序》【美】Jonathan Corbet;Alessandro Rubini;Gerg Kroah-Hartman

macOS/iOS

· 《iOS编程》【美】Christian Keur;Aaron Hillegass

· 《OS X与iOS内核编程)【澳】Halvorsen,O.H.;Clarke,D

Android

· 《第一行代码——Android》郭霖

· 《Android编程权威指南》【美】Brian Hardy;BillPhillips

编程语言

C

· 《C语言程序设计》【美】Brian W.Kernighan;Dennis M.Ritchie

· 《C Primer Plus》【美】Stephen Prata,入门书籍

· 《C和指针》【美】Kenneth A.Reek

· 《C陷阱与缺陷》【美】Andrew Koenig

· 《C专家编程》【美】Peter van der Linden

C++

· 《C++ Primer Plus》【美】Stephen Prata,入门书籍

· 《C++ Primer》【美】Stanley B.Lippman;Josée Lajoie;Barbara E.Moo,进阶书籍

ASM

· 《Intel汇编语言程序设计》【美】Kip Irvine

· 《Intel开发手册》

· 《汇编语言(第3版)》王爽

· 《x86汇编语言:从实模式到保护模式》李忠

Java

· 《Java核心技术》【美】Cay S.Horstmann;Gary Cornell,入门书籍

· 《Java 编程思想》【美】Bruce eckel,进阶书籍

JavaScript

· 《JavaScript DOM编程艺术》【美】Jeremy Keith;【加】Jeffrey Sambells

· 《JavaScript高级程序设计》【美】Zakas.Bicholas C.

· 《Vue.js项目开发实战》张帆

Python

· 《Python核心编程(第2版)》【美】Wesley J·Chun

Shell

· 《Linux Shell脚本攻略》【印】Sarath Lakshman

调试技术

· 《软件调试》张银奎

· 《Debug Hacks》【日】吉冈弘隆;大和一洋;大岩尚宏;安部东洋;吉田俊辅

· 《格蠹汇编:软件调试案例锦集》张银奎

数据结构与算法

· 《数据结构与算法分析——C语言描述》【美】Mark Allen Weiss

· 《算法导论》【美】Thomas H.Cormen;Chales E.Leiserson;Ronald l.Rivest

· 《我的第一本算法书》【日】宫崎修一;石田保辉,入门书籍,无代码进行图解

· 《算法图解:像小说一样有趣的算法入门书》【美】Aditya Bhargava

编译原理

· 《编译系统透视:图解编译原理》新设计团队,入门书籍

· 《编译原理》(龙书)【美】Alfered V.Aho;Monica S.Lam;Ravi Sehi;Jeffrey D.Ullmam

· 《编译与反编译技术实战》庞建民

其他

· 《编程高手箴言》梁肇新

· 《代码整洁之道》【美】Robert C.Martin

· 《代码大全》【美】Steve McConnell

· 《重构:改善既有代码的设计》【美】Martin Fowler

网络技术

· 《TCP/IP详解(卷1:协议)》【美】Kevin R.fall;W.Richard Stevens

· 《Wireshark数据包分析实战》【美】Chris Sanders

安全技术

安全开发

· 《天书夜读:从汇编语言到Windows内核编程》谭文;邵坚磊

· 《Rootkit:系统灰色地带的潜伏者》【美】Bill Blunden

· 《Rootkits——Windows内核的安全防护》【美】Gerg Hoglund;James Butler

· 《BSD ROOTKIT设计——内核黑客指引书》【美】Joseph Kong

· 《寒江独钓:Windows内核安全编程》谭文;杨潇;邵坚磊

逆向工程

· 《加密与解密》段钢

· 《恶意软件分析诀窍与工具箱——对抗“流氓”软件的技术与利器》【美】Michael Hale Ligh;Steven Adair

· 《C++反汇编与逆向分析技术揭秘》钱林松;赵海旭

· 《IDA权威指南》【美】Chris Eagle

· 《逆向工程权威指南》【乌克兰】Dennis Yurichev,多平台入门大全

· 《Android软件安全与逆向分析》丰生强

· 《macOS软件安全与逆向分析》丰生强

· 《iOS应用逆向工程(第2版)》沙梓社;吴航

Web安全

· 《黑客攻防技术宝典:Web实战篇》【美】Marcus Pinto,Dafydd Stuttard

· 《白帽子讲Web安全》吴翰清

· 《Web安全测试》【美】Paco Hope;Ben Waltber

· 《Web前端黑客技术揭秘》钟晨鸣;徐少培

· 《精通脚本黑客》曾云好

软件/系统安全

· 《0day安全:软件漏洞分析技术(第2版)》王清,入门书籍

· 《漏洞战争:软件漏洞分析精要》林桠泉,进阶书籍

· 《捉虫日记》【德】Tobias Klein,进阶书籍

· 《黑客防线2009缓冲区溢出攻击与防范专辑》

· 《内核漏洞的利用与防范》【美】Enrico Perla;Massimiliano Oldani

· 《Fuzzing for Software Security Testing and Quality Assurance(第2版)》【美】Charlie Miller,博文视点翻译中

· 《iOS Hackers’s Handbook》【美】Charlie Miller,不推荐中文版

· 《The Mac Hacker’s Handbook》【美】Charlie Miller

· 《Android安全攻防权威指南》【美】Joshua J.Drake;【西】Pau Oliva Fora;【美】Collin Mulliner

· 《The Art of Softwar Security Assessment:Identifying and Preventing Software Vulnerabilities》【美】Mark Dowd

· 《Android Security Cookbook》【美】Keith Makan; Scott Alexander-Bown,中译本《Android安全攻防实战》

· 《模糊测试-强制性安全漏洞挖掘》【美】Michael Mutton

· 《Exploit编写系列教程》【美】Corelan Team

· 《MacOS and iOS Internals,Volume Ⅲ: Security & Insecurity》【美】Jonathan Levin,博文视点翻译中

· 《灰帽黑客:正义黑客的道德规范、渗透测试、攻击方法和漏洞分析技术》【美】Allen Harper;Shon harris

· 《威胁建模:设计和交付更安全的软件》【美】Adam Shostack

无线电安全

· 《无线电安全攻防大揭秘》杨卿;黄琳

硬件安全

· 《硬件安全攻防大揭秘》简云定,杨卿

汽车安全

· 《智能汽车安全攻防大揭秘》李均;杨卿

· 《汽车黑客大曝光》【美】Craig Smith

产品

· 《人人都是产品经理》苏杰

运营

· 《运营之光2.0:我的互联网运营方法论与自白》黄有璨

设计

· 《写给大家看的设计书》【美】Robin Williams

· 《听故事,学PPT设计》杨雪

运维

· 《Docker技术入门与实战》杨保华;戴王剑;曹亚仑

· 《鸟哥的Linux私房菜》鸟哥

软技能

· 《软技能:代码之外的生存指南》【美】John Sonmez

· 《程序员健康指南》【美】JoeKutner

· 《影响力》【美】Robert B.Cialdini

· 《穷爸爸富爸爸》【美】Robert Toru Kiyosaki

· 《横向领导力》【美】Roger Fisher;Alan Sharpe

· 《职业情商》张新越

· 《程序员的成长课》安晓辉;周鹏

· 《高效演讲:斯坦福最受欢迎的沟通课》【美】Peter Meyers;Shann Nix

· 《程序员的英语》【韩】朴栽浒;李海永

· 《思考,快与慢》【美】丹尼尔·卡尼曼

· 《少有人走的路》【美】斯科特·派克

· 《异类:不一样的成功启示录》【加】 马尔科姆·格拉德威尔

· 《见识》吴军

· 《英语写作手册:风格的要素》【美】William Strunk

· 《非暴力沟通》【美】马歇尔·卢森堡

· 《风格感觉:21世纪写作指南》【美】史蒂芬·平克

· 《浪潮之巅》(上下册)吴军

· 《一本小小的蓝色逻辑书》【加】布兰登·罗伊尔

· 《精进:如何成为一个很厉害的人》采铜

附思维导图:

img

img

HITB 2020:二进制漏洞挖掘仍是会议主流方向

本周Hack In The Box官方已经将大会演讲视频上传到YouTube,之前在官网有提供部分议题的pdf下载,但有些未提供的议题,这次也公开了视频,可以看到议题ppt内容。

今年的议题更多集中在二进制漏洞挖掘上,占比43%,而这些议题涉及(Windows、macOS、IoT、工控等等),其它议题方向包括恶意软件、二进制分析工具、容器安全、漏洞奖励计划等等,可以看出当前工业界的一些研究议题,还是比较喜欢二进制漏洞挖掘这个方向,这次一个Web相关议题都没有。

精彩议题推荐

1、60 CVEs in 60 Days

img

主要分享Windows平台下高权限进程的Symlink攻击(高权限进程在操作文件时,未作严格的权限校验,导致攻击利用符号链接到一些受保护的目录文件,比如C盘的系统DLL文件,后面系统或应用去自动加载时,实现代码执行并提权),这种攻击方式最早是由Project Zero大牛James Forshaw公布的,当时还开源了个利用测试工具(https://github.com/googleprojectzero/symboliclink-testing-tools) ,指定目录参数来测试,但它还算不上完整的漏洞挖掘工具。

漏洞原理较为简单,关键在于如何批量自动化挖掘,为此作者实现了一款叫 Ichanea 的自动化漏洞挖掘工具。

1.29.54

原理:通过过滤驱动捕获文件操作相关的IRP包,然后获取归属进程的相关信息,包括路径、进线程token等等,然后判断是否为高权限进程,若是就拿Token去检测文件的访问权限,如果可以就发消息给高权限的服务进程,创建/RCP/Control的加载点及符号链接进行DLL劫持测试,从而将监控、发现和利用集成一体。

最后在26家厂商(包括微软、Intel、Adobe、华为等等)产品中,挖到上百个漏洞,其中已有60个CVE致谢,产量颇丰。

2、Pwning Adobe Reader Multiple Times with Malformed Strings

屏幕快照 2020-07-05 下午1.30.18

腾讯玄武实验室出品,分享Adobe Reader在处理字符串时的安全问题。通过PDF JS来构造恶意字符串去触发,JS上的漏洞也更便于写exploit。虽然Adobe用了一些自定义的字符串安全处理函数,但其使用不当导致仍会造成漏洞。主要有两方面原因:

1、传错参数,比如拷贝字符时max_bytes参数误传0x7FFFFFFF,可能造成溢出;

2、字符串类型检测不当,比如误将ASNI当作Unicode字符串处理,千万类型混淆漏洞。

感觉这个攻击面还是有点偏门,找到一块新大陆,刷起漏洞来应该很爽,但估计也就一波过,可能没剩下啥了。

3、Exploiting directory permissions on macOS

屏幕快照 2020-07-05 下午1.30.30

有点类似前面Windows Symlink攻击提权的思路,介绍了macOS下系统对文件及目录的权限管控方式,用fs_usage去监控进程的文件操作行为,从而找出一些可能被用于提权的目录/文件。利用的正是文件与目录高低权限的差异化,借助软硬链实现对受保护文件的越权操作。有些只能写,但内容不可控,或者只能删除,也有可被用于root提权的漏洞。最后作者也简单地介绍一些文件操作方面的安全建议,比如对于安装器,若是/tmp就生成随机名目录,其它的要控制好权限,比如就root权限,其它则收回,安装前清理目录,删除移动文件时避免支持链接方式等等。

4、Documents of Doom – Infecting Macos Via Office Macros

屏幕快照 2020-07-05 下午1.31.01

img

以前Office宏病毒在Windows还是流行过一段时间的,其实macOS上也有,作者就列举了2017、2018、2019年的三次真实的宏攻击案例,也介绍了olevba之类的分析工具。

除此之外,还介绍了一些mac版Office沙盒逃逸的漏洞,用户打开doc后,可以无提示无交互的实现代码执行。作者自己也挖过一个沙盒逃逸漏洞,正是利用Python这条漏网之鱼,于用它将app添加版系统的自启动项,实现非沙盒下的执行权限。

5、Fuzzing File System Implementations to Uncover Security Bugs

屏幕快照 2020-07-05 下午1.31.56

PPT上写的关键信息不多,但重要的是作者把工具开源了,针对BSD文件系统(支持FFS、UFS、EXT、ZFS文件系统格式)进行Fuzzing,工具地址:https://github.com/0xricksanchez/fisy-fuzz 。所以重点可以看下该工具,支持Ubuntu,要求KVM、QEMU和libvirt,采用的是暴力Fuzzing 文件系统,直接用到了radamsa,自己也作了全局的随机变异,然后尝试加载,若加载成功就调用syscall执行一些文件操作,看是否崩溃,最后再借助虚拟机快照还原运行环境。

屏幕快照 2020-07-05 下午1.32.14

完整议题列表

  1. 60 CVEs in 60 Days
  2. The State of ICS Security: then and Now
  3. Pwning Adobe Reader Multiple Times with Malformed Strings
  4. Open the Gates – the (In)Security of Cloudless Smart Door Systems
  5. Hiding in Plain Sight: Analyzing Recent Evolutions in Malware Loaders
  6. Building Next-gen Security Analysis Tools with Qiling Framework
  7. Exploiting Directory Permissions on macOS
  8. Documents of Doom – Infecting Macos Via Office Macros
  9. From Man-in-the-Middle to Privesc and Rce: Exploiting the Netlogon Protocol
  10. The Dna of Hidden Cobra – a Look at a Nation State’s Cyber Offensive Programs
  11. Prisoner Number 6
  12. Fuzzing File System Implementations to Uncover Security Bugs
  13. Breaking and Securing Cloud Platforms
  14. Army of Undead: Tailored Firmware Emulation
  15. Bugrank: a Community Bug Bounty Platform
  16. Virtual Lab: Bare-metal Reverse Engineering & Hardware Hacking

议题ppt及视频地址参见:https://conference.hitb.org/lockdown-livestream/

谈谈追踪前沿学术研究的技巧

以前找论文都只知道上中国知网CNKI,很多是中文,且论文质量一般,更重要的还是收费。所以,我离开学校后,有时下载论文,都是找别人帮忙。

最近一年刷Twitter,经常发现一些漏洞研究论文都是在一个叫arXiv的网站提供免费下载,而且经常是会议开始前很早就公开了。

img

这里介绍下http://arXiv.org这个学术论文搜索引擎。

arXiv(读音如英语的 archive )是一个收集物理学、数学、计算机科学与生物学论文预印本的网站。arXiv 原先是由物理学家保罗·金斯巴格在1991年建立的网站,本意在收集物理学的论文预印本,随后括及天文、数学等其它领域。金斯巴格因为这个网站获得了2002年的麦克阿瑟奖。 arXiv 原先挂在洛斯阿拉莫斯国家,现在挂在康奈尔大学下面。

为了防止自己的想法在论文被收录前被他人剽窃,作者会将预稿上传到arvix作为预收录,以证明论文的原创性。

所以上面的论文经常比投稿大会更早放出,而且免费下载。英语通常是学术论文的第一语言,牛逼的学术论文也基本是英语写的,这点上国外的学术检索引擎就占据了一定优势,很多在CNDI是检索不到的,况且免费论文也不适合让你拿来收费。

如果本文只是介绍arXiv让你搜索论文,那就没意思了。

下面介绍如何通过web feed免费订阅最新论文的方法。
我平时是用Inoreader订阅RSS,但arXiv并没有提供RSS。刚好最近Inoreader出了新功能叫Web Feed,通过定时爬取特定页面来实现RSS订阅的类似效果。

这里我以论文标题含fuzz的关键词来检索计算机科学论文,如果不检索标题,可能会出现非漏洞研究论文,所以推荐检索标题会更准确一些。同时,注意开启按最新时间排序。

img

将搜索完生成的链接输入Inoreader搜索:

img

img

订阅效果:

img

以后就可以及时获取最新论文的下载。

技术人的修炼之道:从业余到专业

img

马斯克坐在他们前面一排,正在电脑前打字。“我们心想,“这个呆子,他现在还能干吗?”这时马斯克突然转过身来,亮出了他制作的电子表格。“兄弟们,”他说,“我觉得我们可以自己造火箭。”

马斯克把他的笔记本电脑递给格里芬和坎特雷尔,他们惊呆了。表格里详细列明了建造、装配和发射一枚火箭所需的成本。根据马斯克的计算,他需要建造一枚大小适中的火箭,以满足那些搭载小型卫星和研究设备的细分市场的需求,这样就能节省一笔发射费用。他在表格中还列出了假设的火箭性能特性,内容十分详细。“我说,‘埃隆,你从哪里得到这些数据的?”’坎特雷尔说。

马斯克用了几个月的时间研究航天工业及其背后的物理原理。他从坎特雷尔和其他人那里借来了《火箭推进原理》( RocKet Propulsion E1ements)、《天体动力学基础》( Fundamentals of Astrodynam-ics )、《燃气涡轮和火箭推进的空气动力学》( Aerothermodynamics of Gas Turbine and RocKet Propul-sion ),还有其他各种专业书籍。马斯克仿佛又找到了童年时的状态,他努力吸收关于太空的一切知识,在这一系列近似冥想的学习过程中,他终于意识到,自己制造的火箭可以,而且也应该比俄罗斯人的更便宜。忘了老鼠计划吧。忘了可以回传生长影像的植物吧,它有可能在火星上死掉。通过更低的太空探索成本,马斯克可以激发人们重新思考太空探索。

——摘自《硅谷钢铁侠》

img

造火箭这种事,对于绝大多数人而言,也就吹吹牛逼而已。但马斯克勇于挑战,最后还真让他干成了。

对于跨学科的领域知识,马斯克也是花了不少时间先从基础教科书入手,然后将知识点与现有知识和经历进行关联,以转化为自己的知识,再作迁移学习与应用。哪怕最后他搞出来的可回收火箭比NASA还牛逼,技术上更加创新,但他也是先从底层的基础技术入手,以不变应万变。像计算机科学迅速发展了这么多年,出现了许多新技术,但底层的那些基础知识还是那一些,变化不大。

通常每个学科领域都有一些基础专业课,比如医学有四大基础课程:药理、病理、生理、解剖;计算机也有五大基础课程:操作系统原理、计算机组成原理、计算机网络、数据结构与算法、编译原理。

不过,对于刚接触新领域的人,一般不知道刚开始要学什么,这时搜索引擎就派上用场了。如果有认识的专业人士,问下自然是最快的,但这种情况可遇不可求,所以还是老实地google下吧。

img

刚准备学安全的时候,鬼知道要学啥,要看啥书。一头扎进图书馆,随便挑有“黑客”二字的,能看懂的就借来看,再后来发现“黑客”之书看多了没什么提升,于是开始学一些计算机专业的基础课,就这样不断地来回挑书借书读书,久而久之就知道该学什么了。

所以,判断一个人对新领域是真的感兴趣,还是仅仅好奇而已,最好的方式就是把他扔进图书馆,让他自己挑书看,一本不行再换一本,来回折腾个五六遍,看他能否坚持学习下去。

之前看过一则寓言故事:两个农夫上山砍柴,挑柴回家的路上,累了就在中途休息一下。期间一位农夫突发奇想,就问同伴:你说这皇帝每天会用什么挑柴?另一个人回答:肯定是用金扁担。

农夫受自身阅历限制,对不了解的事情,只能凭借已有知识来理解和猜测。不知与不会是两个概念,业余与专业的区别就在于此:专业者知道自己的不足,业余者则感觉专业的还不如自己。也就是说,专业者知道自己不会什么,业余者不知道自己不会什么。

自己都不知道哪里不足,就不知道要去学什么。帮助我从“不会”进阶到“不知”的是看雪学院,它让我知道了逆向工程、软件漏洞、内核驱动这些知识盲点。在看雪上知道了《加密与解密》、《网络渗透技术》、《0day安全:软件漏洞分析技术》这些经典书籍,但当时的我哪看得懂这些天书。最先看到的是网渗一书,当我翻开第一章的时候,我就懵逼了,什么GDB、SoftICE调试器、IDA反汇编器一类的工具,都是什么鬼啊?然后在安全焦点上看到介绍如何学习网渗一书的建议,其中就提到了《深入理解计算机系统》,然后我花了好长时间把这书读了两遍,还做了笔记。再跟着看雪精华集里的文章都多动手实践,crackme破解一遍,exploitme利用一遍。当时我就一个目标:读懂《网络渗透技术》。后来我大约花了三四年时间才达到这一目标(没办法,天赋不足,后天来凑)。所以,一个好的技术社区可以帮助自己提升认知,认清自己的知识盲点,从而找到适合自己的学习方向。

img

img

学习金字塔告诉我们,通过主动学习后,知识的留存率最高。什么是主动学习?就是说、写、教、做的输出式学习。

:给学弟学妹们分享些技术,给企业/学校作培训,上学术/工业顶会演讲,都可以作为主动学习的方式。

:作演讲也要写ppt或文章,给一些杂志/门户网站投稿,都可以帮助加深对知识的理解,有时还能顺便赚点稿费。直至后来出版社因为之前的技术文章找过来,才有了《漏洞战争》一书。

:自己理解了是一回事,教会别人又是另一回事,要求更高,除了理解知识本身之外,还要以受教者可理解的话也讲述。特别是向非专业者讲述专业知识时,对教授者的知识理解程度更高。

:就是应用实践,比如打CTF,刷漏洞悬赏平台。计算机技术是一项重实践的学科,编程、调试和挖洞无不如此,若毕业生刚来就大谈架构设计、设计模式,那谁来写代码呢?

img

兴趣是第一动力,但不是唯一的。

大学时代,很多人会去勤工俭学,牺牲自己休息和学习的时间。但我没这么干,因为我觉得勤工俭学与学习是个零和游戏,两者此消彼长,而我希望达到1+1>2的效果。当然,自己也不想去端盘子就是。

于是我选择给《黑客防线》投稿,一开始边翻译边学习,边学习边投稿,再拿稿费吃饭上网买书(当时没个人电脑),然后继续保持学习,从翻译到原创。为了写稿,就要不断地学习新知识,不然也没钱吃饭买书。就这样:

学习 —》写稿 —》赚钱 —》买书/上网 —》学习

自此建立起良性循环的学习动力,而内在的学习驱动力比努力的被动学习更加有效。

img

2013年,“自媒体”成为热词。2012年年末,“简书”上线,“今日头条”上线,“知乎”开放用户注册,微信推出订阅号。每个人都可以是媒体,每个人都可以提供知识服务。这一年,人均每周上网时间大幅增加到25小时,阅读一篇文章的平均用时却降到57秒。

——摘自《这样读书就够了》

现在每天快餐式的知识太多了,文章更多的是表达观点、方法或某些知识点的碎片化知识,一般都是不成体系的(但也不是绝对的,有些论文就写得很系统完整),需要自己加工吸收,将其与己有的知识领域关联并应用起来。

《这样读书就够了》介绍了一种方法,教你如何将碎片化知识进行加工,转化为自成体系的知识。

什么是体系?不是点,不是线,而是网,是立体的网络。

最初,你接收到的是一个知识点:

img

然后,你给这个碎片信息加上前因(为什么要这么做)后果(行动之后的结果):

img

其后再加上适用边界(如特定场景、前提条件、使用条件等等):

img

但这样的信息仍然是线性的,需要再加一个维度,让它变得立体,即与自己关联和互动起来:反思和行动。反思(A1)指向过去,行动(A2)指向未来。

img

这就是“举一反三”:为一个信息或知识点构建3个维度。加工后的信息不再是一个孤立的点,而是伸出了6根触角,等待与其他信息连接。当你有了多个这样加工过的知识点之后,不同知识点会相连,互相对接、榫合、支撑,形成一个晶格体系,这就是你自己的知识体系。

img

img

之前付费知识兴起时,我也在“得到”app上买了几门课,听的时候感觉很有道理,听完之后感觉啥也没留下。其中有门课叫《有效训练你的研究能力》,共6篇短文而已,网上搜索下就有,可以不用购买。虽然学完并不能有效训练你的研究能力,可操作性差些,但其中讲到的三种意识可以借鉴下。

作品意识:刻意地追求卓越

本质上就是刻意练习地去追求更好,也不是单纯地完成任务。比如做饭,多数人虽然做一辈子饭,但大多成不了专业厨师,缺乏的就是不断练习不断反思提升的作品意识。

目标意识:防止研究过程跑偏

在研究学习前,经常要收集资料,有时遇到自己感兴趣的资料,可能会多深入学习下,但学着学着就容易忘记原有目标了。所以,搜集资料既要足量,又要克制,避免过多偏离目标的资料干扰。

局外意识:保持研究的客观性

有时我们在调研对比竞品安全检测能力时,可能会直接用自己的测试样本库,而自研的安全系统已经专门针对自己的测试样本库作过对比,那对比结果肯定是有失偏颇的。最好的方式是使用多方样本库进行对比测试,以保证结论的客观性。所以在研究过程中,有时就要跳出局外,以旁观者的角度来看待以保证研究结论的公平可靠。

img

我是个容易产生知识焦虑的人,所以也干过一些伪学习的事。伪学习完全脱离了学习本身,仅仅是为了满足自我的良好感觉,帮助自己摆脱焦虑。个人认为的伪学习主要有以下几种情况:

  1. 单纯拼数量的学习:鼓吹一年要读100,300本书,一年要听多少在线课程,10分钟读透xx书籍等等。
  2. 追捧“大神”式的学习:缺乏辨别能力,盲目追随“大神”,网上各种买课程,想当然地以为听了“大神”的课,自己也变成大神了。
  3. 沉迷于不解决实际问题的学习:一整年看的都是不用思考的书籍,比如小说,只图一时爽,对提升能力无任何帮助。
  4. 干货收藏式学习:看个标题和开头,直接微信收藏,或存印象笔记,然后就没然后了。之前我也有过这种做法,后来一些看得慢的资料就干脆打印出来慢慢学习了。

img

本文主要介绍了一些学习方法和个人入门安全领域的一点经验,更多是想强调基础知识的重要性,输出式的主动学习能够实现更高效的学习,也介绍了知识体系建设方法和研究过程中需要注意的三个点,最后提醒大家避免进入伪学习的坑。第一次在手机上写这么长的文章,且个人经历有限,如有误欢迎指正探讨。

关于Adobe PDF 0day的故事

今天StarLabs 发布了他们之前在天府杯上用的adobe pdf 完整exploit,该漏洞是一个 JS API UAF漏洞,利用代码公布在github上,以及利用思路分析文章:https://starlabs.sg/blog/2020/04/tianfu-cup-2019-adobe-reader-exploitation/

去年天府杯上,Adobe Reader应该是最大的目标了,很多人打,但临赛前,很多人却退赛了。因为当时的比赛规则是奖金池固定,所有攻破团队来平分那笔钱,所以越多人参赛就越吃亏。但即便退赛了,一些攻破团队拿到钱再平分下也没多少了,最后还不如直接报ZDI,甚至可能还不如上HackerOne报个xss。挖个xss多久?可能几天,利用都不用写。但挖个pdf漏洞多久,可能挖洞一周,写利用一个月,这性价比自不必多言,因此这届比赛,奖金规则一直被圈内人吐槽。

当时在现场了解到,可能不少人的pdf 0day都是js api,这种通过js完成利用比较方便通用,当然其它非js模块的漏洞也同样可借助js堆喷利用。这些用js api漏洞的人最应该担心撞洞了,现场也有人用其它模块的pdf 0day,反正最后手上有个洞被撞没了。一个只在当最新版出现的漏洞,当时Project Zero报了一堆那个模块的漏洞,结果坑爹的Adobe修了漏洞1,却造就了漏洞2出来。在Adobe安全公告上,看到那个被撞的漏洞致谢上仍然写的是Project Zero的人(没错,未出现传说中的TFB)……

至少通过这件事情告诉我们,跟着PZ有肉吃!!!

Adobe的JS引擎用的是2013年左右的SpiderMonkey修改的,所以当初像domato这种js fuzzer神器出来之后,直接拿来fuzz,你都可以搞出一堆Adobe Reader的0day出来,也确实被刷了一波,看公告致谢时间,好像是我带的坏头😂…

前两年,pdf中的图片解析漏洞盛行,被玄武的刘姓小哥刷爆了。当时如果我报10个此类漏洞,那么可能就会有3个撞洞,就是这么惨烈,连windows上xps这种偏门格式,都被撞,也跟360的撞过。

在此之后,被刷最多的pdf 漏洞,除了常规的js api外,postscript被国外安全研究员mr_me刷了不少,他写了个ps语法模板生成器去fuzz,产量颇丰。如果没记错的话,据他自己在Twitter上公布的,其2018全年在ZDI的收益是近20万刀,相当于140万元。之前他创办了一个公司,但公司员工就一人。没错,就是他自己,基本就是专职挖洞和培训。今年他入职360 vulcan了,远程办公。

最后聊点pdf的通用利用技术,毕竟本公众号是技术导向的,但请原谅我的排版和无图内容,因为本文是在手机上写的,且全程在车上完成。

上文提到的文章已经给出了完整的利用思路,整体而言:

1. 无论何种内存破坏漏洞,一些逻辑漏洞除外,首先都设法转换成任意读写。利用js array堆喷去内存布局,实现uaf的占坑,或其它越界写的后堆块填充,以实现写内容和位置的控制,而js array本身可读,进而实现信息泄露。

2. 覆盖虚表指针去控制eip。寻找上下文可用的虚表指针去实现劫持,像starlabs用CTextField去创建一批对象,目的就是用来覆盖它的虚表指针

3.绕过DEP和CFI。2019年3月左右,Adobe终于加入了CFI,导致常规的ROP失效。每次这种新安全机制出来的时候,最佳的绕过方式一定是先寻找未受保护的模块或代码块。回望过往的DEP、ASLR、CFI和PAC,无不如此。这次starlab亦然,他们直接搜索Adobe安装目录下的pe文件,若OPTIONAL_HEADER.DllCharacteristics & 0x4000 = 0,即代表无CFI保护,最后他们找到icucnv58.dll用来构造ROP,分配可执行的shellcode来达到任意代码执行。

除了第一步需要依赖漏洞上下文场景来转换任意读写外,利用的难点也是在此,而后续工作都是可以套路化。

可以看到,直至2020年了,Adobe的整体漏洞利用思路依然变化不大,仍是《漏洞战争》中各案例所分享过的方法,只是需要根据漏洞场景作些适配,比如寻找UAF对象同大小的对象,像starlab就用currentValueIndices方法来占坑。不好意思,这里打了下个人广告,可惜公众号app不能直接插入书籍广告,不然就广告彻底一些🤑

持续Fuzzing在DevSecOps中的应用

长期以来,一直有个疑问:

Fuzzing为何一直未被引入DevSecOps中?

刚好本周有两件事引起我的关注:

  1. Google发布CIFuzz以支持Github项目实现CI构建过程中的持续Fuzzing(Continuous Fuzzing)
  2. RSA创新沙盒比赛中ForAllSecure公司的参赛产品Mayhem——下一代Fuzzing解决方案

这两件事其实是往着同一目标前进的,就是将Fuzzing引入到CI持续集成中,直观的表现就是,当往代码仓库提交代码后,可被自动编译并完成Fuzzing,最后输出结果以进入下一开发环节。

这跟我去年11月在”天府杯”上分享的《Fuzzing平台建设的研究与设计》中的思路是类似的,当时国内外还没任何公开的产品,这次CIFuzz与Mayhem的出现,终于填补了这个空白。

先聊聊CIFuzz的实现原理

使用CIFuzz有2个要求:

1、只允许GitHub上的项目使用;

2、项目必须整合OSS-Fuzz

它主要利用GitHub Actions来实现下载、编译和运行oss-fuzz中的Fuzzer,若要fuzzing自己的项目,就得自己把先fuzzer提交到oss-fuzz。整个过程在docker中的ubuntu中运行,整个过程用workflow来定义这些操作行为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
name: CIFuzz
on: [pull_request]
jobs:
Fuzzing:
runs-on: ubuntu-latest
steps:
- name: Build Fuzzers
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
with:
oss-fuzz-project-name: 'example'
dry-run: false
- name: Run Fuzzers
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
with:
oss-fuzz-project-name: 'example'
fuzz-seconds: 600
dry-run: false
- name: Upload Crash
uses: actions/upload-artifact@v1
if: failure()
with:
name: artifacts
path: ./out/artifacts

所说GitHub 为每个 workflow 提供独享 1 核虚拟 CPU, 3.75GB 内存 和 100GB 的磁盘空间,提供相当慷慨的计算资源。对于想将Fuzzing引入CI中的DevSecOps建设,确实挺耗计算资源的。还有另一种方法,就是由开发本地提交代码时,自动完成Fuzzing后再提交,利用的是开发者本地的计算资源,对于Fuzzing平台建设是最节约成本的。

当发现崩溃后,会在前端输出崩溃的栈回溯和测试用例等关键信息:

artifacts

在腾讯内部,我们一般称workflow为流水线,在产品体验上这功能绝对秒杀GitHub,就是我之前贴着这张图:

img

再来看看Mayhem

对于Mayhem的信息是有限的,只有官网提供的相关文档。先来看下Mayhem的工作原理,大体流程跟上面一致的:

image-20200301195430422

它将符号执行与覆盖引导技术结合用于Fuzzing测试,但符号执行整体上是偏于理论,且难以用于大项目,因为它容易出现路径爆炸问题。虽然他们用来打过CGC机器人CTF比赛,但其赛题都是定制的,并不能完全代表真实的软件世界,这点还需要时间来考验。

image-20200301195624394

Mayhem提供有比较友好的前端界面,在功能上要比CIFuzz更加完善和自动化,体现出一个完整商业产品的特点:

img

image-20200301200249609

发现崩溃后,也能够提供更加详细的崩溃信息,包括重现方法、样本下载、崩溃指令和地址等等:

img

img

Continuous Fuzzing实现上的常见问题

个人对持续Fuzzing建设的一些思考总结,列举一些常见问题和解决方案,欢迎私信探讨。

1、如何设置Fuzzing时长,既能保证测试的有效性,又能保证CI流程的流畅,避免产品发布受阻?

以往Fuzzing跑个几天是很常规的姿势,最长的我也跑过几个月的,但这在CI中显然是不合适的,必须为此设置时长限制,Google CIFuzz是默认10分钟,但个人觉得太短了,最好是几小时,但这要结合业务场景来定,有些产品一天构建N次,这得浪费不少计算资源。如果资源有限的话,最好每天一款产品只能Fuzzing一次。

2、如何编写Fuzzer保证测试的有效性?

CIFuzz是自己提供Fuzzer,需要开发者基于libfuzzer编写的fuzzer;而Mayhem没有明说,但一般都得开发者或者安全人员来开发。这个问题之前我也在《Fuzzing平台建设研究与设计》中说过,可以培训开发用libfuzzer来写fuzzer,也可以直接写单元测试程序,以及安全人员作定制化的fuzzer。

3、如何保证Fuzzing执行时的服务器安全?

使用者提交自己的代码并编译执行,如果不作隔离,肯定就后门无数,沦为大家的肉鸡。使用docker作隔离的容器是已经很成熟的方案了,不仅fuzz,其它一些DevSecOps建设中的其它安全测试方案同样适用,比如CI中的代码审计,我们也是用docker来做的。

4、如何提供测试样本?

CIFuzz是自己在oss-fuzz中指定好的样本,Mayhem是明说,但估计也是需要用户提供。在之前的文章,有讲过我的实现思路:以后缀名来区分文件格式,自动爬虫收集,根据输入数据的格式自动提供,对于特殊的输入数据,需要自己另外去收集,比如hook收集等等。本质上,无非就是开发者提供测试数据,或者平台建设者提供各种常见格式的测试样本。

如果你对DevSecOps建设、漏洞挖掘感兴趣,欢迎私信。

终端安全工程师(深圳)

岗位职责:
1.安全评估:对公司内的移动终端产品进行安全评估,并提供自动化检测规则,探索与实践DevSecOps
2.代码审计:开发自动化的代码审计系统
3.应急响应。对外部报告的终端漏洞进行响应,分析漏洞,排查影响范围,并提供检测与防御方案;
4.业界追踪。保持关注业界最新安全动态、新安全技术及发展趋势,促进安全技术的提升;
5.沉淀培训:形成技术知识的沉淀和分享,开展公司内交流和培训工作。

岗位要求:
1.本科及以上学历;
2.2年以上的安全工作经验;
3.熟悉常见的终端安全风险的危害、原理及其防御方案;
4.熟悉x86和ARM汇编,熟练使用IDA、GDB等逆向分析与调试工具
5.熟悉主流语言的代码安全审计技术,具备⼈工审计与自动化审计系统开发能⼒
6.熟悉DevSecOps并且有参与过其中一些安全过程的技术和经验;
7.熟悉移动终端应⽤隐私合规检测技术
7.至少熟悉C/C++、Python、Java其中的⼀门语⾔,能够独立开发漏洞检测工具
8.具备较强的学习能力、动手能力、沟通能力、团队合作意识及综合分析能力;

具备优秀安全基础能力或某一领域深度安全能力并对安全有浓厚兴趣者优先;
有终端自动化审计系统开发经验者优先;
有代码审计系统开发经验者优先;
有知名软件的CVE漏洞发现与利用成果的优先。

WX20200229-165739

用afl玩超级玛丽:通过Fuzzing探索程序空间状态以发现更多执行路径

今年S&P顶会上有一篇研究论文“IJON: Exploring Deep State Spaces via Fuzzing”,他们通过改造AFL来探测程序的空间状态,以发现更多程序行为,并拿游戏”超级玛丽”来作演示:

当前最流行的Fuzzing技术就是基于覆盖率的方法,Edge Coverage应该是当前最有效的覆盖率统计方法,比BasicBlock方式多记录调用边界,而afl对覆盖率的探测很多是暴力猜解的,一些afl家族工具也对其进行扩展,比如切割多字节指令为单字节作数据比较,提取cmp指令的一些常量操作值作变异。但是,这种方法对于一些特定的代码结构,若不去探测程序状态空间的中间点,就很难触发新的覆盖路径。

何为程序状态空间?

状态空间代表程序所有可能状态的集合,状态代表内存和寄存器的一种配置,以及系统提供的状态(比如文件描述符、类似原语)。状态空间比代码覆盖统计空间更大,若改造AFL就需要实现对状态空间的支持,以优化测试用例达到状态的多样性。

论文主要贡献

  1. 分析当前主流Fuzzer的反馈机制,并实现如何用它们表示状态空间;
  2. 扩展当前主流的覆盖反馈Fuzzer的能力,允许分析人员通过程序状态空间解决当前业界方法无法解决的路径约束问题;
  3. 展示了可信平台模块(TPM)、复杂格式解析器、超级马里奥游戏、迷宫和散列映射实现的软件仿真器的状态空间,演示其是如何被Fuzzer有效探索到的。顺便,解决掉一些CGC挑战集合中的难题(CGC专门为机器人自动打CTF而设计的题目,与真实软件场景还是有差异的),也发现了一些真实软件的漏洞(其实就是一个偏门的dmg2img工具而已)。

主要设计原理

作者设计了一套源码注释原语,其实就是给源码加个一两行补丁代码,用来干预Fuzzer的反馈功能。在可交互的Fuzzing会话中,分析人员可以人工介入去分析一直无法触达的执行路径,然后为其增加补丁代码解决路径探索障碍的问题。

afl-gcc或afl-clang本身就是对gcc/clang编译器的封装,添加一些编译选项,以及代码插桩的功能,作者为其编写了个链接库,以实现前面所说的注释原语,包括一些自定义函数和宏等,通过它能够访问AFL用于存储覆盖信息的位图(其实是个哈希表),直接添加和设置条目上去,将状态值直接反馈给Fuzzer。同时,也允许相同的edge coverage存储到不同的覆盖位图中,因为不同的状态值可能触发的是同一处edge coverage,这代表它能够实现更细粒度的反馈,为此它还提供扩展用于存储覆盖位置的共享内存区域。对于状态空间爆炸的问题,也会提供”爬山算法”(hill-climbing)作出优化选择。

作者对超级玛丽作了修改,使所有的键盘命令都可以从标准输入中读取,并且马里奥只能不停地向右跑,只要停下来就死掉,这个设计主要是为节省时间。

作者还用改造后的Ijon与AFL作对比,运行12小时的AFL看其能打到哪一关,而使用注释原语的Ijon只几分钟就通过了大部分的关卡,有些确实过不了。下图是超级玛丽打喷火怪兽那关,线条是Fuzzer发现的所有执行路径,对比还是比较明显的,AFL暴力探测的密集度比较明显,更关键还是没通关,至少从作者统计图上看是如此的。

image-20200229151836427

论文链接:https://www.syssec.ruhr-uni-bochum.de/media/emma/veroeffentlichungen/2020/02/27/IJON-Oakland20.pdf

WX20200229-165739

从研究者的视角看Fuzzing技术发展30年

源起

1988年,在威斯康星大学Barton Miller教授的计算机实验课上(http://pages.cs.wisc.edu/~bart/fuzz/CS736-Projects-f1988.pdf ),首次提出Fuzz生成器(Fuzz Generator)的概念,用于测试Unix程序的健壮性,即用随机数据来测试程序直至崩溃。因此,Barton Miller教授也被多数人尊称为”模糊测试之父”。但是,当时更多是为了验证代码质量和程序的稳定性,而非专门用于挖掘安全漏洞,真正用于软件安全漏洞挖掘的开端要从下面两件事说起。

从学术界到工业界的证明

2001年,芬兰奥卢大学公布PROTOS测试集项目的研究成果(https://rd.springer.com/content/pdf/10.1007%2F978-0-387-35413-2_16.pdf ),首次将Fuzzing技术应用在网络协议的安全测试当中,他们针对不同的网络协议构造出不同的测试用例集,这些在其官网(https://www.ee.oulu.fi/research/ouspg/Protos )上依然可以下载到。2002年,PROTOS逐渐成熟,Microsoft开始为该项目提供资金支持。于是,2003年项目组成立了Codenomicon公司,开始将Fuzzing技术应用于商业产品,也确实发现了不少安全问题。因此,PROTOS项目可以说是Fuzzing技术发展历程中的一次重要里程碑。可能大家对Codenomicon公司不太了解,但说到”心脏滴血”漏洞,应该无人不知无人不晓。没错,它就是Codenomicon公司发现的。

2002年,在BlackHat USA黑客大会上,来自Immunity安全公司(PS:还有人记得Immunity Debugger吗?)的Dave Aitel发表议题“An Introduction to SPIKE, the Fuzzer Creation Kit”,至此著名的Fuzzer工具SPIKE公布了,它是基于块模板定义的网络协议测试工具,优点是支持定义可变长度数据块的能力,除生成随机数据外,它还提供一些现成的边界值生成,以提供触发崩溃的概率。SPIKE的诞生,使得广大用户能够依据自身需求定制网络协议Fuzzer,这对Fuzzing技术的普及起到巨大的推动作用。早些年,笔者也曾写过一篇SPIKE的教程“基于SPIKE的网络协议Fuzzing技术(http://riusksk.me/2011/12/30/spike-fuzz/)",但现在其实基本不用了。

PROTOSSPIKE的诞生,代表着学术界与工业界对Fuzzing技术在商业与安全实战领域的应用提供了有力的证明。

文件Fuzzing技术的兴起

2004年,Peach模糊测试框架的发布,标志着文件Fuzzing时代的到来。最初Peach是用Python开发的,后来在2007年被收购后改用C#重写,并分为社区版和付费版。Peach支持文件格式、网络协议、ActivieX控件等多种形式,通过编写pit文件(xml格式)来定义数据格式,每次开始写的时候其实挺费劲的,后来有人提供自动将010editor格式解析器(仿C语言的bt文件)转换为pit,在一定程度上可以缓解劳动力。笔者第一次通过文件Fuzzing挖到漏洞也是借助Peach实现的。

直至今日,Peach依然还有人在用,更有人将PeachAFL打通,在Github上发布aflsmart的开源项目。

文件Fuzzing应该是当前Fuzzing应用中最为普遍的形式,即使是网络协议等其它目标的Fuzzing,也是可以转换为文件Fuzzing的。比如OpenSSL网络协议Fuzzing,通过源码打Log的方式先收集网络数据为本地文件,再调用其API写个hareness用AFL或libfuzzer进行本地测试,就顺利地将网络协议Fuzzing转换为文件Fuzzing。

语法模板Fuzzing:打开攻击浏览器的大门

2008年,Mozilla安全团队发布了jsfunfuzzDOMfuzz,基于JS语法模板来生成测试用例,以挖掘浏览器漏洞,后来两款工具合称funfuzz( https://github.com/MozillaSecurity/funfuzz ),以开源的形式对外公开。这款工具在当时确实挖到了不少浏览器的漏洞,但其语法模板的可扩展性并不友好,只能在其代码上作修改,这点不如dharma( https://github.com/MozillaSecurity/dharma ),以及后来Project Zero发布的Domato( https://github.com/googleprojectzero/domato )。这种基于语法模板的Fuzzing方式,挖完一波后,就要求保持模板的更新才能持续产出,同时要理解测试目标在JS代码上的触发逻辑,比如JIT可通过for循环来触发代码优化,Dom UAF可通过创建Dom元素,并调用相关元素的方法来触发删除和引用,以探测是否存在UAF的可能。整体上依赖于对语法和目标原理的理解,才能构造出好的语法模板。

funfuzz之后,业界也出现了好多款优秀的JS语法Fuzzing工具,比如grinderndujacrossfuzz等等。当年PC流行时代,用grinder来Fuzzing Windows IE浏览器的人应该比较多。

浏览器一直是网络攻击中最受关注和最常用的入口,过去如是,现今依然。因为系统自带,且用户使用率高,又是远程访问的最佳途径。渲染引擎和JS引擎一直是浏览器主要攻击面,主要以html、js、vbs作为解析语言,因此对这些语言的语法Fuzzing就自然而然的产生了。除此之外,如今WebSQL也开始备受关注,比如Chrome上的sqlite模块,SQL语法的fuzzing也随之而来。

除了浏览器,pdf的JS和flash的as语法解析,也一度作为攻击Adobe Reader和Adobe Flash的入口。

符号执行:学术与工业之争

2008年,基于LLVM的符号执行引擎KLEE发布后,引领了一波程序分析新姿势的潮流。后来,符号执行被应用于Fuzzing中,经常被用来打CTF比赛,用来找key、解混淆、fuzzing等用途。比如,将AFLangr结合的drillerhttps://github.com/shellphish/driller ),还被用在了CGC(Cyber Grand Challenge)自动网络攻防竞赛上,但这种比赛都是特定场景下的比赛,不能完全代表真实的软件世界;还有,将AFL与KLEE结合的kleeflhttps://github.com/julieeen/kleefl ),这款工具知道的人应该不多。

符号执行在学术界中应用得比较多,工业界相对少一些,这是现状。将符号执行应用在Fuzzing中,通过约束求解新路径的条件值,以增加代码覆盖率,可以一定程度上弥补暴力变异的不足。符号执行主要的挑战在于路径爆炸问题,约束求解能力的局限性,以及性能消耗问题,比如内存和时间消耗过大。符号执行与约束求解对于小型应用比较有效果,也常被用于CTF比赛,在CTF中使用最广的当属angr框架。但是,基于当前的业界情况,符号执行仍然比较难以应用于大型软件中。符号执行在Fuzzing中的应用并没有真正带来新的技术浪潮,真正的技术浪潮始于代码覆盖引导技术的引入。

代码覆盖引导技术:Fuzzing技术的分水岭

2013年底,afl-fuzzhttp://lcamtuf.coredump.cx/afl/ )发布了,首次采用源码编译插桩和QEMU模式来实现代码覆盖引导Fuzzing的方式,这绝对是Fuzzing技术发展历程中最重要的一次里程碑,也是技术分水岭,它开启了Fuzzing技术的新篇章。刚发布的时候,afl并没有那么火,主要是在2014和2015年期间,被很多人使用后挖到不少主流开源软件的0day,并在Twitter上宣传,使得更多人关注到并使用,这证明了代码覆盖引导技术在Fuzzing实战中的价值。

随后,基于afl二次开发的fuzzer如雨后春笋般涌现出来,比如winafl、libfuzzer、AFLFast、Vuzzer等等,而且针对各种语言的版本出相继出现,比如go、python、js、ruby等等。一些已知名的Fuzzer也迅速跟进,比如syzkaller内核Fuzzer,它原本是基于API调用模板的,后来也引入了代码覆盖引导能力。同时,业界都在试图将其移植到各种平台上(比如windows、android、IOT平台等等),并实现支持闭源程序的代码覆盖引导能力,这一直是近几年来Fuzzing技术研究的热点方向,比如动静态插桩、虚拟机模拟执行、硬件特性等等。无论是工业界大会(BlackHat、OffensiveCon、CCC等等),还是学术界四大顶会,关于Fuzzing的议题也越来越多,相信这种趋势会持续下去。

系统函数调用模板Fuzzing一度成为攻击内核的常用手段

2015年Google开源了syzkaller,一款用于Fuzzing Linux内核的工具,漏洞产出特别高。现在依然很多人用它来挖各系统平台的内核漏洞,包括Android、macOS、Windows等主流系统平台。syzkaller通过定义系统函数调用模板来实现,在模板中定义系统调用函数参数类型,并解决函数调用的顺序依赖和值依赖问题。Project Zero官方博客就曾写过一篇利用syzkaller fuzz socket挖掘Linux内核漏洞的文章,叫“Exploiting the Linux kernel via packet sockets(syzkaller usage)” ( https://googleprojectzero.blogspot.com/2017/05/exploiting-linux-kernel-via-packet.html ),详细讲述了如何编写模板,以及syzkaller的使用方式。

Windows平台也常被通过构建GUI API调用模板来Fuzzing系统内核,macOS平台内核Fuzzing就常拿IOKit函数开刀,都是基于这种系统函数调用模板的Fuzzing方式实现的。

2016年Google提出”结构感知型Fuzzing”(Structure-Aware Fuzzing ),并基于libfuzzerprotobuf实现了libprotobuf-mutator(https://github.com/google/libprotobuf-mutator),其实现思路与syskaller相似,它弥补了peach的无覆盖引导的问题,也弥补了afllibfuzzer对于复杂输入类型的低效变异问题。正如前面提到的,也有人将aflpeach整合成aflsmart,以此实现类似功能。现在Project Zero也用libprotobuf-mutator来fuzzing iOS内核,详见“SockPuppet: A Walkthrough of a Kernel Exploit for iOS 12.4”(https://googleprojectzero.blogspot.com/2019/12/sockpuppet-walkthrough-of-kernel.html)。

结构感知型Fuzzing并不是什么新技术,跟Peach的实现思路是一样的,只是对输入数据类型作模板定义,以提高变异的准确率。只是当前大家更倾向于将结构感知与覆盖引导等多种技术优势整合一块,基于系统函数模板用于Fuzzing系统内核,相信这种方式未来仍会被经常使用。

助力开源生态安全建设

在工业界中,最知名的Fuzzing平台当属Google的clusterfuzzhttps://github.com/google/clusterfuzz ),运行在25000+台机器上,发现过16000+个Chrome bug,11000+开源项目bug,这个平台整合了OSS-Fuzz(https://github.com/google/oss-fuzz ),既支持libfuzzer和AFL的代码覆盖引导Fuzzing,也支持黑盒Fuzzing。OSS-Fuzzclusterfuzz分别在2016年和2019年开源对外,业界同行可以协同开发,对于提交fuzzer后挖到新漏洞的,Google会美刀奖励提交者,对于主流开源项目的0Day,Google也是有奖励机制的。同时,Google开发了ASanMSanTSanUBSanLSan等多种编译时插桩工具用来帮助检测漏洞,有些漏洞只在开启相关Sanitizer之后才会触发异常,跟在Windows下开启页堆的方式类似,可以帮助更有效地发现崩溃场景,在发现和分析漏洞上提供帮助。

Google对开源生态安全建设的贡献,是各大互联网公司不能比的。他们的贡献不仅帮助提高各大主流开源项目的安全性,也降低了Fuzzing的技术成本,在资金和技术上对开源生态安全的建设提供了大力支持。

语法树变异成为语法解析引擎漏洞挖掘的新方向

2012年,USENIX安全顶会上发布一篇论文“Fuzzing with code fragments”,研究者开发了一款叫LangFuzz的工具,他们从firefox、webkit、chromium等开源的浏览器项目以及网络上去收集js测试样本,然后用ANTLR其进行AST语法树分析,再将样本拆分成非终止语法的代码片断,放入代码池中,最后再基于代码池的代码片断对输入样本作交叉变异,主要取同类型的代码片断作替换或插入,再运行生成的变异样本进行测试。

基于LangFuzz的思路,后面又有人开源了IFuzzer,并发表相关论文公开,在LangFuzz的基础上增加遗传算法,对输入样本进行评估,筛选出优秀的个体进行组装以产生新样本。不过这个工具并没有那么完善,也未见到比较好的实际漏洞产出。

2018年,Project Zero的Samuel Groß发布一款叫fuzzilli的JS语法Fuzzer工具,它整合了语法变异、模板生成、覆盖引导等多种技术,使用自定义中间语言用于语法变异,再将变异后的中间语言转换成JS代码。fuzzilli在3大主流JS引擎的测试中,战果颇丰,发现了不少漏洞,也因此被业界同行拿去作二次开发,又发现了其它新的漏洞。

2019年,有2篇学术论文发布,他们都引用了论文“Fuzzing with code fragments”中的思想,它们分别是”CodeAlchemist: Semantics-Aware Code Generation to Find Vulnerabilities in JavaScript Engines“和”Superion: Grammar-Aware Greybox Fuzzing“,CodeAlchemist将输入样本进行语法树分析和数据流分析,为拆分出来的代码片段设置前置和后置的约束条件,前置条件代表一些引用的变量需要先定义,后置条件代表代码片段的输出结果,通过两者来解决一些未定义变量引用的问题。Superion是将语法树变异规则置入AFL中实现的,借助AFL筛选变异后的输入样本,而且支持多种语言,也是采用ANTLR作语法树分析,其在语法扩展上比较友好。两款工具均在最新JS解析引擎上发现过若干0day漏洞,并且均已在Github上开源。

除了传统的模板Fuzzing,语法变异(无论是AST,还是自定义中间语言)也是一项值得探索的方向。

人工智能在Fuzzing中的应用仍亟待探索

2018年是人工智能元年,很多领域都在探索AI的应用,漏洞挖掘领域亦然。之前笔者阅读过一些AI应用在Fuzzing中的相关议题,主要集中在测试样本生成的训练上,利用已知漏洞的样本或正常样本作训练,然后重新生成测试样本进行测试。可惜从效果上来看,是一种高投入低产出的事情,有些还不如直接暴力变异来得高效高产。但这也不是说,AI没有价值,只是它在这方面的发展时间较短,很多东西仍亟待探索,还有待时间的年轮来证明。

Fuzzing平台建设的研究与设计(paper)

引言

近年来,无论是工业界,还是学术界,Fuzzing技术的应用都非常广泛。每年的BlackHat、OffensiveCon、CCC等工业界顶会,以及学术界四大顶会( S&P、CCS、Security、NDSS ),经常可以见到Fuzzing相关议题。Google Project Zero也公布其近5年的漏洞挖掘方式占比,其中Fuzzing占比37.2%,手工占比54.2%,其它占比8.6%,这对于高产的P0来说,37.2%的占比已经意味着不少漏洞了。按Project Zero官方公布的bug列表来看,当前共有1975个漏洞公开(包括一些无效、未修复的,这里仅作粗略估算),按37.2%来算,大约有735个漏洞是通过Fuzzing挖掘到的,着实不少的数量,况且大多是高质量漏洞。所以说,Fuzzing依然是当前安全界所热衷的漏洞挖掘方式。

本文主要探讨下企业内部关于Fuzzing平台建设的一些想法,个人主要是想表达一个观点:协同Fuzzing,即整合企业内部各工种(开发、测试、安全、运维等等)的力量,将Fuzzing合入CI构建中,通过DevSecOps协同模式来完成产品的Fuzzing工作,以便将漏洞消除在上线前阶段。

Fuzzing平台的价值思考

虽说Project Zero超过一半是人工审计发现的,但对于企业内部,项目之多,代码语言和代码行也是非常之多,很难单纯靠人工来解决的。量级的变化,自然会导致自动化需求的诞生,才能更加高效地发现、消除和监管企业内部的代码风险。

产品从开发到发布,涉及到多工种协作,如果能让他们一块参与到安全工作当中,那么有时也可以弥补安全人力的不足,同时让非安全出身的业余选手也能干专业的事,帮助安全人员覆盖更多的攻击面测试,提升漏洞发现率。

安全人员参与到产品的整个研发流程当中,可以将发现漏洞的时间线提前,有助于在产品上线前发现并解决安全风险,提高产品安全性。

协同Fuzzing平台的设计思路

1578971205508

以往我们在帮业务产品作安全测试时,开始前业务同事会提供文档资料或者开会分享产品功能设计的方方面面,以及担心的安全风险问题,安全同事需要花时间消化,前期双方都需要消耗不少时间成本,况且在有限的时间内,对产品的攻击面剖析也不一定足够到位。

假设当前需要对产品进行Fuzzing测试,一般需要一个支持命令行的测试程序,通常称为harness。开发或者测试的同学可能本身就会开发有相应的测试程序,如果没有,安全测试人员就得自己开发,有API或者源码都好办,没有的话,可能还得做Hook。

对产品最了解的,一般当属开发同学。所以,如果开发者在开发完相应功能后,开发以及质量测试人员若能够编写相应的接口测试程序,将对于安全测试会有很大帮助。一方面是工作效率的提升,另一方面是测试面的覆盖广度提升。

如此之后,我们可以设计出协同Fuzzing平台的工作流水线:

  1. 开发阶段:开发人员编写相应的harness程序,尽可能覆盖用于解析外部数据的处理函数。直接开发或者使用libfuzzer等安全测试库进行开发均可,安全人员也可定期对其进行安全培训,指导libfuzzer等工具的使用。
  2. 构建阶段:对于源码编译场景,支持多种构建触发方式,最佳的方式还是基于git事件触发,即提交代码后触发,然后将源码下载到指定的构建机编译,开发者需要配置编译命令,此处也可以开启ASAN或者AFL编译等功能;对于非编译场景,则直接提供相应的可执行程序下载地址,将其归档打包至用于Fuzzing的服务器上。目前,“腾讯CI”已将构建功能嵌入到自家git平台“工蜂”上,提供覆盖所有主流编译工具和语言,因此未来其在安全领域上的应用还有发挥的空间。
  3. 测试阶段:配置相应的测试命令,即harness程序的参数,以及运行环境,包括Windows、Linux、macOS,如果硬件资源丰富的话,Android和iOS又何尝不可。提交在服务器上布署好常见Fuzzer工具(afl/libfuzzer/honggfuzz等等),或者自主开发的其它Fuzzer,同时部署一些常见文件格式的样本库。对于特殊数据格式,比如自定义协议/文件格式,最好由开发或测试同学提供,否则只能安全测试人员去解决,一些提取样本数据的方法后面会介绍。
  4. 告警阶段:若发现崩溃,则作二次运行确认,确认二次崩溃则告警出来,可邮件、工单、微信等多种方式,将运行命令参数、崩溃场景的栈回溯、可利用性分析等基本信息同步出来。对于崩溃容忍度较低的产品,可设置“质量红线”,去重后的崩溃数量超过多少个禁止发布。开发修复漏洞后,继续从第一步的开发阶段开始继续循环下去,直至无新漏洞发现。

Fuzzing三要素

Github上已有很多知名Fuzzer被开源,圈内也有不少人借此挖到漏洞,直接基于现成工具,或者二次开发挖到的都有,也有人借鉴思路自主开发新的工具。对于一款新漏洞挖掘工具的发布,多数人可能会认为,开源作者应该是已经挖完漏洞了才公布的,应该已经挖不到0day了。但有时,你又会发现,老树开新花的事情还是很常见的。那么决定Fuzzer能否挖到漏洞的关键因素有哪些?根据个人经验,笔者觉得主要有三要素:目标、策略、样本

目标:攻击面分析

对于企业内部产品的测试,直接找开发要设计文档,甚至源码,都可以帮我们快速分析出攻击面。面对黑盒测试时,尤其是主流软件/系统的Fuzzing测试时,能够让我们参考的主要还是其官方文档,比如MSDN、Apple开发文档、Acrobat Javascript API手册等等。当初winafl诞生时,从MSDN找API去Fuzzing的方式屡试不爽,运气好的,一个API拿10个CVE也不是没干过;Apple开发文档中的系统的各个模块介绍,github上的示例代码等等,无不成为寻找攻击面的最佳途径;还有Acrobat 一个JS API产生好几个漏洞的情况,也有人直接写脚本分析API手册,提取API模板作Fuzzing;其它系统平台上写爬虫提取系统函数原型模板,作驱动Fuzzing。

这些从官方手册,以及官方放置在Github的示例代码,无不成为最佳的目标攻击面分析途径。如果你搞过上面这些,应该明白我在说什么。

除了文档,一些业界公开的漏洞信息,比如Project Zero、ZDI、厂商的补丁公告等等都是挖洞方向标。在以上信息都缺失的情况,就只能人工逆向分析来寻找攻击面了。

比如2019年微软的一次补丁公告中,出现了很多Jet数据库引擎的远程代码执行漏洞:

1578992349658

于是从MSDN入手去寻找可能存在的攻击面,然后用手上的Fuzzer框架进行Fuzzing,几小时之后直接挖到一个品相极佳的漏洞,因为生成的poc直接控制了EIP:

1578992386112

策略:变异之法

常见的变异策略主要有以下几种:

  1. 基于暴力:随机数据替换、插入、删除、数值增减、边界值替换、拷贝覆盖等等,比如radamsa等;
  2. 基于模板:文件格式、协议格式、API原型模板、语法模板变异等等,比如peach、domato等;
  3. 基于代码覆盖引导:通过提高代码路径的反馈方式来优化样本,比如AFL、Libfuzzer等等;
  4. 基于语法树变异:通过AST语法树变异来Fuzzing语法解析引擎,比如Fuzzilli,该工具本身也实现基于模板和代码覆盖引导的功能。

除了以上常规的变异方法之外,有时需要针对当前的应急漏洞作新变异规则,或者适配特定的业务场景作定制化,这就要求我们的Fuzzer平台具备可扩展的变异策略插件开发,这种方式不仅可以社区化方式协同,企业内部也可以协同开发,类似oss-fuzz。

举个案例,2018年word公式编辑器开始流行起来,还被在野利用过。当时笔者就用python开发个针对OLE中“Equation Native” 的变异器,然后用riufuzz跑起来(riufuzz是笔者基于honggfuzz二次开发的fuzzer,2018及之前的新功能已在github上开源,之后开发就未开源了,大家可以自行发挥):

1578992857498

有时在变异前、变异后可能有特列的处理机制需要处理,比如pdf js fuzz,输入pdf可能得提取js再作变异,这是变异前处理;再比如png图片变异,变异后会导致crc校验失效,需要作变异后修复。还有对于复合文档中的某特定格式的文件变异后,需要重组打包,比如变异docx中的图片、pdf中的字体图片等等,此过程注意后缀名的变更问题。

样本的收集与筛选

1578993191152

以前笔者都是手工去网上找样本去下载那种包含很多文件的压缩包,但这种方式太费劲了,用过想再更新又得再去找。后来就干脆用scrapy写个爬虫去搜索引擎搜索,像pdf、office文档、图片几乎都是爬不尽的,但它支持的文件格式比较有限。因此,我就改去Github爬虫,很多开发者在开发时,也需要一些测试样本来验证,因此项目内经常包含有各种文件格式的样本,但它的搜索结果只有100页,需要变换关键词(字典库、单词库、输入法词库等等)来搜索,但整体搜索到的数量还是没有Google等搜索引擎多,可以当作互补方案。

若是遇到如openssl这种特殊协议数据,以及其它非完整文件格式的自定义格式,一般就得通过源码加Log,或者Hook技术去dump出二进制流样本数据,以此作为输入样本。

当我们获取的样本过多时,就需要作筛选,以避免过多的无用测试。对于开源项目,用AFL的工具足矣,但闭源程序就需要自己实现,以下就是笔者基于pin开发的语料库蒸馏器,用C++和Python开发的,支持跨平台:

1578993681237

以macOS上的pdf样本筛选为例,整体效果还不错:

1
2
3
总体大小:16.17G => 563.8M
文件数量:10074 => 1105
运行时间:3 天22 小时

效果

1578993924461

基于上述方法论,笔者在近3年内,共获取国际四大厂商(Apple、Microsoft、Google、Adobe)70余次CVE漏洞致谢,其它一些厂商产品的漏洞暂且不计。

总结

本文主要介绍了协同Fuzzing的设计思路,将Fuzzing置入CI构建中的方法,并分享了决定Fuzzing效果的关键三要素:目标、策略、样本,对这些要素一一分析,并附相应的实战案例。未来,我们也会尝试多去实践和推广这种多工种协同Fuzzing的工作方式,并建设更加完善的平台管理控制系统,方便实现多人协同工作。

基于笔者水平有限,这套设计方案有些在企业内部实施的话,难免会有不足之处,欢迎业界同行斧正。

Frida框架在Fuzzing中的应用

由于Fridahttps://frida.re )动态插桩框架的跨平台、简单易用,现在已经被广泛应用于安全领域。相比Xposed而言,虽不能更底层地去Hook系统进程,但它可以免启动,应对App的hook完全够用,更关键的是,它完全可以用JavaScript来写代码,免去编译的烦恼,调试也方便。

之前在工作中,也就用Frida去Hook Android与iOS应用来做安全测试,效果挺好的,开发起来也挺高效的。本文主要围绕Fuzzing领域,来分析和记录最近一些使用Frida的Fuzzer。

定制型Fuzzer

Frida来Fuzzing APP的方法,首先推荐Project Zero大神写的Adventures in Video Conferencing系列博文,详细介绍了Hook WhatApps和iMessage的输入数据处理函数并进行Fuzzing的方法,同时也开源了Hook iMessage的工具:https://github.com/googleprojectzero/iOS-messaging-tools/tree/master/iMessage ,提供dump和发送消息的功能,自己在额外构造变异数据去Fuzzing。

这种方式特别适用于拥有私有的定制协议或数据格式的APP Fuzzing,只是需要花时间去逆向分析程序的输入数据解析流程,找到关键的处理函数。

通用型Fuzzer

最近又看到两款使用Frida的Fuzzer,出自同一人之手,用PythonJS写的,代码量不多:

  1. frida-js-afl-instr(https://github.com/andreafioraldi/frida-js-afl-instr ):打通AFL++Frida实现内存Fuzzing的工具,仅限Linux平台
  2. frida-qbdi-fuzzer(https://github.com/andreafioraldi/frida-qbdi-fuzzer ):基于FridaQBDI的Android Fuzzer,借鉴AFL的代码覆盖引导思路,实现Android平台下闭源程序的覆盖引导Fuzzing。

下面直接画时序图来看它的原理,就不贴源码分析了:

frida-js-afl-instr原理图

image-20191130121915743

frida-qbdi-fuzzer原理图

image-20191130122032208

总结

用Frida来实现闭源程序的代码覆盖引导,代码量很少,以Python和JS就可以快速开发起来,但涉及到python等进程的启动,肯定没有纯C/C++的代码运行速度快,但对于Fuzzing,一般还是够用的,还是值得学习和使用的。