该命令有一个可选参数。用于查看特定文件中的规则,不输入则默认输出rules文件夹下的所有规则。

#print information of all available plugins
./5greplay info
#print information of rules encoded in `rules/nas-smc-replay-attack.so`
./5greplay info rules/4.nas-smc-replay-attack.so

wireshark 过滤 ssid Wireshark 过滤ngap没消息_#include


0.0.7版本内置了16种规则,不再一一列举,最初的0.0.1版本仅有3种

wireshark 过滤 ssid Wireshark 过滤ngap没消息_5G_02


wireshark 过滤 ssid Wireshark 过滤ngap没消息_wireshark 过滤 ssid_03


wireshark 过滤 ssid Wireshark 过滤ngap没消息_#include_04

(三)list

该命令列出了5Greplay支持的所有协议及其属性。该命令没有参数。

可支持的协议特别多

wireshark 过滤 ssid Wireshark 过滤ngap没消息_wireshark 过滤 ssid_05


wireshark 过滤 ssid Wireshark 过滤ngap没消息_5g_06


wireshark 过滤 ssid Wireshark 过滤ngap没消息_HTTP_07

(四)extract

该命令在0.0.2及之后的版本中可用。

它用于从pcap文件或网卡中提取给定协议的属性值。当我们想要查看pcap文件包中的内容时,可以使用该命令。

ubuntu22@ubuntu22-virtual-machine:~/5greplay-0.0.7$ ./5greplay extract -h
mmt-5greplay: 5Greplay v0.0.7-77dda18 using DPI v1.7.9 (8694eaa6) is running on pid 69299
extract [<option>]
Option:
-t <trace file>: Gives the trace file to analyse.
-i <interface> : Gives the interface name for live traffic analysis. Either -i or -t can be used but not both.
-p             : Protocol's name to be extracted. Default: ethernet
-a : Attribute's attribute to be extracted. Default: src
-d             : Index of protocol to extract. For example: ETH.IP.UDP.GTP.IP, if d=3 (or ignored) IP after ETH, d=6 represent IP after GTP. Default: 0
-r             : ID of protocol stack. Default: 1
-h             : Prints this help then exit

(五)extract

该命令可以重放

通过捕获来自给定网卡的流量来提供实时流量,

或者保存在pcap文件中的流量。

wireshark 过滤 ssid Wireshark 过滤ngap没消息_wireshark 过滤 ssid_08

ubuntu22@ubuntu22-virtual-machine:~/5greplay-0.0.7$ ./5greplay replay -h
mmt-5greplay: 5Greplay v0.0.7-77dda18 using DPI v1.7.9 (8694eaa6) is running on pid 69358
replay [<Option>]
Option:
    -v               : Print version information, then exits.
    -c <config file> : Gives the path to the configuration file (default: ./mmt-5greplay.conf).
    -t <trace file>  : Gives the trace file for offline analyse.
    -i <interface>   : Gives the interface name for live traffic analysis.
    -X attr=value    : Override configuration attributes.
                        For example "-X output.enable=true -Xoutput.output-dir=/tmp/" will enable output to file and change output directory to /tmp.
                        This parameter can appear several times.
    -x               : Prints list of configuration attributes being able to be used with -X, then exits.
    -h               : Prints this help, then exits.
#Note: you may want to change parameters inside mmt-5greplay.conf
#replay online traffic comming from eth0
sudo ./5greplay replay -i eth0
#replay offline traffic being stored inside a pcap file
sudo ./5greplay replay -t ~/pcap/5G-traffic.pcap

配置参数

(一)示例

5greplay工具中,rules目录下有规则示例文件,为xml文件,0.0.7版本提供了16个规则示例

(二)嵌入函数

嵌入式函数是允许实现计算功能的函数,如果在仅使用安全规则布尔表达式中的经典运算符来定义的话太过复杂。可以使用现有的嵌入式函数或实现新函数。在这两种情况下,它们都可以通过使用以下语法在布尔表达式中使用:

#<name\_of\_function>(<list of parameters>)

