การป้องกันการ hack In-app Purchase (2) by

31
Oct
1

ต่อจากบทความที่แล้ว วันนี้เรามาดูขั้นตอนการ verify จริงๆ กัน มีดังนี้

Android

  1. Login เข้า https://play.google.com/apps/publish/
  2. เลือก Settings (Icon ฟันเฟือง)
  3. เลือก API Access แล้วกดเปิดใช้งาน Google Play Android Developer API
  4. ที่หัวข้อ Linked Project ใน API Access หลังเปิดใช้งานให้คลิกที่ Google Play Android Developer
  5. คลิก APIs & auth
  6. คลิก Credentials
  7. คลิกปุ่ม Create new Client ID
  8. เลือก Application Type เป็น Web Application
  9. ช่อง Authorized Javascript Origins และ Authorized Redirect URI ใส่เป็น http://google.com หรืออะไรก็ได้ทั้งคู่ แต่ให้จำค่าในช่องนี้ไว้
  10. จด Client ID กับ Client Secret เอาไว้
  11. กด Create Client ID
  12. ใส่ช่อง url ใน Web Browser ไปว่า
    https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/androidpublisher&response_type=code&access_type=offline&redirect_uri=...&client_id=...
    (แก้ใข … เป็นข้อมูลจากข้อ 9-10)
  13. คลิก Allow Access
  14. Browser จะ redirect ไป google.com (หรือเว็บอื่นตาม redirect_uri ที่ตั้งไว้) แต่เราไม่ต้องสนใจตัวเนื้อหาในเว็บ ให้ดูที่ URL ที่มัน redirect ไปสังเกตดูจะพบตัวแปร code ใน url ของ browser หน้าตาประมาณนี้ “4/eWdxD7b-YSQ5CNNb-c2iI83KQx19.wp6198ti5Zc7dJ3UXOl0T3aRLxQmbwI.” (เป็นแค่ข้อมูลตัวอย่าง ต้องใช้ของคุณเอง) ก็ให้ copy ข้อมูลส่วนนี้เก็บเอาไว้
  15. ลง Google Chrome Extension Postman (หรือ extension อื่นๆ เอาไว้ให้ทดสอบยิง GET/POST ผ่าน web browser ได้ง่ายๆ)
  16. เปิด Postman แล้วเลือกประเภทการยิง request เป็น POST
  17. เลือกประเภทเป็น form-data แล้วกรอก URL ไปว่า
    https://accounts.google.com/o/oauth2/token
    โดยกรอกข้อมูลในช่อง key, value ข้างใต้ดังนี้ (key:value)

    • grant_type : authorization_code
    • code : <ข้อมูลจากข้อ 14>
    • client_id : <ข้อมูลจากข้อ 10>
    • client_secret : <ข้อมูลจากข้อ 10>
    • redirect_uri : <ข้อมูลจากข้อ 9>
  18. กด Send จะได้รับข้อมูลมาเป็น JSON ให้ Copy ส่วนของ refresh_token เก็บไว้ใช้งานตลอดไปใน server ของเราเองเลย (refresh_token ไม่มีวันหมดอายุ ไม่ต้องขอใหม่ ใช้ได้ตลอด)
  19. (ตั้งแต่ข้อนี้เป็นต้นไปให้คุณทดลองใช้ postman ยิงไปดูก่อน หลังจากทำจนเสร็จแล้วเห็นว่าใช้งานได้ ให้ทำใหม่ตั้งแต่ข้อนี้เป็น code ฝั่ง server ของคุณเองโดยอาจยิง Curl ไปเพื่อให้กระบวนการขอ access_token เป็นไปโดยอัตโนมัติไม่ต้องใช้งานผ่าน browser เพื่อตรวจสอบความถูกต้องของการสั่งซื้อกับ Server Google) ใช้ postman เลือกยิงแบบ POST เหมือนเดิมไปที่ url
    https://accounts.google.com/o/oauth2/token
    โดยกรอก key:value ดังนี้

    • grant_type : refresh_token
    • client_id : <ข้อมูลจากข้อ 10>
    • client_secret : <ข้อมูลจากข้อ 10>
    • refresh_token: <ข้อมูลจากข้อ 18>
  20. copy ข้อมูลส่วนของ access_token เก็บไว้
  21. ใช้ postman เลือกยิง url แบบ GET ไปที่
    https://www.googleapis.com/androidpublisher/v2/applications/<packageName>/purchases/products/<product_id>/tokens/<token>?access_token=<access_token>

    • packageName - ชื่อ package ของ app เช่น com.lvup.pokdeng
    • product_id - product_id ที่สร้างจากบทความที่แล้ว
    • token - purchase token ที่ได้จาก app ฝั่ง client (มื่อถือผู้ใช้)หลังซื้อสำเร็จที่เราสั่งให้ยิงมาที่ server ของเราเพื่อตรวจสอบ (คิดซะว่าเป็น transaction id ที่ทาง google สร้างขึ้น)
    • access_token – ข้อมูลจากข้อ 20
  22. ได้ผลลัพธ์มาหน้าตาแบบนี้
    {
      "kind": "androidpublisher#productPurchase", // ค่าคงที่มาแบบนี้เสมอทุกครั้ง
      "purchaseTimeMillis": long, // เวลาที่สั่งซื้อ เป็น milliseconds
      "purchaseState": integer, // สถานะการสั่งซื้อ 0 เป็นซื้อสำเร็จ และ 1 คือยกเลิกการสั่งซื้อ
      "consumptionState": integer, // สถานะการใช้งาน 0 คือรอการใช้งานและ 1 คือใช้งานไปแล้ว
      "developerPayload": string // ค่าที่เราส่งมาจากฝั่ง client ที่จะเก็บใน server ของ google ไว้ด้วย เช่น transaction id ของเราที่สร้างขึ้นมาเอง
    }
  23. เรียบร้อยจ้า

