Sunday, January 15, 2012

Mua hàng không mất tiền - Lỗ hổng trong một số cổng thanh toán trực tuyến ở Việt Nam


Đây là bài tham luận tôi đã trình bày tại TetCon 2012. Nội dung của bài này sẽ được đăng lên trang chủ của hội thảo. Tôi post lại ở đây để làm kỉ niệm. 

Lỗ hổng này tôi đã tình cờ phát hiện được trong khi đang phát triển một dịch vụ có sử dụng API của một cổng thanh toán trực tuyến. Lỗ hổng này về mặt kỹ thuật thì không có gì mới và cũng không phức tạp cho lắm. Tôi cũng khá ngạc nhiên là lỗ hổng này được lập lại ở nhiều cổng thanh toán trực tuyến khác nhau. Vì một số lý do nên tôi không nêu tên cụ thể các cổng thanh toán trực tuyến, nhưng nếu bạn có làm việc trực tiếp với họ thì bạn sẽ biết được tên các cổng thanh toán trực tuyến này. Do thời gian có hạn nên tôi đã không tìm hiểu hết các cổng thanh toán trực tuyến đang hoạt động ở Việt Nam. Tuy nhiên dựa vào nội dung của bài tham luận này bạn có thể biết được cổng thanh toán mà bạn đang phát triển có nằm trong trường hợp này hay không. 

----------

Tóm tắt

Thanh toán trực tuyến là một trong những loại hình dịch vụ phát triển mạnh nhất ở Việt Nam trong vài năm vừa qua. Bây giờ chỉ với một chiếc thẻ nội địa hay thẻ tín dụng, bạn có thể mua và thanh toán được rất nhiều mặt hàng khác nhau, từ quần áo, sách vở, vé xem film cho đến vé máy bay. Có thật sự là phải cần có thẻ mới mua được hàng? Trong bài tham luận này, chúng tôi sẽ trình diễn một cách mua hàng không mất tiền, bằng cách khai thác lỗ hổng an ninh trong một vài hệ thống thanh toán trực tuyến phổ biến ở Việt Nam. Những lỗ hổng này đã được thông báo đến các bên liên quan trước khi bài tham luận này được gửi đến TetCon 2012.


1. Giới thiệu

Cùng với sự phát triển của thương mại điện tử, sự ra đời của các cổng thanh toán trực tuyến là một nhu cầu tất yếu. Cổng thanh toán đóng vai trò quan trọng trong việc đem đến sự giao dịch thuận tiện giữa người mua và người bán. Ngoài việc giúp cho giao dịch giữa người bán và người mua được tiến hành thuận tiện, việc đảm bảo an toàn cho các giao dịch này là một yêu cầu bắt buộc.

