Jump to content

Recommended Posts

Như ae đã biết, vụ checkout shopee giờ khá khoai. Hnay rảnh rỗi - sang tháng mới - tặng ae đoạn code checkout Shopee. Mà chính xác hơn là solution cho ae quất. 

Giá trị: 10.000.000 VND :v (ảo tưởng tí)

1. x-track-id là gì?

Như ae thấy, giờ khi call place_order, trong header sẽ có thằng x-track-id. Vậy nó là con mẹ gì vậy?

Shopee giờ khôn hơn rồi. Đầu tiên, em nó sẽ dùng vài thông tin trong đoạn trả về của api checkout/get + thông tin account đặt hàng => Mã hóa SHA512 => tạo ra 1 chuỗi x-track-id.

SHA512 là mã hóa 1 chiều, nên cơ bản là không thể giải mã. Vậy shopee check valid cái x-track-id thế nào?

Cũng giống như việc check password vậy, shopee sẽ dựa vào thông tin bạn post lên ở api place_order và cũng mã hóa các thông tin cần thiết => sau đó so sánh kq đó với chính cái x-track-id bạn post llên trong header.

Lý thuyết thì vậy rồi, giờ là cách tính x-track-id.

Hidden Content

    Give reaction or reply to this topic to see the hidden content.

Kết luận 1: chuỗi mã hóa thì fix bởi các tham số như trên, còn key mã hóa thì sẽ phụ cmn thuộc vào userid của thằng đang mua. Và thằng x-track-id này lại trở thành key của hàm mã hóa data json.

 

2. X-CV-ID là gì? Tôi có cần post cái của nợ gì mã hóa lên không?

- Thực ra m cũng đ' biết X-CV-ID là cm gì.

- Tôi có cần post cái của nợ gì mã hóa lên không? Trả lời: Tùy các bạn, nó phụ thuộc vào độ nguy hiểm của các bạn. Riêng tôi, tôi thích đơn giản, yêu màu tím !

Đoạn jav dài quá, chưa beautify nên thôi nợ k post nhé. Về cơ bản ae thấy khi nó post api place_order => nó sẽ tự chèn X-CV-ID = 100.

Tôi k biết là gì, tại sao lại 100 mà đ' phải 999 hay 9999. Như tôi đã đề cập ở trên đấy "Tùy các bạn, nó phụ thuộc vào độ nguy hiểm của các bạn". Các bạn thích post data mã hóa cho nguy hiểm hoặc thích số 100 thì cứ cho nó là 100 đi.

Còn tôi, tôi thích số 69 anh em ạ. Nên tôi cho nó = 69. Vì nó là 69 nên tôi chỉ cần post đoạn json như trước kia lên mà thôi. K cần thiết mã hóa làm gì cả.

Kết luận 2: 

- X-CV-ID >= 100 ==> thì post data mã hóa (Mà trong bài này m có hướng dẫn cách mã hóa data json đ' đâu?)

-  0 < X-CV-ID < 100 ==> Post cái json như mọi khi bạn vẫn làm :)

2020-03-01_09h41_22.png


2020-03-01_09h41_57.png

 

Chốt: AE chỉ cần tính đúng x-track-id là đủ.

Ae đã có 10tr cho tháng 3 chưa? Ngại gì k thử nhỉ.

Hãy để lại 1 vài like và ít còm men cho người ae thiện lành nào !

  • Like 23
  • Thanks 2
  • Love 4

Share this post


Link to post
Share on other sites

Post mã hóa thì nhận lại mã hóa, post json thì nhận lại json.

Shopee chơi đúng kiểu gieo nhân nào, ăn quả đấy =))

Share this post


Link to post
Share on other sites

@Wikipedia ồ ồ ồ.. thật là sảng khoái :c23: bài viết rất ổn áp .. thay mặt đội ngũ ban quản trị, dân code dạo, đội mmo cám ơn sự chia sẻ của bạn :c14:

Share this post


Link to post
Share on other sites
7 giờ trước, Wikipedia said:

Như ae đã biết, vụ checkout shopee giờ khá khoai. Hnay rảnh rỗi - sang tháng mới - tặng ae đoạn code checkout Shopee. Mà chính xác hơn là solution cho ae quất. 

Giá trị: 10.000.000 VND :v (ảo tưởng tí)

1. x-track-id là gì?

Như ae thấy, giờ khi call place_order, trong header sẽ có thằng x-track-id. Vậy nó là con mẹ gì vậy?

