uos(统信)--suricata环境搭建

以下内容只针对suricata 4.1.2

1. 安装 suricata

apt update                //更新源
apt install suricata jq   //在线安装 jq是用来显示Suricata的EVE JSON输出信息的工具
apt-get install suricata-update        //安装升级软件

2. 启动命令

systemctl start suricata		//启动
systemctl restart suricata		//重启
systemctl status suricata		//查看状态
systemctl enable suricata		//开机自启

3. suricata基本配置文件

 /etc/suricata 下的几个配置文件:

  • classification.config  用于定义和分类不同类型的网络事件,比如哪些是潜在的攻击、哪些是正常的网络活动等。

  • reference.config  包含了一些安全网站,漏洞平台的URL网址,用来联系外部的恶意攻击检测网站。

  • suricata.yaml 是Suricata的主要配置文件,它包含了规则配置、接口配置、日志配置、检测配置等。

  • threshold.config  用于定义流量的阈值和速率限制。设置在特定时间内对特定事件或签名的触发次数进行限制。

  • rules/ 规则目录,存放不同种类的规则文件 *.rules,规则用来判定流量攻击类型,并定义攻击类型和告警种类等。

4. 修改 suricata.yaml配置文件

HOME_NET IP网段配置

其中配置文件中已经包含了RFC 1918相关的网络(具体可以参考suricata相关文档)
修改IP为系统本身网卡IP网段

修改规则路径

修改内容

default-rule-path: /etc/suricata/rules

rule-files:
 - suricata.rules
 - /opt/local.rules

修改日志文件路径

修改内容

default-log-dir: /var/log/suricata/

更改af-packet和pcap的网络名称

5. 更新规则集合来源库

这个方式是参考微软云网络监察程序那章直接下载suricata的一些规则集的,也可以使用suricata update 来更新规则集(这种方式百度会有,这里不再详述)。

# 下载规则集
wget https://rules.emergingthreats.net/open/suricata/emerging.rules.tar.gz
# 将其解压到/etc/suricata
sudo tar -zxvf emerging.rules.tar.gz -C /etc/suricata

将所有原本警告的规则集调整成彻底丢弃包

如果没有这样做,多数的危险行为还是会被放行,所以我们直接丢弃所有的危险行为。
建立一个将警告转换成丢弃包的调整设定文件:

sudo touch /etc/suricata/modify.conf

编辑modify.conf

re:. ^alert drop

注意:

更新规则集时,请关闭suircata
因为规则集中有恶意程序的特征
会被suricata自己阻挡掉,导致更新失败

更新规则集

# 所有规则合并成 suricata.rules
sudo suricata-update --modify-conf /etc/suricata/modify.conf
# 不合并
sudo suricata-update --modify-conf /etc/suricata/modify.conf --no-merge

重新启动suricata。

6. 将suricata设置为IPS(入侵防御系统)

预设的suricata运行时并不是以入侵防御系统(IPS)运行的,而是以入侵检测系统(IDS)运作的。
所以真正遇到某种攻击时,也只会发出警告。
所以我们需要对suricata做出一些改变。

修改参数脚本

sudo vi /etc/default/suricata

这个脚本会定义suircata会用IDS(只有警告)或者IPS(警告+防御)来执行。
将这段:

LISTENMODE=af-packet

修改为:

LISTENMODE=nfqueue

这样就能从IDS转变为IPS了.他就能在NFQUEUE中等待流量传入。

将网路切换为NFQUEUE

Suricata本身不具有拦截功能,需要配合iptables使用。根据你的流量场景,配置相应的iptables规则。如果是经过设备的流量,使用FORWARD链;如果是设备产生的流量,则使用INPUT和OUTPUT链。
    格式:
        iptables -I OUTPUT -j NFQUEUE --queue-num <你的队列号>  --queue-bypass
    例:

iptables -I FORWARD -j NFQUEUE --queue-num 1 --queue-bypass
iptables -I OUTPUT -j NFQUEUE --queue-num 1 --queue-bypass
iptables -I INPUT -j NFQUEUE --queue-num 1 --queue-bypass

检查iptables配置

iptables -vnL

NFQ模式运行Suricata

要使用NFQ模式运行Suricata,必须使用-q选项。例如:

suricata -c /etc/suricata/suricata.yaml -q 1

