资料来源:
https://github.com/Velocidex/velociraptor
Velociraptor是一种免费的开源数字取证和响应平台,可以帮助安全专家快速识别和解决网络安全问题。它提供了一套高效的工具,可以自动化和简化常见的取证和响应任务,同时提供了可视化的仪表板和数据导出功能,以便用户更好地分析和理解数据。”””
根据官方描述,velociraptor主要提供数据的存储服务(json),而数据的处理(例如evtx文件处理为json格式发送的过程是在断点完成的),对于服务器的处理量可以大大降低而提高数据的查询效率
docker部署
docker的部署十分方便
-
git clone <https://github.com/weslambert/velociraptor-docker
> cd velociraptor-docker
- 根据需要更改
.env
中的凭据值(admin/admin) docker-compose up
GUI配置部署
在通过velociraptor.exe gui
进行部署时,会在输出的前几行显示出配置文件,默认的web root为admin/password
通过velociraptor.exe —config C:\\Users\\<CONFIG_PATH.yaml> user matoujin —role admin
来添加各种角色的用户
通过velociraptor.exe gui —database <DIR_NAME>
指定本地目录来保存notebook笔记以及数据,否则会在temp目录中被默认销毁。以此实现多个database在本地的维护
离线收集(指无法部署客户端的情况)
https://docs.velociraptor.app/training/
通过VQL实现在端点进行信息收集
(貌似有个坑,docker下并不会打包一个自定义的offline collector,我没有在任何地方找到它)
(macos下的gui会在离线collector拉取github镜像的时候卡住,离线模式不可用)
目前在windows通过gui可以实现不报错()
采用RCE方案
wmic /node:”WIN” /user:Administrator process call create “C:\velo.exe”
关于VQL
VQL并不对Client做真正的Query
运行vql的三种方式: Command Line: velociraptor.exe -v query “select * from info()”
Command line in Artifact :
notebook功能:

notebook支持markdown以及VQL语句,和notion的block一样,使用cell进行区分

