#!/usr/bin/env python3
# @Time    : 2020-02-17
# @Author  : caicai
# @File    : poc_iis_6.0_shortname.py
import copy
from myscan.config import scan_set
import socket
import ssl


class POC():
    def __init__(self, workdata):
        self.dictdata = workdata.get("dictdata")  # python的dict数据，详情请看docs/开发指南Example dict数据示例
        self.url = workdata.get("data")  # self.url为需要测试的url，值为目录url，会以/结尾,如https://www.baidu.com/home/ ,为目录
        self.result = []  # 此result保存dict数据，dict需包含name,url,level,detail字段，detail字段值必须为dict。如下self.result.append代码
        self.name = "iis 6.0 webdav rce "
        self.vulmsg = '''CVE-2017-7269，仅在windows2003版本出现，脚本使用socket，支持http和https，仅仅使用PROPFIND方法验证，如检测出，请使用
        https://github.com/zcgonvh/cve-2017-7269 工具验证"'''
        self.level = 3  # 0:Low  1:Medium 2:High

    def verify(self):
        # 根据config.py 配置的深度，限定一下目录深度
        if self.url.count("/") > int(scan_set.get("max_dir", 1)) + 2:
            return

        host = self.dictdata.get("url").get("host")
        port = self.dictdata.get("url").get("port")
        sendmsg = self.getsendmsg(port)
        recvdata = b""
        try:
            if self.dictdata.get("url").get("protocol") == "http":
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.settimeout(8)
                sock.connect((host, int(port)))
                sock.send(sendmsg)
                recvdata = sock.recv(4096)
                sock.close()
            else:
                context = ssl._create_unverified_context()
                with socket.create_connection((host, int(port))) as conn:
                    with context.wrap_socket(conn) as sconn:
                        sconn.send(sendmsg)
                        recvdata = sconn.recv(4096)
        except Exception as ex:
            pass
        if recvdata != b"" and b"Content-Type: text/xml" in recvdata and b"207 Multi-Status" in recvdata:
            self.result.append({
                "name": self.name,
                "url": self.url,
                "level": self.level,  # 0:Low  1:Medium 2:High
                "detail": {
                    "vulmsg": self.vulmsg,
                    "request": sendmsg,
                    "response": recvdata
                }
            })

    def getsendmsg(self, port):
        return b'PROPFIND / HTTP/1.1\r\nHost: localhost:' + str(port).encode() + b'\r\nContent-Length: 0\r\n\r\n'
