原文:“steganography” - obfuscating PDF exploits in depth
译者:neal1991
welcome to star my articles-translator, providing you advanced articles translation. Any suggestion, please issue or contact me
LICENSE: MIT
上礼拜发现的关于使用 this.getPageNumWords() & this.getPageNthWord() 方法来进行混淆的 PDF 漏洞不久,我们发现另外一个,一个在 PDF 漏洞中更加强大的混淆利用技术。这种技术使用所谓的“隐写术”方法来隐藏嵌入在 PDF 文件中的图像中的恶意 Javascript 代码,它非常强大,因为它可以绕过几乎所有的 AV 引擎。
我们的 EdgeLogic 引擎将样本检测为 “exploit CVE-2013-3346”,与前一个相同。
https://edgespot.io/analysis/ebc5617447c58c88d52be6218384158ccf96ec7d7755179a31d209a95cd81a69/ 样本首先在 2017-10-10 提交给 VirusTotal,文件名为 “oral-b oxyjet spec.pdf”。
上周只有 1 个 AV 引擎检测到这种攻击(但是,截至写作时,检测增加到 5/57)。
https://www.virustotal.com/#/file/ebc5617447c58c88d52be6218384158ccf96ec7d7755179a31d209a95cd81a69/detection 打开后,伪装成 IRS 文件的 PDF 看起来很正常。
什么是 DDOS DDOS(Distributed Denial of Service),即分布式拒绝服务,是一种针对于网络服务的攻击行为。对于 DDOS 我们可以这样通俗地理解,假如有一家商店在售卖商品,突然涌过来一大帮人说要买东西,这里面有的人是真正地顾客,有的人只是过来捣乱的,但是售货员如果没办法及时处置,就会导致一种拒绝服务攻击了。而分布式拒绝服务攻击,则是因为黑客控制了很多台肉鸡来发动攻击。这种攻击近些年来越来越流行,对于攻击者来说,成本小,但是相对收益大,对于受害者来说,造成的伤害却是巨大的。因为对于服务提供者来说,一旦服务不可用,就会造成不可挽回的损失,可能会导致用户量的流失。根据腾讯云发布的《2018年泛互联网行业DDoS攻击态势报告》,2018年 DDOS 攻击已经进入 TB 时代,2018 年的攻击峰值为 1.23Tbps(同比增长121%),而业界的攻击峰值更是达到惊人的 1.94Tbps。
有人说对于 DDOS 攻击,有钱的话,就死命扩容,没钱的话,就忍一忍。虽然是玩笑话,但是有一定的道理。最近也是自己了解 DDOS 攻击这一块知识,下面简单介绍一下自己看到的一些。
DDOS 攻击类型 常见的 DDOS 攻击主要包括以下几类:网络层攻击、传输层攻击、会话层攻击以及应用层攻击。
传输层 DDOS 攻击 传输层 DDoS 攻击一般是针对于 TCP 以及 UDP 协议地攻击,主要是指 Syn Flood,Ack Flood,UDP Flood,ICMP Flood、RstFlood 等攻击。
以最常见的 DDOS 攻击 Sync Flood 为例,它利用了 TCP 协议的三次握手机制,当服务端接收到一个 Syn 请求时,服务端必须使用一个监听队列将该连接保存一定时间。因此,通过向服务端不停发送 Syn 请求,但不响应 Syn+Ack 报文,从而消耗服务端的资源。当等待队列被占满时,服务端将无法响应正常用户的请求,达到拒绝服务攻击的目的。
DNS DDoS 攻击 DNS 服务对于企业来说是比较重要的,因此针对 DNS 服务的 DDOS 攻击也是比较常见的。DNS DDoS 攻击主要是指 DNS Request Flood、DNS Response Flood、虚假源+真实源 DNS Query Flood、权威服务器和 Local 服务器攻击。
近几年由于 Github 信息泄露导致的信息安全事件屡见不鲜,且规模越来越大。就前段时间华住集团旗下酒店开房记录疑似泄露,涉及近5亿个人信息。后面调查发现疑似是华住的程序员在 Github 上上传的 CMS 项目中包含了华住敏感的服务器及数据库信息,被黑客利用导致信息泄露(这次背锅的还是程序猿)。
起源 对于大型 IT 公司或者其他行业,这种事件发生的概率实在是太常见了,只不过看影响的范围。现在大家看到的,也仅仅只是传播出来的而已。企业没办法保证所有人都能够遵守规定不要将敏感信息上传到 Github,尤其是对于那种特别依赖于外包的甲方企业,而甲方的开发人员也是一无所知,这种事件发生也就是司空见惯了。
废话说了一大通(可能是最近看安全大佬的文章看多了),终于要介绍一下我的这个项目,GShark。这个工具主要是基于 golang 实现,这也是第一次学习 golang 的项目,结合 go-macron Web 框架实现的一个系统。其实最初我是看到小米安全开源的 x-patrol 项目。网上这种扫描 Github 敏感信息的工具多如皮毛,我看过那种 star 数上千的项目,感觉实现方式也没有很好。因为说到底,大家都是通过 Github 提供的 API 结合相应的关键字来进行搜索的。但是,x-patrol 的这种实现方式我觉得是比较合理的,通过爬虫爬取信息,并对结果进行审核。所以,最初我是一个 x-patrol 的使用者。使用过程中,也遇到过一些问题,因为这个库似乎就是小米的某个固定的人维护的,文档写的不是特别清晰。中间我有提过 PR,但都被直接拒绝掉了。后来,我就想基于 x-patrol 来实现一套自己的系统,这也就是 GShark 的来由了。目前,这个项目与 x-patrol 已经有着很大的变化,比如移除了本地代码的检测,因为这个场景没有需求,其实我本身自己也实现了一个基于 lucene 的敏感信息检索工具。另外,将前端代码进行了梳理,并使用模板引擎来做模板的嵌套使用。基于 casbin实现基于角色的权限控制等等。
原理 讲完了起源,接着讲一讲这个系统的原理。基本上,这类工具都是首先会在 Github 申请相应的 token 来实现,接着通过相应的 API 来进行爬取。本项目主要是基于 Google 的 go-github。这个 API 使用起来还是比较方便的。通过这个 API 我们可实现在 Github 来进行搜索,其实这基本上等同于 Advanced Search。因为 API 提供的搜索能力肯定就是 Github 本身所具有的搜索能力。最基本的包括关键及,以及一些 owner 信息以及 star 数等等。
对于 SIEM 平台来说,好用的查询方式非常重要。之前有体验基于 ELK 搭建的平台,在 kibana 上面是可以通过一些 filter 来做一些过滤并且是支持 lucene 的语法,包括一些简单的逻辑查询以及 wildquery 等等。但是的确是在做一些汇聚之类时不是很方便,一般需要通过 json 来构建更高级的查询语句。后来好像也有转 SQL 之类的插件,但我也没有使用过,总的来说体验比较一般。
Qradar Qradar 是 IBM 一款比较成熟的商业 SIEM 平台(尽管他们的 BUG 一大堆,但架不住别的更差啊),基本上也是属于业界 TOP 5。商业产品的好处就是不用自己太折腾,搞搞就可以用,缺点就是贵。AQL(Ariel Query Language)是 Qradar 中的一种查询语言,与普通的 SQL 的语句类似,但是阉割了一些功能也增加了一些功能。以下是 AQL 的基本流程:
可以看出 AQL 是一种非常类似于 SQL 的语言,所以基本上你用过 SQL 学会 AQL 也就分分钟的事情,而且你也不会拿它去做特别复杂的嵌套查询(因为它也不支持。。。)
Tips 虽然 AQL 终于让我们有枪可以搞一搞了,但是还是有一些地方值得吐槽的地方。第一就是很多 ID 不知道其具体的映射,就比如我们想查询一些事件的名称或者规则的名称,AQL 是不存在字段名是事件名称或者规则名称的。不过你可以通过函数来进行转换,比如使用 QIDNAME(qid) 来获取事件名称,RULENAME(123) 来获取规则名称。你没办法知道事件名称或者规则名称到底是对应什么 ID,目前我用的办法就是先去 IBM Develop API 里面先去查询。第二,AQL 查询的结果我发现有某个规则的查询结果和用 filter 查询的结果不一致,不知道这是不是特例。还有其他的,想到再说。
下面就是我在使用过程中一些小经验:
引号的使用 在 AQL 中,单引号和双引号的使用是有区别的。单引号一般可以表示字符串或者作为字段的别名,如果你的字段包含了空格,那么你必须使用单引号。双引号一般用来表示自定义属性的名称。还有一个值得注意的地方就是,当你在使用 WHERE, GROUP BY, ORDER BY 的时候,你必须要使用双引号来使用别名,而不是单引号,是不是有点绕。其实有个好的方法就是不要使用单引号了,直接使用帕斯卡命名或者使用下划线连接,比如 EventName 或者 Event_Name,其实你自己想怎么命名都可以啦。
鄙人不才,只能做个 web 狗了。那就好好学习 web 吧。拼命地刷 writeup 就好了。上题目,Phone number。提示只有 phone number is a good thing.
打开链接可以看到是一个登陆页面,查看源代码,没有什么东西。不过,这个页面还有个注册页面,注册页面有用户名密码以及 phone,查看其源代码也没有什么异常情况。这道题初步看来应该是一道 sql 注入题了,那么注入点在哪呢?当然是 phone 了(来自于上帝视角)。如果正经地来说还是因为题目的提示啦。
注入点的确就是 phone,不过是要使用 16进制字符。为什么呢?上帝告诉我的,我也不知道。好吧,接下来就是 sql 注入四步曲了,爆数据库名,爆表名,爆字段,最后查数据,拿 flag。是不是很开心!
正常用户 首先,我们首先注册一个正常用户,注册之后登录,可以看到页面。这里面有一个 check 的按钮,点击一下,可以看到页面提示 There only 369 people use the same phone as you。查看源代码,可以看到注释里面有一句话:听说admin的电话藏着大秘密哦,这也是一个小提示。这里面的369应该就是通过 sql 语句从数据库拿到的,语句可能就是类似于 select count(*) from user where phonenum = 12 这种的,从而查出和你电话号码一样的用户数了,那么我可以信誓旦旦地告诉你,这就是一个注入点啦!
数据库名 因为 phone 可能使用的是数字,所以这是一个数字型的注入。那么,我买可以随便注册一个用户名了,首先获取数据库名的语句是 1 and 1 = 2 union select database(),把这个语句转化为16进制字符。将这个16进制字符串作为 phone 来进行注册,这里注意的一个点就是,前台对于 phone 的长度做了限制, maxlength="11",打开开发者工具设置大一点就可以了。注册成功之后,我么就可以看到:
Hello, txt1 Your phone is 1 and 1 = 2 union select database().
Python 作为一种常用的胶水语言,可用于各种用途。最近有个需求需要获取 SIME 平台的数据并形成月度报告。我的想法就是通过平台的 API 获取数据,然后基于 word 以及 matplotlib 来生成可视化报告。在这里要介绍一个比较好用的 python 库,docxtpl。这个库是一个基于 python-docx 的库,可以通过模板来生成报告。下面就介绍一下如何使用这些库,以及使用过程中的一些小问题。
模板 docxtpl 是基于 jinja2 引擎的语法,类似于常见的 html 模板语法,变量经常会放在 {{}} 中。假如我们希望在模板中设置变量 a 的值,那么我么可以在模板中填写 {{a}}。最后,我们通过 render 来渲染模板即可。
doc = Docxtpl(filename) context = { "a": "13413" } doc.Render(context) 那么如果我们希望在模板中插入一个图片该怎么做呢,可以使用 InlineImage 去实例化图片:
from docxtpl import DocxTemplate, InlineImage # for height and width you have to use millimeters (Mm), inches or points(Pt) class : from docx.shared import Mm, Inches, Pt import jinja2 from jinja2.
前段时间获取到黑产的一些代码,不得不感叹黑产的代码实在在写的是好得很,思路巧妙,环环相扣。不得不说,技术不好,黑产都做不了了。虽然分析了好多天,但是也只是一知半解。这里抽出一小部分来讲一下。二话不说,先上代码:
最初的代码是经过混淆的,代码经过整理如下:
var createImgElement = function(urla, b) { var imgElement = document.createElement('img'); var canvasEle = document.createElement('canvas'); imgElement['crossOrigin'] = true; imgElement['onload'] = function() { canvasEle.width = this.width; canvasEle.height = this.height; var canvasContext = canvasEle.getContext('2d') canvasContext.drawImage(this, 0, 0, this.width, this.height); for (var canvasContext = canvasContext.getImageData(0, 0, this.width, this.height), cancasDataLength = canvasContext.data.length, arr = [], i = 0; i < cancasDataLength; i += 4) { var code = canvasContext.
Wmic, 即 Windows Management Instrumentation Command-Line Utility,通过这个工具我们可以获取计算本地的很多信息。
起源 我起初是希望写一个 bat 脚本来获取计算机安装的程序和功能列表以及计算机最近安装的一些补丁信息。程序和功能列表以及补丁信息可以通过计算机的控制面板去查看,但是这样一点都不 geek,能用脚本解决的当然要用脚本去解决啦。
程序和功能 通过 wmic product 我们可以获取程序和功能的安装信息。
wmic product get name,description
这样我们就可以获取计算机上安装的程序和功能列表以及其相应的描述。当然除了 name 以及 description 之外我们还可以使用 vendor 以及 version 来获取程序的厂商名称以及对应的版本号。另外,如果我们希望把结果导入到 txt 文件中,我们还可以使用万能的管道符号:
wmic product get name, description > products.txt
这样我们就可以获取结果的 txt 文件,是不是很方便。然而,当我们将使用 wmic 导出的结果和控制面板中的程序和功能相比较的话,我们会发现有些程序没有出现在结果中,比如 Google Chrome。
通过 wmic 只能获取大部分程序列表,它们的安装包一般都是使用 Windows Installer 制作的,安装过程中调用 Windows Installer 服务进行安装。但是 Windows Installer 并不是唯一的制作安装包的工具,因此 wmic 往往可能获取的还不是完整的程序和功能列表。至于完整的程序和功能列表,可以参考这篇文章。
补丁信息 经常我们需要获取计算机的补丁安装情况。通过 systeminfo 可以获取一部分补丁安装信息,但是信息一般比较少。在这里,我们依然可以通过使用 wmic 来获取补丁安装信息。
wmic qfe list full
原文:Elasticsearch Team Development Constitution
译者:neal1991
welcome to star my articles-translator , providing you advanced articles translation. Any suggestion, please issue or contact me
LICENSE: MIT
前言 我们作为 Elasticsearch 核心开发人员团队希望尽可能快地向可靠,健壮,安全,可扩展且易于使用的系统迁移。我们希望为创新而努力,取代传统的构造和功能,删除脆弱的代码,并致力于改善用户体验,同时在我们快速变化的同时保持用户增长。
对于我们来说,拥有一个团队的前进方向的共识是非常重要的,甚至更重要的是团队为什么要走上一条特定的路。当 Elasticsearch 创立之初时,它具有无尽的灵活性,易用性和丰富的 API。我们这帮年轻的团队成立了一家公司,并且突然用户数井喷式发展。支持组织几乎无法满足越来越多的客户,这是幸福的烦恼。然而,随着用户数量的增长,事情发生的可能性也越来越大,不幸的是,这比我们聘用支持工程师的速度要快得多。我们了解到,大多数灵活性来自宽松处理,从大多数情况下可行的功能,但不是全部。例如,用户可以使用请求发送的脚本基本上是一个远程代码执行引擎,如果出错,它是致命的。即使最基本的功能,比如设置,也非常灵活,但非常脆弱。在没有单位的情况下指定一个数字是很好的,除非许多用户不知道默认单位是什么。我们只是试图做正确的事情,结果证明并不是总是对的。
现在我们处于不同的位置。我们的用户基数比 2013 年的用户基数大得多,但我们的支持机构并没有以同样的速度增长。是的,我们处理比 2013 年更多的支持案例,但这在我们当时的系统中是不可能的。现在我们已经从一个脆弱而灵活的系统转向了范围较窄的软件。我们定义了更多的边界:更严格的输入验证,允许我们对权限进行细粒度控制的安全模型,甚至还有一个插件模型,可以以极大的灵活性来添加风险更高的功能。
但等等,我们还差得远呢!仍然有无穷无尽的问题会造成致命的后果。聚合可以通过一个请求来撑爆服务器。用户感觉需要运行 30+GB 堆的 Elasticsearch。我们仍然提供了 27 种指定布尔值的不同方式。这份清单还有其它内容…
我们对我们的用户,支持组织,云托管团队和第三方提供商负有巨大责任,提供可靠,稳健,安全且易于使用的系统。出于这个原因,我们都应该努力创新,取代传统的构造和功能,删除脆弱的代码,并改善用户体验。我们与其他公司相比的优势是我们的创新,创新需要速度。我们必须在留住用户的同时下采取行动并接受变革创新。
以下章节是用于设计,重构或从 Elasticsearch 代码库中删除代码的原则和指导原则的集合。这些点是无序的,大部分是未分类的,应该被看作是 Elasticsearch 团队内软件开发的一个组成部分。
设计特性 过程优于结果。 我们多年来一直遵循这种方法,这使我们能够随着时间的推移做出巨大的变化,而不会因大量的请求而产生巨大的响应。例如,补齐建议程序在 Elasticsearch 的早期版本中添加,而不支持实时更新和特定的删除。这意味着删除 Elasticsearch 中的文档不会立即反映在建议中。这是一个很难的问题,大约三年后,我们增加了对 Lucene 建议器和 Elasticsearch 的 bitset 过滤器的支持。与此同时,对于许多用户来说,这是一个可以接受的解决方案,修复了许多错误,并朝着基于文档的建议器发展。这就是过程优于结果。
为今天设计!谨慎使用抽象。 计算机科学教授教育学生以灵活性和信息隐藏的名义广泛使用抽象层。当然 Elasticsearch 广泛使用抽象; 没有任何涉及数百万行代码的项目可以以其他方式进行工作并生存。但经验表明,过度或过早的抽象可能与过早优化一样有害。抽象应该用于所需的级别,不要再进一步。
OutOfMemoryError 异常应该可以算得上是一个非常棘手的问题。JAVA 的程序员不用像苦逼的 C 语言程序员手动地管理内存,JVM 帮助他们分配内存,释放内存。但是当遇到内存相关的问题,就比如 OutOfMemoryError,如何去排查并且解决就变成一个非常令人头疼的问题。在 JAVA 中,所有的对象都存储在堆中,通常如果 JVM 无法再分配新的内存,内存耗尽,并且垃圾回收器无法及时回收内存,就会抛出 OutOfMemoryError。
我之前在做一个工具,需要读取大量的文件,比如 word 或者 excel,而我给机器分配的最大的内存只有 2G。所以,很多人的机器往往会因为 OutOfMemoryError 异常导致程序中止运行。后来我发现一个现象,OutOfMemoryError 可以通过 Error 或者 Throwable 去捕获,OutOfMemoryError 类继承关系如下:
java.lang.Object java.lang.Throwable java.lang.Error java.lang.VirtualMachineError java.lang.OutOfMemoryError 因此 OutOfMemoryError 是一个 Error 而不是一个 Exception,并且据我观察,OutOfMemoryError 无法被 throw 到上一层函数中。
private void OutOfMemoryErrorTest() { try { // do something might lead to OutOfMemoryError error } catch (Error e) { e.printStackTrace(); } } 发生 OutOfMemoryError 的原因 越早找出 OutOfMemoryError 的原因就越利于我们解决问题。到底是因为 JAVA 的堆满了还是因为原生堆就满了呢?为了找到其原因,我们可以通过异常的细节信息来获得提示。