Skip to content
GitLab
探索
项目
群组
代码片段
项目
群组
代码片段
/
帮助
帮助
支持
社区论坛
快捷键
?
提交反馈
登录
切换导航
菜单
打开侧边栏
wazuh
Osquery
提交
69bcf70b
未验证
提交
69bcf70b
编辑于
4年前
作者:
kumarak
提交者:
GitHub
4年前
浏览文件
操作
下载
电子邮件补丁
差异文件
Add sigurl column to pass yara signatures with the queries (#6607)
上级
5f48f935
master
build_aarch64_run_tests
release/v5.2.3
5.3.0
5.2.3
5.2.2
5.2.1
5.2.0
5.1.0
5.0.1
5.0.0
4.9.0
4.8.0
4.7.0
4.6.0
4.5.1
4.5.0
无相关合并请求
变更
4
隐藏空白变更内容
行内
左右并排
显示
4 个更改的文件
osquery/tables/yara/yara.cpp
+92
-3
osquery/tables/yara/yara.cpp
osquery/tables/yara/yara_utils.cpp
+22
-0
osquery/tables/yara/yara_utils.cpp
osquery/tables/yara/yara_utils.h
+7
-0
osquery/tables/yara/yara_utils.h
specs/yara/yara.table
+2
-0
specs/yara/yara.table
有
123 个添加
和
3 个删除
+123
-3
osquery/tables/yara/yara.cpp
+
92
-
3
浏览文件 @
69bcf70b
...
...
@@ -7,7 +7,12 @@
* SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
*/
#include
<osquery/remote/http_client.h>
#include
<osquery/remote/transports/tls.h>
#include
<boost/algorithm/string.hpp>
#include
<boost/filesystem.hpp>
#include
<regex>
#include
<thread>
#ifdef LINUX
...
...
@@ -21,11 +26,13 @@
#include
<osquery/logger/logger.h>
#include
<osquery/utils/status/status.h>
#include
"osquery/tables/yara/yara_utils.h"
#include
<osquery/remote/uri.h>
#include
<osquery/tables/yara/yara_utils.h>
#ifdef CONCAT
#undef CONCAT
#endif
#include
<yara.h>
namespace
osquery
{
...
...
@@ -57,7 +64,7 @@ namespace tables {
using
YaraRuleSet
=
std
::
set
<
std
::
string
>
;
typedef
enum
{
YC_NONE
=
0
,
YC_GROUP
,
YC_FILE
,
YC_RULE
}
YaraRuleType
;
typedef
enum
{
YC_NONE
=
0
,
YC_GROUP
,
YC_FILE
,
YC_RULE
,
YC_URL
}
YaraRuleType
;
using
YARAConfigParser
=
std
::
shared_ptr
<
YARAConfigParserPlugin
>
;
...
...
@@ -97,6 +104,57 @@ static YARAConfigParser getYaraParser(void) {
return
yaraParser
;
}
bool
isRuleUrlAllowed
(
std
::
set
<
std
::
string
>
signature_set
,
std
::
string
url
)
{
Uri
test_uri
(
url
);
for
(
const
auto
&
sig
:
signature_set
)
{
Uri
sig_uri
(
sig
);
// The uri scheme, host and path matches are case sensitive
if
((
sig_uri
.
host
()
==
test_uri
.
host
())
&&
(
sig_uri
.
scheme
()
==
test_uri
.
scheme
()))
{
// Check the regex pattern for the allowed URL
const
std
::
regex
pat
(
sig_uri
.
path
());
if
(
std
::
regex_match
(
test_uri
.
path
(),
pat
))
{
return
true
;
}
}
}
return
false
;
}
Status
getRuleFromURL
(
const
std
::
string
&
url
,
std
::
string
&
rule
)
{
auto
yaraParser
=
getYaraParser
();
if
(
isNull
(
yaraParser
))
{
return
Status
::
failure
(
"YARA config parser plugin not found"
);
}
try
{
auto
signature_set
=
yaraParser
->
url_allow_set
();
if
(
!
isRuleUrlAllowed
(
signature_set
,
url
))
{
VLOG
(
1
)
<<
"YARA signature url "
<<
url
<<
" not allowed"
;
return
Status
::
failure
(
"YARA signature url not allowed"
);
}
http
::
Client
client
(
TLSTransport
().
getInternalOptions
());
http
::
Response
response
;
http
::
Request
request
(
url
);
response
=
client
.
get
(
request
);
// Check for the status code and update the rule string on success
// and result has been transmitted to the message body
if
(
response
.
status
()
==
200
)
{
rule
=
response
.
body
();
}
else
{
VLOG
(
1
)
<<
"Can't fetch rules from url response code: "
<<
response
.
status
();
}
}
catch
(
const
std
::
exception
&
e
)
{
return
Status
::
failure
(
e
.
what
());
}
return
Status
::
success
();
}
void
doYARAScan
(
YR_RULES
*
rules
,
const
std
::
string
&
path
,
QueryData
&
results
,
...
...
@@ -126,6 +184,9 @@ void doYARAScan(YR_RULES* rules,
case
YC_RULE
:
row
[
"sigrule"
]
=
SQL_TEXT
(
sigfile
);
break
;
case
YC_URL
:
row
[
"sigurl"
]
=
SQL_TEXT
(
sigfile
);
break
;
case
YC_NONE
:
break
;
}
...
...
@@ -177,6 +238,24 @@ Status getYaraRules(YARAConfigParser parser,
break
;
}
case
YC_URL
:
{
std
::
string
rule_string
;
auto
request
=
getRuleFromURL
(
sign
,
rule_string
);
// rule_string will be empty if there is partial fetch or
// the function failed to fetch the YARA rules from URL
if
(
!
request
.
ok
()
||
rule_string
.
empty
())
{
LOG
(
WARNING
)
<<
"Failed to get YARA rule url: "
<<
sign
;
continue
;
}
auto
status
=
compileFromString
(
rule_string
,
&
tmp_rules
);
if
(
!
status
.
ok
())
{
LOG
(
WARNING
)
<<
"YARA compile error: "
<<
status
.
toString
();
continue
;
}
break
;
}
default:
return
Status
::
failure
(
"Unsupported YARA rule type"
);
}
...
...
@@ -239,6 +318,15 @@ QueryData genYara(QueryContext& context) {
}
}
if
(
context
.
hasConstraint
(
"sigurl"
,
EQUALS
))
{
auto
sigurls
=
context
.
constraints
[
"sigurl"
].
getAll
(
EQUALS
);
auto
status
=
getYaraRules
(
yaraParser
,
sigurls
,
YC_URL
,
scanContext
);
if
(
!
status
.
ok
())
{
LOG
(
WARNING
)
<<
status
.
toString
();
return
results
;
}
}
// scan context is empty. One of sig_group, sigfile, or sigrule
// must be specified with the query
if
(
scanContext
.
empty
())
{
...
...
@@ -294,8 +382,9 @@ QueryData genYara(QueryContext& context) {
// Rule string is hashed before adding to the cache. There are
// possibilities of collision when arbitrary queries are executed
// with distributed API. Clear the hash string from the cache
// Also cleanup the cache block if rules are downloaded from url
for
(
const
auto
&
sign
:
scanContext
)
{
if
(
sign
.
first
==
YC_RULE
)
{
if
(
sign
.
first
==
YC_RULE
||
sign
.
first
==
YC_URL
)
{
auto
it
=
rules
.
find
(
hashStr
(
sign
.
second
,
sign
.
first
));
if
(
it
!=
rules
.
end
())
{
rules
.
erase
(
hashStr
(
sign
.
second
,
sign
.
first
));
...
...
This diff is collapsed.
Click to expand it.
osquery/tables/yara/yara_utils.cpp
+
22
-
0
浏览文件 @
69bcf70b
...
...
@@ -15,6 +15,8 @@
#include
<osquery/registry/registry_factory.h>
#include
<osquery/tables/yara/yara_utils.h>
#include
<osquery/remote/uri.h>
namespace
osquery
{
DECLARE_bool
(
enable_yara_string
);
...
...
@@ -382,6 +384,26 @@ Status YARAConfigParserPlugin::update(const std::string& source,
}
}
if
(
yara_config
.
HasMember
(
"signature_urls"
))
{
auto
&
sigurl
=
yara_config
[
"signature_urls"
];
if
(
!
sigurl
.
IsArray
())
{
VLOG
(
1
)
<<
"YARA signature_url must be an array"
;
}
else
{
VLOG
(
1
)
<<
"Compiling YARA signature_url for allowed list"
;
for
(
const
auto
&
element
:
sigurl
.
GetArray
())
{
if
(
element
.
IsString
())
{
auto
url_string
=
element
.
GetString
();
try
{
Uri
test_uri
(
url_string
);
url_allow_set_
.
insert
(
url_string
);
}
catch
(
const
std
::
exception
&
)
{
VLOG
(
1
)
<<
"Invalid signature url: "
<<
element
.
GetString
();
}
}
}
}
}
// The "file_paths" set maps the rule groups to the "file_paths" top level
// configuration key. That similar key keeps the groups of file paths.
if
(
yara_config
.
HasMember
(
"file_paths"
))
{
...
...
This diff is collapsed.
Click to expand it.
osquery/tables/yara/yara_utils.h
+
7
-
0
浏览文件 @
69bcf70b
...
...
@@ -66,6 +66,7 @@ int YARACallback(YR_SCAN_CONTEXT* context,
* Pseudo-code:
* getParser("yara")->getKey("yara");
*/
class
YARAConfigParserPlugin
:
public
ConfigParserPlugin
{
public:
/// Request a single "yara" top level key.
...
...
@@ -78,12 +79,18 @@ class YARAConfigParserPlugin : public ConfigParserPlugin {
return
rules_
;
}
std
::
set
<
std
::
string
>&
url_allow_set
()
{
return
url_allow_set_
;
}
Status
setUp
()
override
;
private:
// Store compiled rules in a map (group => rules).
std
::
map
<
std
::
string
,
YR_RULES
*>
rules_
;
std
::
set
<
std
::
string
>
url_allow_set_
;
/// Store the signatures and file_paths and compile the rules.
Status
update
(
const
std
::
string
&
source
,
const
ParserConfig
&
config
)
override
;
};
...
...
This diff is collapsed.
Click to expand it.
specs/yara/yara.table
+
2
-
0
浏览文件 @
69bcf70b
...
...
@@ -13,6 +13,8 @@ schema([
additional=True, hidden=True),
Column("strings", TEXT, "Matching strings"),
Column("tags", TEXT, "Matching tags"),
Column("sigurl", TEXT, "Signature url",
additional=True, hidden=True)
])
implementation("yara@genYara")
examples([
...
...
This diff is collapsed.
Click to expand it.
编辑
预览
支持
Markdown
0%
请重试
或
添加新附件
.
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录
菜单
探索
项目
群组
代码片段