其中1要与iptables设置的队列号一致。

7. 监控日志

tail -f /var/log/suricata/fast.log

8. 附加

检查suricata.yaml完整性

suricata -T -c /etc/suricata/suricata.yaml

9. 附加规则

注:以下规则如果设置多个,sid不能重复

禁用http目标URL(已测试)

drop http any any -> any any (msg:"Block access to example.com"; content:"example.com"; http_host; sid:1; rev:1;)
  • drop:这是规则的动作部分,指定当规则匹配时,流量将被丢弃,即阻止该流量通过。

  • http any any -> any any:这指定了规则的流量方向和协议。http 表示规则适用于 HTTP 流量,any any -> any any 表示从任何 IP 地址和端口到任何 IP 地址和端口的流量都将被检查。

  • msg:"Block access to example.com":这是当规则触发时显示的消息,说明规则的目的是阻止对 example.com 的访问。

  • content:"example.com";:这是规则的内容部分,指定了规则匹配的条件。在这里,规则检查 HTTP 流量中的 Host 头部是否包含 "example.com"。

  • http_host;:这是一个关键字,告诉 Suricata 在 HTTP 流量的 Host 头部中查找 "example.com"。

  • sid:1;:这是规则的唯一标识符(Signature ID),用于区分不同的规则。

  • rev:1;:这是规则的版本号。

禁用ftp指定xml文件传输(已测试)

# 允许传输 XML 文件
pass ftp-data any any -> any any (msg:"Allowed XML file transfer"; fileext:"xml"; sid:1000001; rev:1;)

# 阻止传输非 XML 文件
drop ftp-data any any -> any any (msg:"Blocked non-XML file transfer"; sid:1000002; rev:1;)
  • pass:这是规则的动作部分,指定当规则匹配时,流量将被允许通过,即不进行任何阻止或警报。

  • ftp-data any any -> any any:这指定了规则的流量方向和协议。ftp-data 表示规则适用于 FTP 数据连接,any any -> any any 表示从任何 IP 地址和端口到任何 IP 地址和端口的 FTP 数据流量都将被检查。

  • msg:"Allowed XML file transfer":这是当规则触发时显示的消息,说明规则的目的是允许 XML 文件的传输。

  • fileext:"xml";:这是规则的内容部分,指定了规则匹配的条件。在这里,规则检查 FTP 数据传输中是否包含以 ".xml" 结尾的文件。

禁用http只允许xml文件(未测试)

pass http $EXTERNAL_NET any -> $HOME_NET any (msg:"HTTP Download of non-XML File"; flow:established,to_server;content:".xml"; http_uri; classtype:policy-violation; sid:1000001; rev:1;)

drop http $EXTERNAL_NET any -> $HOME_NET any (msg:"HTTP Download of non-XML File"; flow:established,to_server; classtype:policy-violation; sid:1000002; rev:1;)
  • pass:这是规则的动作部分,指定当规则匹配时,流量将被允许通过,即不进行任何阻止或警报。
  • http:指定要检查的协议是HTTP。
  • $EXTERNAL_NET any -> $HOME_NET any:指定流量的方向,从任何外部网络到任何内部网络。
  • msg:"HTTP Download of non-XML File":当规则匹配时,将显示的消息。
  • flow:established,to_server:指定规则只匹配已建立的连接,并且流量是流向服务器的。
  • http_uri:指定要检查的数据部分是HTTP请求的URI。
  • content:!".xml":指定要检查的内容,这里使用否定匹配,表示不匹配任何以.xml结尾的URI。
  • classtype:policy-violation:指定警报的分类类型。
  • sid:1000001:指定规则的ID。
  • rev:1:指定规则的版本号。

禁用smtp只允许xml文件(未测试)

pass smtp any any -> any any (msg:"Blocked Non-XML File Attachment in SMTP"; flow:established,to_server; file_data; content:".xml"; classtype:policy-violation; sid:1000001; rev:1;)