SELECT X,Y,Z FROM plugin(arg=1) WHERE X=1
SELECT <Column Selectors> FROM <VQL Plugin with Args> WHERE <Filter Condition>
关于第二个可选参数,由于VQL中并没有真正的“表”,只有从插件中获取的信息集
插件的定义:插件可以看作“行”(信息)的总和;插件允许参数:强类型,允许嵌套;
Columns Selectors中支持log函数:
SELECT OS, log(message=”I ran” From info()

可以达到输出日志的效果。由于生命周期lazy evaluation机制,如果where的条件没有达成,log函数(即Column Selectors)也不会发生“查询”或者理解为“执行”。如果where(Filter Condition)涉及到了取用Column Selectors中函数值,那么Selectors的函数仍然会发生执行。(Filter Condition中的相关条件需要前置)
变量与Foreach
全局变量
LET var = 1
获取自身进程的情况并获取所有列
SELECT * FROM pslist(pid=getipid())
查看目标文件的情况并获取所有列
SELECT * FROM stat(filename=”C:\\”)
SELECT * FROM forearch (
row={
select Name, CommandLine, Exe FROM pslist(pid=getpid())
},query={
SELECT Btime,Mtime,FullPath FORM stat(filename=Exe)
})
row作为子范围数据集,query作为从数据集中提取数据,并将只返回当前pid所运行的Exe的创建时间、修改时间、绝对路径.
glob(globs=””)
是对搜索文件的使用方法,基于通配符
SELECT FullPath ,hash(path=FullPath)
FROM glob(globs=”C:/Windows/System32/*”)
WHERE NOT IsDir
如果加上foreach的应用。scope()返回当前作用域,可以理解为不做任何操作的NOP
SELECT * FORM foreach(
row = {
select FullPath from glob(globs="C:/Windows/System32/*")
where NOT IsDir
}, query = {
select FullPath , hash(FullPath) from scope()
}) limit 10
关于hash()函数,它会返回MD5、SHA1、SHA256三种哈希值组成的json,只需要将hash().SHA256
就可以得到对应的text类型值,样例如下
select FullPath , hash(FullPath).SHA256 from scope()
select FullPath , hash(FullPath).SHA256 AS SHA256 from scope()
select FullPath , hash(FullPath).SHA256 AS SHA256 from scope() where SHA256 == ”abc“
并且路径支持模糊匹配(?),例如
FullPath = “.png”
可以直接匹配到png后缀
关于LET表达式
通过LET表达式实现了存储查询,LET只实现了QL语句的存储,并不实现QL的实际检索,符合Lazy evaluation
LET processes = select Name, CommandLine, Exe FROM pslist()
LET times = SELECT Btime,Mtime,FullPath FROM stat(filename=Exe)
SELECT * FROM foreach(
row=processes,query=times
)
如果要实现LET的存储,可以使用< =
LET processes <= select Name, CommandLine, Exe FROM pslist()
如果实现LET的传参功能(方法):
LET TargetPid(pid) = pslist(pid)
SELECT Name, CommandLine, Exe FROM TargetPid(pid = 12345)
另,VQL并不会进行强制类型转换。
例子:如何创建工件来检测wmic process call create cmd.exe
?
wmic实际上是调用了System32中的cmd.exe
首先要检查ps进程,由于wmic可以执行命令,所以要查看CommandLine和exe
select Name , Pid, Ppid, CommandLine, Exe,* from pslist()
LIMIT 5
由于创建新的进程并调用命令行相当于CommandLine执行cmd.exe
select Name , Pid, Ppid, CommandLine, Exe,* from pslist()
WHERE CommandLine =~ "cmd.exe"
LIMIT 5
然后查询父进程的名称,找到恶意进程
select Name , Pid, Ppid,
{select Name FROM pslist(Pid=Ppid)} AS PARENTNAME,
CommandLine, Exe,* from pslist()
WHERE CommandLine =~ "cmd.exe" and PARENTNAME =~ "WmiPrvSE"
LIMIT 5
VQL-Artifacts
Artifact就是VQL和yaml的集合
通过

的铅笔键,可以修改Artifacts并进行自定义

name:确保了每个artifact不被覆盖
description:注释
type:CLIENT/CLIENT_EVENT/SERVER/SERVER_EVENT
client_event和server_event成对作用于端点控制。
parameters:运行工件时的参数(默认string)
sources-precondition:运行query的前提条件,如果precondition不满足,则不进行下面的query
parameters:
- name: ProcessRegex
default: cmd.exe
sources:
- precondition:
SELECT OS FROM info() where OS = 'windows'
query: |
select Name , Pid, Ppid,
{select Name FROM pslist(Pid=Ppid)} AS PARENTNAME,
CommandLine, Exe,* from pslist()
WHERE CommandLine =~ ProcessRegex and PARENTNAME =~ "WmiPrvSE"
如果存在语法错误,会在保存后报错。
在使用工件时,可以使用通配符“.”作为参数
Exercise 1
//format进行格式化字符串输出
SELECT format(format="%v:%v", args=[Laddr.IP,Laddr.Port]),pid,Timestamp,{
//进程信息
SELECT Exe, parse_pe(file=Exe).VersionInformation AS VersionInformation,
//解析PE文件,获得制作商信息(恶意文件分析技巧)
authenticode(filename=Exe),
//exe文件的签名者
Username,CommandLine FROM pslist(pid=PID)
//进程信息
} AS ProcessInfo,{
//dll信息通过modules函数获取
SELECT ExePath From modules(pid=Pid)
} AS LinkedDlls
FROM netstat()
//获取网络连接信息
where status =~ "Listen"
如果涉及到时间戳不对的问题,可以在工件中添加一个参数,
- name: DataBefore
type: timestamp
然后在参数设置中设置为localhost,就可以使用本地时间
log()
在任何操作的前面加上log()都会输出日志
SELECT * FROM pslist()
WHERE log(message=format(format="%T %v", args=[timestamp(now(), Name])) AND Username =~ "mk"
VQL call artifacts
SELECT * FROM Artifact.Windows.System.Pslist()
VQL IF
SELECT * FROM IF(
condition=<sub query or value>,
then={ <sub query or value> },
else={ <sub query or value> }
SELECT * FROM SWITCH(
a={ <sub query or value> },
b={ <sub query or value> }
)
SELECT * FROM CHAIN(
a={ <sub query or value> },
b={ <sub query or value> }
)
//顺序执行所有子查询,结合所有返回列
Aggregate func
实现多行的收集,具有内部状态
count()(可以实现group by、order by函数)
事件查询
事件查询实现监控架构
SELECT * FROM clock()
VQL取证
?sram
文件查找:glob()
对斜杠不区分
**
表示递归搜索 C:\user\**\*.exe,默认递归10min后取消
SELECT * FROM glob(globs=’’’C:\\user\\**\\*.exe’’’)
‘’‘原始字符串解决转义斜杠问题
(无法避免软连接递归的问题。造成资源浪费)
SELECT * FROM glob(globs=[’’’C:\\user\\**\\*.exe’’’],[’’’C:\\user\\**\\*.dll’’’])
glob只匹配文件名,不对文件类型进行校验,需要自行校验模块
文件访问系统
SELECT * FROM glob(globs=’’’/*’’’, accessor="register")
这种情况下,就将注册表作为根目录进行文件访问
SELECT * FROM glob(globs=’’’/C:/*’’’, accessor="ntfs")
如果文件路径带有特殊字符,与查询列名冲突,可以用反引号包裹表示为列名
//查询用户登录
SELECT * FROM glob(globs='''/HKEY_CURRENT_USER/**/RUN/*''',accessor="reg")
SELECT Name,ModTime,
常用文件正则
parse_string_with_regex(string=Data.value,,reg='^”([^”]+)')
parse_string_with_regex(string=Data.value,,reg=['^”([^”]+)', '^([^" ]+ ?',)
如果存在环境变量
expand(path=<PATH_WITH_ENV>)
LET X = SELECT Name,FullPath,ModTime, Data.value AS StartupPath,
parse_string_with_regex(string=Data.value,,reg=['^”([^”]+)', '^([^" ]+ ?',) AS Parse
FROM glob(globs='''/HKEY_CURRENT_USER/**/RUN/*''',accessor="reg")
SELECT Name, FullPath,ModTime,StartupPath,hash(path=expand(path=Parse,g1)) AS Hash
FROM X
对字符串的hash(对accessor的运用)
SELECT hash(path=”hello world”, accessor=”data”) FORM scope()
还有url函数的使用,同样使用accessor
yara
example:未知恶意软件分析
SELECT * FROM pslist() WHERE Name =~ "Chrome"
SELECT * FROM handles(pid=112312)
where type =~ "File"
//找到了chrome打开的文件
SELECT * FROM foreach(
row={SELECT * FROM pslist() WHERE Name =~ "Chrome"},
query={
SELECT * FROM handles(pid=Pid)
where type =~ "File"
}
)
//找到url
LET YaraRule = '''
rule URL {
Strings : $a = /https?:\\/\\/[a-z0-9]\\/+&#:\\?.-]+/i
condition: any of them
}
'''
SELECT * FROM foreach(
row={
SELECT FullPath FROM glob(globs=''C:\\User\\**\\Chrome\\User Data\\Default\\**')
WHERE NOT IsDir
},
query={
//content用于获得上下文
SELECT str(String.Data) AS URL FROM yara(files=Fullpath,rules=YaraRule,number=10000,content=10)
}
MFT NTFS
略
攻击痕迹取证
prefetch pf文件
工件:WIndows.Froensics.Prefetch
pf的时间戳最多存储8次,但是runcount可以记录程序运行次数
工件:WIndows.Timeline.Prefetch
每个时间戳都会占用一行
eventlog
SELECT * FROM parse_evtx(”C:\\system.evtx”)
evtx-data(github)dump所有evtx到sqlite中
工件:Windows.Eventlogs.EvtxHunter
evtx日志的开启情况其实是通过修改注册表获取

也就是说通过读取所有日志对应注册表键值就可以知道所有evtx的日志开启情况
select basename(path=dirname(path=FullPath)), Data.value From glob(globs=”HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WINEVT\\Channels\\*\\Enabled”, accessor=”registry”)
dirname只返回路径(去除键名),basename只取出路径的最后一截
获取注册表所有键值
select * From read_reg_key(globs=”HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WINEVT\\Channels\\*\\”)
etw event_tracer
etw是由provider集合的,负责事件监督
terminial : logman query providers
查看所有provider以及guid
logman query providers Microsoft-WIndows-DNS-client
查看对应provider的事件关键字(事件类型)、告警类型、应用调用provider情况
select * FROM watch_etw(guid=”{1C95126E-7EEA-49A9-A3FE-A378B03DDB4D}”) Where System.ID=3006

watch_etw是可以取代watch_evtx的,evtx本质上也是由etw provider提供支持的,所以只需要将evtx日志中的provider和guid找到,通过事件类型查询就可以得到etw_watc同样的效果
sysmon tracer
工件:WIndows.Sysinternals.SysmonLogForward
SysmonLogForward在VQL层上也是通过调用watch_etw来实现的,因为即使在sysmonlog在客户端被关闭的情况下,etw仍然工作,sysmon仍然可以得到日志
volatile state 易受攻击主机判断
内存分析并不是一个最佳方案(内存的镜像的存储和内存实际变化速度不匹配)

恶意软件需要确保它只有一个副本在运行。一个常见的方法是使用mutex互斥锁(或named mutex)创建一个具有常量名称的突变体:如果命名的突变体已经存在,则退出确保仅运行单个副本。
mutex监测
工件:Windows.Detection.Mutants
环境变量
工件:Windows.Detection.EnvironmentVariables
获取所有进程的环境变量
进程链
工件:Generic.System.Pstree
where Callchain=~ “cmd.+wmi”
支持通配符
内存映射
example:powershell是否发出http请求
SELECT * FROM foreach(
row={
SELECT * FROM pslist() WHERE Name=~ "powershell"
},
query={
SELECT * FROM vad(pid=PID) WHERE MappingName=~"winhttp.dll"
}
)
端点文件采集
端点文件采集,更倾向于保存端点的当前状态
Kap
纯粹的文件收集引入数据,需要通过解析上传文件才能进行分析
example:
SELECT * FROM foreach(
row = {
SELECT * FROM uploads(
client_id='C.xxxxx',flow_id='F.xxxx')
WHERE vfs_path =~ "evtx"
},query={
//已经上传到的服务器的文件要加file_stone来转换文件系统
SELECT * FROM parse_evtx(filename=file_stone(vfs_path))
})
AutoRuns
工件:Windows.Sysintelnets.AutoRuns
第三方工件
#1 额外工件
CCXlabs实验室提供额外工件,在工件界面直接导入
CCXDigger/artifacts/CyberCX/Windows at master · CCXLabs/CCXDigger
#2 yara规则拓展
malpeida提供检查一些签名监测,使用yara并且带入到vql进行扫描,可以使用processmemory工件进行监测
进程分析框架:
第一步找到所有进程(符合条件)
LET processes = SELECT Name as ProcessName ,CommandLine ,Pid,
FROM Pslist()
WHERE Name =~ processRegex
第二步,通过yara规则匹配内存
LET hits = SELECT * FROM foreach(
row=processes,
query={
SELECT ProcessName, CommandLine, Pid, Strings.Offset as Offsets
FROM proc_yara(rules=yaraRule, pid=Pid)
}
)
第三步,通过第二步得到的信息,对proc作转储到服务器
SELECT * FROM foreach(
rows=hits,
query={
SELECT ProcessName,CommandLine,Pid,Offsets,FullPath,
upload(file=FullPath) as CrashDump
From proc_dump(pid=Pid)
})
#3 攻击面分析扩展
https://github.com/redcanaryco/atomic-red-team
ATT&CK框架的示例,通过模拟攻击,对相关影响资源进行本地监测,然后自定义工件
Elastic
略
Extending
调用pS
LET Script="dir /"
SELECT * FROM execve(argv="powershell","-executionpolicy", "unrestricted","-c",Script])
#1 服务器配置(VPS Centos)
进入引导配置模式,
velociraptor config generate -i
选择自签名,
然后DNS处输入IP,
What is the public DNS name of the Master Frontend (e.g. [www.example.com](<http://www.example.com/>)): YOUR IP
其余看自己情况或者默认
然后修改server配置文件中的GUI:bind_address为0.0.0.0(不然非本地访问不到)

然后Velociraptor使用指定的linux二进制文件创建服务器Debian软件包。该软件包将包含Velociraptor可执行文件、服务器配置文件和相关启动脚本。
./velociraptor-v0.6.7-5-linux-amd64 --config server.config.yaml rpm server --binary velociraptor-v0.6.7-5-linux-amd64

(如果是debian,请使用官方说明生成deb包)然后安装rpm包
yum install velociraptor_0.6.7-5_server.rpm
systemctl status velociraptor_server
注意rpm name:velociraptor-server.x86_64

补充:在修改配置文件的时候需要重新生成服务器
#2 客户端配置 MAC
service install
指令可用于在Mac客户端上安装Velociraptor。以下命令通过launchd安装二进制和配置到/usr/local/sbin.Persistence(使用ps -eaf | grep velo
和sudo launchctl list | grep velo
检查)
# velociraptor --config client.config.yaml service install
可以使用以下命令卸载该服务:
# /usr/local/sbin/velociraptor service remove --config=/usr/local/sbin/velociraptor.config.yaml
使用ps -eaf | grep velo
和sudo launchctl list | grep velo
确认。

卸载如下
/usr/local/sbin/velociraptor service remove --config=/usr/local/sbin/velociraptor.config.yaml
停止服务如下:
macos守护进程目录如下

sudo launchctl unload -w /Library/LaunchDaemons/com.velocidex.velociraptor.plist
(但是目前只能采集到系统数据,文件采集权限似乎被macos阻止了,后续会更新解决办法)
Comments | NOTHING