سمارٹ کنٹریکٹ کے بگز تلاش کرنے کے لیے سلدر کا استعمال کیسے کریں
سلدر کا استعمال کیسے کریں
اس ٹیوٹوریل کا مقصد یہ دکھانا ہے کہ سمارٹ کنٹریکٹس میں خودکار طریقے سے بگز تلاش کرنے کے لیے سلدر کا استعمال کیسے کیا جائے۔
- انسٹالیشن
- کمانڈ لائن کا استعمال
- سٹیٹک تجزیہ کا تعارف: سٹیٹک تجزیہ کا مختصر تعارف
- API: Python API کی تفصیل
انسٹالیشن
سلدر کے لیے Python >= 3.6 درکار ہے۔ اسے pip کے ذریعے یا Docker کا استعمال کرتے ہوئے انسٹال کیا جا سکتا ہے۔
pip کے ذریعے سلدر:
pip3 install --user slither-analyzer
Docker کے ذریعے سلدر:
docker pull trailofbits/eth-security-toolbox
docker run -it -v "$PWD":/home/trufflecon trailofbits/eth-security-toolbox
آخری کمانڈ eth-security-toolbox کو ایک Docker میں چلاتی ہے جسے آپ کی موجودہ ڈائریکٹری تک رسائی حاصل ہے۔ آپ اپنے ہوسٹ سے فائلیں تبدیل کر سکتے ہیں، اور Docker سے فائلوں پر ٹولز چلا سکتے ہیں
Docker کے اندر، چلائیں:
solc-select 0.5.11
cd /home/trufflecon/
سکرپٹ چلانا
Python 3 کے ساتھ Python سکرپٹ چلانے کے لیے:
python3 script.py
کمانڈ لائن
کمانڈ لائن بمقابلہ صارف کے متعین کردہ سکرپٹس۔ سلدر پہلے سے طے شدہ ڈیٹیکٹرز کے ایک سیٹ کے ساتھ آتا ہے جو بہت سے عام بگز تلاش کرتے ہیں۔ کمانڈ لائن سے سلدر کو کال کرنے سے تمام ڈیٹیکٹرز چلیں گے، سٹیٹک تجزیہ کے تفصیلی علم کی ضرورت نہیں ہے:
slither project_paths
ڈیٹیکٹرز کے علاوہ، سلدر میں اپنے پرنٹرز (opens in a new tab) اور ٹولز (opens in a new tab) کے ذریعے کوڈ کا جائزہ لینے کی صلاحیتیں موجود ہیں۔
نجی ڈیٹیکٹرز اور GitHub انضمام تک رسائی حاصل کرنے کے لیے crytic.io (opens in a new tab) کا استعمال کریں۔
سٹیٹک تجزیہ
سلدر سٹیٹک تجزیہ فریم ورک کی صلاحیتوں اور ڈیزائن کو بلاگ پوسٹس (1 (opens in a new tab)، 2 (opens in a new tab)) اور ایک اکیڈمک پیپر (opens in a new tab) میں بیان کیا گیا ہے۔
سٹیٹک تجزیہ مختلف اقسام میں موجود ہے۔ آپ کو غالباً احساس ہوگا کہ clang (opens in a new tab) اور gcc (opens in a new tab) جیسے کمپائلرز ان تحقیقی تکنیکوں پر انحصار کرتے ہیں، لیکن یہ (Infer (opens in a new tab)، CodeClimate (opens in a new tab)، FindBugs (opens in a new tab) اور رسمی طریقوں پر مبنی ٹولز جیسے Frama-C (opens in a new tab) اور Polyspace (opens in a new tab) کی بھی بنیاد ہے۔
ہم یہاں سٹیٹک تجزیہ کی تکنیکوں اور محققین کا جامع جائزہ نہیں لیں گے۔ اس کے بجائے، ہم اس بات پر توجہ مرکوز کریں گے کہ سلدر کے کام کرنے کے طریقے کو سمجھنے کے لیے کیا ضروری ہے تاکہ آپ اسے بگز تلاش کرنے اور کوڈ کو سمجھنے کے لیے زیادہ مؤثر طریقے سے استعمال کر سکیں۔
کوڈ کی نمائندگی
متحرک تجزیہ (dynamic analysis) کے برعکس، جو ایک ہی ایگزیکیوشن پاتھ کے بارے میں استدلال کرتا ہے، سٹیٹک تجزیہ ایک ہی وقت میں تمام پاتھس کے بارے میں استدلال کرتا ہے۔ ایسا کرنے کے لیے، یہ ایک مختلف کوڈ کی نمائندگی پر انحصار کرتا ہے۔ دو سب سے عام نمائندگیاں ایبسٹریکٹ سنٹیکس ٹری (AST) اور کنٹرول فلو گراف (CFG) ہیں۔
ایبسٹریکٹ سنٹیکس ٹریز (AST)
جب بھی کمپائلر کوڈ کو پارس کرتا ہے تو AST کا استعمال کیا جاتا ہے۔ یہ شاید سب سے بنیادی ڈھانچہ ہے جس پر سٹیٹک تجزیہ کیا جا سکتا ہے۔
مختصراً، ایک AST ایک سٹرکچرڈ ٹری ہے جہاں، عام طور پر، ہر لیف (leaf) میں ایک متغیر (variable) یا مستقل (constant) ہوتا ہے اور اندرونی نوڈز آپرینڈز (operands) یا کنٹرول فلو آپریشنز ہوتے ہیں۔ درج ذیل کوڈ پر غور کریں:
function safeAdd(uint a, uint b) pure internal returns(uint){
if(a + b <= a){
revert();
}
return a + b;
}
متعلقہ AST اس میں دکھایا گیا ہے:
سلدر solc کے ذریعے ایکسپورٹ کردہ AST کا استعمال کرتا ہے۔
اگرچہ اسے بنانا آسان ہے، لیکن AST ایک نیسٹڈ (nested) ڈھانچہ ہے۔ بعض اوقات، اس کا تجزیہ کرنا سب سے سیدھا کام نہیں ہوتا۔ مثال کے طور پر، ایکسپریشن a + b <= a کے ذریعے استعمال ہونے والے آپریشنز کی شناخت کرنے کے لیے، آپ کو پہلے <= اور پھر + کا تجزیہ کرنا ہوگا۔ ایک عام طریقہ نام نہاد وزیٹر پیٹرن (visitor pattern) کا استعمال کرنا ہے، جو ٹری کے ذریعے بار بار (recursively) نیویگیٹ کرتا ہے۔ سلدر میں ExpressionVisitor (opens in a new tab) میں ایک عام وزیٹر شامل ہے۔
درج ذیل کوڈ یہ پتہ لگانے کے لیے ExpressionVisitor کا استعمال کرتا ہے کہ آیا ایکسپریشن میں اضافہ (addition) شامل ہے:
from slither.visitors.expression.expression import ExpressionVisitor
from slither.core.expressions.binary_operation import BinaryOperationType
class HasAddition(ExpressionVisitor):
def result(self):
return self._result
def _post_binary_operation(self, expression):
if expression.type == BinaryOperationType.ADDITION:
self._result = True
visitor = HasAddition(expression) # expression وہ ایکسپریشن ہے جسے ٹیسٹ کیا جانا ہے
print(f'The expression {expression} has a addition: {visitor.result()}')
کنٹرول فلو گراف (CFG)
دوسری سب سے عام کوڈ کی نمائندگی کنٹرول فلو گراف (CFG) ہے۔ جیسا کہ اس کے نام سے ظاہر ہوتا ہے، یہ ایک گراف پر مبنی نمائندگی ہے جو تمام ایگزیکیوشن پاتھس کو ظاہر کرتی ہے۔ ہر نوڈ میں ایک یا ایک سے زیادہ ہدایات ہوتی ہیں۔ گراف میں کنارے (edges) کنٹرول فلو آپریشنز (if/then/else، لوپ، وغیرہ) کی نمائندگی کرتے ہیں۔ ہماری پچھلی مثال کا CFG یہ ہے:
CFG وہ نمائندگی ہے جس کی بنیاد پر زیادہ تر تجزیے بنائے جاتے ہیں۔
کوڈ کی بہت سی دوسری نمائندگیاں موجود ہیں۔ آپ جو تجزیہ کرنا چاہتے ہیں اس کے مطابق ہر نمائندگی کے فوائد اور نقصانات ہیں۔
تجزیہ
سلدر کے ساتھ آپ جو سب سے آسان قسم کے تجزیے کر سکتے ہیں وہ سنٹیکٹک (syntactic) تجزیے ہیں۔
سنٹیکس تجزیہ
سلدر پیٹرن میچنگ جیسی اپروچ کا استعمال کرتے ہوئے تضادات اور خامیوں کو تلاش کرنے کے لیے کوڈ کے مختلف اجزاء اور ان کی نمائندگی کے ذریعے نیویگیٹ کر سکتا ہے۔
مثال کے طور پر درج ذیل ڈیٹیکٹرز سنٹیکس سے متعلق مسائل تلاش کرتے ہیں:
-
سٹیٹ ویری ایبل شیڈونگ (opens in a new tab): تمام حالت (state) کے متغیرات پر اعادہ (iterate) کرتا ہے اور چیک کرتا ہے کہ آیا کوئی وراثت میں ملے کنٹریکٹ سے کسی متغیر کو شیڈو کرتا ہے (state.py#L51-L62 (opens in a new tab))
-
غلط ERC-20 انٹرفیس (opens in a new tab): غلط ERC-20 فنکشن کے دستخط تلاش کریں (incorrect_erc20_interface.py#L34-L55 (opens in a new tab))
سیمینٹک تجزیہ
سنٹیکس تجزیہ کے برعکس، ایک سیمینٹک (semantic) تجزیہ گہرائی میں جائے گا اور کوڈ کے "معنی" کا تجزیہ کرے گا۔ اس فیملی میں تجزیوں کی کچھ وسیع اقسام شامل ہیں۔ وہ زیادہ طاقتور اور مفید نتائج کا باعث بنتے ہیں، لیکن انہیں لکھنا بھی زیادہ پیچیدہ ہے۔
سیمینٹک تجزیے سب سے جدید کمزوریوں (vulnerabilities) کا پتہ لگانے کے لیے استعمال ہوتے ہیں۔
ڈیٹا انحصار کا تجزیہ
ایک متغیر variable_a کو variable_b پر ڈیٹا پر منحصر کہا جاتا ہے اگر کوئی ایسا پاتھ ہو جس کے لیے variable_a کی قدر variable_b سے متاثر ہوتی ہو۔
درج ذیل کوڈ میں، variable_a کا انحصار variable_b پر ہے:
// ...
variable_a = variable_b + 1;
سلدر بلٹ ان ڈیٹا انحصار (opens in a new tab) کی صلاحیتوں کے ساتھ آتا ہے، جس کی وجہ اس کی درمیانی نمائندگی ہے (جس پر بعد کے سیکشن میں بحث کی گئی ہے)۔
ڈیٹا انحصار کے استعمال کی ایک مثال خطرناک سخت برابری (strict equality) ڈیٹیکٹر (opens in a new tab) میں مل سکتی ہے۔ یہاں سلدر ایک خطرناک قدر (incorrect_strict_equality.py#L86-L87 (opens in a new tab)) کے ساتھ سخت برابری کے موازنہ کو تلاش کرے گا، اور صارف کو مطلع کرے گا کہ اسے حملہ آور کو کنٹریکٹ میں پھنسانے سے روکنے کے لیے == کے بجائے >= یا <= کا استعمال کرنا چاہیے۔ دیگر کے علاوہ، ڈیٹیکٹر balanceOf(address) پر کال کی واپسی کی قدر کو خطرناک سمجھے گا (incorrect_strict_equality.py#L63-L64 (opens in a new tab))، اور اس کے استعمال کو ٹریک کرنے کے لیے ڈیٹا انحصار انجن کا استعمال کرے گا۔
فکسڈ پوائنٹ کمپیوٹیشن
اگر آپ کا تجزیہ CFG کے ذریعے نیویگیٹ کرتا ہے اور کناروں (edges) کی پیروی کرتا ہے، تو آپ کو پہلے سے دیکھے گئے نوڈز نظر آنے کا امکان ہے۔ مثال کے طور پر، اگر ایک لوپ کو ذیل میں دکھایا گیا ہے:
for(uint i; i < range; ++){
variable_a += 1
}
آپ کے تجزیے کو یہ جاننے کی ضرورت ہوگی کہ کب رکنا ہے۔ یہاں دو اہم حکمت عملیاں ہیں: (1) ہر نوڈ پر ایک محدود تعداد میں اعادہ (iterate) کریں، (2) ایک نام نہاد فکس پوائنٹ (fixpoint) کا حساب لگائیں۔ فکس پوائنٹ کا بنیادی مطلب یہ ہے کہ اس نوڈ کا تجزیہ کرنے سے کوئی بامعنی معلومات فراہم نہیں ہوتی ہیں۔
استعمال ہونے والے فکس پوائنٹ کی ایک مثال مکرر داخلہ (reentrancy) ڈیٹیکٹرز میں مل سکتی ہے: سلدر نوڈز کو دریافت کرتا ہے، اور بیرونی کالز، سٹوریج میں لکھنے اور پڑھنے کو تلاش کرتا ہے۔ ایک بار جب یہ فکس پوائنٹ (reentrancy.py#L125-L131 (opens in a new tab)) پر پہنچ جاتا ہے، تو یہ دریافت کو روک دیتا ہے، اور مختلف مکرر داخلہ پیٹرنز (reentrancy_benign.py (opens in a new tab)، reentrancy_read_before_write.py (opens in a new tab)، reentrancy_eth.py (opens in a new tab)) کے ذریعے یہ دیکھنے کے لیے نتائج کا تجزیہ کرتا ہے کہ آیا مکرر داخلہ موجود ہے۔
موثر فکسڈ پوائنٹ کمپیوٹیشن کا استعمال کرتے ہوئے تجزیے لکھنے کے لیے اس بات کی اچھی سمجھ کی ضرورت ہوتی ہے کہ تجزیہ اپنی معلومات کو کیسے پھیلاتا ہے۔
درمیانی نمائندگی
ایک درمیانی نمائندگی (IR) ایک ایسی زبان ہے جس کا مقصد اصل زبان کی نسبت سٹیٹک تجزیہ کے لیے زیادہ موزوں ہونا ہے۔ سلدر Solidity کا اپنی IR میں ترجمہ کرتا ہے: SlithIR (opens in a new tab)۔
اگر آپ صرف بنیادی چیکس لکھنا چاہتے ہیں تو SlithIR کو سمجھنا ضروری نہیں ہے۔ تاہم، اگر آپ جدید سیمینٹک تجزیے لکھنے کا ارادہ رکھتے ہیں تو یہ کارآمد ثابت ہوگا۔ SlithIR (opens in a new tab) اور SSA (opens in a new tab) پرنٹرز آپ کو یہ سمجھنے میں مدد کریں گے کہ کوڈ کا ترجمہ کیسے کیا جاتا ہے۔
API کی بنیادی باتیں
سلدر میں ایک API ہے جو آپ کو کنٹریکٹ اور اس کے فنکشنز کی بنیادی خصوصیات کو دریافت کرنے دیتی ہے۔
کوڈ بیس لوڈ کرنے کے لیے:
from slither import Slither
slither = Slither('/path/to/project')
کنٹریکٹس اور فنکشنز کی دریافت
ایک Slither آبجیکٹ میں یہ ہوتا ہے:
contracts (list(Contract): کنٹریکٹس کی فہرستcontracts_derived (list(Contract): ان کنٹریکٹس کی فہرست جو کسی دوسرے کنٹریکٹ کو وراثت میں نہیں ملے ہیں (کنٹریکٹس کا ذیلی سیٹ)get_contract_from_name (str): اس کے نام سے ایک کنٹریکٹ واپس کریں
ایک Contract آبجیکٹ میں یہ ہوتا ہے:
name (str): کنٹریکٹ کا نامfunctions (list(Function)): فنکشنز کی فہرستmodifiers (list(Modifier)): فنکشنز کی فہرستall_functions_called (list(Function/Modifier)): کنٹریکٹ کے ذریعے قابل رسائی تمام اندرونی فنکشنز کی فہرستinheritance (list(Contract)): وراثت میں ملے کنٹریکٹس کی فہرستget_function_from_signature (str): اس کے دستخط سے ایک فنکشن واپس کریںget_modifier_from_signature (str): اس کے دستخط سے ایک موڈیفائر (Modifier) واپس کریںget_state_variable_from_name (str): اس کے نام سے ایک سٹیٹ ویری ایبل (StateVariable) واپس کریں
ایک Function یا Modifier آبجیکٹ میں یہ ہوتا ہے:
name (str): فنکشن کا نامcontract (contract): وہ کنٹریکٹ جہاں فنکشن ڈکلیئر کیا گیا ہےnodes (list(Node)): فنکشن/موڈیفائر کے CFG پر مشتمل نوڈز کی فہرستentry_point (Node): CFG کا انٹری پوائنٹvariables_read (list(Variable)): پڑھے گئے متغیرات کی فہرستvariables_written (list(Variable)): لکھے گئے متغیرات کی فہرستstate_variables_read (list(StateVariable)): پڑھے گئے حالت (state) کے متغیرات کی فہرست (متغیرات کا ذیلی سیٹ جو پڑھے گئے ہیں)state_variables_written (list(StateVariable)): لکھے گئے حالت (state) کے متغیرات کی فہرست (متغیرات کا ذیلی سیٹ جو لکھے گئے ہیں)