iOS

  1. ข้อมูลจาก client (มือถือผู้ใช้) จะมาในรูปแบบ payload ซึ่งเป็น string json ยาวๆ ก้อนหนึ่งถูก encode ด้วย base64 เอาไว้ ให้ยิงข้อมูลจาก client (มือถือผู้ใช้) มายัง server
  2. ที่ฝั่ง server ให้เรายิงแบบ POST ไปที่ url

    https://sandbox.itunes.apple.com/verifyReceipt

    (สำหรับ transaction ที่ใช้ทดสอบ) หรือ

    https://buy.itunes.apple.com/verifyReceipt

    สำหรับ server จริง ซึ่งถ้าใช้ postman ในการทดสอบยิงจะต้องเปลี่ยนชนิดที่เลือกจาก form-data เป็น raw แล้วเอาข้อมูล json string ทั้งก้อนที่ได้รับมา มาเปลี่ยนจาก “receipt_base64″ เป็น “receipt-data” แล้วยิงเข้า  url ที่กล่าวไว้ จะได้รับข้อมูลมาเป็น JSON ถ้า status เป็น 0 แสดงว่ายิงสำเร็จ จะมีข้อมูลอื่นๆ ติดมาด้วยโดยให้เช็คจาก array ชื่อ in_app เป็นหลัก และดูที่สมาชิก array ตัวสุดท้าย จะเป็นรายการล่าสุดที่พึ่งสั่งซื้อจริงๆ (หาก array มีข้อมูลมากกว่า 1 บางครั้งจะมีข้อมูลการสั่งซื้อครั้งก่อนๆ ให้มาด้วย จึงต้องตรวจสอบจากสมาชิกตัวสุดท้ายของ array เสมอ) โดยมีข้อมูลที่น่าเก็บไว้คือ product_id, transaction_id และ purchase_date_ms (หากมีคำว่า original อาจเป็นข้อมูลการสั่งซื้อครั้งแรก ไม่ใช่ข้อมูลการสั่งซื้อปัจจุบัน)

  3. เสร็จแล้วจ้า