drop smtp any any -> any any (msg:"Blocked Non-XML File Attachment in SMTP"; flow:established,to_server; classtype:policy-violation; sid:1000002; rev:1;)
  • pass:这是规则的动作部分,指定当规则匹配时,流量将被允许通过,即不进行任何阻止或警报。
  • drop:表示当流量符合规则时,将丢弃(阻止)该流量。
  • smtp:指定要检查的协议是SMTP。
  • any any -> any any:表示对任何源IP和端口到任何目的IP和端口的流量进行检查。
  • msg:"Blocked Non-XML File Attachment in SMTP":当规则匹配时,将显示的消息。
  • flow:established,to_server:指定规则只匹配已建立的连接,并且流量是流向服务器的。
  • file_data:SMTP应用层关键字,用于匹配文件数据。
  • content:!".xml":指定要检查的内容,这里使用否定匹配,表示匹配不以.xml结尾的文件名。
  • classtype:policy-violation:指定警报的分类类型。
  • sid:1000002:指定规则的ID。
  • rev:1:指定规则的版本号。

禁用pop3只允许xml文件(未测试)

pass tcp  any any -> any 110 (msg:"POP3 File Transfer Blocked";content:".xml"; flow:to_server,established; sid:1000001; rev:1;)
drop tcp  any any -> any 110 (msg:"POP3 File Transfer Blocked";flow:to_server,established; sid:1000002; rev:1;)
  • pass:这个操作指令告诉Suricata允许匹配此规则的数据包通过。通常,用于IDS的规则会使用alertdrop,分别用于生成警报或丢弃恶意流量。

  • tcp:指定要检查的流量类型为TCP协议。

  • any any -> any 110:指定源地址和目的地址(any any)以及目的端口(110),即POP3协议的标准端口。这意味着规则将匹配所有发送到POP3端口的TCP流量。

  • msg:"POP3 File Transfer Blocked":如果流量匹配规则,将显示这条消息。不过,由于使用了pass操作,这条消息实际上不会被触发,因为pass规则通常不生成警报。

  • content:".xml":指定规则要检查的内容,即寻找包含.xml字符串的数据包。然而,这个检查可能不会如您所期望的那样工作,因为POP3协议传输的是邮件内容,而不是文件系统上的文件名。

  • flow:to_server,established:指定规则只匹配已经建立的连接,并且流量是朝向服务器的(客户端到服务器)。

  • sid:1000001:指定规则的ID,用于唯一标识这条规则。

  • rev:1:指定规则的修订版本号。

防御ICMP 重定向(ICMP Redirect)(未测试)

drop icmp $EXTERNAL_NET any -> $HOME_NET any (msg:"ICMP Redirect Detected"; itype:5; classtype:misc-activity; sid:1000001; rev:1;)
  • drop:这是规则的动作部分,指定当规则匹配时,流量将被丢弃,即阻止该流量通过。

  • icmp $EXTERNAL_NET any -> $HOME_NET any:这指定了规则的流量方向和协议。icmp 表示规则适用于 ICMP 流量,$EXTERNAL_NET any -> $HOME_NET any 表示从外部网络到内部网络的任何主机的 ICMP 流量都将被检查。

  • msg:"ICMP Redirect Detected":这是当规则触发时显示的消息,说明检测到 ICMP 重定向报文。

  • itype:5:这是规则的内容部分,指定了规则匹配的条件。在这里,itype:5 表示 ICMP 类型码为 5,即 ICMP 重定向消息。

  • classtype:misc-activity:这指定了警报的分类类型,表示这是一个与网络活动相关的警报。

  • sid:1000001:这是规则的唯一标识符(Signature ID),用于区分不同的规则。

  • rev:1:这是规则的版本号。

防御smurf攻击(已测试,不是标准方法)

SMURF攻击是一种基于ICMP(Internet Control Message Protocol)协议的拒绝服务(DoS)攻击。攻击者利用ICMP Echo Request报文的特性,通过伪造源IP地址向目标网络中的广播地址发送大量的Echo Request报文,导致目标网络被淹没,无法正常工作。

防御方式(禁止icmp echo命令)