Shopee giờ khôn hơn rồi. Đầu tiên, em nó sẽ dùng vài thông tin trong đoạn trả về của api checkout/get + thông tin account đặt hàng => Mã hóa SHA512 => tạo ra 1 chuỗi x-track-id.

SHA512 là mã hóa 1 chiều, nên cơ bản là không thể giải mã. Vậy shopee check valid cái x-track-id thế nào?

Cũng giống như việc check password vậy, shopee sẽ dựa vào thông tin bạn post lên ở api place_order và cũng mã hóa các thông tin cần thiết => sau đó so sánh kq đó với chính cái x-track-id bạn post llên trong header.

Lý thuyết thì vậy rồi, giờ là cách tính x-track-id.

Trước tiên chia sẻ với a/e hàm Encrypt HMACSHA512 trước đã nhé

Nội dung ẩn

 


private string SHA512_ComputeHash(string text, string secretKey)
        {
            var hash = new StringBuilder(); ;
            byte[] secretkeyBytes = Encoding.UTF8.GetBytes(secretKey);
            byte[] inputBytes = Encoding.UTF8.GetBytes(text);
            using (var hmac = new HMACSHA512(secretkeyBytes))
            {
                byte[] hashValue = hmac.ComputeHash(inputBytes);
                foreach (var theByte in hashValue)
                {
                    hash.Append(theByte.ToString("x2"));
                }
            }

            return hash.ToString();
        }

 

 

 

rồi, nó cần 2 tham số. Giờ mình nói cái text trước nhé. Nó là tập cmn hợp của các thông tin sau:


 u = t.userId || 0,
      s = n(["client_id"], 0),
      d = n(["cart_type"], 0),
      f = n(["device_info", "device_fingerprint"], ""),
      l = n(["device_info", "device_id"], ""),
      _ = a(["shop", "shopid"], 0),
      p = c(["itemid"], 0),
      E = c(["modelid"], 0),
      h = c(["quantity"], 0),
      m = i(["buyer_address_data", "addressid"], 0),
      O = i(["selected_logistic_channelid"], 0),
      b = function(e) {
       void 0 === e && (e = {});
       var t = function(t, n) {
         return Object(o.a)(e, t) || n
        },
        n = t(["selected_payment_channel_data", "version"], 0);
       if (0 === n || 1 === n) {
        var r = t(["selected_payment_channel_data", "payment_channelid"], 0);
        return {
         paymentChannelId: r,
         paymentChannelItemId: 0,
         paymentChannelExternalItemId: 0,
         paymentOptionInfo: ""
        }
       }
       var a = t(["selected_payment_channel_data", "channel_id"], 0),
        i = t(["selected_payment_channel_data", "channel_item_option_info", "channel_item_id"], 0),
        c = t(["selected_payment_channel_data", "channel_item_option_info", "external_channel_item_id"], 0),
        u = t(["selected_payment_channel_data", "channel_item_option_info", "option_info"], "");
       return {
        paymentChannelId: a,
        paymentChannelItemId: i,
        paymentChannelExternalItemId: c,
        paymentOptionInfo: u
       }
      }(e),
      R = b.paymentChannelId,
      v = b.paymentChannelItemId,
      g = b.paymentChannelExternalItemId,
      C = [u, s, d, f, l, _, p, E, h, m, O, R, b.paymentOptionInfo, v, g, n(["promotion_data", "free_shipping_voucher_info", "free_shipping_voucher_id"], 0), n(["promotion_data", "use_coins"], 0) ? 1 : 0, n(["checkout_price_data", "total_payable"], 0)].join("_");
     return "buyerId,clientId,cartType,deviceFingerprint,deviceId,shopIds,itemIds,itemModelIds,itemQuantities,addressIds,logisticChannelIds,paymentChannelId,paymentOptionInfo,paymentChannelItemId,paymentChannelExternalItemId,fsvId,useCoins,totalPayable".split(",").forEach(function(e, t) {}), C

t.userid chính là userid của thằng đang checkout nhé.

Ae nào đọc tốt đoạn js kia thì đọc nhé. Riêng tôi, mù cmn jav

còn đây là code c#