ข้อมูลอ้างอิง:

https://developers.google.com/android-publisher/api-ref/purchases/products/get

https://developers.google.com/android-publisher/authorization

https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html

การป้องกันการ hack In-app Purchase by

29
Sep
1

ใครทำ app มาก็ย่อมที่จะไม่ต้องการให้ app ของเราโดน hack แหล่งหาเงินของเราอย่าง In-app purchase (ต่อไปนี้ขอเรียกสั้นๆ ว่า IAP) ไปได้ ในบทความนี้จะแนะนำ App ประเภทเกมเป็นหลัก ซึ่งหลักๆ การป้องกันการ hack จะแบ่งเป็นสองวิธีหลักๆ ดังนี้

1. ป้องกันที่ตัวมือถือ (Client) ซึ่งวิธีนี้อาจทำโดยเข้ารหัสตัวแปรไม่ให้ทำ Memory Hacking ได้ง่ายๆ หรือรวมไปถึงการตรวจสอบตามมาตรฐาน SDK ของทั้ง iOS และ Android ว่า Server ส่งค่ามาถูก ผ่านกระบวนการมาถูกหรือไม่ ซึ่งวิธีนี้อาจโดนแก้เกมได้ด้วยการสร้าง server จำลองขึ้นมาภายในตัวมือถือเองและหลอก app ว่ามันได้ติดต่อ server apple หรือ google จริงๆ แล้ว ทำให้ app เราไม่สามารถรู้ได้เลยว่าเรากำลังคุยกับ server ตัวจริงหรือไม่

2. ป้องกันที่การส่งข้อมูลระหว่าง Client กับ Server ให้มีการ encrypt ตัวแปรก่อนส่ง และ decrypt ตัวแปรออกมาเซพลงฐานข้อมูล วิธีนี้จะป้องกันการ hack ที่มาจากการดัก packet network ว่า app เรายิงเข้า server ที่ URL ไหนหลังจากสั่งซื้อ IAP สำเร็จ แล้วทำการยิง URL นั้นซ้ำเพื่อปั้มหน่วยเงิน Premium ในเกมของเรารัวๆ เหมือนซื้อครั้งเดียวแล้วจะรู้ช่องทางในการปั๊มเงินไปตลอดกาล ซึ่งแม้ว่าจะป้องกันการยิงตรงได้ด้วยการนำตัวแปรแวดล้อมอื่นๆ จากตัวเครื่องเช่นเวลามา encrypt ตัวแปรที่จะส่งให้ server ด้วยแล้ว แต่ถ้า Hacker สามารถ Decompile .apk กลับมาเป็น source code ได้(อย่างสวยงาม) Hacker ก็สามารถล่วงรู้ algorithm ที่เราใช้ encrypt ตัวแปรก่อนส่งเข้า server ได้อยู่ดี และสุดท้ายก็จะสามารถเลียนแบบการ encrypt เพื่อหลอก server ของเราว่ายิงมาจาก client จริงๆ ได้

3. ป้องกันด้วยการเก็บข้อมูลของเกมทุกอย่างไว้ที่ server แล้วโหลดข้อมูลจาก server มา update ที่ client ทุกครั้งก่อนเล่น และยิงข้อมูล transaction ไปตรวจสอบที่ server google/apple โดยตรง วิธีนี้ถือเป็นวิธีที่ปลอดภัยที่สุดและจะทำให้เราสามารถป้องกันการ hack ได้ 100% (ถ้า server ของเราเองไม่มีช่องโหว่ที่โจมตีได้จากช่องทางอื่น) แต่จะมีข้อเสียสองอย่างคือไม่สามารถทำเป็นเกม offline อย่างสมบูรณ์ได้ เพราะต้องเชื่อมต่อ internet ตลอดเวลาเพื่อ sync ข้อมูล และอย่างที่สองคือจะมีค่าใช้จ่ายเป็นค่าเช่า server ของเราเอง ซึ่งหากยอมรับในสองข้อนี้ได้ วิธีนี้จะเป็นวิธีที่ดีที่สุด สำหรับขั้นตอนหลักการทำงานดูได้จากรูปด้านล่าง ให้เปลี่ยนจาก iTune Store เป็น Play Store หรือผู้ให้บริการของ platform OS นั้นๆ เช่น Apple, Google, Amazon และ Soomla Server คือ Server ของเราเองที่เช่าเอาไว้ ซึ่งไม่ว่าจะเป็น Store ที่ไหนก็ตามจะมีวิธียืนยัน Transaction แบบนี้เหมือนๆ กันหมด ใช้ได้ทุกเจ้าครับ

