daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

1723-pentesting-pptp.md (10141B)


      1 ---
      2 title: "1723 - Pentesting PPTP"
      3 section: "Network Services"
      4 sectionSlug: "network-services-pentesting"
      5 sourcePath: "src/network-services-pentesting/1723-pentesting-pptp.md"
      6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/network-services-pentesting/1723-pentesting-pptp.md"
      7 sha: "188de82beb54e70956b2952367a0af91d26758b8"
      8 isIndex: false
      9 modified: true
     10 license: "CC-BY-NC-4.0"
     11 ---
     12 
     13 # 1723 - Pentesting PPTP
     14 
     15 ## Basic Information
     16 
     17 **Point-to-Point Tunneling Protocol (PPTP)** is an old VPN tunneling protocol used for **remote access**. It uses **TCP port 1723** for the control channel and **IP protocol 47** (**GRE**) to carry the PPP payload. The traffic inside the tunnel is commonly protected with **MPPE**, while authentication is frequently based on **MS-CHAPv2**.
     18 
     19 From an offensive perspective, the interesting part is usually not the control connection itself but the fact that **capturing a PPTP/MS-CHAPv2 handshake can enable offline password or NT-hash recovery**. Also remember that a host can answer on TCP/1723 while the tunnel still fails because **GRE (protocol 47) is filtered**.
     20 
     21 From an assessment perspective, exposed PPTP in 2026 is usually a **legacy signal**. Modern Microsoft guidance has started pushing it out of default deployments: **new RRAS setups on Windows Server 2025 don't accept PPTP by default**, and **MSCHAPv2-based WiFi/VPN connections are explicitly called out as being subject to NTLMv1-like attacks**. If you still find PPTP enabled externally, it often means an old compatibility path was kept alive on purpose.<sup>[[5]](#references)[[6]](#references)</sup>
     22 
     23 **Default Port**:1723
     24 
     25 ## Enumeration
     26 
     27 ```bash
     28 nmap -Pn -sSV -p1723 <IP>
     29 nmap -Pn -sV --script pptp-version -p1723 <IP>
     30 nmap -Pn -sO --protocol 47 <IP>
     31 ```
     32 
     33 `nmap`'s `pptp-version` NSE script can sometimes extract **hostname, vendor, or firmware** details from the PPTP control channel, which is useful for quickly spotting legacy routers/VPN concentrators.
     34 
     35 If you only confirm `tcp/1723` and miss GRE, you can easily get a false sense that the VPN is reachable. During troubleshooting or sniffing, capture both the control and encapsulated traffic:
     36 
     37 ```bash
     38 sudo tcpdump -ni <iface> 'tcp port 1723 or gre' -w pptp-handshake.pcap
     39 tshark -r pptp-handshake.pcap -Y 'pptp || gre || ppp || chap'
     40 ```
     41 
     42 If you are capturing **on the VPN endpoint itself** instead of from a SPAN/mirror port or another on-path vantage point, keep in mind that local PPP capture can be incomplete. On Linux in particular, normal libpcap capture on the PPP interface may miss PPP control traffic; for local troubleshooting you may need to capture the GRE packets on the physical interface or use `pppd record` style logging to preserve the control exchange.
     43 
     44 If you can influence the `pppd` invocation on a Linux client/server, the built-in recorder is often more reliable than sniffing `pppX`:
     45 
     46 ```bash
     47 # Add to the pppd options / peer file
     48 record /tmp/pptp.record
     49 
     50 # Decode the recorded PPP conversation later
     51 pppdump -p /tmp/pptp.record
     52 ```
     53 
     54 ### [Brute Force](https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/generic-hacking/brute-force.md#pptp)
     55 
     56 ## Attack Notes
     57 
     58 ### MS-CHAPv2 handshake capture
     59 
     60 For PPTP, the relevant material is the PPP authentication exchange transported inside GRE. In MS-CHAPv2 the response depends on:
     61 
     62 - The server **AuthenticatorChallenge**
     63 - The client **Peer-Challenge**
     64 - The **username**
     65 - The **NT-Response**
     66 
     67 That means a packet capture is often enough to move the attack offline. If you can sniff the initial connection, request the user to reconnect, or position yourself on-path, capture the handshake and extract the challenge/response data.
     68 
     69 Useful quick filters:
     70 
     71 ```bash
     72 tshark -r pptp-handshake.pcap -Y 'chap'
     73 tshark -r pptp-handshake.pcap -Y 'ppp and chap'
     74 ```
     75 
     76 ### Extract the exact MS-CHAPv2 fields with `tshark`
     77 
     78 Wireshark's CHAP dissector exposes enough data to script the extraction without relying only on `chapcrack`:
     79 
     80 ```bash
     81 tshark -r pptp-handshake.pcap -Y 'chap.code == 1 || chap.code == 2' \
     82   -T fields -e frame.number -e chap.code -e chap.identifier -e chap.value -e chap.name
     83 ```
     84 
     85 - `chap.code == 1` is the **server Challenge** packet; `chap.value` is the 16-byte **AuthenticatorChallenge**.
     86 - `chap.code == 2` is the **client Response** packet; `chap.value` is laid out as `PeerChallenge[16] | Reserved[8] | NT-Response[24] | Flags[1]`.
     87 - `chap.identifier` helps you match the correct Challenge and Response if the capture contains retries or multiple negotiations.
     88 - `chap.name` usually contains the username used in the exchange.
     89 
     90 Example split of a response `chap.value`:
     91 
     92 ```bash
     93 python3 - <<'PY'
     94 resp = bytes.fromhex('<chap.value from CHAP Response>')
     95 print('PeerChallenge =', resp[:16].hex())
     96 print('Reserved      =', resp[16:24].hex())
     97 print('NT-Response   =', resp[24:48].hex())
     98 print('Flags         =', f'{resp[48]:02x}')
     99 PY
    100 ```
    101 
    102 This is handy when you want to mass-process PCAPs, validate what `chapcrack` extracted, or feed the values into a custom `hashcat`/`asleap` conversion script.
    103 
    104 ### Convert the handshake into a `hashcat` workload
    105 
    106 For PPTP/MS-CHAPv2, the 24-byte `NT-Response` alone is not the full story. Per RFC 2759, the effective 8-byte challenge is derived from:<sup>[[3]](#references)</sup>
    107 
    108 - The server **AuthenticatorChallenge**
    109 - The client **Peer-Challenge**
    110 - The **UserName**
    111 
    112 In practice, this means you need to preserve those fields during extraction if you want to move from a packet capture into a modern GPU workflow. A useful pattern is:
    113 
    114 1. Parse the capture with `chapcrack` or `tshark`
    115 2. Extract the **username**, **peer-challenge**, **authenticator challenge**, and **NT-Response**
    116 3. Convert the result into a `hashcat`-compatible `NetNTLMv1/ESS` style line
    117 
    118 Do not throw away the rest of the response blob too early: in the CHAP Response `Value`, the **Peer-Challenge**, **reserved bytes**, **NT-Response**, and **flags** all sit next to each other, and parsing mistakes there are a common reason for uncrackable conversions.
    119 
    120 The exact `hashcat` representation commonly used for MS-CHAPv2 is:<sup>[[4]](#references)</sup>
    121 
    122 ```text
    123 <user>::<domain_or_blank>:<peer_challenge>:<nt_response>:<authenticator_challenge>
    124 ```
    125 
    126 Example attack:
    127 
    128 ```bash
    129 hashcat -m 5500 -a 0 mschapv2.hashes /usr/share/wordlists/rockyou.txt
    130 ```
    131 
    132 This is operationally useful when you want to keep everything local instead of sending a token to an external cracking service, or when you already have a tuned `hashcat` rules/masks workflow.
    133 
    134 ### Parse and decrypt with `chapcrack`
    135 
    136 `chapcrack` is still one of the cleanest ways to process a PPTP capture:<sup>[[1]](#references)</sup>
    137 
    138 ```bash
    139 chapcrack.py parse -i pptp-handshake.pcap
    140 ```
    141 
    142 If you recover the underlying secret material, you can decrypt the PPTP packet capture:
    143 
    144 ```bash
    145 chapcrack.py decrypt -i pptp-handshake.pcap -o pptp-decrypted.pcap -n <recovered_nt_hash_or_token>
    146 ```
    147 
    148 This is especially useful when the goal is not only credential recovery but also **session decryption** and post-auth traffic analysis.
    149 
    150 ### Crack challenge/response material
    151 
    152 If you already extracted the challenge/response pair, `asleap` can still be used directly against PPTP/MS-CHAPv2 material:
    153 
    154 ```bash
    155 asleap -C 58:16:d5:ac:4b:dc:e4:0f -R 50:ae:a3:0a:10:9e:28:f9:33:1b:44:b1:3d:9e:20:91:85:e8:2e:c3:c5:4c:00:23 -W /usr/share/wordlists/rockyou.txt
    156 ```
    157 
    158 `asleap` also supports working from packet captures or precomputed lookup tables, but for PPTP assessments the most common workflow is:
    159 
    160 1. Capture the PPTP handshake
    161 2. Extract the challenge/response
    162 3. Run offline cracking with `asleap`, `chapcrack`, or a custom workflow
    163 
    164 Recent tradecraft also includes **NT-hash-first** workflows such as `assless-chaps`, which recover the **NT hash** from MS-CHAPv2/NTLMv1 challenge-response material using a prepared hash database. This can be faster than conventional password cracking if you maintain a good NT-hash corpus:<sup>[[2]](#references)</sup>
    165 
    166 ```bash
    167 ./assless-chaps <challenge> <response> <hashes.db>
    168 ```
    169 
    170 This matters because for PPTP the recovered **NT hash is operationally valuable by itself**: once obtained, it can be used to validate the crack, decrypt captures, and pivot into Windows-oriented reuse checks.
    171 
    172 If you plan to use this at scale during assessments, the practical bottleneck is usually not the cracking step but maintaining a **good NT-hash database**. `assless-chaps` becomes especially useful when you can prebuild SQLite databases from breached NTLM corpora, HIBP-derived NT hashes, or aggressive in-house rule expansions generated with `hashcat`.<sup>[[2]](#references)</sup>
    173 
    174 ### Protocol weakness summary
    175 
    176 - PPTP depends on a **separate GRE data channel**, so firewalls often expose `tcp/1723` while silently breaking the tunnel.
    177 - **MS-CHAPv2 security effectively collapses to recovering DES-derived material / NT-hash-equivalent secrets**, making passive capture much more dangerous than with modern VPNs.
    178 - Even if the password is not immediately recovered, the handshake can usually be **stored and attacked offline later**.
    179 - In current enterprise environments, a reachable PPTP listener often indicates a **deliberately preserved legacy path**, not a default deployment, which makes it especially interesting for password-reuse and lateral-movement testing.
    180 
    181 ## References
    182 
    183 - [1] [moxie0/chapcrack](https://github.com/moxie0/chapcrack)
    184 - [2] [sensepost/assless-chaps](https://github.com/sensepost/assless-chaps)
    185 - [3] [RFC 2759 - Microsoft PPP CHAP Extensions, Version 2](https://www.rfc-editor.org/rfc/rfc2759.html)
    186 - [4] [hashcat - example hashes (mode 5500, MS-CHAPv2)](https://hashcat.net/wiki/doku.php?id=example_hashes)
    187 - [5] [Microsoft Learn - Configure VPN protocols on RRAS](https://learn.microsoft.com/en-us/windows-server/remote/remote-access/configure-vpn-protocols)
    188 - [6] [Microsoft Learn - Windows Defender Credential Guard considerations and known issues](https://learn.microsoft.com/en-us/windows/security/identity-protection/credential-guard/considerations-known-issues)