了解Rasp - RASP VS WAF & 簡單分析

0x01 引言


RASP(Runtime application self-protection)運行時應用自我保護罕扎,是一種植入到應用程序內(nèi)部或其運行時環(huán)境的安全技術(shù)。RASP可將自身注入到應用程序中,與應用程序融為一體,實時監(jiān)測记焊、阻斷攻擊,使程序自身擁有自保護的能力终吼。

實時監(jiān)測烛愧、阻斷攻擊這兩個詞看好像與waf(Web Application Firewall,web應用防護系統(tǒng))很像希痴,那它們有什么不同之處呢者甲?RASP到底是做什么的?實現(xiàn)原理是什么润梯?一場”修行”又開始了过牙。

0x02 RASP vs WAF


1、簡介

  • WAF

    Web應用防火墻是通過執(zhí)行一系列針對HTTP/HTTPS的安全策略來專門為Web應用提供保護的一款產(chǎn)品纺铭。

    聊點陽間的東西寇钉,waf就好像“WEB應用小區(qū)”的門衛(wèi),門衛(wèi)手里有個小冊子(俗稱特征庫:存放以往來小區(qū)做壞事的壞蛋特征如壞蛋總是戴頭套)舶赔。當小區(qū)外邊人要進小區(qū)串門的時候扫倡,它就會攔下來問:來者何人?并根據(jù)這個人的特征和手里的小冊子核對,如果沒有“在案”的壞蛋特征撵溃,就一律放行疚鲤。

    從壞人的角度看,似乎這樣的門衛(wèi)并非無懈可擊缘挑,壞人可以換裝集歇、整容等等手段去騙過門衛(wèi)。

  • RASP

    RASP(Runtime application self-protection)運行時應用自我保護语淘,是一種植入到應用程序內(nèi)部或其運行時環(huán)境的安全技術(shù)诲宇。RASP可將自身注入到應用程序中,與應用程序融為一體惶翻,實時監(jiān)測姑蓝、阻斷攻擊,使程序自身擁有自保護的能力吕粗。

    聊點陽間的東西纺荧,相當于在小區(qū)里每家每戶都安排了一位管家,無事不登三寶殿颅筋,壞人進入小區(qū)肯定是要干壞事的宙暇,所以RASP思路就是:你戴不戴頭套我不管,就看你做不做出格(攻擊動作)的事议泵。

    就好像客给,越獄的方法千萬種,總要離開牢房肢簿;撩妹的手段永遠在變花樣靶剑,但目標都是...

2、部署&產(chǎn)品特性

  • WAF

    • 外部邊界入口統(tǒng)一部署

    • 支持串聯(lián)池充、旁路桩引、反向代理三種方式部署

    • 容易形成單點故障,影響面大

    簡單說就是收夸,如果小區(qū)門口門衛(wèi)今天喝多了坑匠,可能在門口睡著了導致小區(qū)的人不管好的壞的都進不去。

  • RASP

    • 服務器上單獨部署卧惜,嵌入在應用程序內(nèi)部厘灼,應用代碼無感知

    • 與開發(fā)語言強相關(guān),但防護插件可共用

產(chǎn)品特性對比如下:

a57a6de47b9031c1d923bf55d700505e.png

3咽瓷、性能&檢測能力

  • WAF

    • 規(guī)則越多设凹,匹配時對性能消耗就越大

    • 和硬件配置相關(guān)

    • 對服務器CPU無影響

    • 業(yè)務報文多一次轉(zhuǎn)發(fā),延遲變大

  • RASP

    • 只在關(guān)鍵點檢測茅姜,不是所有請求都匹配所有規(guī)則

    • 對服務器CPU性能有消耗

    • 非防護狀態(tài)延遲增大3-5%闪朱,防護狀態(tài)延遲增大4.6 – 8.9%

檢測能力對比如下:

e2e2cd15-d1bc-4b24-bd97-bbdf2b83a7a9.png

百度Openrasp 官方檢測能力說明:https://rasp.baidu.com/doc/usage/web.html

4、優(yōu)劣分析

接著聊小區(qū)門衛(wèi)與管家的事兒,列舉幾個關(guān)鍵點:

1)門衛(wèi)手里有個小冊子(俗稱特征庫:存放以往來小區(qū)做壞事的壞蛋特征如壞蛋總是戴頭套)

Waf誤報多奋姿,壞蛋總是戴頭套锄开,但不一定戴頭套的全是壞人。

Waf維護成本高称诗,小冊子需要不斷更新添加新的特征萍悴。

Waf漏報多容易被繞過,小冊子要在發(fā)生偷盜事件后再去更新特征比較被動寓免,而且壞人騙過門衛(wèi)的手段太多了退腥,換衣服、化妝再榄、整容等等。