blogger-image-1085999334_new

หมายเหตุ : ภาพจาก http://blog.soom.la/2013/10/announcing-server-side-verification-for.html

3.1 ติดต่อ iTune Store เพื่อสั่งซื้อไอเท็มที่ต้องการ
3.2 ได้รับข้อมูลการสั่งซื้อซึ่งจะมี transaction id อยู่ในนั้นด้วย (ของ Google Play จะเป็น purchaseToken ของ App Store จะเป็น payload)
3.3 นำข้อมูลการสั่งซื้อนั้นยิงไปที่ server ของเราเอง
3.4 นำข้อมูลการสั่งซื้อจาก server ของเราเองนั้นยิงไปที่ server ของ iTune Store อีกทีเพื่อตรวจสอบว่าเป็นรายการที่เกิดขึ้นจริงหรือไม่
3.5 iTune Store ตอบกลับมา หากถูกต้องก็จะได้รับคำยืนยันว่ามีการสั่งซื้อรายการนี้จริง และ server ของเราก็จะบันทึกข้อมูลการสั่งซื้อเอาไว้ และไปเพิ่มไอเท็มที่ผู้เล่นสั่งซื้อลงฐานข้อมูล ขั้นตอนนี้จะไม่มีใครสร้าง server มาหลอก client ของเราว่าเป็น server ตัวจริงได้ เพราะ server ของเราจะเก็บข้อมูลปัจจุบันของผู้เล่นเอาไว้เองด้วย และข้อมูลผู้เล่นตรงนี้จะไม่สามารถถูกแก้ไขค่าได้หากผู้เล่นไม่ได้ผ่านการกดซื้อ IAP มาจริงๆ (คือต่อให้ตั้ง server หลอกมา สุดท้ายเวลาผู้เล่นคนอื่นเข้ามาเล่นก็เห็นข้อมูลที่แท้จริงของคนๆ นี้ที่ server เราซึ่งไม่ได้ผ่านการโกงมาอยู่ดี)
3.6 ส่งข้อมูลผู้เล่นหลังการสั่งซื้อกลับ Client (เช่นเพิ่มจำนวนไอเท็มที่สั่งซื้อมากลับไปยัง Client)

เท่านี้ก็จะสามารถป้องกันการ Hack IAP ได้อย่างสมบูรณ์ ซึ่งหากคุณใช้ Unity ผมแนะนำ Plugin ที่ชื่อว่า  Soomla (ที่ผมยืมรูปมาใช้ในบทความนี้นี่แหละ) เพราะมันฟรีและใช้ได้ทั้ง Google Play, Amazon Store, App Store ครบถ้วนเลยทีเดียว สำหรับครั้งหน้าผมจะมาลงรายละเอียดการยืนยัน Transaction การสั่งซื้อของทั้ง App Store และ Google Play นะครับ

Client Hacking by

24
May
0

XSS (Cross site script) คือมีผู้ฝัง script ไว้ที่ server แล้วมีผู้ใช้มาร้องขอข้อมูลจาก server จากนั้น script ใน server จะถือโอกาสขโมยข้อมูลของเครื่องผู้ใช้ไปเช่น cookie

กู้เงิน | เศรษฐกิจพอเพียง | สินเชื่อบุคคล | สมัครบัตรกดเงินสด | สินเชื่อ | เงินกู้ด่วน | ยืมเงินทรูมูฟ | เงินด่วนนอกระบบ