Trong bài tham luận này, chúng tôi sẽ tập trung phân tích một cơ chế hoạt động phổ biến trong các cổng thanh toán trực tuyến hiện nay ở Việt Nam. Trong cơ chế này, 3 thành phần cơ bản tham gia vào quá trình thanh toán gồm có người mua (customer), địa chỉ bán hàng (merchant's site) và cổng thanh toán (payment gateway). Dòng chảy dữ liệu giữa các thành phần này được mô tả như trong hình 1.

Hình 1. Dòng chảy dữ liệu của quá trình mua bán thông qua cổng thanh toán

Sau khi người mua vào website của người bán chọn lựa mặt hàng cần mua và đồng ý thực hiện việc thanh toán, quá trình thanh toán sẽ diễn ra như sau:

  • Bước (1): Trình duyệt của người mua hàng sẽ gởi yêu cầu thanh toán về máy chủ trang web bán hàng. Thông tin được gởi về có thể bao gồm: mã đơn hàng, danh sách các mặt hàng, tổng số tiền cần thanh toán,...
  • Bước (2): Ứng dụng web của người bán hàng sẽ xử lý đơn hàng và sẽ trả kết quả về cho người mua hàng dưới dạng một yêu cầu chuyển hướng HTTP (HTTP redirect). Đích đến của yêu cầu chuyển hướng này là địa chỉ của cổng thanh toán. Thông tin trong yêu cầu chuyển hướng có thể bao gồm định danh của đơn vị bán hàng, mã đơn hàng, số tiền cần thanh toán, địa chỉ trả về kết quả nếu việc thanh toán thành công,... Ngoài ra, để đảm bảo cho cổng thanh toán xác định được rằng yêu cầu gởi đến này được tạo ra từ ứng dụng của người bán hàng, dữ liệu được gởi đi bao gồm một chữ ký của bên bán hàng trên các thông tin còn lại. Chúng tôi sẽ mô tả về các tạo ra chữ ký này trong phần tiếp theo.
  • Bước (3): Trình duyệt của người mua hàng sau khi nhận được yêu cầu chuyển hướng từ phía người bán sẽ tự động chuyển đến trang web của cổng thanh toán. Ứng dụng web của cổng thanh toán sẽ tiếp nhận yêu cầu này và bắt buộc người mua hàng phải thực hiện các thao tác trên cổng thanh toán như đăng nhập, điền thông tin thẻ tín dụng hoặc ATM, xác nhận đơn hàng,...
  • Bước (4): Sau khi người mua hàng thực hiện thành công các bước theo đúng quy trình của cổng thanh toán, phía cổng thanh toán sẽ trả về kết quả cho người mua hàng dưới dạng một yêu cầu chuyển hướng HTTP. Đích đến của yêu cầu chuyển hướng này là địa chỉ máy chủ của trang web bán hàng (địa chỉ này được gởi đến cổng thanh toán như ở bước 2). Thông tin đi kèm trong yêu cầu chuyển hướng này dùng để xác nhận với trang web bán hàng rằng người mua đã thanh toán thành công. Các thông tin này cũng được đi kèm với một chữ ký như ở trong bước 2.
  • Bước (5): Trình duyệt của người mua hàng sẽ tự động chuyển hướng trang web bán hàng sau khi nhận yêu cầu chuyển hướng từ cổng thanh toán như trong bước 4.
  • Bước (6): Trang web bán hàng sẽ kiểm tra thông tin được gởi đến. Nếu thông tin này có nội dung mô tả đúng như khi khách hàng đã thanh toán đơn hàng và có chữ ký hợp lệ thì giao dịch được thực hiện thành công. 

Ưu điểm của quy trình này là ngắn gọn và đơn giản. Nó đem lại sự thuận tiện cho người dùng. Tuy nhiên việc hiện thực nó không đúng có thể tạo ra một lỗ hổng nghiêm trọng giúp cho một người có thể thực hiện mua hàng mà không cần phải thanh toán tiền. Trong bài tham luận này, chúng tôi sẽ phân tích lỗ hổng trong một cách hiện thực của của cơ chế thanh toán này. Lỗ hổng này có thể khai thác được và được tìm thấy trong một số cổng thanh toán trực tuyến phổ biến ở Việt Nam.


2. Một cơ chế tạo chữ ký không an toàn

Trong mô hình thanh toán được mô tả như phần trên, để có thể xác thực được các thông điệp được gởi qua lại, website bán hàng thường được cổng thanh toán cung cấp cho một mã định danh (merchant code) và một khóa chia sẻ chung bí mật (shared secret key). Khóa bí mật này dùng để xác thực các thông điệp được trao đổi giữa các bên.

Trong một số cổng thanh toán chúng tôi đã tiến hành khảo sát, quá trình tạo ra chữ ký cho các thông điệp được thực hiện như sau:
  1. Sắp xếp các thông số được truyền trong thông điệp theo thứ tự bảng chữ cái dựa trên tên của thông số. Ví dụ: order_id=123, merchant_id=1230, amount=100000 được sắp xếp thành amount=100000, merchant_id=1230, order_id=123.
  2. Kết hợp khóa bí mật và giá trị của các thông số đã được sắp xếp thành một chuỗi ký tự. Ví dụ: SECRET1000001230123
  3. Tính giá trị băm của chuỗi này bằng thuật toán MD5 (hoặc SHA1)
  4. Thêm giá trị băm này vào danh sách các tham số được gởi đi như là một chữ ký xác thực. Ví dụ: signature=7BD70B91F6F026FBFFFA552A7D59B5BD
Bên nhận được thông điệp cũng thực hiện lại quá trình này nhưng sử dụng khóa bí mật được lưu trữ tại hệ thống của mình trong bước 2. Nếu chữ ký được tạo ra giống với chữ ký được gởi đến thì thông điệp được xem là hợp lệ và tiếp tục được xử lý như một giao dịch bình thường.

Việc tạo ra chữ ký theo phương pháp này có thể bị tấn công bằng một số cách sau:
  • Do không có dấu phân cách giữa các giá trị và tên của tham số không được sử dụng trong việc tạo ra chữ ký điện tử, nên chữ ký được tao ra cho danh sách tham số amount=100000&merchant_id=1230&order_id=123 sẽ giống với chữ ký được tạo ra cho amount=100000&order_id=123&status=0&tranx_id=123.
  • Do MD5 có thể bị tấn công bằng phương pháp mở rộng chiều dài (length-extension attack), một người có thể chèn thêm dữ liệu bất kỳ vào cuối thông điệp mà có thể tạo ra chữ ký xác thực hợp lệ mà không cần phải biết khóa bí mật. Chúng tôi sẽ nói về cách tấn công này trong phần tiếp theo.
Trong một số cổng thanh toán trực tuyến mà chúng tôi tiến hành khảo sát, một số có thể bị tấn công bằng cách thứ nhất, một số có thể bị tấn công bằng phương pháp thứ hai. Bằng cách khai thác được một trong hai cách này, một người có thể làm giả một thông điệp được gởi từ cổng thanh toán trực tuyến xác nhận rằng người mua đã thanh toán tiền và gởi thông điệp giả mạo này về cho website bán hàng. Và như vậy, người này có thể mua hàng thành công mà không cần phải thông qua cổng thanh toán trực tuyến và không cần phải mất tiền.


3. Tấn công mở rộng chiều dài trên MD5 (Length-Extension Attack)

Tấn công mở rộng chiều dài là một loại tấn công khá phổ biến đối với các hàm băm được xây dựng trên cấu trúc lặp Merkle-Damgård [1] như MD0-MD5 và SHA0-SHA2. Với phương pháp tấn công này, một người có thể dựa trên giá trị băm h(m) và chiều dài len(m) của thông điệp m để tính giá trị băm h(m||pad(m)||m') với bất kỳ thông điệp m' nào. Tham khảo [2] có mô tả về dạng tấn cống này trên API của một dịch vụ chia sẻ ảnh khá phổ biến là Flickr.

Trong các hàm băm được xây dựng trên cấu trục lặp Merkle-Damgård, thông điệp đầu vào được chia ra thành một chuỗi các khối (block) có kích thước bằng nhau và được xử lý theo thứ tự bằng một hàm nén một chiều (one-way compression function). Trong thuật toán MD5, hàm nén nhận vào 2 giá trị - một giá trị móc nối (chaining value) có kích thước 128-bit và một khối (block) thông điệp có kích thước 512-bit - và tạo ra một giá trị móc nối 128-bit khác được sử dụng làm đầu vào cho bước lặp tiếp theo. Thông điệp ban đầu được đệm (padded) để có kích thước là một bội số của 512-bit và được chia thành một chuỗi các khối có kích thước 512-bit. Hàm nén được tính một cách lặp lại với một giá trị móc nối ban đầu và khối thông điệp đầu tiên. Sau khi khối thông điệp cuối cùng được xử lý, giá trị móc nối cuối cùng là kết quả hàm băm của thông điệp ban đầu.

Hình 2. Cấu trúc lặp Merkle-Damgård (sao chép từ Wikipedia)

Do cấu trúc lặp của thuật toán, một người có thể chỉ dựa vào giá trị băm và chiều dài của một thông điệp để tính giá trị băm của một thông điệp dài hơn được bắt đầu bằng thông điệp ban đầu, bao gồm cả giá trị đệm đã được thêm vào để cho thông điệp ban đầu có kích thước là một bội số của 512-bit (hình 3). Vấn đề này đã được mô tả trong [3].

Hình 3. Tấn công mở rộng chiều dài (sao chép từ [4])


Đối với cơ chế tạo chữ ký như đã được mô tả trong phần 2, chúng ta có thể sử dụng phương pháp tấn công mở rộng chiều dài để tính chữ ký của bất kỳ thông điệp m' nào với m' bắt đầu bằng m||p, với p là giá trị được đệm vào SECRET||p trong cấu trúc lặp Merkle-Damgård.
signature1 = MD5(SECRET||m)
signature2 = MD5(SECRET||m||p||x)
Ví dụ, dựa trên thông điệp yêu cầu chuyển hướng được gởi từ website bán hàng về cho khách hàng (như trong bước 2 của hình 1), một người có thể làm giả một thông điệp xác nhận thanh toán thành công được gởi về từ cổng thanh toán (như trong bước 4 của hình 1), và gởi thông điệp này đến website bán hàng để hoàn tất việc mua hàng.
response1 = “amount=100000&merchant_id=1230&order_id=567&signature=[sig1]”
m1 = “1000001230567"
sig1 = MD5(SECRET || m1)
x = 10000056701156
m2 = m1 || p1 || x
sig2 = MD5(SECRET || m2)
response2 = “aaa=[m1||p1]&amount=100000&order_id=567&status=0&tranx_id=1156”

4. Phương án vá lỗi đề nghị

Do bản chất của lỗ hổng này là như nhau nên chúng tôi đề xuất phương án vá lỗi được mô tả trong phần 5.5 của tham khảo [2]. Bạn đọc quan tâm có thể tìm hiểu thêm trong tài liệu này.

5. Kết luận

Trong bài tham luận này chúng tôi đã mô tả về một lỗ hổng mật mã xuất hiện trong một số cổng thanh toán trực tuyến ở Việt Nam. Bằng việc khai thác lỗ hổng này, một người có thể mua hàng nhưng không cần phải trả tiền. Điều này có thể gây tổn hại rất lớn đến cổng thanh toán trực tuyến cũng như  các website bán hàng có liên quan. Do tính chất nhạy cảm của vấn đề, chúng tôi quyết định không nêu tên cụ thể của cổng thanh toán và chi tiết về cơ chế hoạt động của các cổng thanh toán này trong bài viết.

Lỗ hổng được trình bày trong bài viết đã được biết đến từ rất lâu trong cộng đồng làm về mật mã học (xem [5]). Tuy nhiên sau nhiều năm, vẫn còn rất nhiều website gặp phải lỗ hổng này. Trên thế giới, lỗ hổng này được tìm thấy ở một dịch vụ chia sẻ ảnh phổ biến là Flickr vào năm 2009 (xem [2]). Và một cách tình cờ, chúng tôi tìm thấy được lỗ hổng này xuất hiện trong một số cổng thanh toán trực tuyến phổ biến ở Việt Nam. Do không có đủ thời gian và nguồn lực, chúng tôi đã không kiểm tra trường hợp này đối với tất cả các cổng thanh toán cũng như các dịch vụ khác. Nhưng qua bài viết này, chúng tôi hi vọng rằng các đơn vị đang phát triển dịch vụ trực tuyến ở Việt Nam có cái nhìn cẩn trọng hơn trong việc hiện thực các chức năng liên quan đến mật mã học nhằm đem đến những sản phẩm tốt và an toàn cho người dùng.

6. Tham khảo
[1] http://en.wikipedia.org/wiki/Merkle%E2%80%93Damg%C3%A5rd_construction
[2] Thai Duong, Juliano Rizzo. Flickr’s API Signature Forgery Vulnerability, September 2009.
[3] B. Kaliski and M. Robshaw. Message Authentication with MD5. RSA Labs' CryptoBytes, Vol. 1 No. 1, Spring 1995.
[4] H. Travis. Web 2.0 Cryptology, A Study in Failure. OWASP, 2009. Retrieved September 13, 2009, from http://www.subspacefield.org/security/web_20_crypto.pdf.
[5]  G. Tsudik. Message authentication with one-way hash functions. ACM Computer Communications Review, 22(5):29–38, 1992.

1 comment:

  1. Recommend WebSphere Datapower để fix lỗi trên theo chuẩn quốc tế PCI DSS
    http://thysmichels.com/2011/03/13/datapower-and-the-pci-dss-data-security-standard/

    ReplyDelete