~sircmpwn/pass-rotate

ref: 7a0f1572c61de44c5ceed81c5d65c6830bc45865 pass-rotate/passrotate/providers/namecheap.py -rw-r--r-- 3.4 KiB
7a0f1572 — Matthias Gabriel add option to override the pass name to be used when rotating the password 4 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
from passrotate.provider import Provider, ProviderOption, PromptType, register_provider
from passrotate.forms import get_form
from urllib.parse import urlparse
from bs4 import BeautifulSoup
import base64
import requests

class Namecheap(Provider):
    """
    [namecheap.com]
    username=Your Namecheap username
    """
    name = "NameCheap"
    domains = [
        "namecheap.com"
    ]
    options = {
        "username": ProviderOption(str, "Your Namecheap username")
    }

    def __init__(self, options):
        self.username = options["username"]

    def prepare(self, old_password):
        # what the hell is wrong with you Namecheap
        self._session = requests.Session()
        r = self._session.get("https://www.namecheap.com/myaccount/login.aspx")
        form = get_form(r.text, type="body")
        form.update({
            "LoginUserName": self.username,
            "LoginPassword": "*************",
            "hidden_LoginPassword": base64.b64encode(old_password.encode()).decode().rstrip("="),
            "ctl00$ctl00$ctl00$ctl00$base_content$web_base_content$home_content$page_content_left$ctl02$LoginButton":
                "Sign in and Continue"
        })
        r = self._session.post("https://www.namecheap.com/myaccount/login.aspx", data=form)
        url = urlparse(r.url)
        if url.path == "/myaccount/login.aspx":
            raise Exception("Failed to log into Namecheap with current password")
        if url.path == "/myaccount/twofa/secondauth.aspx":
            form = get_form(r.text, id="aspnetForm")
            form.update({
                "ctl00$ctl00$ctl00$ctl00$base_content$web_base_content$home_content$page_content_left$CntrlAuthorization$ddlVerifyMethod":
                    "Text",
                "ctl00$ctl00$ctl00$ctl00$base_content$web_base_content$home_content$page_content_left$CntrlAuthorization$btnSendVerification":
                    "Send Security Code"
            })
            r = self._session.post("https://www.namecheap.com/myaccount/twofa/secondauth.aspx", data=form)
            if "You have reached the limit" in r.text:
                raise Exception("Namecheap has locked us out of further 2FA attempts. Wait 60 minutes and try again.")
            while url.path == "/myaccount/twofa/secondauth.aspx":
                form = get_form(r.text, id="aspnetForm")
                code = self.prompt("Enter your SMS authorization code", PromptType.sms)
                form.update({
                    "ctl00$ctl00$ctl00$ctl00$base_content$web_base_content$home_content$page_content_left$CntrlAuthorization$txtAuthVerification":
                        code,
                })
                r = self._session.post("https://www.namecheap.com/myaccount/twofa/secondauth.aspx", data=form)
                url = urlparse(r.url)
        r = self._session.get("https://ap.www.namecheap.com/Profile/Security")
        soup = BeautifulSoup(r.text, "html.parser")
        self._ncCompliance = soup.find("input", attrs={ "name": "ncCompliance" }).get("value", "")

    def execute(self, old_password, new_password):
        r = self._session.post("https://ap.www.namecheap.com/profile/security/password/change", data={
            "newPassword": new_password,
            "oldPassword": old_password,
        }, headers={
            "_NcCompliance": self._ncCompliance
        } ,allow_redirects=False)
        if r.status_code != 200:
            raise Exception("Failed to update NameCheap password")

register_provider(Namecheap)