drop icmp $EXTERNAL_NET any -> $HOME_NET any (msg:"ICMP Smurf Attack Detected"; itype:0; icode:0; classtype:misc-activity; sid:1000001; rev:1;)
  • drop:动作关键字,表示匹配该规则的数据包将被丢弃。
  • icmp:指定协议为ICMP。
  • $EXTERNAL_NET any -> $HOME_NET any:表示从任何外部网络到任何内部网络的流量。这里$EXTERNAL_NET$HOME_NET是Suricata中的变量,需要在规则配置中定义,代表外部和内部网络地址。
  • msg:"ICMP Smurf Attack Detected":当规则被触发时显示的消息。
  • itype:8:指定ICMP类型为8,即ICMP echo请求。
  • icode:0:指定ICMP代码为0,这是echo请求的标准代码。
  • classtype:misc-activity:指定分类类型为“misc-activity”,表示这是一种杂项网络活动。
  • sid:1000001:指定规则的ID。
  • rev:1:指定规则的版本。

TCP_FLAG防御(未测试)

可以设置规则来检测TCP标志位的异常组合,例如同时设置SYN和FIN标志位,或者没有设置任何标志位的数据包。

在Suricata中,flags关键字用于指定TCP数据包的标志位。关键字flags后面通常跟随的是具体的TCP标志位,如S(SYN)、A(ACK)、F(FIN)、R(RST)、P(PSH)、U(URG)等。这些标志位可以组合使用,以匹配具有特定标志位设置的数据包。

drop tcp any any -> any any (msg:"Invalid TCP Flags"; flags:0; sid:1000002; rev:1;)
drop tcp any any -> any any (msg:"Invalid TCP Flags"; flags:SAFPUR; sid:1000003; rev:1;)
drop tcp any any -> any any (msg:"SYN and FIN Set"; flags:SF; sid:1000004; rev:1;)
  • drop:表示匹配该规则的数据包将被丢弃。
  • tcp:指定协议为TCP。
  • any any -> any any:表示规则适用于任何源IP和端口到任何目的IP和端口的流量。
  • msg:"Invalid TCP Flags":当规则被触发时显示的消息。
  • flags:0:表示匹配没有设置任何TCP标志位的数据包。
  • flags:SAFPUR:表示匹配全部TCP标志位的数据包。
  • flags:SF:表示匹配SYN和FIN的数据包。
  • sid:1000002:指定规则的ID。
  • rev:1:指定规则的版本。

Land防御(已测试)

LAND攻击是一种TCP协议攻击,其中攻击者发送一个SYN请求,其源和目标IP地址相同,源和目标端口也相同。这种攻击通常会导致目标系统消耗大量资源,因为它尝试响应一个无法完成的连接。

注:由于版本比较低,所以只能实现源和目标IP校验是否相同。

drop ip any any -> any any (msg:"LAND Attack Detected"; sameip; sid:1000001; rev:1;)
  • drop:这是规则的动作部分,表示如果数据包匹配此规则,则应该被丢弃。
  • ip any any -> any any:这部分定义了规则的协议和端口。在这个例子中,它表示匹配所有IP协议的数据包,不考虑端口号(因为any用于源端口和目标端口)。然而,这里的表示方法有些冗余,因为ip已经隐含了协议类型,而端口部分对于纯IP层规则来说通常是不必要的。
  • (msg:"LAND Attack Detected"):这是规则的元数据部分,提供了一个描述性消息,当规则触发时会被记录。
  • sameip:检查源IP地址和目标IP地址是否相同。
  • sid:1000001:这是规则的唯一标识符(Signature ID)。
  • rev:1:这是规则的版本号。

Tracert防御(未测试)

在Suricata中防御TRACERT攻击,通常需要检测具有特定特征的TCP数据包,这些数据包可能表示正在进行的TRACERT操作。TRACERT利用ICMP时间超过(Time Exceeded)消息来追踪数据包从源到目的地的路径。因此,防御TRACERT的规则可能需要检测ICMP协议中的时间超过消息。

drop icmp $EXTERNAL_NET any -> $HOME_NET any (msg:"Possible TRACERT Attack Detected"; itype:11; icode:0; sid:1000003; rev:1;)
  • drop:这是规则的动作部分,表示如果数据包匹配此规则,则应该被丢弃。
  • icmp:指定协议为ICMP。
  • $EXTERNAL_NET any -> $HOME_NET any:表示从任何外部网络到任何内部网络的流量。这里$EXTERNAL_NET$HOME_NET是Suricata中的变量,需要在规则配置中定义,代表外部和内部网络地址。
  • msg:"Possible TRACERT Attack Detected":当规则被触发时显示的消息。
  • itype:11:指定ICMP类型为11,即时间超过消息。
  • icode:0:指定ICMP代码为0,表示时间超过消息的一般情况。
  • sid:1000003:指定规则的ID。
  • rev:1:指定规则的版本。

