最近在弄点蛋疼的东西.爬虫,扫描。扫描交给sqlmapapi来进行.现在的资料不是很多,但是还是可以找到一些
《使用sqlmapapi.py批量化扫描实践》http://drops.wooyun.org/tips/6653
看看他所封装的sqlmapapi的类
#!/usr/bin/python
#-*-coding:utf-8-*-
import requests
import time
import json
class AutoSqli(object):
"""
使用sqlmapapi的方法进行与sqlmapapi建立的server进行交互
By Manning
"""
def __init__(self, server='', target='',data = '',referer = '',cookie = ''):
super(AutoSqli, self).__init__()
self.server = server
if self.server[-1] != '/':
self.server = self.server + '/'
self.target = target
self.taskid = ''
self.engineid = ''
self.status = ''
self.data = data
self.referer = referer
self.cookie = cookie
self.start_time = time.time()
#新建扫描任务
def task_new(self):
self.taskid = json.loads(
requests.get(self.server + 'task/new').text)['taskid']
print 'Created new task: ' + self.taskid
#得到taskid,根据这个taskid来进行其他的
if len(self.taskid) > 0:
return True
return False
#删除扫描任务
def task_delete(self):
if json.loads(requests.get(self.server + 'task/' + self.taskid + '/delete').text)['success']:
print '[%s] Deleted task' % (self.taskid)
return True
return False
#扫描任务开始
def scan_start(self):
headers = {'Content-Type': 'application/json'}
#需要扫描的地址
payload = {'url': self.target}
url = self.server + 'scan/' + self.taskid + '/start'
#http://127.0.0.1:8557/scan/xxxxxxxxxx/start
t = json.loads(
requests.post(url, data=json.dumps(payload), headers=headers).text)
self.engineid = t['engineid']
if len(str(self.engineid)) > 0 and t['success']:
print 'Started scan'
return True
return False
#扫描任务的状态
def scan_status(self):
self.status = json.loads(
requests.get(self.server + 'scan/' + self.taskid + '/status').text)['status']
if self.status == 'running':
return 'running'
elif self.status == 'terminated':
return 'terminated'
else:
return 'error'
#扫描任务的细节
def scan_data(self):
self.data = json.loads(
requests.get(self.server + 'scan/' + self.taskid + '/data').text)['data']
if len(self.data) == 0:
print 'not injection:\t'
else:
print 'injection:\t' + self.target
#扫描的设置,主要的是参数的设置
def option_set(self):
headers = {'Content-Type': 'application/json'}
option = {"options": {
"smart": True,
...
}
}
url = self.server + 'option/' + self.taskid + '/set'
t = json.loads(
requests.post(url, data=json.dumps(option), headers=headers).text)
print t
#停止扫描任务
def scan_stop(self):
json.loads(
requests.get(self.server + 'scan/' + self.taskid + '/stop').text)['success']
#杀死扫描任务进程
def scan_kill(self):
json.loads(
requests.get(self.server + 'scan/' + self.taskid + '/kill').text)['success']
def run(self):
if not self.task_new():
return False
self.option_set()
if not self.scan_start():
return False
while True:
if self.scan_status() == 'running':
time.sleep(10)
elif self.scan_status() == 'terminated':
break
else:
break
print time.time() - self.start_time
if time.time() - self.start_time > 3000:
error = True
self.scan_stop()
self.scan_kill()
break
self.scan_data()
self.task_delete()
print time.time() - self.start_time
if __name__ == '__main__':
t = AutoSqli('http://127.0.0.1:8774', 'http://192.168.3.171/1.php?id=1')
t.run()
它的工作过程是
get请求创建任务, 获取到任务id
get请求特定的任务id设置参数
post请求特定的任务id开始扫描指定url
get请求特定的任务id获取状态
get请求特定的任务id获取测试结果
get请求特定的任务id删除任务
进入到lib/utils/api.py的server类,可以发现通过向server提交数据进行与服务的交互。 一共分为3种类型。
Users’ methods 用户方法
Admin function 管理函数
sqlmap core interact functions 核心交互函数
可以提交数据的种类如下。
用户方法
@get("/task/new")
@get("/task//delete")
管理函数
@get("/admin//list")
@get("/admin//flush")
核心交互函数
@get("/option//list")
@post("/option//get")
@post("/option//set")
@post("/scan//start")
@get("/scan//stop")
@get("/scan//kill")
@get("/scan//status")
@get("/scan//data")
@get("/scan//log//")
@get("/scan//log")
@get("/download///")
最后对于是否是有注入漏洞, 代码里面是这么判断的, 如果返回的字典中, data里面有值, 那么就有注入
然后从https://github.com/smarttang/w3a_Scan_Console/blob/master/module/sprider_module.py里面得到爬虫模块.稍微整合一下
#!/usr/bin/python
# vim: set fileencoding=utf-8:
import sys
import urllib2
import re
from BeautifulSoup import BeautifulSoup
import autosql
class SpriderUrl:
# 初始化
def __init__(self,url):
self.url=url
#self.con=Db_Connector('sprider.ini')
#获得目标url的第一次url清单
def get_self(self):
urls=[]
try:
body_text=urllib2.urlopen(self.url).read()
except:
print "[*] Web Get Error:checking the Url"
soup=BeautifulSoup(body_text)
links=soup.findAll('a')
for link in links:
# 获得了目标的url但还需要处理
_url=link.get('href')
# 接着对其进行判断处理
# 先判断它是否是无意义字符开头以及是否为None值
# 判断URL后缀,不是列表的不抓取
if re.match('^(javascript|:;|#)',_url) or _url is None or re.match('.(jpg|png|bmp|mp3|wma|wmv|gz|zip|rar|iso|pdf|txt|db)$',_url):
continue
# 然后判断它是不是http|https开头,对于这些开头的都要判断是否是本站点, 不做超出站点的爬虫
if re.match('^(http|https)',_url):
if not re.match('^'+self.url,_url):
continue
else:
urls.append(_url)
else:
urls.append(self.url+_url)
rst=list(set(urls))
for rurl in rst:
try:
self.sprider_self_all(rurl)
# 进行递归,但是缺点太明显了,会对全部的页面进行重复递归。然后递交进入autosql
# AutoSqli('http://127.0.0.1:8775', rurl).run
except:
print "spider error"
def sprider_self_all(self,domain):
urls=[]
try:
body_text=urllib2.urlopen(domain).read()
except:
print "[*] Web Get Error:checking the Url"
sys.exit(0)
soup=BeautifulSoup(body_text)
links=soup.findAll('a')
for link in links:
# 获得了目标的url但还需要处理
_url=link.get('href')
# 接着对其进行判断处理
# 先判断它是否是无意义字符开头以及是否为None值
# 判断URL后缀,不是列表的不抓取
try:
if re.match('^(javascript|:;|#)',str(_url)) or str(_url) is None or re.match('.(jpg|png|bmp|mp3|wma|wmv|gz|zip|rar|iso|pdf|txt|db)$',str(_url)):
continue
except TypeError:
print "[*] Type is Error! :"+str(_url)
continue
# 然后判断它是不是http|https开头,对于这些开头的都要判断是否是本站点, 不做超出站点的爬虫
if re.match('^(http|https)',_url):
if not re.match('^'+self.url,_url):
continue
else:
urls.append(_url)
else:
urls.append(self.url+_url)
res=list(set(urls))
for rurl in res:
try:
print rurl
#AutoSqli('http://127.0.0.1:8775', rurl).run
except:
print "spider error"
spi="http://0day5.com/"
t=SpriderUrl(spi)
# # 第一次捕获
t.get_self()
最好的办法还是存进数据库里面,然后检查是否重复。
for rurl in res:
if self.con.find_item("select * from url_sprider where url='"+rurl+"' and domain='"+self.url+"'"):
continue
else:
try:
self.con.insert_item("insert into url_sprider(url,tag,domain)values('"+rurl+"',0,'"+self.url+"')")
except:
print "[*] insert into is Error!"
注:本文无法朔源,暂只标注转载链接,后续发现本文作者将补齐作者链接。