string client_id = "0";
                string carType = "0";
                long shopid = obj.shoporders[0].shop.shopid;
                long itemid = obj.shoporders[0].items[0].itemid;
                long modelid = obj.shoporders[0].items[0].modelid;
                long qty = obj.shoporders[0].items[0].quantity;
                long channelId = obj.shipping_orders[0].selected_logistic_channelid;
                long paymentChannelId = obj.selected_payment_channel_data.payment_channelid;
                string paymentOptionInfo = "";
                string paymentChannelItemId = "0";
                string paymentChannelExternalItemId = "0";
                string useCoin = "1";
                long totalPayable = obj.checkout_price_data.total_payable;

                string finger = obj.device_info.device_fingerprint;
                string deviceid = obj.device_info.device_id;


                var list = new List<string>
                {
                    userid.ToString(),
                    client_id,
                    carType,
                    finger,
                    deviceid,
                    shopid.ToString(),
                    itemid.ToString(),
                    modelid.ToString(),
                    qty.ToString(),
                    addressid.ToString(),
                    channelId.ToString(),
                    paymentChannelId.ToString(),
                    paymentOptionInfo,
                    paymentChannelItemId,
                    paymentChannelExternalItemId,
                    ship.ToString(),
                    useCoin,
                    totalPayable.ToString()
                };

                string msg = string.Join("_", list);

thế là ra được cái thằng "text" rồi nhé. Nó chính là thằng sẽ được mã hóa để tạo ra x-track-id.

Giờ đến lượt secretkey. Thằng này thì đơn giản hơn.

Secretkey này có 3 thông tin join lại: usershopid_timestamp_nhan-to-bi-an

(Thật ra thằng này có nhiều hơn 3 thông tin, như secretBaseKey và UA. Như ae chỉ cần 3 thằng này là đủ. Ae nào muốn tìm hiểu thêm cái  này thì inbox chỗ nhạy cảm)

usershopid và timestamp thì thôi nhé. Ae tự thủ dâm nha.

còn nhân tố bí ẩn thì sao?


var n = "";
            switch (e % 10) {
            case 0:
                n = Object(o.a)(t, ["promotion_data", "free_shipping_voucher_info", "free_shipping_voucher_id"], 0) || 0;
                break;
            case 1:
                n = t.shipping_orders.reduce(function(e, t) {
                    return e + parseInt(t.selected_logistic_channelid, 10) || 0
                }, 0);
                break;
            case 2:
                var r = Object(o.a)(t, ["selected_payment_channel_data", "payment_channelid"], 0) || 0
                  , a = Object(o.a)(t, ["selected_payment_channel_data", "channel_id"], 0);
                n = r || a || 0;
                break;
            case 3:
                n = Object(o.a)(t, ["checkout_price_data", "total_payable"], 0);
                break;
            case 4:
                n = t.shoporders.reduce(function(e, t) {
                    return e + Object(o.a)(t, ["shop", "shopid"], 0)
                }, 0);
                break;
            case 5:
                n = t.shipping_orders.reduce(function(e, t) {
                    return e + Object(o.a)(t, ["order_total"], 0)
                }, 0);
                break;
            case 6:
                n = t.shoporders.reduce(function(e, t) {
                    return e + Object(o.a)(t, ["order_total"], 0)
                }, 0);
                break;
            case 7:
                n = t.shipping_orders.reduce(function(e, t) {
                    return e + Object(o.a)(t, ["buyer_address_data", "addressid"], 0)
                }, 0);
                break;
            case 8:
                n = t.shipping_orders.reduce(function(e, t) {
                    return e + Object(o.a)(t, ["shipping_fee"], 0)
                }, 0);
                break;
            case 9:
                n = t.shipping_orders.reduce(function(e, t) {
                    return e + Object(o.a)(t, ["shipping_fee"], 0) + Object(o.a)(t, ["shipping_fee_discount"], 0)
                }, 0)
            }

thằng ml e kia chính là userid nhé. ae tự lắc não với đoạn này nhé. game is easy.

Kết luận 1: chuỗi mã hóa thì fix bởi các tham số như trên, còn key mã hóa thì sẽ phụ cmn thuộc vào userid của thằng đang mua. Và thằng x-track-id này lại trở thành key của hàm mã hóa data json.

 

2. X-CV-ID là gì? Tôi có cần post cái của nợ gì mã hóa lên không?

- Thực ra m cũng đ' biết X-CV-ID là cm gì.

- Tôi có cần post cái của nợ gì mã hóa lên không? Trả lời: Tùy các bạn, nó phụ thuộc vào độ nguy hiểm của các bạn. Riêng tôi, tôi thích đơn giản, yêu màu tím !