Teardrop防御(未测试)

Teardrop攻击是一种拒绝服务(DoS)攻击,它通过发送分片的IP数据包,使得目标机器在尝试重组这些数据包时发生缓冲区溢出,从而导致系统崩溃。这种攻击主要影响早期的操作系统,如Windows 95、98、NT等,但近年来也有发现对某些版本的Android和iOS系统有效。

drop ip $EXTERNAL_NET any -> $HOME_NET any (msg:"Possible Teardrop Attack Detected"; fragbits:M; sid:1000004; rev:1;)
  • drop:这是规则的动作部分,表示如果数据包匹配此规则,则应该被丢弃
  • ip:指定协议为IP。
  • $EXTERNAL_NET any -> $HOME_NET any:表示从任何外部网络到任何内部网络的流量。这里$EXTERNAL_NET$HOME_NET是Suricata中的变量,需要在规则配置中定义,代表外部和内部网络地址。
  • msg:"Possible Teardrop Attack Detected":当规则被触发时显示的消息。
  • fragbits:M:指定检测IP数据包的碎片位,M表示“更多片段”位被设置,这是Teardrop攻击的特征之一。
  • sid:1000004:指定规则的ID。
  • rev:1:指定规则的版本。

Fraggle防御(未测试)

在Suricata中实现对Fraggle攻击的防御,可以通过检测UDP数据包的特征来实现。Fraggle攻击类似于Smurf攻击,但使用的是UDP协议而不是ICMP。攻击者通过向目标网络的广播地址发送大量伪造的UDP数据包,导致目标网络中的主机尝试响应这些数据包,从而引发洪水般的流量。

drop udp any any -> any broadcast (msg:"Possible Fraggle Attack Detected"; dsize:>1024; sid:1000005; rev:1;)
  • drop:这是规则的动作部分,表示如果数据包匹配此规则,则应该被丢弃。
  • udp:指定协议为UDP。
  • any any -> any broadcast:表示规则适用于任何源IP和端口到任何目的IP和广播端口的流量。
  • msg:"Possible Fraggle Attack Detected":当规则被触发时显示的消息。
  • dsize:>1024:指定数据包大小大于1024字节,这是一个示例阈值,可以根据实际情况调整。
  • sid:1000005:指定规则的ID。
  • rev:1:指定规则的版本。

WinNuke防御(已测试)

WinNuke攻击是一种拒绝服务攻击。WinNuke攻击又称带外传输攻击,它的特征是攻击目标端口,被攻击的目标端口通常是139、138、137,而且URG位设为“1”,即紧急模式。

drop tcp $EXTERNAL_NET any -> $HOME_NET [137,138,139] (msg:"WinNuke Attack Detection"; flow:to_server; flags:APU; sid:1000001; rev:1;)

  • drop:这是规则的动作部分,表示如果数据包匹配此规则,则应该被丢弃。

  • tcp:指定协议为TCP。

  • $EXTERNAL_NET any:表示源地址是外部网络,any表示任何端口。

  • ->:表示流量的方向,从左到右。

  • $HOME_NET [137,138,139]:表示目的地址是内部网络,端口是137、138或139。这些端口分别是NetBIOS名称服务(137/UDP)、NetBIOS数据报服务(138/UDP)和NetBIOS会话服务(139/TCP)。

  • msg:"WinNuke Attack Detection":当规则触发时,会在日志中记录这条消息。

  • flow:to_server:指定规则适用于流向服务器的流量。

  • flags:AUP:指定TCP标志位。A代表ACK,U代表URG,P代表PSH。WinNuke攻击通常使用这些标志位的组合。

  • sid:1000001:规则的唯一标识符(Signature ID),用于在规则集中唯一标识这条规则。

  • rev:1:规则的修订版本号,用于跟踪规则的变更。

Large_icmp防御(已测试)

在网络入侵检测和防御系统中,ICMP(Internet Control Message Protocol)流量的监控是一个重要的方面,因为它可以被用来发动各种类型的攻击,比如ICMP洪水攻击或者利用ICMP重定向进行网络窃听。Suricata作为一个高性能的网络入侵检测和防御系统(IDS/IPS),提供了对ICMP流量的监控和防御能力。