2)RASP 相當于在小區(qū)里每家每戶都安排了一位管家&你戴不戴頭套我不管享潜,就看你做不做出格(攻擊動作)的事

Rasp檢測更全面精準困鸥,每家每戶都安排一位管家肯定比小區(qū)門口的門衛(wèi)更了解每家每戶的情況。

Rasp漏洞響應更快可預防未知漏洞剑按,不過多新的偷盜方法肯定要有把錢裝到口袋的動作疾就,不管是0day還是Nday都要獲取權(quán)限執(zhí)行命令。

Rasp消耗服務器資源多艺蝴,Waf是一個門衛(wèi)放小區(qū)門口就行猬腰,Rasp可能需要N多個管家安排到每家每戶。

Rasp技術(shù)棧太多時使用不方便猜敢,需要根據(jù)業(yè)務不同開發(fā)語言姑荷、開發(fā)不同語言的探針。

0x03 以O(shè)penRasp為例了解實現(xiàn)原理


經(jīng)過簡單的對比我們已經(jīng)對RASP有了一定了解缩擂,那它是怎么實現(xiàn)的呢鼠冕?下面以百度的OpenRasp 為例看看它的實現(xiàn)原理。

閱讀官方文檔胯盯,發(fā)現(xiàn)啟動方式為:

java -javaagent:/opt/spring-boot/rasp/rasp.jar -jar XXX.jar

java -h
     -javaagent:<jar 路徑>[=<選項>]
                  加載 Java 編程語言代理, 請參閱 java.lang.instrument

發(fā)現(xiàn)是用到了探針技術(shù)懈费,原理見:

了解完Java 探針的原理后我們來簡單看下OpenRasp的實現(xiàn)原理,可以發(fā)現(xiàn)其入口同樣是premainagentmain方法博脑,并且都會在pox.xml中標注:

<!--pom.xml-->

    <manifestEntries>
      <Premain-Class>com.baidu.openrasp.Agent</Premain-Class>
      <Agent-Class>com.baidu.openrasp.Agent</Agent-Class>
      <Main-Class>com.baidu.openrasp.Agent</Main-Class>
      <Can-Redefine-Classes>true</Can-Redefine-Classes>
      <Can-Retransform-Classes>true</Can-Retransform-Classes>
  </manifestEntries>

// 所以入口就是 com.baidu.openrasp.Agent

        /**
     * 啟動時加載的agent入口方法
     *
     * @param agentArg 啟動參數(shù)
     * @param inst     {@link Instrumentation}
     */
    public static void premain(String agentArg, Instrumentation inst) {
        init(START_MODE_NORMAL, START_ACTION_INSTALL, inst);
    }

    /**
     * attach 機制加載 agent
     *
     * @param agentArg 啟動參數(shù)
     * @param inst     {@link Instrumentation}
     */
    public static void agentmain(String agentArg, Instrumentation inst) {
        init(Module.START_MODE_ATTACH, agentArg, inst);
    }

繼續(xù)往下看憎乙,在com.baidu.openrasp.transformer.CustomClassTransformer.java為Instrumentation注冊了transformer,從此之后的類加載都會被Transformer攔截。

    public CustomClassTransformer(Instrumentation inst) {
        this.inst = inst;
        inst.addTransformer(this, true);    // 注冊Transformer
        addAnnotationHook();    // 加載所有hook點
    }