例如:

(#em\_is\_search\_engine( http.user_agent ) == true)

其中http是协议名称,user_agent是属性名称(即数据包元数据)。
请参阅此处获取协议和属性的完整列表。(注释:这里非常类似wireshark里面的过滤器语法规则)
xml规则中使用的协议和属性名称区分大小写。它们通常是小写的。
为了避免混淆,新的嵌入函数名应该以前缀em_开头。

1. 特殊条款

true将被数字1代替。
例如:

#em\_check(tcp.src\_port)== true

false将替换为数字0。
例如:

#em\_check(tcp.src\_port)== false
2.实现一个新的嵌入式函数

在每个规则文件中,都有一个允许用户添加嵌入式功能的部分。

<embedded_functions><![CDATA[
//code C
static inline bool em\_check( double port ){
   if( port == 80 || port == 8080 )
      return true;
   return false;
}
]]></embedded_functions>

除了这个标签之外,还可以实现如下两个其他功能:
(1)void on_load(){ … }当xml文件中的规则被加载到5Greplay时被调用
(2)void on_unload(){ … }退出5Greplay时被调用
3.预安装嵌入式函数
在规则的布尔表达式中,可以使用一个或多个嵌入函数
(1)is_exist( proto.att ) 检查一个事件是否具有协议属性,例如is_exist( http.method ) 如果当前事件包含协议HTTP并且属性方法具有非空值,将会返回true,否则返回false
通常情况下,5Greplay 有一个过滤器,只有在其布尔表达式中使用的任何 proto.att 包含值时,才允许验证规则中的事件。如果其中一个不包含值,则不会验证该规则。这样可以减少布尔表达式的验证次数,从而提高性能。
例如,给定的事件具有以下布尔表达式:
((ip.src != ip.dst) && (#em_check_URI(http.uri) == 1))
只有当 ip.src 和 ip.dst 以及 http.uri 不为空时,才会验证该事件,因此只验证 HTTP 数据包(不会验证每个 IP 数据包)。
但是,如果使用下面的表达式,则与前一个表达式的含义完全相同:
((ip.src != ip.dst) && ((#is_exist(http.uri) == true ) && (#em_check_URI(http.uri) == 1)))
5Greplay 需要针对任何 IP 数据包验证该表达式, is_exist 会告诉 5Greplay 从其过滤器中排除 http.uri。
(2)is_null( proto.att ), 例如,#is_null(http.uri) 检查 http.uri 的值是否存在
(3)is_empty( proto.att ), 例如,#is_empty(http.uri) 检查值是否为空或字符串值是否为空,即长度是否为零。
(4)is_same_ipv4(const uint32_t*, const char *),例如,#is_same_ipv4(ip.src, “10.0.0.1”) 检查 ip.src 的值是否为 “10.0.0.1”。
(5)我们可以使用任何标准 C 函数作为嵌入函数,例如,(#strstr( http.user_agent, ‘robot’) != 0) 检查 http.user_agent 是否包含子字符串 “robot”。
请注意,在使用 C 语言函数之前,必须包含包含该嵌入函数的库。以下库已被预包含:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "mmt\_lib.h"
#include "pre\_embedded\_functions.h"

因此,在使用未在这些库中定义的函数时,我们需要包含其库。例如

<embedded_functions><![CDATA[
#include <math.h>
static inline bool function em\_check( double port ){
    double x = sqrt( port );
    return x >= 5;
}
]]></embedded_functions>

(三)反应函数

反应函数允许我们在满足某个规则时执行某些操作。每次满足规则时,这些函数都会被调用。
要实现和使用反应式函数,我们需要:
在 <embedded_functions> 标签内实现一个 C 函数。
函数名称的前缀应为 em_,以避免与 5Greplay 内部已有的函数混淆。
函数的格式如下:

typedef void (\*mmt_rule_satisfied_callback)(
        const rule\_t \*rule,                  //rule being validated被验证的规则
        int verdict,                     //DETECTED, NOT\_RESPECTED
        uint64\_t timestamp,              //moment (by time) the rule is validated验证规则的时刻(按时间计算
        uint64\_t counter,                //moment (by order of message) the rule is validated验证规则的时刻(按报文顺序排列
        const mmt\_array\_t \* const trace  //historic of messages that validates the rule验证规则的消息历史记录
);

将函数名放入要反应的规则的 if_satisfied 属性中。例如:if_satisfied=“em_print_out”

<beginning>
<embedded_functions><![CDATA[
static void em\_print\_out(
      const rule\_info\_t \*rule, int verdict, uint64\_t timestamp,
      uint64\_t counter, const mmt\_array\_t \* const trace ){
   const char\* trace_str = mmt\_convert\_execution\_trace\_to\_json\_string( trace, rule );
   printf( "detect rule %d\n%s\n", rule->id, trace_str );
   //you can call a system command, for example:您可以调用系统命令,例如
   //char command[1001];
   //snprintf( command, 1000, "echo rule %d is validated by %s", rule->id, trace\_str );
   //system( command );
}
]]></embedded_functions>


<!-- Property 10: HTTP using a port different from 80 and 8080.-->
<property value="THEN" delay_units="s" delay_min="0" delay_max="0" property_id="10" type_property="EVASION"
    description="HTTP using a port different from 80 and 8080." if_satisfied="em\_print\_out">
    <event value="COMPUTE" event_id="1"
        description="HTTP packet using a port different from 80 and 8080"
           boolean_expression="((http.method != '')&&((tcp.dest\_port != 80)&&(tcp.dest\_port != 8080)))"/>
    <event value="COMPUTE" event_id="2"
           description="HTTP packet"
           boolean_expression="(ip.src != ip.dst)"/>
</property>
</beginning>
3.1 支持的功能

我们实现了多个功能,以支持修改协议属性值、丢弃数据包、转发数据包或将其复制到输出网卡。新函数将逐次实现和添加。
以下函数必须在反应函数内部调用。
1.get_numeric_value( proto_id, att_id, event_id, trace)
从满足条件的跟踪中返回事件 ID 的 proto_id.att_id 字段的 uint64_t 值。
2.set_numeric_value( proto_id, att_id, uin64_t )
标记用于将 proto_id.att_id 改为 uint64_t 值。只有在发送数据包时,例如通过显式调用 forward_packet 时,才会应用该更改。
3.forward_packet()
立即转发当前数据包
4.drop_packet()
不转发当前数据包
5.update_sctp_param( uint32_t ppid, uint32_t flags, uint16_t stream_no, uint32_t timetolive )
更新 sctp_sendmsg 函数中的参数,该函数用于在 5Grepay 与目标之间创建 SCTP 通信通道。

3.2预定义的反应式函数

以下函数已被定义
#drop() 用于丢弃当前数据包
#update( proto_id.att_id, expression ) 用于更改当前数据包,然后将其转发给发出的网卡。
proto_id 和 att_id 分别表示要更改的协议和属性
expression 为表达式格式,用于获取要分配给协议属性的值
示例
#update(ngap.ran_ue_id, (ngap.ran_ue_id + 100) 将使 ran_ue_id 增加 100
#update(ngap.ran_ue_id,(ngap.ran_ue_id.1 * 2) 将把当前数据包的 ran_ue_id 替换为 event_id=1 的数据包的 ran_ue_id 的两倍。
#fuzz(proto.att, proto.att, …)会更改当前数据包,然后将其副本转发到发出的网卡。
目前(2022 年 2 月 10 日)只支持数值
每个 proto.att 都将设置一个由 C random 函数生成的新随机值。请参阅 rules/7.fuzz-ngap.xml 中的示例,了解如何覆盖随机函数。

3.3示例

以下XML文件定义了3条规则:

<beginning>
<embedded_functions><![CDATA[

static void em\_modif\_then\_forward(
      const rule\_info\_t \*rule, int verdict, uint64\_t timestamp,
      uint64\_t counter, const mmt\_array\_t \* const trace ){
   const char\* trace_str = mmt\_convert\_execution\_trace\_to\_json\_string( trace, rule );
   //forward the original packet (without any modification)
   forward\_packet();
   //get old value ran\_ue\_id
   uint64\_t ran_ue_id = get\_numeric\_value( PROTO_NGAP, NGAP_ATT_RAN_UE_ID, 2, trace );

   //clone 9 times the current packet
   for( int i=1; i<10; i++ ){
      //increase ran\_ue\_id
      set\_numeric\_value( PROTO_NGAP, NGAP_ATT_RAN_UE_ID, ran_ue_id + i );
      //forward the packet having the modified ran\_ue\_id
      forward\_packet();
   }
}
]]></embedded_functions>

<property value="THEN"  delay_units="s" delay_min="0+" delay_max="1" property_id="100"
    description="Forwarding NAS security mode COMPLETE that answers to NAS security mode COMMAND "
    if_satisfied="em\_modif\_then\_forward">
    <event value="COMPUTE" event_id="1" description="NAS Security mode COMMAND"
           boolean_expression="(nas\_5g.message\_type == 93)"/>
    <event value="COMPUTE" event_id="2" description="NAS Security mode COMPLETE"
           boolean_expression="(nas\_5g.security\_type == 4)"/>
</property>

<property property_id="101" if_satisfied="#drop()"
    description="Do not forward any UDP packets having dest\_port other than 2152">
    <event event_id="1" description="From UE and GTP packets"
           boolean_expression="( (udp.dest\_port != 2152 ) )"/>
</property>

<property property_id="102" description="" if_satisfied="#update(ngap.procedure\_code, (ngap.procedure\_code.1 + 100))">
    <event event_id="1" description="having RAN UE ID"
           boolean_expression="(ngap.ran\_ue\_id != 0)"/>
</property>

规则 100 将匹配 2 个不同的数据包(因为它有 2 个事件和 delay_min=“0+”):
第一个数据包是 NAS 安全模式 COMMAND(nas_5g.message_type == 93)
第二个数据包是 NAS 安全模式 COMPLETE(nas_5g.message_type == 4)
在获取第二个数据包时,会调用 em_modif_then_forward 函数。在该函数中,我们可以修改第二个数据包的内容,然后将其注入到发出的网络中。该函数首先通过调用 forward_packet()转发第二个数据包,不做任何修改。然后调用 get_numeric_value 获取第二个数据包中 NGAP 协议 NGAP_ATT_RAN_UE 属性的当前值。然后通过调用 set_numeric_value 来标记该值的增加,并将变化范围内的数据包转发到网络。
注意:如果调用函数 set_numeric_value 两次来修改协议的同一属性,则只执行第二次调用。
规则 101 通过明确调用 drop() 函数,不转发 dest_port 不是 2152 的 UDP 数据包。
规则 102 检查数据包中是否包含不为零的 ngap ran_ue_id。如果是,则将 procedure_code 值增加 100。(默认情况下,它会将修改后的数据包转发到输出网卡)。

(四)编译规则

5Greplay 规则是以 XML 格式的纯文本指定的。这些规则需要编码成合适的格式,即动态 C 库,然后才能供 5Greplay 使用。
编译后的规则必须放在 ./rules 文件夹中。
5Greplay 提供了一个编译器来完成这样的任务。为此,我们需要事先安装 gcc,例如 sudo apt install gcc。
使用编译器编译 XML 文件中的规则。例如
./5greplay compile rules/1.so rules/1.xml
程序使用 3 个参数,格式为: output_file property_file [gcc 参数]
其中
output_file:是包含编译结果的文件路径,可以是 .c 文件或 .so 文件。
property_file:是可以找到属性文件的路径。
选项:
-c:只生成 C 代码。该选项允许在编译前手动修改生成的代码。生成 C 代码后,工具会打印出编译时需要执行的命令。
gcc 参数:用于生成 C 代码并编译以获得 .so 文件。这些参数将直接传送给 gcc 编译器,例如:-I /tmp -lmath