CVE-2024-40116 CVE-2024-34783等——Cicso多个安全漏洞_2024年cve漏洞库

本人从事网路安全工作12年,曾在2个大厂工作过,安全服务、售后服务、售前、攻防比赛、安全讲师、销售经理等职位都做过,对这个行业了解比较全面。

最近遍览了各种网络安全类的文章,内容参差不齐,其中不伐有大佬倾力教学,也有各种不良机构浑水摸鱼,在收到几条私信,发现大家对一套完整的系统的网络安全从学习路线到学习资料,甚至是工具有着不小的需求。

最后,我将这部分内容融会贯通成了一套282G的网络安全资料包,所有类目条理清晰,知识点层层递进,需要的小伙伴可以点击下方小卡片领取哦!下面就开始进入正题,如何从一个萌新一步一步进入网络安全行业。

学习路线图

其中最为瞩目也是最为基础的就是网络安全学习路线图,这里我给大家分享一份打磨了3个月,已经更新到4.0版本的网络安全学习路线图。

相比起繁琐的文字,还是生动的视频教程更加适合零基础的同学们学习,这里也是整理了一份与上述学习路线一一对应的网络安全视频教程。

网络安全工具箱

当然,当你入门之后,仅仅是视频教程已经不能满足你的需求了,你肯定需要学习各种工具的使用以及大量的实战项目,这里也分享一份我自己整理的网络安全入门工具以及使用教程和实战。

项目实战

最后就是项目实战,这里带来的是SRC资料&HW资料,毕竟实战是检验真理的唯一标准嘛~

面试题

归根结底,我们的最终目的都是为了就业,所以这份结合了多位朋友的亲身经验打磨的面试题合集你绝对不能错过!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

    if (order and order ~= "") then fld["order"]=tonumber(order) end
   
end
table.sort(fields,function (a,b) return a["order"] < b["order"] end)
return fields

end

function LOAD_URL_LIST(name,absolute_path,bookmark_number)

local f
local ret={}
local sso_enabled=0;
local name_md5 = MD5(name)

if absolute_path and “” ~= absolute_path then
f=io.open(absolute_path,“r”)
else
f=io.open(“/bookmarks/”…name_md5,“r”)
end

if not f then return {} end

local function get_value(value)

  if not value then return nil end
  if string.len(value) == 0 then return "" end
  return string.sub(value,2) 

end

local path = “/url-list/”

local function lget_value(textdomain,value)
if nil == value then return nil end
if string.len(value) == 0 then return “” end
if string.sub(value,1,1) == ‘+’ then
if string.len(value) > 1 then
return gettext.dgettext(textdomain,string.sub(value,2))
else
return “”
end
else
return string.sub(value,2)
end
end

ret[“list”] = name_md5
ret[“title”] = lget_value(“url-list”,io.get_metadata_str(f,path…“title”))
ret[“favorite”] = get_value(io.get_metadata_str(f,path…“favorite”));
ret[“bookmark”]={}

local i = bookmark_number or 1
while true do
local path = “/url-list/bookmark/”…i…“/”
local url = get_value(io.get_metadata_str(f,path…“url”));

  if nil ~= url then
     ret["bookmark"][i]={}
     ret["bookmark"][i]["n"]=i
     ret["bookmark"][i]["list"] = name\_md5   
     ret["bookmark"][i]["id"] = get\_value(io.get\_metadata\_str(f,path.."id"))
     ret["bookmark"][i]["favorite"] = get\_value(io.get\_metadata\_str(f,path.."favorite"))
     ret["bookmark"][i]["title"]       = lget\_value("url-list",io.get\_metadata\_str(f,path.."title"))
     ret["bookmark"][i]["method"]    = get\_value(io.get\_metadata\_str(f,path.."method"))
     ret["bookmark"][i]["subtitle"]  = lget\_value("url-list",io.get\_metadata\_str(f,path.."subtitle"))
     ret["bookmark"][i]["thumbnail"] = lget\_value("url-list",io.get\_metadata\_str(f,path.."thumbnail"))
     ret["bookmark"][i]["smart-tunnel"] = get\_value(io.get\_metadata\_str(f,path.."smart-tunnel"))
     ret["bookmark"][i]["window"] = get\_value(io.get\_metadata\_str(f,path.."window"))
     ret["bookmark"][i]["wait-time"] = get\_value(io.get\_metadata\_str(f,path.."wait-time"))
     ret["bookmark"][i]["preload-page-url"] = get\_value(io.get\_metadata\_str(f,path.."preload-page-url"))
     ret["bookmark"][i]["pre-login-page-url"] = get\_value(io.get\_metadata\_str(f,path.."pre-login-page-url"))
     ret["bookmark"][i]["control-id"]         = get\_value(io.get\_metadata\_str(f,path.."control-id"))
     ret["bookmark"][i]["before-post-script"] = get\_value(io.get\_metadata\_str(f,path.."before-post-script"))

     -- injected form submit 
     ret["bookmark"][i]["injected-form-submit"] = get\_value(io.get\_metadata\_str(f,path.."injected-form-submit"))
     ret["bookmark"][i]["pre-login-page-url"] = get\_value(io.get\_metadata\_str(f,path.."pre-login-page-url"))
     ret["bookmark"][i]["control-id"] = get\_value(io.get\_metadata\_str(f,path.."control-id"))
     ret["bookmark"][i]["login-page-url"] = get\_value(io.get\_metadata\_str(f,path.."login-page-url"))
     ret["bookmark"][i]["landing-page-url"] = get\_value(io.get\_metadata\_str(f,path.."landing-page-url"))
     ret["bookmark"][i]["form-id"] = get\_value(io.get\_metadata\_str(f,path.."form-id"))
     ret["bookmark"][i]["post-param"] = {}

     url = get\_value(io.get\_metadata\_str(f,path.."url"))

     url = substitute\_macro(url,false)

     -- Normalize CIFS URLs (cifs://\\host/...)

     if(string.sub(url,1,9)=="cifs://\\\\") then 
        url="cifs://"..(string.sub(url,10) or "") 
        url=string.gsub(url,"\\","/")
     end

     ret["bookmark"][i]["url"] = url

     if string.find(ret["bookmark"][i]["url"], "csco\_sso=1")   then
        sso\_enabled=1;
     end

     local j=1

     while true do
        local path = "/url-list/bookmark/"..i.."/post-param/"..j.."/"
        local name = get\_value(io.get\_metadata\_str(f,path.."name"))

        if nil ~= name then
           ret["bookmark"][i]["post-param"][j]={}
           ret["bookmark"][i]["post-param"][j]["name"]  = get\_value(io.get\_metadata\_str(f,path.."name"))
           ret["bookmark"][i]["post-param"][j]["value"] = get\_value(io.get\_metadata\_str(f,path.."value"))
        else
           break
        end
        j=j+1
     end
  else
     break
  end

  -- if loading just one bookmark from the list	
  if bookmark\_number then
break
  end	

  i=i+1

end
f:close()

local sso = io.open(“sessions/”…SESSION_INDEX()…“/sso”,“w”)
if sso then
if 1 == sso_enabled then
– allow sso call
io.set_metadata_str(sso, “allowed”, “yes”)
end
sso:close()
end

return ret

end

function post_params2js_array(bookmark)

return “[{ ‘l’ : '”…(bookmark[“list”] or “”)…“', ‘n’ : “…(bookmark[“n”] or “0”)…”}]”

–[[
local post_params=“null”

if table.getn(bookmark[“post-param”])>0 then
post_params = “[”
for i,prm in bookmark[“post-param”] do

     local name
     name = string.gsub(prm["name"],"'","\\'") or "";
     name = string.gsub(name,"\\","\\\\") or "";


     local value 
     value = string.gsub(prm["value"],"'","\\'") or "";
     value = string.gsub(value,"\\","\\\\") or "";

     post\_params = post\_params ..(((i>1) and ",") or "" ) .. "{name : '"..name.."', value : '"..value.."'}"
  end
  post\_params = post\_params.."]"

end

return post_params
–]]

end

function show_bookmarks()

end

function BookmarkApplyACL(bookmark,proto,host,port,path,defports,otherports)
if (port ~= nil and port ~= “”) then
bookmark[“enabled”],bookmark[“dns_error”] = SESSION_CHECK_URL(proto,host,port,path);
else
–check default port
if (defports[proto]) then
bookmark[“enabled”],bookmark[“dns_error”] = SESSION_CHECK_URL(proto,host,defports[proto],path);
end
–check other ports, if there are any
if (otherports[proto]) then
local i, p = next(otherports[proto])
while (i and bookmark[“enabled”]) do
bookmark[“enabled”],bookmark[“dns_error”] = SESSION_CHECK_URL(proto,host,p,path)
i, p = next(otherports[proto], i)
end
end
end
end

function BookmarkApplySupportCheck(bookmark)
if (bookmark[“method”] == “post” and bookmark[“smart-tunnel”] == “yes” and browser_info.os ~= “Windows”) then
bookmark[“support_error”] = 1
bookmark[“enabled”] = false
end
end

function GROUP_SELECTOR_ENABLED()
return true;
end

function print_tree(s,d)

if(nil == d) then d = 0 end
if(nil == s) then OUT(“nil”);return end

for k,v in s do
OUT(string.rep(" “,d*5)); OUT(k);
if(type(v)“table”) then
OUT(“
”);
print_tree(v,d+1)
else
if(type(v)
“boolean”) then
if v then OUT( “#true”) else OUT(” #false") end
OUT(“
”)
else
if(type(v)==“function”) then
OUT(“= (function)
”)
else
OUT(“=”…v…“
”);
end
end
end
end
end

function mangle_url(str)

local s,e,p
local path;

if nil == str then return “/+CSCOE+/blank.html” end

s, e = string.find(str,“http[s]?😕/([^/?]+)”)

if(s ~= nil) then
p = ((string.sub(str,e+1,e+1) == “/”) and e+1 ) or e
path = string.sub(str,p+1);
return ‘/+CSCO+00’…ROT13STR2HEX(string.sub(str,1,e))…‘++/’…path;

end
end

function get_applications(no_session_check)


– This function may be used in context where there is no webvpn session (for example Customization Editor)
– Use if(not no_session_check) in places where you retrieve session data

local c_app = {};

local n1 = 0
local n2 = 0

local i = 0;
local lang

if is_asdm then
lang = “en”
else
lang = get_selected_language()
end
– Stock applications

local app = {}

i=i+1
app[i]={}
app[i][“tab-title”] = L(“Home”)
app[i][“id”] = “home”
app[i][“order”] = i*1000

i=i+1
app[i]={}
app[i][“tab-title”] = L(“Web Access”)
app[i][“id”] = “web-access”
app[i][“protocol”] = “http,https”
app[i][“default-port”] = “80,443”
app[i][“url-list-title”] = L(“Web Bookmarks”)
app[i][“order”] = i*1000

i=i+1
app[i]={}
app[i][“tab-title”] = L(“File Access”)
app[i][“id”] = “file-access”
app[i][“protocol”] = “cifs,ftp”
app[i][“default-port”] = “138,21”
app[i][“other-port”] = {cifs = {“139”}}
app[i][“url-list-title”] = L(“File Bookmarks”)
app[i][“order”] = i*1000

i=i+1
app[i]={}
app[i][“tab-title”] = L(“Application Access”)
app[i][“id”] = “app-access”
app[i][“url-list-title”] = L(“File Bookmarks”)
app[i][“order”] = i*1000

i=i+1
app[i]={}
app[i][“tab-title”] = L(“AnyConnect”)
app[i][“id”] = “net-access”
app[i][“order”] = i*1000

if IS_TARGET_UNICORN then

  i=i+1
  app[i]={}
  app[i]["tab-title"] = L("Terminal Servers")
  app[i]["id"] = "rdp"
  app[i]["order"] = i\*1000
  app[i]["protocol"] = "rdp"
  app[i]["default-port"] = "800"
  app[i]["type"] = "1"

end

-- Plugins 

local a = lfs.attributes(“/plugin”)

if a and a.mode == “directory” then
for fname in lfs.dir (“/plugin”) do
if fname ~= “.” and fname ~= “…” then
local f=io.open(“/plugin/”…fname…“/index.html”,“r”)

        if f then
           i=i+1
           app[i]={}
           
           
           app[i]["tab-title"] = io.get\_metadata\_str(f,"tab-title")
           app[i]["url-list-title"] = io.get\_metadata\_str(f,"bookmark-title")

           if lang and  lang ~= "en" and lang ~= "en-us"  then
              
              app[i]["tab-title"] = io.get\_metadata\_str(f,lang..":tab-title") or app[i]["tab-title"] 
              app[i]["url-list-title"] = io.get\_metadata\_str(f,lang..":bookmark-title") or app[i]["url-list-title"]


           end

           app[i]["id"] = io.get\_metadata\_str(f,"id")
           app[i]["protocol"] = io.get\_metadata\_str(f,"protocol")
       -- TODO  facilitate default port from plugin's manifest
       local p\_protocol = {}
       for s in string.gfind(app[i]["protocol"],"[%w]+") do
	  table.insert(p\_protocol,"0")
       end
       app[i]["default-port"] = table.concat(p\_protocol,",")
           app[i]["type"] = "1"
           app[i]["order"] = i\*1000
           
           f:close()
        end
     end
  end

end

c_app = CUSTOM_OBJECTS(“/custom/portal/application”,{{“id”,false},{“order”,false},{“tab-title”,true},{“url-list-title”,true},{“mode”,false}})

n1= table.getn(c_app);
n2= table.getn(app);

for i1 = 1,n1,1 do
for i2 = 1,n2,1 do

     if(app[i2]["id"] == c\_app[i1]["id"]) then 

        if(nil ~= c\_app[i1]["order"]) then app[i2]["order"] = tonumber(c\_app[i1]["order"]); end; 
        if(nil ~= c\_app[i1]["tab-title"]) then app[i2]["tab-title"] = c\_app[i1]["tab-title"]; end;
        if(nil ~= c\_app[i1]["mode"]) then app[i2]["mode"] = c\_app[i1]["mode"]; end; 
        if(nil ~= c\_app[i1]["url-list-title"]) then app[i2]["url-list-title"] = c\_app[i1]["url-list-title"]; end; 

     end;
  end;

end;

if not no_session_check then

   local ua = HTTP\_HEADER\_BY\_NAME('user-agent')
   local stapps = ""
   if (ua and string.find (ua, "Macintosh")) then
      stapps = SESSION\_GET\_SMART\_TUNNELED\_APPS("mac")

–[[
elseif (ua and string.find (ua, “Linux”)) then
stapps = SESSION_GET_SMART_TUNNELED_APPS(“linux”)
–]]
elseif (ua) then
stapps = SESSION_GET_SMART_TUNNELED_APPS(“windows”)
end
local no_smart_tunnel = stapps == “”

  for i2 = 1,n2,1 do
  
     if (app[i2]["id"] == "net-access" and not (SESSION\_ANYCONNECT\_ENABLED() and SESSION\_ANYCONNECT\_CONFIGURED())) or (app[i2]["id"] == "app-access" and not (SESSION\_FEATURE\_ENABLED("port-forwarding")) and no\_smart\_tunnel) then
        app[i2]["mode"] = "disable"
     end
  
  end

end

table.sort(app,compare);

return app;
end;

function GetColumns()

local cols = CUSTOM_OBJECTS(“/custom/portal/column”,{{“width”,false,“percent”},{“order”,false,nil,“0”}})

local function s(a,b)

  return tonumber(a["order"])<tonumber(b["order"]) 

end

if table.getn(cols) == 0 then
return {{width=“100”,order=“0”,pane={}}}
end

table.sort(cols,s)

for _,col in cols do
col[“pane”]={}
end

return cols
end

function CUSTOM_OBJECTS(path,fields)

local f
local ret

id = fields[1][1]

local first_item = path…“/1/”…id

if “” ~= asdm_custom_file then
f=io.open(asdm_custom_file,“r”)
else
f=io.open(“/customization/”…MD5(custom_profile),“r”)
end

if nil == f then return {} end

ret = {}

for i=1,10000,1 do

  ptype = io.get\_metadata\_str(f,path.."/"..i.."/"..id)

  if nil == ptype then break end

  ret[i]= {}
  for \_,fname in fields do
     local name = fname[1]
     local can\_localize = fname[2]
     local type = fname[3]
     local def\_value = fname[4]

     ret[i][name] = io.get\_metadata\_str(f,path.."/"..i.."/"..name)

     if  ret[i][name] and string.len(ret[i][name]) > 1 then
        
        if type  then
           if type == "number" then
              ret[i][name] = tonumber(string.sub(ret[i][name],2))
           end

           if type == "percent" then
              ret[i][name] = string.gsub(ret[i][name],"%%"," ")
              ret[i][name] = tonumber(string.sub(ret[i][name],2)) or 0
           end
       
        else   
           local localize = string.sub(ret[i][name],1,1)
           if localize == "+" and can\_localize then
              ret[i][name] =  gettext.dgettext("customization",string.sub(ret[i][name],2))
           else
              ret[i][name] = string.sub(ret[i][name],2)
           end
        end
     else
        ret[i][name] = def\_value
     end
  end

end

f:close()

return ret

end

function CUSTOM(param,default,localize)

local f;

local function file_name()

  if "" ~= asdm\_custom\_file then
     return(asdm\_custom\_file)
  else
     return "/customization/"..MD5(custom\_profile)
  end

end

f=io.open(file_name(),“r”)
if not f then return default end

local s = io.get_metadata_str(f,“/custom/”…param);

f:close()

if s and string.len(s)>1 then
local localize = string.sub(s,1,1)
if localize == “-” then
return string.sub(s,2)
else
return gettext.dgettext(“customization”,string.sub(s,2))
end
end

if nil == default then default = “” end

return default

end

function CheckAlerts()

local reason = 0
local user_alert = SESSION_USER_ALERT()
local idle_alert_time = SESSION_IDLE_ALERT_INTERVAL() * 60
local end_alert_time = SESSION_END_ALERT_INTERVAL() * 60
local max_connect_time = SESSION_MAX_CONNECT_TIME()

tin = max_connect_time -(SESSION_TIME() - SESSION_LOGIN_TIME())

if end_alert_time > 0 and max_connect_time ~=0 and tin <= end_alert_time + 5 then
reason=1
else
tin = SESSION_MAX_IDLE_TIME() - SESSION_IDLE_TIME()

  if idle\_alert\_time > 0 and tin <= idle\_alert\_time + 5 then
     reason = 2
  end

end

if reason == 0 and (not user_alert or user_alert==“” ) then return false end

return true

end

function FileURL(url)

return “javascript: parent.doURL('”…ROT13STR2HEX(clean_escape(url))…“‘,’‘,’‘,false,’', false)”;

end

function GetPostParams()
local s
local state = 10
local params = {}
local name=nil
while nil~=state do
s,state = HTTP_READ_URL_ENCODED_BODY(state)
if state == 10 then
params[name]=HTTP_URL_DECODE(s,1)
elseif state15 then
name = HTTP_URL_DECODE(s,1)
params[name]=“”
name=nil
elseif state
20 then
name = HTTP_URL_DECODE(s,1)
params[name]=“”
elseif state==30 then
if nil == name then
params[HTTP_URL_DECODE(s,1)]=“”
else
params[name]=HTTP_URL_DECODE(s,1)
end

     break;
  end

end
return params

end

function UpdateAsdmSession(cookie)
if not IS_TARGET_UNICORN then
local f=io.open(‘asdm/’…cookie, “a+”)
if f ~= nil then
f:close()
return true;
end
end
end

function CheckAsdmSession(cookie, no_redirect)
– remove expired

local diff

TRACE_CUSTOM("ASDM Cookie = "…(cookie or “”),10)

pcall(function()
for file in lfs.dir(“asdm”) do
if file ~= “.” and file ~= “…” then
local f = ‘asdm/’…file
local attr = lfs.attributes (f)

              assert (type(attr) == "table")
              diff = (SESSION\_TIME() - attr["modification"])
              if diff > 360000 then
                 os.remove(f)
              end
           end
        end
     end)

local f=io.open(‘asdm/’…cookie, “r”)
if f ~= nil then
f:close()
return true;
end

if not no_redirect then
OUT(“”)
end
TRACE_CUSTOM(“Wrong ASDM cookie = “…(cookie or “”)…”\n”,1)
return false,diff

end

function GetDefaultPorts(applications)
local ret={}
local extra={}
for _,ap in applications do
local protocol={}
local ports={}
if ap[“protocol”] then

     for s in string.gfind(ap["protocol"],"[%w]+") do
        table.insert(protocol,s)
     end
     
     if ap["default-port"] then
        for s in string.gfind(ap["default-port"],"[%w]+") do
           table.insert(ports,s)
        end
     end

     for i,v in protocol do
        ret[v]=ports[i]
        if ap["other-port"] then
            extra[v]=ap["other-port"][v]
        end
     end

  end

end
return ret,extra

end

function GetRGB(a)

local r = tostring(tonumber(string.sub(a, 2, 3), 16))
local g = tostring(tonumber(string.sub(a, 4, 5), 16))
local b = tostring(tonumber(string.sub(a, 6, 7), 16))

return r,g,b

end

function gui_title_style(page)

local title_style = CUSTOM(page…“/title-panel/style”,“”)

local ret = “”

if title_style ~= “” then

  ret =  "."..page.."-title {"..title\_style.."}" 

else

  local bgc = CUSTOM(page.."/title-panel/background-color","#2b76ad")
  local color = CUSTOM(page.."/title-panel/font-color","#ffffff")
  local font\_size = CUSTOM(page.."/title-panel/font-size","")
  local font\_weight = CUSTOM(page.."/title-panel/font-weight","")


  local gradient = CUSTOM(page.."/title-panel/gradient","no")
  local gr=""



  if gradient=="yes" then

     local r,g,b = GetRGB(bgc)

     gr="background-image:url('/+CSCOU+/gradient.gif?r="..r.."&g="..g.."&b="..b.."');"

  else
        
     gr="background-color:"..bgc..";"
        
  end
 



  ret = ret .. "."..page.."-title {" 
  ret = ret .. ((color ~="" and "color:"..color..";") or "")
  ret = ret .. ((font\_size ~="" and "font-size:"..font\_size..";") or "") 
  ret = ret .. ((font\_weight ~="" and "font-weight:"..font\_weight..";") or "")
  ret = ret .. gr
  ret = ret .. "}\n"

end

if page==“auth-page” then
local bgc = CUSTOM(page…“/logon-form/title-background-color”,“”)
local color = CUSTOM(page…“/logon-form/title-font-color”,“”)
ret = ret … “.”…page…“-form-title {”
ret = ret … ((bgc ~=“” and “background-color:”…bgc…“;”) or “”)
ret = ret … ((color ~=“” and “color:”…color…“;”) or “”)
ret = ret … “}\n”
end

return ret

end

function get_persistant_setting(key)

local ret=“”
local f=io.open(“/sessions/”…SESSION_INDEX()…“/key-value”,“r”)

if(nil ~= f) then

    ret = io.get\_metadata\_str(f, key)
    if(nil == ret) then
        ret=""
    end
    f:close()
end
return ret

end

function set_persistant_setting(key,value)

local ret=“”
local f=io.open(“/sessions/”…SESSION_INDEX()…“/key-value”,“w”)
if(nil ~= f) then
io.set_metadata_str(f, key, value)
f:close()
end
end

function ExtractLuaErrorString(s)

local b,e

if s then
b,e = string.find(s,“:[0-9]+:”)

  while b do 
     s = string.sub(s,e+1)
     b,e = string.find(s,":[0-9]+:")
  end

end

学习路线:

这个方向初期比较容易入门一些,掌握一些基本技术,拿起各种现成的工具就可以开黑了。不过,要想从脚本小子变成黑客大神,这个方向越往后,需要学习和掌握的东西就会越来越多以下是网络渗透需要学习的内容:
在这里插入图片描述

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值