接著我們來看攔截后的操作:

    /**
     * 過濾需要hook的類叉趣,進行字節(jié)碼更改
     *
     * @see ClassFileTransformer#transform(ClassLoader, String, Class, ProtectionDomain, byte[])
     */
    @Override
    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
                            ProtectionDomain domain, byte[] classfileBuffer) throws IllegalClassFormatException {
        if (loader != null) {
            DependencyFinder.addJarPath(domain);
        }
        if (loader != null && jspClassLoaderNames.contains(loader.getClass().getName())) {
            jspClassLoaderCache.put(className.replace("/", "."), new SoftReference<ClassLoader>(loader));
        }
        for (final AbstractClassHook hook : hooks) {
            if (hook.isClassMatched(className)) {   
                CtClass ctClass = null;
                try {
                    ClassPool classPool = new ClassPool();
                    addLoader(classPool, loader);
                    ctClass = classPool.makeClass(new ByteArrayInputStream(classfileBuffer));
                    if (loader == null) {
                        hook.setLoadedByBootstrapLoader(true);
                    }
                    classfileBuffer = hook.transformClass(ctClass);
                    if (classfileBuffer != null) {
                        checkNecessaryHookType(hook.getType());
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (ctClass != null) {
                        ctClass.detach();
                    }
                }
            }
        }
        serverDetector.detectServer(className, loader, domain);
        return classfileBuffer;
    }

可以看到在這里hook.isClassMatched(className)檢測當前攔截的類是否為已經(jīng)注冊的hook的類泞边,如果是的話則利用javassist的方法創(chuàng)建ctClass = classPool.makeClass(new ByteArrayInputStream(classfileBuffer));, javassist 與之前文章中提到的ASM相似都是修改字節(jié)碼的工具,想了解的可以的官方搜一下使用方法疗杉。

在這里classfileBuffer = hook.transformClass(ctClass); 獲取處理后的字節(jié)碼繁堡,展開看下代碼:

    /**
     * 轉(zhuǎn)化目標類
     *
     * @param ctClass 待轉(zhuǎn)化的類
     * @return 轉(zhuǎn)化之后類的字節(jié)碼數(shù)組
     */
    public byte[] transformClass(CtClass ctClass) {
        try {
            hookMethod(ctClass);
            return ctClass.toBytecode();
        } catch (Throwable e) {
            if (Config.getConfig().isDebugEnabled()) {
                LOGGER.info("transform class " + ctClass.getName() + " failed", e);
            }
        }
        return null;
    }

這里直接調(diào)用具體hook類的hookMethod(ctClass);方法來執(zhí)行具體的邏輯,完成字節(jié)碼的生成及寫入,如OgnlHook#hookMethod代碼示例如下:

    /**
     * (none-javadoc)
     *
     * @see com.baidu.openrasp.hook.AbstractClassHook#hookMethod(CtClass)
     */
    @Override
    protected void hookMethod(CtClass ctClass) throws IOException, CannotCompileException, NotFoundException {
        String src = getInvokeStaticSrc(OgnlHook.class, "checkOgnlExpression",
                "$_", Object.class);
        insertAfter(ctClass, "topLevelExpression", null, src);
    }

    /**
     * struct框架ognl語句解析hook點
     *
     * @param object ognl語句
     */
    public static void checkOgnlExpression(Object object) {

        if (object != null) {
            String expression = String.valueOf(object);
            if (expression.length() >= Config.getConfig().getOgnlMinLength()) {
                HashMap<String, Object> params = new HashMap<String, Object>();
                params.put("expression", expression);
                HookHandler.doCheck(CheckParameter.Type.OGNL, params);
            }
        }
    }

getInvokeStaticSrc用于獲取調(diào)用靜態(tài)方法的代碼字符串椭蹄,然后通過insertAfter在目標類的目標方法的出口插入相應的源代碼闻牡,從而完成一次對字節(jié)碼的修改操作。

今天就先到這兒吧绳矩,要去團建...感興趣的朋友也可以看下這篇文章實際操作一遍罩润。

https://mp.weixin.qq.com/s/LtoDe353uXPA8oT2D9FE8A


參考鏈接:

http://blog.nsfocus.net/rasp-tech/
http://blog.nsfocus.net/openrasp-tech/
https://www.freebuf.com/articles/network/167166.html    // 文章比喻的寫法是參考這篇文章去寫的,很有意思建議大家看下原文
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末翼馆,一起剝皮案震驚了整個濱河市割以,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌应媚,老刑警劉巖严沥,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異中姜,居然都是意外死亡消玄,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門丢胚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來翩瓜,“玉大人,你說我怎么就攤上這事携龟⊥玫” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵峡蟋,是天一觀的道長坟桅。 經(jīng)常有香客問我,道長蕊蝗,這世上最難降的妖魔是什么桦卒? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮匿又,結(jié)果婚禮上方灾,老公的妹妹穿的比我還像新娘。我一直安慰自己碌更,他們只是感情好裕偿,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著痛单,像睡著了一般嘿棘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上旭绒,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天鸟妙,我揣著相機與錄音焦人,去河邊找鬼。 笑死重父,一個胖子當著我的面吹牛花椭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播房午,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼矿辽,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了郭厌?” 一聲冷哼從身側(cè)響起袋倔,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎折柠,沒想到半個月后宾娜,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡扇售,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年前塔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缘眶。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖髓废,靈堂內(nèi)的尸體忽然破棺而出巷懈,到底是詐尸還是另有隱情,我是刑警寧澤慌洪,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布顶燕,位于F島的核電站,受9級特大地震影響冈爹,放射性物質(zhì)發(fā)生泄漏涌攻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一频伤、第九天 我趴在偏房一處隱蔽的房頂上張望恳谎。 院中可真熱鬧,春花似錦憋肖、人聲如沸因痛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鸵膏。三九已至,卻和暖如春怎炊,著一層夾襖步出監(jiān)牢的瞬間谭企,已是汗流浹背廓译。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留债查,地道東北人非区。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像攀操,于是被迫代替她去往敵國和親院仿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容