Đoạn jav dài quá, chưa beautify nên thôi nợ k post nhé. Về cơ bản ae thấy khi nó post api place_order => nó sẽ tự chèn X-CV-ID = 100.

Tôi k biết là gì, tại sao lại 100 mà đ' phải 999 hay 9999. Như tôi đã đề cập ở trên đấy "Tùy các bạn, nó phụ thuộc vào độ nguy hiểm của các bạn". Các bạn thích post data mã hóa cho nguy hiểm hoặc thích số 100 thì cứ cho nó là 100 đi.

Còn tôi, tôi thích số 69 anh em ạ. Nên tôi cho nó = 69. Vì nó là 69 nên tôi chỉ cần post đoạn json như trước kia lên mà thôi. K cần thiết mã hóa làm gì cả.

Kết luận 2: 

- X-CV-ID >= 100 ==> thì post data mã hóa (Mà trong bài này m có hướng dẫn cách mã hóa data json đ' đâu?)

-  0 < X-CV-ID < 100 ==> Post cái json như mọi khi bạn vẫn làm :)

2020-03-01_09h41_22.png


2020-03-01_09h41_57.png

 

Chốt: AE chỉ cần tính đúng x-track-id là đủ.

Ae đã có 10tr cho tháng 3 chưa? Ngại gì k thử nhỉ.

Hãy để lại 1 vài like và ít còm men cho người ae thiện lành nào !

Ớ ... cuối cùng cái cốt yếu là chỉ cần tìm thằng hash512 là xong phim à ?:167788150085138:, @Wikipedia anh mò kinh thật ... đỡ tốn công giải mã hóa nhọc hết cả đầu não..

Share this post


Link to post
Share on other sites
ngay bây giờ, Thiên Chi Kiều Nữ said:

Ớ ... cuối cùng cái cốt yếu là chỉ cần tìm thằng hash512 là xong phim à ?:167788150085138:, @Wikipedia anh mò kinh thật ... đỡ tốn công giải mã hóa nhọc hết cả đầu não..

Nó có đoạn nếu xcdid >= 100 thì encrypt data và post text. Else thì post như bt. Chỉ tiêm thêm 2 cái header xcvid và xtrackid. Post json thì kq nhận về là json. Post encrypt data thì nhận kq cũng bị encrypt.

Vấn đề là tìm đc cái key để mã hóa xtrackid :v

  • Haha 1

Share this post


Link to post
Share on other sites
14 phút trước, Wikipedia said:

Nó có đoạn nếu xcdid >= 100 thì encrypt data và post text. Else thì post như bt. Chỉ tiêm thêm 2 cái header xcvid và xtrackid. Post json thì kq nhận về là json. Post encrypt data thì nhận kq cũng bị encrypt.

Vấn đề là tìm đc cái key để mã hóa xtrackid :v

Có thể cho mỵ phỏng vấn :167788170085136:làm sao anh @Wikipedia có thể debug ra cách tìm trackid loằng ngoằng thế kia không ?  :167788283418458:chứ mỵ cứ thấy mã hóa là đầu hàng dồi à :a28:

Share this post


Link to post
Share on other sites
21 phút trước, Thiên Chi Kiều Nữ said:

Có thể cho mỵ phỏng vấn :167788170085136:làm sao anh @Wikipedia có thể debug ra cách tìm trackid loằng ngoằng thế kia không ?  :167788283418458:chứ mỵ cứ thấy mã hóa là đầu hàng dồi à :a28:

Ít ra còn lần theo file js được. Chứ bài toán khoai hơn là ở app. Cách mã hóa trackid có vẻ lại khác. K biết là có thêm tham số gì @@ khá là toang.

Khả năng cao là dùng đến tham số UA và secretKeyBase nào đó.

Share this post


Link to post
Share on other sites
Posted (edited)
On 3/1/2020 at 6:34 PM, Wikipedia said:

Ít ra còn lần theo file js được. Chứ bài toán khoai hơn là ở app. Cách mã hóa trackid có vẻ lại khác. K biết là có thêm tham số gì @@ khá là toang.

 Khả năng cao là dùng đến tham số UA và secretKeyBase nào đó.

Cảm ơn bác, e cũng vừa debug web ra được mấy hôm trước. Còn mỗi bên app khó nhai nhất, e thử combine 1 số info (dựa trên js) xong hash và compare với SHA512 gốc nhưng vẫn chưa nhai được :( 

Edited by ltpnha

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...