-
Notifications
You must be signed in to change notification settings - Fork 130
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mitmproxy Certificate Issue #120
Comments
Yep, sounds like you've figured out the right answer here 👍. I did have a script that did this specifically at some point, but it was a couple years ago, and it appears that I've lost it… The simple mitmproxy examples should be a pretty good place to start. |
I was able to get the certificate replaced in the response using the following (cert_replacer.py): from bs4 import BeautifulSoup
from mitmproxy import http
class CertReplacer:
def response(self, flow: http.HTTPFlow) -> None:
xml = BeautifulSoup(flow.response.content, "lxml-xml")
if xml.policy and xml.policy.cert:
xml.policy.cert.string = "\n" + flow.server_conn.cert.to_pem().decode("utf-8")
flow.response.content = str(xml).encode("utf8")
addons = [CertReplacer()] and:
I've verified in the mitmproxy response output that the certificate is indeed being replaced in the XML response for the POST to https://vpn.example.com/global-protect/getconfig.esp, but I am still getting the same "The server certificate is invalid. Please contact your IT administrator" message on the client. I've verified that I added the mitmproxy root certificates to Windows correctly by visiting https://vpn.example.com/ in Microsoft Edge and do not observe any certificate errors/warnings and rebooted Windows entirely for good measure.
<?xml version="1.0" encoding="utf-8"?>
<policy>
<portal-name>EXAMPLE-GP-PORTAL</portal-name>
<portal-config-version>4100</portal-config-version>
<version>4.1.4-13 </version>
<client-role>global-protect-full</client-role>
<agent-user-override-key>****</agent-user-override-key>
<root-ca>
<entry name="EXAMPLE-LINUX-VPN">
<cert>
-----BEGIN CERTIFICATE-----
MIIGZDCCBUygAwIBAgIIM35AgIy/tuYwDQYJKoZIhvcNAQELBQAwgbQxCzAJBgNV
[snip]
G2RzopMtgJg=
-----END CERTIFICATE-----
</cert>
<install-in-cert-store>yes</install-in-cert-store>
</entry>
</root-ca>
<connect-method>on-demand</connect-method>
<on-demand>yes</on-demand>
<refresh-config>yes</refresh-config>
<refresh-config-interval>24</refresh-config-interval>
<authentication-modifier>
<none/>
</authentication-modifier>
<authentication-override>
<accept-cookie>no</accept-cookie>
<generate-cookie>no</generate-cookie>
<cookie-encrypt-decrypt-cert/>
</authentication-override>
<use-sso>yes</use-sso>
<ip-address/>
<host/>
<gateways>
<cutoff-time>5</cutoff-time>
<external>
<list>
<entry name="vpn.example.com">
<priority-rule>
<entry name="Any">
<priority>1</priority>
</entry>
</priority-rule>
<priority>1</priority>
<description>vpn.example.com</description>
</entry>
</list>
</external>
</gateways>
<gateways-v6>
<cutoff-time>5</cutoff-time>
<external>
<list>
<entry name="vpn.example.com">
<fqdn>vpn.example.com</fqdn>
<priority-rule>
<entry name="Any">
<priority>1</priority>
</entry>
</priority-rule>
<priority>1</priority>
</entry>
</list>
</external>
</gateways-v6>
<agent-ui>
<can-save-password>yes</can-save-password>
<passcode/>
<agent-user-override-timeout>0</agent-user-override-timeout>
<max-agent-user-overrides>0</max-agent-user-overrides>
<help-page/>
<welcome-page>
<display>no</display>
<page/>
</welcome-page>
<agent-user-override>allowed</agent-user-override>
<enable-advanced-view>yes</enable-advanced-view>
<enable-do-not-display-this-welcome-page-again>yes</enable-do-not-display-this-welcome-page-again>
<can-change-portal>yes</can-change-portal>
<show-agent-icon>yes</show-agent-icon>
<password-expiry-message/>
</agent-ui>
<hip-collection>
<hip-report-interval>3600</hip-report-interval>
<max-wait-time>20</max-wait-time>
<collect-hip-data>yes</collect-hip-data>
<default>
<category>
<member>host-info</member>
<member>data-loss-prevention</member>
<member>patch-management</member>
<member>firewall</member>
<member>antivirus</member>
<member>anti-spyware</member>
<member>disk-backup</member>
<member>disk-encryption</member>
</category>
</default>
</hip-collection>
<agent-config>
<save-user-credentials>1</save-user-credentials>
<portal-2fa>no</portal-2fa>
<internal-gateway-2fa>no</internal-gateway-2fa>
<auto-discovery-external-gateway-2fa>no</auto-discovery-external-gateway-2fa>
<manual-only-gateway-2fa>no</manual-only-gateway-2fa>
<client-upgrade>prompt</client-upgrade>
<logout-remove-sso>yes</logout-remove-sso>
<krb-auth-fail-fallback>yes</krb-auth-fail-fallback>
<retry-tunnel>30</retry-tunnel>
<retry-timeout>5</retry-timeout>
<enforce-globalprotect>no</enforce-globalprotect>
<captive-portal-exception-timeout>0</captive-portal-exception-timeout>
<traffic-blocking-notification-delay>15</traffic-blocking-notification-delay>
<display-traffic-blocking-notification-msg>yes</display-traffic-blocking-notification-msg>
<traffic-blocking-notification-msg><div style="font-family:'Helvetica Neue';"><h1 style="color:red;text-align:center; margin: 0; font-size: 30px;">Notice</h1><p style="margin: 0;font-size: 15px; line-height: 1.2em;">To access the network, you must first connect to GlobalProtect.</p></div></traffic-blocking-notification-msg>
<allow-traffic-blocking-notification-dismissal>yes</allow-traffic-blocking-notification-dismissal>
<display-captive-portal-detection-msg>no</display-captive-portal-detection-msg>
<captive-portal-detection-msg><div style="font-family:'Helvetica Neue';"><h1 style="color:red;text-align:center; margin: 0; font-size: 30px;">Captive Portal Detected</h1><p style="margin: 0; font-size: 15px; line-height: 1.2em;">GlobalProtect has temporarily permitted network access for you to connect to the Internet. Follow instructions from your internet provider.</p><p style="margin: 0; font-size: 15px; line-height: 1.2em;">If you let the connection time out, open GlobalProtect and click Connect to try again.</p></div></captive-portal-detection-msg>
<certificate-store-lookup>user-and-machine</certificate-store-lookup>
<scep-certificate-renewal-period>7</scep-certificate-renewal-period>
<ext-key-usage-oid-for-client-cert/>
<retain-connection-smartcard-removal>yes</retain-connection-smartcard-removal>
<rediscover-network>yes</rediscover-network>
<resubmit-host-info>yes</resubmit-host-info>
<can-continue-if-portal-cert-invalid>yes</can-continue-if-portal-cert-invalid>
<user-switch-tunnel-rename-timeout>0</user-switch-tunnel-rename-timeout>
<pre-logon-tunnel-rename-timeout>-1</pre-logon-tunnel-rename-timeout>
<show-system-tray-notifications>no</show-system-tray-notifications>
<max-internal-gateway-connection-attempts>0</max-internal-gateway-connection-attempts>
<portal-timeout>30</portal-timeout>
<connect-timeout>60</connect-timeout>
<receive-timeout>30</receive-timeout>
<enforce-dns>yes</enforce-dns>
<flush-dns>no</flush-dns>
<proxy-multiple-autodetect>no</proxy-multiple-autodetect>
<wsc-autodetect>yes</wsc-autodetect>
<mfa-enabled>no</mfa-enabled>
<mfa-listening-port>4501</mfa-listening-port>
<mfa-trusted-host-list/>
<mfa-notification-msg>You have attempted to access a protected resource that requires additional authentication. Proceed to authenticate at</mfa-notification-msg>
<ipv6-preferred>yes</ipv6-preferred>
</agent-config>
<portal-userauthcookie>empty</portal-userauthcookie>
<portal-prelogonuserauthcookie>empty</portal-prelogonuserauthcookie>
<scep-cert-auth-cookie>-AQ==P[snip]jExsgmHA==</scep-cert-auth-cookie>
</policy> |
In looking through that XML, the only thing I see that might be problematic is the pair of: Does this mean that this cookie is somehow entangled with the certificate I'm replacing? |
Nice 👍. My old version was 💯× uglier. I think I see the problem.
However, with the client version that I tested, you can also just empty this whole section (replace with
I don't think so. One other thing you may run into: some old versions of the official client get confused trying to do DNS when connected through a proxy. In that case, you'll have to replace the gateway hostnames ( |
I got really excited because of course it's called I think you're on to something with the DNS suggestion, but I think it may be more complex than just switching the After striking out, I dug into the logs on Windows and see (in PanGPS.log):
From the log messages, it almost looks like the client is resolving the domain name to an IP address, then making a request with the IP directly, causing mitmproxy to generate a cert with the IP instead of the domain name in the CN. But if I look at I'll work on this more when I have time, but figured I'd post my progress (or lack thereof) in case you had further insight. Thanks for your help so far! |
Just double-checking… are you running mitmproxy with this option? (It's required to get mitmproxy to connect to servers which it itself doesn't consider secure.) Another user reminded me of this at #118 (comment)
|
Doh! I assumed that if I was seeing traffic to the gateway that I didn't need the Thanks! |
I'm attempting to use openconnect with GlobalProtect and Okta and am having some issues. I've got mitmproxy setup to attempt to see what's going on, but GlobalProtect on Windows says "The server certificate is invalid. Please contact your IT administrator" when I attempt to use it over the proxy.
I saw you mentioned writing a python shim in #78 (comment) to work around this certificate issue - do you have any more detailed pointers on that, or even an example script you could share?
I've dug around a little, and my initial guess is that I need to figure out how to script mitmproxy to replace the "-----BEGIN CERTIFICATE-----" block with my mitmproxy cert?
The text was updated successfully, but these errors were encountered: