HTTPS có thực sự bảo mật?



  • HTTPS secure

    HTTPS hay còn được gọi là HTTP Secure, hoặc HTTP over SSL, HTTP over
    TLS là một giao thức được coi là bảo mật hơn của giao thức truy cập
    Web HTTP thông thường. Bản thân nó đã có nghĩa "bảo mật" nhưng liệu
    thực sự nó có đủ bảo mật như chúng ta vẫn nghĩ hay không? Trong bài
    viết này, chúng ta sẽ tìm hiểu thêm về HTTPS và cách thức bảo mật của
    nó.

    Tại sao chúng ta cần đến HTTPS

    Hiện nay Google đã
    thêm
    tiêu chí sử dụng HTTPS để
    đánh giá các trang Web. Tuy nhiên, không phải lúc nào chúng ta cũng
    cần đến HTTPS. Chúng ta chỉ cần chúng khi bảo mật thông tin mà thôi.

    Tại sao phải bảo mật thông tin?

    Trong thời chiến tranh, rất nhiều thông tin quân sự, tình báo chỉ có
    thể thông tin cho một số người, những người khác, nhất là kẻ địch
    không được biết. Tuy nhiên, vì nhiều lý do, việc truyền tải tin tức
    không thể trực tiếp từ người gửi đến thẳng người nhận, mà phải thông
    qua một số trung gian nhất định. Việc truyền tải như vậy khiến tin
    tức dễ dàng bị lọt ra ngoài. Ví dụ, các phương thức truyền tin bằng
    điện tín dễ dàng bị bắt trộm sóng và nghe lén.

    Vì vậy, người ta dùng nhiều phương thức khác nhau đễ mã hóa đoạn tin
    cần gửi, để đảm bảo rằng, ngoại trừ người cần nhận, những người khác
    dù nghe được cũng không hiểu gì. Nếu bạn đã từng xem
    phim Windtalkers thì bạn có
    thể hiển được tầm quan trọng của mã hóa trong chiến tranh là như thế
    nào.

    Tương tự như vậy, trên Internet hiện nay có rất nhiều kiểu tấn công
    kiểu nghe lén như vậy. Một hình thức phổ biến được gọi là Eavesdrop,
    ngoài ra còn một kiểu tấn công mạnh hơn nữa gọi là Man in the Middle.
    Tuy nhiên, nội dung bài viết này sẽ không đi sâu vào chi tiết các kiểu
    tấn công đó, có thể tôi sẽ trở lại trong bài viết sắp tới. Những gì
    tôi muốn nói ở đây là những gì chúng ta làm trên Internet không bao
    giờ là riêng tư theo đúng nghĩa cả.

    > Big Brother is watching you

    Mạng Internet là một nơi kết nối rất nhiều máy tính, một gói tin đi từ
    người gửi trước khi đến với người nhận sẽ phải đi qua rất nhiều máy
    trung gian khác nhau. Vì vậy, việc bị đọc trộm các gói tin này đã trở
    thành một phần tất yếu của lịch sử. Không ai có thể ngăn chặn được
    những kẻ táy máy tìm cách đọc trộm gói tin của chúng ta trên đường đi.
    Thậm chí, cơ chế hoạt động của Internet cho phép việc nghe lén này
    diễn ra hết sức dễ dàng. Nếu không tin, bạn có thể cài
    thử Wireshark và xem mạng mà bạn đang sử
    dụng có những hoạt động nhộn nhịp như thế nào.

    Những gì chúng ta làm trên Internet có nhiều thứ người khác biết cũng
    chẳng sao. Nhưng cũng có nhiều thứ chúng ta chẳng muốn ai biết cả.
    Và một nhu cầu hết sức chính đáng của con người là che giấu một số thứ
    có thể gọi là "bí mật" đó khỏi con mắt nhòm ngó của những người xung
    quanh. Vì việc xem trộm các gói tin diễn ra hết sức bình thường như
    vậy, nên chúng ta cần đến các phương thức mã hóa để đảm bảo rằng, gói
    tin mà chúng ta gửi đi chỉ có chúng ta và nơi nhận hiểu được. Tất cả
    những kẻ táy máy đọc trộm trên đường dù đọc được cũng không hiểu được
    gì.

    Đó là lý do chúng ta cần đến HTTPS trong các giao dịch Web, HTTPS sẽ
    giúp chúng ta mã hóa quá trình giao dịch của máy chủ Web và trình
    duyệt. Ngoài ra, HTTPS còn một số tác dụng khác nữa, như xác thực máy
    chủ (tránh bị phishing), v.v...

    HTTPS bảo mật giao dịch như thế nào?

    Khi trình duyệt truy cập trang Web sử dụng HTTPS, trình duyệt và máy
    chủ sẽ thiết lập một kết nối SSL bằng cách sử dụng giao
    thức SSL Handshake.
    Quá trình thiết lập kết nối này hoàn toàn trong suốt với người dùng,
    thông thường người dùng không cần quan tâm đến nó.

    Để thiết lập kết nối SSL, có 3 khóa được sử dụng: public key, private
    key và session key. Public key và private lập thành một cặp: mọi thứ
    cần mã hóa được mã hóa bằng public key và giải mã bằng private key.
    Session key là khóa dùng trong phương thức mã hóa đối xứng, nó được
    dùng cho cả quá trình mã hóa và giải mã.

    > Nếu bạn chưa hiểu hết về các phương thức mã hóa bằng public key và
    > mã đối xứng, có lẽ bạn nên tìm hiểu về chúng trước khi chúng ta tiếp
    > tục.

    Việc mã hóa bằng public key rất tốn kém nên nó chỉ được dùng vào thời
    điểm thiết lập kết nối, sau khi kết nối được thiết lập, mã hóa đối
    xứng sẽ được sử dụng (với khóa là session key). Toàn bộ quá trình
    diễn ra như sau:

    1. Trình duyệt kết nối với máy chủ sử dụng HTTPS.
    2. Máy chủ trả về một SSL certificate, trong đó có chứa public key
      dùng để mã hóa.
    3. Trình duyệt kiểm tra certificate (quá trình này chúng ta sẽ tìm
      hiểu ở phần sau). Nếu mọi thứ đều ổn hoặc người dùng cố xử lý tiếp
      thì trình duyệt sẽ sinh ngẫu nhiên session key và gửi cho server
      (dữ liệu được mã hóa bằng public key).
    4. Máy chủ sử dụng private key giải mã gói tin lấy session key, gửi
      phản hồi đã nhận key cho trình duyệt.
    5. Từ đây trở đi, máy chủ và trình duyệt gửi nhận các gói tin được mã
      hóa bằng session key.

    SSL certificate

    SSL certificate là giấy chứng nhận được dùng khi thiết lập kết nối
    giữa trình duyệt và máy chủ. SSL certificate về mặt kỹ thuật là những
    tập tin kích thước tương đối nhỏ trong đó có lưu thông tin về public
    key cùng với các thông tin khác về tổ chức chủ sở hữu của trang Web.

    Một số thông tin được lưu trong SSL certificate:

    • Domain, tên server, hostname
    • Tên công ty, tổ chức, địa chỉ liên hệ
    • Thời hạn sử dụng
    • Public key

    Tuy nhiên, giấy chứng nhận này hoàn toàn có thể bị làm giả. Giống như
    chúng ta viết sơ yếu lý lịch vậy, làm sao để biết chúng ta đã viết
    những thông tin chính xác? Chúng ta cần phải có xác nhận của chính
    quyền địa phương. SSL certificate cũng tương tự như vậy, để đảm bảo
    chứng nhận này không phải là giả, chúng ta cần đến Certificate
    Authority.

    Certificate Authority (CA)
    thể xác nhận rằng certificate là thật, họ sẽ sử dụng chữ ký điện tử
    với private key của riêng họ. CA sẽ đóng vai trò như những công chứng
    viên đã được cấp giấy phép hành nghề, chữ ký của họ được tin tưởng và
    certificate được họ chứng nhận có thể coi là hợp lệ.

    Thường thì CA bán các giấy chứng nhận này và họ sẽ xác nhận cho giấy
    tờ mà họ cấp. Vì vậy, thường chúng ta phải mua SSL certificate với
    giá cũng không rẻ lắm. Kỳ thực giá trị của SSL certificate không chỉ
    ở bản thân giấy chứng nhận, mà nó con bao gồm một phần không nhỏ giá
    thương hiệu của người bán.

    Thực ra chữ ký của CA cũng cần phải được xác thực. Giống như chúng ta
    kiểm tra lại chữ ký của công chứng viên vậy. Các certificate của CA
    sẽ được chứng nhận bởi những CA cấp cao hơn, và quá trình này là một
    quá trình đệ quy như sau:

    validation chain

    Mỗi certificate sẽ được chứng nhận bằng certificate cấp cao hơn, và
    cấp cao nhất gọi là CA Root certificate. CA Root certificate cũng là
    một SSL certificate, nhưng nó dùng để xác thực và gắn chữ ký điện tử
    cho các certificate thương mại được bán cho người dùng. Những root
    certificate này thường được cài đặt sẵn trên trình duyệt và khi trình
    duyệt nhận certificate từ website nào đó, nó sẽ dùng root certificate
    để kiểm tra những certificate nhận được có hợp lệ hay không.

    Nhờ quá trình xác thực trên, mà khi sử dụng HTTPS, chúng ta không chỉ
    đơn giản mã hóa thông tin, mà chúng ta còn chứng thực được mình đang
    làm việc với đúng đối tượng mà chúng ta muốn.

    Vì quá trình xác thực, mã hóa và giải mã rất phức tạp như trên, nên
    HTTPS tốn nhiều thời gian để xử lý hơn HTTP. Trong nhiều trường hợp
    HTTPS là không cần thiết, nhiều hãng lớn
    như CNN, BBC không
    sử dụng HTTPS cho trang Web của họ, đơn giản vì nó là các trang tin
    tức, không có thông tin nhạy cảm nào mà việc phản hồi nhanh với người
    dùng quan trọng hơn.

    HTTPS có thực sự bảo mật?

    Trong nhiều trường hợp, HTTPS với dấu hiệu màu xanh trên thanh địa chỉ
    là dấu hiện cho thấy những gì chúng ta thao tác sẽ được bảo mật.
    Nhưng liệu nó đã đủ bảo mật hay chưa? Ý kiến cá nhân của tôi là chưa.
    HTTPS cũng giống như bạn ra khỏi ra mà khóa kín cửa vậy. Kỳ thực khóa
    cửa chỉ phòng người ngay chứ chẳng tránh được kẻ gian. Nếu có kẻ đã
    cố tính vào nhà ăn trộm thì khóa cửa chắc mấy cũng chỉ cần cắt một
    nhát là đứt. HTTPS có lẽ có phần tương tự như vậy.

    Với máy chủ và Web app

    HTTPS là một cơ chế bảo mật giao dịch giữa người dùng và máy chủ. Có
    thể nói, đối với máy chủ Web cũng như các ứng dụng Web, nó không có
    tác dụng gì trong việc bảo mật máy chủ và ứng dụng.

    Việc bảo mật ứng dụng cần rất nhiều quá trình phức tạp, bao gồm chống
    tấn công DDoS, chống XSS, CSRF, v.v..

    Với người dùng

    Vậy với người dùng thì sao? Chẳng phải HTTPS giúp người dùng mã hóa
    dữ liệu, xác thực máy chủ hay sao? Câu trả lời thật phũ phàng là vẫn
    có rất nhiều cách để phá vỡ HTTPS. Tạm thời chưa nói đến các phương
    thức mã hóa có những lỗ hổng nhất định, vẫn còn rất nhiều phương pháp
    khác nhau để phá bỏ hệ thống xác thực certificate:

    • Đột nhập vào hệ thống của CA. Như chúng ta đã biết, có hàng
      trăm
      CA được trình duyệt tin tưởng. Những
      kẻ tấn công chỉ cần tìm một trong số các CA này có khả năng đột nhập
      là đủ. Và thực tế
      thì
      chuyện này cũng đã từng xảy ra với
      những hậu quả thật khủng khiếp.
    • Đột nhập các router gần CA hoặc gần nạn nhân, đọc và giả mạo các gói
      tin DNS đến và đi, tấn công việc trao đổi email giữa nạn nhân và CA.
      Các phương thức mã hóa email không giúp ích được gì trong trường hợp
      này, vì STARTTLS hoàn toàn
      có thể bị phá vỡ.
    • Đột nhập các máy chủ DNS được sử dụng với CA hoặc giả mạo các gói
      tin DNS với domain của nạn nhân. Nhiều
      khi
      việc này khá dễ dàng.
    • Tấn công một số giao thức mạng khác, ví dụ TCP, để tấn công các gói
      tin của nạn nhân.
    • Một số CA có thể bị chính quyền nước sở tại bắt buộc cung cấp
      certificate độc hại
      như đã từng bị. Bởi vì CA có
      mặt ở rất nhiều quốc gia khác nhau mà nhiều chính phủ có thể tìm
      cách yêu cầu CA làm như vậy.

    Trên đây là những vẫn đề của hệ thống ngoài khiến dữ liệu của chúng ta
    vẫn có thể bị đánh cắp dù HTTPS vẫn hoạt động tốt. Nhưng ngay cả
    HTTPS bản thân nó cũng có những vẫn đề nhất định. Ví dụ như lỗ
    hổng
    Heartbleed (trái
    tim rỉ máu). Lỗ hổng này có khả năng phơi bày các nội dung chứa trong
    bộ nhớ máy chủ, cho phép kẻ tấn công sao chép các mã khóa của máy chủ.
    Có được khóa rồi, chúng dễ dàng giải mã các thông tin được trao đổi.

    Và ngay cả cơ chế xác thực bằng root certificate cũng không hoàn toàn
    an toàn. Hãy xem kiểu tấn công Man in the Middle như sau:

    MitM

    Ví dụ, bạn cần vào https://www.gmail.com,
    nhưng có kẻ nào đó giả crack vào quá trình trao đổi giữa bạn và máy
    chủ. Và bạn tin tưởng rằng, với certificate đã được chứng thực, bạn
    có thể yên tâm rằng mình an toàn, những kết nối với máy chủ không phải
    Gmail sẽ không thể được xác thực bằng SSL certificate.

    Nhưng bạn đã nhầm rồi.

    Những gì thực sự có thể diễn ra rất khác với bạn tưởng tượng:

    1. Bạn kết nối đến https://www.gmail.com
    2. Kẻ tấn công chuyển hướng truy vấn của bạn đến máy chủ hắn đã chuẩn
      bị sẵn.
    3. Vì máy chủ này chứa SSL certificate hoàn toàn hợp lệ, trình duyệt
      của bạn sẽ không thể biết được bạn đã kết nối sai máy chủ.
    4. Bạn thao tác với máy chủ giả, mọi dữ liệu sẽ bị kẻ tấn công đọc
      được, hắn ta có thể thay đổi nó, và gửi nó cho máy chủ Gmail thật.
    5. Bạn hoàn toàn không hề hay biết rằng kết nối được bảo mật của mình
      hoàn toàn không hề bảo mật.

    Tại sao kẻ tấn công có thể có được SSL certificate hợp lệ? Kẻ tấn
    công có thể lợi dụng root certificate (được cài đặt sẵn trong các
    trình duyệt, mà trình duyệt mã nguồn mở thì không thiếu) để tạo ra các
    SSL certificate cho website của hắn. Nếu vậy thì có trời mới biết thứ
    nào là thật, thứ nào là giả.

    Nói một cách ngắn gọn, có rất nhiều con đường khác nhau để bẻ khóa
    HTTPS.

    > No system is safe

    Các giao thức bảo mật Web có thể đủ tốt để phòng chống những kẻ tấn
    công vãng lai, không có nhiều thời gian và động lực. Nhưng nó vẫn còn
    quá nhỏ bé trong một thế giới mà công nghệ và các phương thức tấn công
    ngày càng phát triển.

    Ví dụ minh họa

    Mời các bạn thử sức với bài CTF sau, đây sẽ là một ví dụ minh họa đơn
    giản cho thấy HTTPS dễ bị tổn thương như thế nào?

    http://ksnctf.sweetduet.info/problem/33

    Đề bài cho một file pcap, đây là file capture các gói tin trong mạng.
    Trong file này thể hiện rất rõ ràng quá trình thiết lập kết nối SSL và
    trao đổi dữ liệu. Sử dụng Wireshark, chúng ta có thể thấy được toàn
    bộ quá trình trao đổi dữ liệu này.

    1. Client hello, đây là bước mở đầu, trình duyệt thông báo cho máy chủ
      biết về thuật toán mã hóa.
    2. Server hello, đây là bước máy chủ phản hồi rằng đã chấp nhận thuật
      toán mã hóa của trình duyệt.
    3. Certificate, đây là bước máy chủ gửi SSL certificate cho trình
      duyệt.
    4. Change cipher spec, đây là bước trình duyệt gửi cho máy chủ thông
      tin về session key được sinh ngẫu nhiên.

    Tiếp theo là quá trình trao đổi dữ liệu sử dụng session key, như chúng
    ta có thể thấy, ở packet thứ 12 là Application data, đây là packet
    HTTP đã được mã hóa bằng session key.

    https data

    Để hiểu được các gói tin này, chúng ta cần phải tìm được private key
    của server. Trước hết, bằng cách Export selected packet bytes, chúng
    ta dễ dàng lấy được thông tin public key của certificate nhận được từ
    máy chủ:

    certificate

    Việc sinh ra public key và private key được thực hiện theo cách thức
    của
    RSA.
    Từ các packet thu được, chúng ta có thể thu được public key của máy
    chủ

    inspect public key

    Modulus ở đây là tích của hai thừa số nguyên tố. Chỉ cần phân tích
    được nó thì chúng ta có thể tìm được private key. Về lý thuyết, việc
    này là hoàn toàn có thể. Tuy nhiên, việc phân tích nó có thể nói là
    quá sức của những máy tính cá nhân bình thường, vì giá trị của nó quá
    lớn. (Tuy nhiên, sau
    này,
    máy tính lượng tử
    thể sẽ giải quyết được vấn đề tính toán này)

    Rất may, chúng ta có thêm gợi ý thứ 2. Ở đây, client đang giao tiếp
    với hai server (192.168.0.39 và 192.168.0.40). Chúng ta dễ dàng lấy
    được public key của server thứ 2. Và trong bài toán này, hai server
    sử dụng public key tương tự nhau, phải chăng chúng có cùng thừa số
    nguyên tố. Chúng ta sẽ tìm cách lấy chúng ra.

    python3
    def gcd(a, b):
        while b != 0:
            r = a % b
            a, b = b, r
        return a
    
    mod1 = """
    00:a5:a7:ce:44:46:2e:8a:c6:e4:da:5e:8a:8d:58:
    e0:03:b8:26:75:68:b3:58:10:6c:f0:64:12:88:4c:
    ee:b7:cc:42:51:c2:cc:e2:db:74:68:9d:1a:fa:10:
    9b:de:97:62:40:2e:81:d9:6c:b6:c8:c6:c5:ae:bc:
    8d:45:a9:6b:f2:14:a6:18:b4:99:a8:c6:13:40:35:
    c5:03:9b:f9:a3:9b:c4:71:90:e4:cc:45:60:cb:75:
    ab:8d:63:63:5c:de:e8:e5:0f:58:15:b2:91:80:cc:
    51:a4:c8:cf:76:a8:bb:e6:e6:1c:68:ac:a3:85:fd:
    f9:9e:71:2b:10:a6:be:7e:d7:94:cf:27:54:0b:7a:
    a0:0f:59:da:55:79:04:0a:9b:3b:7c:23:e9:e2:2a:
    15:c2:9e:b0:c0:60:b9:6d:1f:48:d1:c4:58:e2:c4:
    12:51:29:62:ce:5a:f8:85:23:7b:61:38:df:6c:9e:
    85:d1:01:c2:66:c3:b8:0b:02:ff:97:d6:fd:e4:65:
    98:e1:9e:3f:a1:df:2c:56:bd:34:ad:df:e7:16:56:
    9a:2e:d4:2c:64:42:bf:2d:b5:e9:a5:1c:c2:d7:dd:
    44:97:71:7d:dd:9a:8a:66:ae:28:1e:1a:2a:bf:7d:
    f7:a5:97:79:b4:99:cc:0f:81:67:a1:9e:3c:a5:c9:
    bb:e3
    """
    
    mod2 = """
    00:a4:da:ad:49:ea:e0:b5:c5:9d:a0:45:29:78:ae:
    98:7e:1b:96:f1:49:de:db:62:27:4c:97:f9:9a:c4:
    54:4a:a9:0d:b4:aa:f9:a0:96:7f:11:8b:70:09:09:
    7b:cb:0b:ae:b4:a1:96:36:77:7a:77:47:e0:6a:d8:
    44:96:c9:c6:1d:18:a7:b5:ca:77:65:85:a8:17:52:
    6e:d6:d9:f0:f2:ab:d8:c4:34:c6:2c:bf:02:5e:b7:
    ce:5a:83:e4:a7:f9:93:8f:38:62:de:24:e6:29:2f:
    43:27:0f:fd:a7:57:c1:7a:aa:79:7f:f9:fe:18:fd:
    1c:b2:39:21:dc:58:5d:45:50:38:4f:f5:c4:f2:4e:
    6d:fc:6d:4f:44:b5:69:34:58:08:23:92:47:c2:0d:
    26:6c:d0:f5:e3:73:88:9e:d4:e4:59:59:0b:7d:74:
    2d:28:37:c1:c4:8d:cf:94:18:e2:21:91:ab:4a:0b:
    ca:0e:d7:9b:1d:45:c0:ca:5d:36:ea:69:60:c9:36:
    0c:11:41:23:29:fd:5d:90:ff:34:67:f2:d8:2e:23:
    02:1a:df:3b:6d:8b:e2:49:03:b7:6e:ff:c9:38:15:
    4e:c2:19:f3:44:11:8f:1c:41:fe:c3:11:71:b6:29:
    45:a0:7e:35:76:2a:96:1a:05:79:53:89:08:60:52:
    de:c7
    """
    
    pubs = [int(''.join(mod.replace('\n', '').split(':')), 16)
            for mod in (mod1, mod2)]
    
    p = gcd(*pubs)
    

    Từ đây, chúng ta có thể lấy ra được thừa số nguyên tố còn lại từ
    Modulus. Việc chúng ta cần làm lúc này khá đơn giản, tìm cách ghi
    private key ra file theo định
    dạng
    PEM
    để Wireshark hiểu và dự giải mã cho chúng ta là được:

    python3
    e = 65537
    
    from Crypto.PublicKey import RSA
    
    def inverse(a, n):
        t = 0
        newt = 1
        r = n
        newr = a
        while newr != 0:
            quotient = r // newr
            t, newt = newt, t - quotient * newt
            r, newr = newr, r - quotient * newr
        if r > 1:
            return 0
        if t < 0:
            t = t + n
        return t
    
    for i, pub in enumerate(pubs):
        q = pub // p
        with open("key%d.pem" % (i + 1), "w") as f:
            n = p * q
            phi = (p - 1) * (q - 1)
            comps = (n, e, inverse(e, phi))
            x = RSA.construct(comps)
            pk = x.exportKey().decode()
            f.write(pk)
    

    Vậy là chúng ta đã thu được hai file PEM chứa private key của hai máy
    chủ. Giờ chỉ cần thêm vào cho Wireshark là được

    add pem file

    add keys

    Vậy là đủ, Wireshark sẽ giải mã các gói tin cho chúng ta, lúc này
    chúng ta có thể thấy được các packet HTTP

    decrypted packet

    Và dễ dàng lấy được những thông tin chúng ta cần.

    flag

    Có thể nói rằng đây chỉ là một bài CTF nên người ra đề đã cố tình để
    lộ ra một vài sơ hở. Nhưng cũng nên nhớ rằng, tôi cũng chỉ là "tay
    mơ" đang tập tành chơi, còn ngoài kia có biết bao nhiêu người tài năng
    khác, họ có thể tìm ra lỗ hổng bảo mật ngay cả khi mà người thiết kế
    giao thức vẫn còn chưa nghĩ đến nó.

    Kết luận

    HTTPS thực sự chỉ đủ bảo mật ở mức độ chấp nhận được. Nếu muốn thực
    sự an toàn trên Internet, chúng ta cần nhiều biện pháp hơn thế. HTTPS
    cũng giống như bạn ra khỏi nhà mà khóa cửa, phần lớn chúng ta vẫn tạm
    hài lòng với tình trạng như vậy, nhưng vẫn có nhiều người chưa hẳn yên
    tâm và còn phải khóa thêm vài lớp, mua thêm két sắt để cất giữ đồ đạc
    quan trọng.



Có vẻ như bạn đã mất kết nối tới LaptrinhX, vui lòng đợi một lúc để chúng tôi thử kết nối lại.