在Suricata的规则集中,可以编写特定的规则来检测和防御Large_icmp攻击。例如,可以设置规则来监控ICMP数据包的大小,并在超过某个阈值时触发警报或采取防御措施。规则可能类似于以下形式.

drop icmp any any -> any any (msg:"Large ICMP packet detected"; dsize:>576; sid:1000001; rev:1;)
  • drop:这是规则的动作部分,指定当规则被触发时,应该执行的操作。在这个例子中,drop意味着任何匹配这条规则的数据包都将被丢弃,即不会被传递到目标主机。

  • icmp:这指定了规则适用于ICMP协议的数据包。

  • any any:这部分指定了源地址和目的地址。any表示规则不限制源或目的IP地址,适用于所有IP地址。

  • ->:这个箭头表示数据包的流向,从左边的源地址流向右边的目的地址。

  • any any(再次出现):这同样表示规则不限制目的IP地址,适用于所有IP地址。

  • (msg:"Large ICMP packet detected";:这是规则的元数据部分,提供了当规则被触发时,Suricata将记录的消息。在这个例子中,消息是"Large ICMP packet detected",意味着“检测到大型ICMP数据包”。

  • dsize:>576;:这是规则的条件部分。dsize代表数据包的大小(以字节为单位),>576表示规则将匹配大于576字节的数据包。ICMP数据包的标准大小通常为576字节(包括IP头和ICMP头),因此大于这个大小的数据包可能是异常的。

  • sid:1000001;:这是规则的ID,用于唯一标识这条规则。在Suricata中,规则ID(SID)通常是一个数字,用于在日志和警报中引用特定的规则。

  • rev:1;:这是规则的修订号,用于标识规则的版本。当规则被更新或修改时,修订号会增加,以便于跟踪规则的变化。

Ping of death防御(未测试)

"Ping of Death" 是一种网络攻击手段,它通过发送一个大于64KB的ICMP数据包来攻击目标主机,导致某些操作系统无法正确处理这些数据包,从而可能引起系统崩溃。

对于“Ping of Death”攻击,这种攻击利用的是IP数据包的分片,而不是ICMP协议的特定字段。攻击者会发送一个超过IP数据包最大传输单元(MTU)大小的数据包,导致接收端无法正确重组数据包,从而可能造成系统崩溃。

如果您想要检测可能的“Ping of Death”攻击,您应该关注数据包的大小,而不是ICMP的特定字段。以下是一个示例规则,它使用content关键字来检查ICMP数据包的负载大小:

drop icmp any any -> any any (msg:"Ping of Death attack detected"; itype:3; icode:4; content:"|00 00|"; depth:4; sid:1000001; rev:1;)

  • drop:这是规则的动作部分,指定当规则被触发时,应该执行的操作。在这个例子中,drop意味着任何匹配这条规则的数据包都将被丢弃,即不会被传递到目标主机。

  • icmp:这指定了规则适用于ICMP协议的数据包。

  • msg:"Ping of Death attack detected":当规则被触发时显示的消息。

  • itype:3 匹配ICMP类型为3的数据包,即目的不可达。

  • icode:4 匹配ICMP代码为4的数据包,即分片和组装错误。

  • content:"|00 00|":这是ICMP数据包中的一个模式,表示数据包的开始。

  • depth:4:表示检查数据包的前四个字节。

  • sid:1000001:这是规则的唯一标识符。

  • rev:1:这是规则的版本号。

TCP关键字过滤(未测试)

drop tcp any any -> any any (msg:"Keyword Interception"; content:"<KEYWORD>"; sid:1000001; rev:1;)
  • drop 这是规则的动作部分,指定当规则被触发时,应该执行的操作。在这个例子中,drop意味着任何匹配这条规则的数据包都将被丢弃,即不会被传递到目标主机。

  • tcp 指定了规则适用于TCP协议。

  • any any -> any any 表示规则适用于任何IP地址和端口的流量。

  • msg 提供了当规则触发时的警报消息。

  • content 后面跟着的是你要拦截的关键字,<KEYWORD> 需要替换成你想要拦截的实际关键字。

  • sid 是规则的唯一标识符,通常是一个数字。

  • rev 是规则的版本号。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值