الخلفية
مقالة CertiK السابقة "ممارسة لعبة جديدة على السلسلة " "كشفت تقنية RugPull واسعة النطاق" عن عنوان حصاد آلي احتيالي واسع النطاق للخروج 0xdf1a يستهدف الروبوتات الجديدة. أكمل هذا العنوان أكثر من 200 خروج في حوالي شهرين فقط. عملية احتيال (يشار إليها فيما يلي بشكل جماعي باسم RugPull )، ولكن هذه العصابة ليس لديها سوى طريقة RugPull واحدة.
استخدمت المقالة السابقة رمز MUMI كمثال لوصف طريقة RugPull للمجموعة الموجودة خلف العنوان:قم بتعديل الرمز المميز لعنوان الضريبة مباشرة من خلال رصيد الباب الخلفي للكود، ولكن لم يتم تعديل إجمالي المعروض من الرموز المميزة، ولا إرسال حدث نقل، لذلك لم يتمكن المستخدمون الذين شاهدوا etherscan من اكتشاف سلوك المشروع المتمثل في سك الرموز المميزة سرًا.
تستخدم مقالة اليوم الرمز المميز "ZhongHua" كمثال لتحليل طريقة RugPull أخرى للمجموعة: استخدام منطق وظيفة الضرائب المعقدة للتغطية على وظيفة نقل RugPull. بعد ذلك، نقوم بتحليل تفاصيل طريقة RugPull أخرى على العنوان 0xdf1a من خلال حالة الرمز المميز "ZhongHua".
عملية احتيال متعمقة
في هذه الحالة، طرف المشروع تم استبدال ما مجموعه 999 مليار ZhongHua بحوالي 5.884 WETH، مما أدى إلى استنزاف سيولة المجمع. من أجل الحصول على فهم أعمق لعملية احتيال RugPull بأكملها، دعونا نفرز الأحداث من البداية.
نشر الرموز المميزة
يناير الساعة 1 :40 صباحًا في الثامن عشر (بالتوقيت العالمي الموحد، نفس أدناه)، نشر عنوان المهاجم (؟0x74fc) رمز ERC20 المميز المسمى ZhongHua (؟0x71d7)، واستخرج مسبقًا مليار رمز مميز وأرسلها إلى عنوان المهاجم (؟0x74fcfc) ).
يتوافق عدد الرموز المميزة التي تم تعدينها مسبقًا مع العدد المحدد في الكود المصدري للعقد.
إضافة السيولة
1:50 (10 دقائق بعد إنشاء الرمز المميز)، عنوان المهاجم (?0x74fc) منح أذونات الموافقة على رموز ZhongHua إلى Uniswap V2 Router استعدادًا لإضافة السيولة.
بعد دقيقة واحدة، يستدعي عنوان المهاجم (?0x74fc) وظيفة addLiquidityETH في جهاز التوجيه لإضافة السيولة لإنشاء مجمع سيولة ZhongHua-WETH (?0x5c8b)، وإضافة جميع الرموز المميزة التي تم تعدينها مسبقًا و1.5 ETH إلى تجمع السيولة، وحصلت أخيرًا على ما يقرب من 1.225 من رموز LP.
من سجلات نقل الرمز المميز المذكورة أعلاه، يمكننا أن نرى أنه في عملية نقل واحدة، أرسل المهاجم (؟0x74fc) 0 رمزًا مميزًا إلى عقد رمز ZhongHua نفسه.
هذا النقل ليس تحويلاً عاديًا لإضافة السيولة. من خلال النظر إلى الكود المصدري لعقد الرمز المميز، وجدنا أنه تم تنفيذ وظيفة _getAmount، وهي يقوم المسؤول عن تحويل الأموال من العنوان بخصم الأموال وحساب رسوم المناولة التي سيتم تحصيلها، ثم يرسل رسوم المناولة إلى عنوان الرمز المميز، ثم يقوم بتشغيل حدث النقل للإشارة إلى أن عنوان الرمز المميز يتلقى رسوم المعالجة.
ستحدد وظيفة _getAmount ما إذا كان مرسل النقل هو _المالك. إذا كان _المالك، فسيتم تعيين رسوم المعالجة على 0. _يتم تعيين المالك بواسطة معلمة الإدخال الخاصة بالمنشئ عند نشر العقد القابل للامتلاك.
يرث عقد رمز ZhongHua العقد القابل للملكية ويستخدم msg.sender الخاص بأداة النشر كمعلمة إدخال للمنشئ القابل للملكية أثناء النشر.
لذا فإن عنوان المهاجم (?0x74fc) هو _مالك عقد الرمز المميز. يتم إرسال نقل الرمز المميز 0 الذي يضيف السيولة من خلال وظيفة _getAmount، لأنه سيتم استدعاء _getAmount ضمن وظيفتي النقل والتحويل.
تأمين السيولة بشكل دائم
1 عند في الساعة 51:00 (خلال دقيقة واحدة من إنشاء مجمع السيولة)، سيرسل عنوان المهاجم (؟0x74fc) جميع رموز LP البالغ عددها 1.225 والتي تم الحصول عليها عن طريق إضافة السيولة مباشرة إلى عنوان 0xdead لإكمال القفل الدائم لرموز LP المميزة.
على غرار حالة رمز MUMI، عندما يتم قفل LP، من الناحية النظرية لم يعد عنوان المهاجم (؟0x74fc) لديه القدرة على تنفيذ RugPull عن طريق إزالة السيولة. في عملية احتيال RugPull التي تتم بقيادة العنوان 0xdf1a، والتي تستهدف الروبوتات الجديدة، تُستخدم هذه الخطوة بشكل أساسي لخداع البرنامج النصي لمكافحة الاحتيال للروبوتات الجديدة.
من وجهة نظر المستخدم، تمت إضافة جميع الرموز المميزة المُعدَّنة مسبقًا إلى مجمع السيولة، ولم يحدث أي شيء غير طبيعي.
RugPull
2:10 صباحًا بعد دقائق (حوالي 30 دقيقة من إنشاء رمز ZhongHua)، نشر عنوان المهاجم 2 (؟0x5100) عقد هجوم (؟0xc403) خصيصًا لـ RugPull.
على غرار حالة رموز MUMI، لم يستخدم جانب المشروع عنوان الهجوم لنشر عقد رمز ZhongHua، وعقد الهجوم المستخدم لـ RugPull ليس مفتوح المصدر. والغرض هو جعل الأمر أكثر صعوبة للفنيين لتتبع المصدر. تتمتع بعض عمليات الاحتيال في RugPull بهذه الخاصية.
في الساعة 7:46 صباحًا (حوالي 6 ساعات بعد إنشاء عقد الرمز المميز)، أجرى عنوان المهاجم 2 (؟0x5100) عملية RugPull.
من خلال استدعاء طريقة "swapExactETHForTokens" لعقد الهجوم (؟0xc403)، قام بنقل 999 مليار رمز ZhongHua من عقد الهجوم وتبادل حوالي 5.884 ETH، و استنزفت معظم السيولة في المجمع.
نظرًا لأن عقد الهجوم (?0xc403) ليس مفتوح المصدر، فقد قمنا بتفكيك الكود الثانوي الخاص به وكانت النتائج كما يلي:
https://app.dedaub.com/ethereum/address/0xc40343c5d0e9744a7dfd8eb7cd311e9cec49bd2e/decompiled
عقد الهجوم (?0xc403) ) تتمثل الوظيفة الرئيسية لوظيفة "swapExactETHForTokens" في استخدام الموافقة أولاً لمنح جهاز التوجيه UniswapV2 الحد الأقصى لعدد أذونات نقل رمز ZhongHua، ثم استخدام جهاز التوجيه لتحديد عدد رموز ZhongHua "xt" المملوكة للمتصل (عقد الهجوم (?0xc403)) ) يتم تحويله إلى ETH وإرساله إلى عنوان "_rescue" المعلن في عقد الهجوم (?0xc403).
يمكنك أن ترى أن العنوان المطابق لـ "_rescue" هو بالضبط ناشر عقد الهجوم (؟0xc403): عنوان المهاجم 2 (؟0x5100).
معلمة الإدخال xt لمعاملة RugPull هذه هي 999,000,000,000,000,000,000، أي ما يعادل 999 مليار رمز ZhongHua (العلامة العشرية لـ ZhongHua هي 9).
في النهاية، استخدم المشروع 999 مليار ZhongHua لتصريف WETH في مجمع السيولة وإكمال RugPull.
على غرار حالة MUMI في المقالة السابقة، نحتاج أولاً إلى تأكيد مصدر رموز ZhongHua المميزة في عقد الهجوم (؟0xc403)< /قوي>. لقد تعلمنا من المقالة السابقة أن إجمالي المعروض من رموز ZhongHua يبلغ مليارًا، وبعد نهاية RugPull، لا يزال إجمالي المعروض من رموز ZhongHua التي استفسرنا عنها في Block Explorer 1 مليار. عدد الرموز المباعة بموجب عقد الهجوم (؟0xc403) هو 999 مليار، وهو 999 ضعف إجمالي العرض المسجل في العقد وهذا يتجاوز بكثير إجمالي العرض من أين تأتي كمية الرموز؟
لقد فحصنا تاريخ حدث نقل ERC20 للعقد ووجدنا أنه، مثل حالة RugPull لرمز MUMI، فإن عقد الهجوم (؟0xc403) في حالة رمز ZhongHua المميز لم يتضمن أيضًا أي حدث نقل رمز ERC20.
في حالة MUMI، تأتي الرموز المميزة للعقد الضريبي من التعديلات المباشرة على الرصيد في عقد الرمز المميز، مما يتسبب في أن يمتلك العقد الضريبي الرموز المميزة التي تتجاوز إجمالي العرض بكثير. نظرًا لأن عقد الرمز المميز MUMI لا يقوم بتعديل العرض الإجمالي للرمز المميز عند تعديل الرصيد، ولا يؤدي إلى تشغيل حدث النقل، لذلك لا يمكننا رؤية سجل نقل الرمز المميز للعقد الضريبي في حالة MUMI، كما لو تم استخدام العقد الضريبي بالنسبة لرموز RugPull، يبدو الأمر وكأنك تظهر من فراغ.
بالعودة إلى حالة ZhongHua، يبدو أيضًا أن رموز ZhongHua في عقد الهجوم (؟0xc403) تظهر من لا شيء، لذلك نذهب أيضًا إلى ZhongHua عقد رمزي ابحث عن الكلمة الرئيسية "الرصيد" في ملف .
تظهر النتائج أن هناك ثلاثة تعديلات فقط على متغير الرصيد في عقد الرمز المميز بأكمله، وهي "_getAmount"، " _transferFrom" وفي وظيفة "_transferBasic".
يتم استخدام "_getAmount" لمعالجة منطق تحصيل رسوم التحويل، ويتم استخدام "_transferFrom" و"_transferBasic" لمعالجة منطق التحويل، والشكل التالي لا تظهر رموز MUMI بشكل عام لتعديل بيان الرصيد بشكل صريح.
الأهم من ذلك، أن عقد الرمز المميز MUMI لم يقم بتشغيل حدث النقل عندما قام بتعديل رصيد العقد الضريبي مباشرة. ولهذا السبب لا يمكننا الاستعلام عن حدث نقل الرمز المميز للعقد الضريبي في متصفح الكتلة، ولكن العقد الضريبي أسباب امتلاك عدد كبير من العملات.
ومع ذلك، في عقد رمز ZhongHua، سواء كانت وظيفة "_getAmount" أو "_transferFrom" أو "_transferBasic"، بعد تعديل الرصيد، لديهم تم تشغيل حدث النقل بشكل صحيح. يتعارض هذا مع الموقف الذي لم نتمكن فيه من العثور على حدث النقل الذي تم فيه نقل الرمز المميز عندما استفسرنا عن حدث النقل المتعلق بعقد الهجوم (?0xc403) .
هل من الممكن أنه على عكس حالة MUMI، فإن الرموز المميزة في عقد الهجوم هذا (؟0xc403) ظهرت بالفعل من لا شيء؟
التقنيات السرية
< strong> من أين أتت الرموز المميزة لمهاجمة العقد؟
أثناء تحليل الحالة عندما اكتشفنا أن كل تعديل في عقد ZhongHua عندما يؤدي التوازن إلى تشغيل حدث النقل بشكل صحيح، ولكن لا يزال يتعذر العثور على سجل نقل الرمز المميز أو حدث النقل المتعلق بعقد الهجوم (؟0xc403)، فأنت بحاجة إلى العثور على أفكار تحليل جديدة.
لقد استفسرنا عن عدد كبير من سجلات النقل واستخدمنا وظيفة "performZhongSwap" في العقد باعتبارها اختراقًا. هذه الوظيفة مسؤولة عن تحويل الرموز المميزة في للبيع، في حوادث RugPull الأخرى التي قمنا بتحليلها، هناك العديد من الحالات التي يتم فيها استخدام هذا النوع من الوظائف كباب خلفي لـ RugPull.
على الرغم من فحص الوظائف الأخرى، لم يتم العثور على أي شيء. لذلك بدأنا في التركيز على وظيفة "النقل" نفسها، وبغض النظر عن كيفية تنفيذ المهاجم لـ RugPull، يجب أن يحتوي منطق تنفيذ وظيفة "النقل" على أهم المعلومات.
النقل القاتل
تستدعي وظيفة "النقل" في عقد الرمز المميز وظيفة "_transferFrom" مباشرة.
يبدو أن وظيفة "النقل" تنفذ عملية نقل الرمز المميز، وسيتم تشغيل حدث النقل بعد اكتمال النقل.
ولكنقبل نقل الرموز المميزة، ستستخدم وظيفة "النقل" أولاً وظيفة "_isNotTax" لتحديد ما إذا كان مرسل النقل هو ضرائب أم لا. عنوان مجاني: إذا لم يكن الأمر كذلك، فاستخدم وظيفة "_getAmount" لتحصيل الضرائب، وإذا كان الأمر كذلك، فلن يتم تحصيل أي ضرائب وسيتم إرسال الرموز المميزة مباشرة إلى المستلم. وهنا تكمن المشكلة بالضبط.
كما ذكر أعلاه، في تنفيذ "_getAmount"، يتحقق عقد الرمز المميز من رصيد المرسل ويتحقق من رصيد المرسل يتم إجراؤها وإرسال الرسوم إلى عقد الرمز المميز.
المشكلة هي أن "_getAmount" يتم استخدامه فقط عندما المرسل ليس عند الاتصال بالعنوان المعفى من الضرائب. عندما يكون المرسل عنوانًا معفيًا من الضرائب، تتم إضافة المبلغ مباشرة إلى رصيد المستلم.
تصبح المشكلة واضحة جدًا في هذا الوقت:عندما يتم استخدام العنوان المعفي من الضرائب كمرسل للنقل، فإن عقد الرمز المميز لا يتحقق مما إذا كان رصيد المرسل كافي ولا توجد حتى عملية خصم المبلغ من رصيد المرسل. وهذا يعني أنه يمكن إرسال أي مبلغ من الرموز المميزة إلى أي عنوان طالما أنه عنوان معفى من الضرائب يحدده عقد الرمز المميز. ولهذا السبب يمكن لعقد الهجوم (؟0xc403) أن ينقل مباشرة 999 ضعف إجمالي المعروض من الرموز المميزة.
بعد الفحص، وجد أن عقد الرمز المميز قام فقط بتعيين _taxReceipt كعنوان معفي من الضرائب في المُنشئ، وكان العنوان المقابل لـ _taxReceipt هو عقد الهجوم (؟ 0xc403).
تم منذ ذلك الحين تحديد طريقة رمز RugPull الخاص بـ ZhongHua:استخدم المهاجم منطقًا محددًا للتحايل على الامتيازات يسمح التحقق من رصيد العنوان للعنوان المميز بنقل الرموز المميزة من لا شيء، وبالتالي إكمال RugPull.
كيفية تحقيق الأرباح
باستخدام الثغرة الأمنية المذكورة أعلاه، يستدعي عنوان المهاجم 2 (?0x5100) مباشرة المملوكة لـ "swapExactETHForTokens" من عقد الهجوم المميز (؟0xc403) تكمل RugPull. في وظيفة "swapExactETHForTokens"، منح عقد الهجوم (؟0xc403) إذن نقل الرمز المميز إلى Uniswap V2 Router، ثم تم استدعاء وظيفة تبادل الرمز المميز لجهاز التوجيه مباشرة لتبادل 999 مليار رمز ZhongHua مقابل 5.88 ETH في المجمع.
في الواقع، بالإضافة إلى معاملة RugPull المذكورة أعلاه، قام طرف المشروع أيضًا ببيعها 11 مرة من خلال عقد الهجوم (؟0xc403). strong>الرموز، تم الحصول على إجمالي 9.64ETH، بالإضافة إلى معاملة RugPull الأخيرة، تم الحصول على إجمالي 15.52ETH. تبلغ التكلفة 1.5 إيثريوم فقط لإضافة السيولة، ورسوم بسيطة لنشر العقود، ومبلغ صغير من إيثريوم لحث الروبوتات الجديدة على التبادل النشط.
حتى أن فريق المشروع استخدم عناوين EOA مختلفة لاستدعاء عقد الهجوم (؟0xc403) لبيع الرموز المميزة. يبدو أن المرسلين المختلفين يبيعون العملات المميزة للتخفي نيتها الحقيقية المتمثلة في صرف الأموال بشكل مستمر.
الملخص
الآن بالنظر إلى الوراء والتفكير في حالة RugPull لرمز ZhongHua بأكمله، وجدت أن الطريقة نفسها بسيطة جدًا ولكنه يلغي فقط التحقق من رصيد الرمز المميز للعنوان المميز. ولكن لماذا لم يكن الأمر سلسًا عند تحليل هذه الحالة؟ قد يكون هناك سببين رئيسيين:
1. الحماية الأمنية والهجوم لهما رؤى مختلفة. بالنسبة لممارسي الأمن، يعد التحقق من الرصيد في الكود هو الضمان الأمني الأساسي الذي يجب إكماله، لذلك يعتقد معظم ممارسي الأمن دون وعي أن وظيفة "التحويل" ستكمل التحقق من رصيد المستخدم بطبيعة الحال كن حذرًا من مثل هذه الثغرات الأمنية (أو أعتقد أن هذه الثغرات الأمنية أساسية للغاية ولن يستخدمها المهاجمون).
ومع ذلك، من وجهة نظر المهاجم، غالبًا ما تكون طريقة الهجوم الأكثر فاعلية هي الأبسط: عدم التحقق من الرصيد فعال وسهل استغلاله. تجاهل تقنية RugPull، فلا يوجد سبب لعدم استخدامها. هذا هو الحال بالفعل، على الأقل من منظور توصيف الحالة، فإن طريقة RugPull في حالة رمز ZhongHua تترك أقل قدر من الآثار، ويصعب تتبعها أكثر من الأنواع الأخرى من RugPull قم بمراجعة الكود يدويًا لتحديد موقع الباب الخلفي للكود.
2. يقوم جانب المشروع بإخفاء رمز الباب الخلفي الذي لا يتطلب التحقق من الرصيد للعناوين المميزة. حتى أن فريق المشروع نفذ بشكل مستقل مجموعة كاملة من منطق حساب تحويل الضرائب ومنطق سحب عنوان الرمز المميز ومنطق إعادة الاستثمار للعناوين غير المميزة، مما يجعل من المعقول تنفيذ منطق نقل معقد للرموز المميزة. عند تحويل الأموال إلى عناوين عادية أخرى، لا يختلف السلوك عن السلوك العادي دون النظر إلى الكود بعناية، لا يمكن العثور على أي أدلة.
بمقارنة حالات RugPull الخاصة بهذا الفريق لرموز MUMI ورموز ZhongHua، يستخدم كلاهما أساليب سرية نسبيًا للتحكم في حقوق العناوين المميزة لكميات كبيرة من الرموز المميزة .
في حالة رمز MUMI RugPull، قام طرف المشروع بتعديل الرصيد مباشرة دون تعديل TotalSupply أو تشغيل حدث النقل، مما يجعل المستخدم غير قادر على إدراك الامتيازات: يحتوي العنوان بالفعل على كمية كبيرة من الرموز المميزة.
تعتبر حالة رمز ZhongHua أكثر شمولاً من خلال عدم التحقق مباشرة من رصيد العنوان المميز، بخلاف النظر إلى كود المصدر ، من المستحيل بأي وسيلة معرفة أن العنوان المميز يمتلك بالفعل عددًا غير محدود من الرموز المميزة (استخدام BalanceOf للاستعلام عن رصيد العنوان المميز سيظهر 0، ولكن يمكن نقل عدد غير محدود من الرموز المميزة).
تعكس حالة RugPull الخاصة برمز ZhongHua مشكلات الأمان المحتملة لمعيار الرمز المميز، ولا يمكن استخدام معيار الرمز المميز ERC20 إلا لتقييد الأمان لا يمكن للرجل أن يحرس ضد الأشرار. غالبًا ما يخفي المهاجمون أبوابًا خلفية يصعب اكتشافها على أساس تطبيق منطق العمل القياسي. من خلال توحيد سلوك الرمز المميز، على الرغم من تقليل مرونة الوظائف، يتم تجنب إمكانية وجود أبواب خلفية مخفية ويتم توفير المزيد من الأمان.