ancwrd1 / snx-rs

Open Source Linux Client For Check Point VPN Tunnels
GNU Affero General Public License v3.0
120 stars 9 forks source link

login type `vpn_Cert_Username_Password` does not work #29

Closed Znuff closed 4 months ago

Znuff commented 4 months ago

As per title, my server responds with:

Supported tunnel protocols:
        IPSec
        SSL
        L2TP
Available login types:
        vpn_Cert_Username_Password (Certificate + Username Password)

I'm trying to use something like:

./snx-rs --mode standalone --server-name <IP> --cert-type pkcs12 --cert-path USERNAME.pfx --cert-password "CERT_PASS" --login-type vpn_Cert_Username_Password --user-name "USERNAME" --password "BASE64_PASS"  --log-level trace --tunnel-type ssl --ignore-server-cert true

I've tried with version 2.0.2, 2.1.0, 2.2.0 and latest 2.2.7, and none worked.

The initial server reply is:

2024-07-31T02:06:19.091904Z TRACE snxcore::ccc: Reply from server: (CCCserverResponse
        :ResponseHeader (
                :id (2)
                :type (ClientHello)
                :session_id ()
                :return_code (600)
        )
        :ResponseData (
                :protocol_version (
                        :protocol_version (100)
                        :features (0x1)
                )
                :upgrade_configuration (
                        :available_client_version (0)
                        :client_upgrade_url ()
                        :upgrade_mode (ask_user)
                )
                :connectivity_info (
                        :default_authentication_method (legacy)
                        :client_enabled (true)
                        :supported_data_tunnel_protocols (
                                : (IPSec)
                                : (SSL)
                                : (L2TP)
                        )
                        :connectivity_type (IPSec)
                        :server_ip (10.0.0.101)
                        :ipsec_transport (auto_detect)
                        :tcpt_port (443)
                        :natt_port (4500)
                        :connect_with_certificate_url ("/clients/cert/")
                        :cookie_name (CPCVPN_SESSION_ID)
                        :internal_ca_fingerprint (
                                :1 (637377740f767c7678016b716a770c666167091f160c0e13020d666c0f0d1608757417040a131c1a1d0d70011b60776b0d170e660e0b037e)
                        )
                )
                :end_point_security (
                        :ics (
                                :run_ics (false)
                                :ics_base_url ("/clients/ICS/components")
                                :ics_version (403006000)
                                :ics_upgrade_url ("/clients/ICS/components/icsweb.cab")
                                :ics_images_url ("/clients/ICS/components/ICS_images.cab")
                                :ics_images_ver (403006000)
                                :ics_cab_url ("/clients/ICS/components/cl_ics.cab")
                                :ics_cab_version ("994000010
")
                        )
                )
                :login_options_data (
                        :login_options_list (
                                :0 (
                                        :id (vpn_Cert_Username_Password)
                                        :secondary_realm_hash (44f683a84163b3523afe57c2e008bc8c)
                                        :display_name ("Certificate + Username Password")
                                        :show_realm (1)
                                        :factors (
                                                :0 (
                                                        :factor_type (certificate)
                                                        :securid_card_type ()
                                                        :certificate_storage_type (any)
                                                        :custom_display_labels (
                                                                :header ("Please provide certificate in order to authenticate")
                                                        )
                                                )
                                                :1 (
                                                        :factor_type (password)
                                                        :securid_card_type ()
                                                        :certificate_storage_type ()
                                                        :custom_display_labels (
                                                                :header ("Additional authentication required, please provide password to authenticate")
                                                                :username ("User name")
                                                                :password (Password)
                                                        )
                                                )
                                        )
                                )
                        )
                        :login_options_md5 (ff41d4c3578affbfa98a1f96b582feb4)
                )
        )
)

2.0.2 returns:

2024-07-31T02:12:02.727206Z DEBUG snxcore::tunnel::connector: Authenticating to endpoint: SERVER_IP
2024-07-31T02:12:02.727917Z  WARN snxcore::ccc: Disabling all certificate checks!!!
2024-07-31T02:12:02.749411Z TRACE snxcore::ccc: Request to server: (CCCclientRequest
        :RequestData (
                :client_logging_data (
                        :os_name ("Android"))
                :client_type (SYMBIAN)
                :selectedLoginOption (vpn_Cert_Username_Password))
        :RequestHeader (
                :id (3)
                :type (CertAuth)))
2024-07-31T02:12:02.753902Z TRACE hyper_util::client::legacy::pool: checkout waiting for idle connection: ("https", SERVER_IP)
2024-07-31T02:12:02.754288Z TRACE hyper_util::client::legacy::connect::http: Http::connect; scheme=Some("https"), host=Some("SERVER_IP"), port=None
2024-07-31T02:12:02.754585Z DEBUG hyper_util::client::legacy::connect::http: connecting to SERVER_IP:443
2024-07-31T02:12:02.763222Z DEBUG hyper_util::client::legacy::connect::http: connected to SERVER_IP:443
2024-07-31T02:12:02.793661Z TRACE hyper_util::client::legacy::client: http1 handshake complete, spawning background dispatcher task
2024-07-31T02:12:02.794354Z TRACE hyper_util::client::legacy::pool: checkout dropped for ("https", SERVER_IP)
2024-07-31T02:12:02.839457Z TRACE snxcore::ccc: Reply from server: (CCCserverResponse
        :ResponseHeader (
                :id (3)
                :type (CertAuth)
                :session_id ()
                :return_code (600)
        )
        :ResponseData (
                :authn_status (done)
                :is_authenticated (false)
                :error_message (485a5f4d4832652b275a312957425b263121432124653a562a017268702b3759394320653a352c272c6c)
                :error_code (106)
        )
)

2024-07-31T02:12:02.847934Z  WARN snxcore::tunnel::connector: Authentication failed!
Error: Authentication failed!

2.1.0 and 2.2.0 return:

2024-07-31T02:10:03.800760Z DEBUG snxcore::tunnel::ssl::connector: Authenticating to endpoint: SERVER_IP
2024-07-31T02:10:03.801181Z  WARN snxcore::ccc: Disabling all certificate checks!!!
2024-07-31T02:10:03.814394Z TRACE snxcore::ccc: Request to server: (CCCclientRequest
        :RequestData (
                :client_logging_data (
                        :os_name ("Android"))
                :client_type (SYMBIAN)
                :selectedLoginOption (vpn_Cert_Username_Password))
        :RequestHeader (
                :id (3)
                :type (CertAuth)))
2024-07-31T02:10:03.817054Z TRACE hyper_util::client::legacy::pool: checkout waiting for idle connection: ("https", SERVER_IP)
2024-07-31T02:10:03.817367Z TRACE hyper_util::client::legacy::connect::http: Http::connect; scheme=Some("https"), host=Some("SERVER_IP"), port=None
2024-07-31T02:10:03.817648Z DEBUG hyper_util::client::legacy::connect::http: connecting to SERVER_IP:443
2024-07-31T02:10:03.825902Z DEBUG hyper_util::client::legacy::connect::http: connected to SERVER_IP:443
2024-07-31T02:10:03.854514Z TRACE hyper_util::client::legacy::client: http1 handshake complete, spawning background dispatcher task
2024-07-31T02:10:03.855088Z TRACE hyper_util::client::legacy::pool: checkout dropped for ("https", SERVER_IP)
2024-07-31T02:10:03.899208Z TRACE snxcore::ccc: Reply from server: (CCCserverResponse
        :ResponseHeader (
                :id (3)
                :type (CertAuth)
                :session_id ()
                :return_code (600)
        )
        :ResponseData (
                :authn_status (done)
                :is_authenticated (false)
                :error_message (485a5f4d4832652b275a312957425b263121432124653a562a017268702b3759394320653a352c272c6c)
                :error_code (106)
        )
)

2024-07-31T02:10:03.904919Z  WARN snxcore::tunnel::ssl::connector: Authentication failed!
Error: Authentication failed!

While 2.2.7 throws out a 599 issue, probably related to #26:

2024-07-31T03:37:15.466184Z DEBUG snxcore::tunnel::ssl::connector: Authenticating to endpoint: SERVER_IP
2024-07-31T03:37:15.466542Z  WARN snxcore::ccc: Disabling all certificate checks!!!
2024-07-31T03:37:15.480402Z TRACE snxcore::ccc: Request to server: (CCCclientRequest
        :RequestData (
                :client_logging_data (
                        :device_id ("{7F72264F-D07C-5240-A8EC-19760E79F781}")
                        :os_name (Windows))
                :client_type (TRAC)
                :selectedLoginOption (vpn_Cert_Username_Password))
        :RequestHeader (
                :id (3)
                :type (CertAuth)))
2024-07-31T03:37:15.480511Z TRACE hyper_util::client::legacy::pool: checkout waiting for idle connection: ("https", SERVER_IP)
2024-07-31T03:37:15.480568Z TRACE hyper_util::client::legacy::connect::http: Http::connect; scheme=Some("https"), host=Some("SERVER_IP"), port=None
2024-07-31T03:37:15.480583Z DEBUG hyper_util::client::legacy::connect::http: connecting to SERVER_IP:443
2024-07-31T03:37:15.489020Z DEBUG hyper_util::client::legacy::connect::http: connected to SERVER_IP:443
2024-07-31T03:37:15.517508Z TRACE hyper_util::client::legacy::client: http1 handshake complete, spawning background dispatcher task
2024-07-31T03:37:15.517737Z TRACE hyper_util::client::legacy::pool: checkout dropped for ("https", SERVER_IP)
2024-07-31T03:37:15.562655Z TRACE snxcore::ccc: Reply from server: (CCCserverResponse
        :ResponseHeader (
                :id (3)
                :type (CertAuth)
                :session_id ()
                :return_code (599)
        )
        :ResponseData ()
)

Error: Request failed, error code: 599

Regardless of 2.2.7 (and I'd assume starting with 2.2.1, but I got tired of compiling every version, I'm sorry), it's pretty clear that snx-rs can not, or rather, does not know how to handle vpn_Cert_Username_Password.

Also, while the auth scheme is called vpn_Cert_Username_Password, the actual "username" seems to be completely irrelevant, and at least on the Windows client, the username is inferred from the certificate name (ie: renaming the cert to Brown Cow.pfx will show "Brown Cow" as the username in the client), so technically, only the password is required to be sent for auth to the server.

Unfortunately I wasn't able to gather any meaningful info with mitmproxy.

It seems that the server is asking the client to connect via port 4500, UDP, so after it does the initial handshake, the actual authentication is performed in the next packet(s) on UDP, and there was no discernable data in the raw frames.

chrome_2Ywk3ctN2c

Furthermore, after the initial handshake/connection via mitmproxy, the client will get "smart" and then connect to the server IP directly, bypassing the actual IP entered during the setup process, which makes further testing very tedious, as you have to delete and re-add the connection.

Also, not proxying UDP 4500 will result in the client never connecting, so I couldn't "trick" it to exclusively do it's job on 443.

ancwrd1 commented 4 months ago

Hello, could you try the IPSec tunnel with the latest version? I am not sure the SSL tunnel could be used with both certificate and password authentication at the same time.

Znuff commented 4 months ago

I've tried IPSec with all versions, in all of them I'm getting "No CCC session in reply!":

2024-07-31T13:52:52.086915Z TRACE isakmp::transport: Received message: IsakmpMessage {
    cookie_i: 15121821750522300887,
    cookie_r: 17469804346980390903,
    version: 16,
    exchange_type: Transaction,
    flags: IsakmpFlags(
        ENCRYPTION,
    ),
    message_id: 6985227,
    payloads: [
        Hash(
            BasicPayload {
                data: b"\xd1\xabE*\x9f\x9bx\x18\xac\x07y\xcdA\xea\x90'\x97\x92d.",
            },
        ),
        Attributes(
            AttributesPayload {
                attributes_payload_type: Request,
                identifier: 41718,
                attributes: [
                    DataAttribute {
                        attribute_type: 13,
                        value: Short(
                            0,
                        ),
                    },
                    DataAttribute {
                        attribute_type: 18,
                        value: Long(
                            b"Certificate authentication completed successfully.\npassword: \0(msg_obj\n\t:format (1.0)\n\t:id (VPN_CUMULATE_PROMPT)\n\t:def_msg (\"Certificate authentication completed successfully.\npassword: \")\n\t:arguments (\n\t\t:0 (\n\t\t\t:type (msg_obj)\n\t\t\t:val (msg_obj\n\t\t\t\t:format (1.0)\n\t\t\t\t:def_msg (\"Certificate authentication completed successfully.\n\")\n\t\t\t\t:arguments (\n\t\t\t\t\t:0 (\n\t\t\t\t\t\t:type (string)\n\t\t\t\t\t\t:val (\"[cert_info]\")\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t)\n\t\t\t:def_text (\"Certificate authentication completed successfully.\n\")\n\t\t)\n\t\t:1 (\n\t\t\t:type (msg_obj)\n\t\t\t:val (msg_obj\n\t\t\t\t:format (1.0)\n\t\t\t\t:id (CPSC_INTERNAL_ENTER_PASSWORD)\n\t\t\t\t:def_msg (\"password: \")\n\t\t\t\t:arguments ()\n\t\t\t)\n\t\t\t:def_text (\"password: \")\n\t\t)\n\t)\n\t:authentication_state (new_factor)\n)\n",
                        ),
                    },
                    DataAttribute {
                        attribute_type: 15,
                        value: Long(
                            b"",
                        ),
                    },
                ],
            },
        ),
    ],
}
2024-07-31T13:52:52.087057Z DEBUG isakmp::ikev1::service: End sending OM request
2024-07-31T13:52:52.087536Z DEBUG isakmp::transport: Sending ISAKMP message of size 80 to SERVER_IP:500
2024-07-31T13:52:52.087568Z TRACE isakmp::transport: Sending message: IsakmpMessage {
    cookie_i: 15121821750522300887,
    cookie_r: 17469804346980390903,
    version: 16,
    exchange_type: Informational,
    flags: IsakmpFlags(
        0x0,
    ),
    message_id: 1251997944,
    payloads: [
        Delete(
            DeletePayload {
                doi: 0,
                protocol_id: Isakmp,
                spi_size: 16,
                spi: [
                    b"\xd1\xdb\x80\xc3d\xa8I\xd7",
                    b"\xf2q6~\x9dWW\xf7",
                ],
            },
        ),
        Hash(
            BasicPayload {
                data: b"8\xf3\xa2\x1b\xe1S\xa1\x02n(f\x946\xc3\xe1[\xf8\xb9XR",
            },
        ),
    ],
}
Error: No CCC session in reply!

The message seems to suggest that it's waiting for a password, too (CPSC_INTERNAL_ENTER_PASSWORD).

ancwrd1 commented 4 months ago

Ok thanks, I will have a look into it. So far the cert+pwd wasn't a common authentication combination. Should be relatively simple to fix.

ancwrd1 commented 4 months ago

Could you please try the issue29-cert-pwd branch and see if it works?

Znuff commented 4 months ago

I can confirm this works in ipsec mode!

ancwrd1 commented 4 months ago

Ok thanks, I will create a new release.