<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            原文地址:http://drops.wooyun.org/papers/1395

            0x00 背景


            當這個《Struts2 Tomcat class.classLoader.resources.dirContext.docBase賦值造成的DoS及遠程代碼執行利用!》在Tomcat下的利用出來以后,它其實秒殺的不是一個框架,而是所有表單數據綁定功能不安全實現的J2EE MVC模式框架(因為國內運營商共享協議的限制,遠程代碼執行漏洞在國內難以大規模實現.但DoS漏洞還是存在的!).

            0x01 細節


            稍微列一下清單:

            Struts1框架:?

            2013年已經停止更新了,所以不會有補丁,出于節操,報了一下官方,Struts2項目leader?波蘭小胖子 Lukasz Lenar 是這樣回復的:

            2014040921474585720.png

            如圖:

            2014040922063313735.png

            webWork框架:

            struts2框架的前身,由于與struts2框架合并,所以不會有補丁!

            2014040922091186766.png

            Struts2框架:

            前面文章已經介紹了(不過發現,到現在很多重要廠商都沒修復!)

            Spring?框架:

            已經在cve-2010-1622中,補丁對class.classLoader的限制.但利用從此可以簡化!

            還有就是,自己早年學習java時,寫的簡易框架,也可以打(只是表單填充需要多寫一行代碼手動調用填充,而其他常規框架是自動的)40.gif

            就以自己寫的框架說明問題:

            表單參數綁定功能是MVC模式的框架一項非常重要的功能,比如:

            沒有表單參數綁定功能的時代,我們填充javabean的屬性都需要:

            #!java
            ... 
            dto.setUserName(request.getParameter("userName"));  
            dto.setPassWord(request.getParameter("passWord"));  
            .... 
            

            框架表單參數綁定出現以后,就節約了很多硬編碼(這是框架的主要作用之一!)

            通常實現表單參數綁定需要用到Java的兩個重要機制:

            內省(introspector)與反射(reflection)

            而Apache?commons-beanutils組件就提供了javaBean的內省與反射操作簡化API

            哥的框架使用commons-beanutils,實現表單參數綁定的部分代碼塊:

            #!java
            ... 
            public static Object parseRequest(HttpServletRequest request, Object bean) throws ServletException, IOException {
                    Enumeration enums = request.getParameterNames();
                    while (enums.hasMoreElements()) {
                        Object obj = enums.nextElement();
                        try {
                            Class cls = PropertyUtils.getPropertyType(bean, obj.toString());
                            Object beanValue = ConvertUtils.convert(request.getParameter(obj.toString()), cls);
                            HashMap map = new HashMap();
                            BeanUtils.populate(bean, map);
                            PropertyUtils.setProperty(bean, obj.toString(), beanValue);
                        } catch (Exception e) {
                            // e.printStackTrace();
                        }
                    }
                    return bean;
                }
            ... 
            

            這里不會框架的可以用servlet測試一下漏洞!

            這里有一個重要的問題,就是為什么能訪問到基類Object.class ?

            看內省機制,內省是?Java?語言對?Bean?類屬性、事件的一種缺省處理方法。例如類?A?中有屬性?name,?那我們可以通過?getName,setName?來得到其值或者設置新的值。通過?getName/setName?來訪問?name?屬性,這就是默認的規則(*但是只要有?getter/setter?方法中的其中一個,那么?Java?的內省機制就會認為存在一個屬性)。

            本身就業務邏輯講,訪問javaBean的屬性就夠了,是不需要訪問其他基類的Object.class,但是內省機制使用不當,就會造成這個問題.

            問題非常簡單,在內省機制獲取javaBean屬性的一個小細節,測試代碼:

            #!java
            public class TestBean {
            
                private String id;
                private String name;
            
                public String getId() {
                    return id;
                }
            
                public void setId(String id) {
                    this.id = id;
                }
            
                public String getName() {
                    return name;
                }
            
                public void setName(String name) {
                    this.name = name;
                }
            
            }
            
            
            
            public class Test {
            
                public static void main(String[] args) throws IntrospectionException,
                        IllegalArgumentException, IllegalAccessException,
                        InvocationTargetException {
            
                    TestBean dto = new TestBean();
            
                    BeanInfo bi = Introspector.getBeanInfo(dto.getClass());
            
                    // BeanInfo bi = Introspector.getBeanInfo(dto.getClass(),Object.class);
            
                    PropertyDescriptor[] props = bi.getPropertyDescriptors();
                    for (int i = 0; i < props.length; i++) {
                        System.out.println(props[i].getName());
                    }
                    BeanInfo bi = Introspector.getBeanInfo(dto.getClass());
                }
            
            }
            

            獲取包括父類的所有屬性,如圖:

            2014040922595023935.png

            如果不想獲取父類的屬性.可以使用

            #!java
            Introspector.getBeanInfo(dto.getClass(),Object.class);
            

            其中第二個參數就是終止遍歷到的父類(如:終止到基類Object),如圖(這才是表單綁定實現正確的做法):

            2014040923033384924.png

            然后只要屬性有set器,參數就會被填充,以及后面的Tomcat的一些屬性被掛載到class.classLoader下等原因,然后Tomcat的屬性被訪問到并且賦值.然后才是發生上面的利用!

            0x02 總結


            任何使用commons-beanutils組件或內省(及反射)不安全實現表單參數綁定功能的框架,都會受影響(當然,我這里只測試了Tomcat,其他web容器感興趣的也可以測試一下利用思路!).

            J2EE規范在現今使用極廣了,但如果不是Struts2漏洞,或許很少有人關注Java安全,這點很是奇怪!

            Author:?Nebula, HelloWorld security team

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线