Ruka kwenda kwenye maudhui makuu

Jinsi ya kutumia Slither kupata hitilafu za mkataba-erevu

solidity
smart contracts
security
testing
Advanced
Trailofbits
9 Juni 2020
7 minute read

Jinsi ya kutumia Slither

Lengo la mafunzo haya ni kuonyesha jinsi ya kutumia Slither kupata hitilafu kiotomatiki katika mikataba-erevu.

Usakinishaji

Slither inahitaji Python >= 3.6. Inaweza kusakinishwa kupitia pip au kwa kutumia docker.

Slither kupitia pip:

pip3 install --user slither-analyzer

Slither kupitia docker:

docker pull trailofbits/eth-security-toolbox
docker run -it -v "$PWD":/home/trufflecon trailofbits/eth-security-toolbox

Amri ya mwisho huendesha eth-security-toolbox kwenye docker ambayo ina ufikiaji wa saraka yako ya sasa. Unaweza kubadilisha faili kutoka kwa mwenyeji wako, na uendeshe zana kwenye faili kutoka kwa docker

Ndani ya docker, endesha:

solc-select 0.5.11
cd /home/trufflecon/

Kuendesha hati

Ili kuendesha hati ya python na python 3:

python3 script.py

Mstari wa amri

Mstari wa amri dhidi ya hati zilizobainishwa na mtumiaji. Slither inakuja na seti ya vitambuzi vilivyobainishwa awali vinavyopata hitilafu nyingi za kawaida. Kuita Slither kutoka kwa mstari wa amri kutaendesha vitambuzi vyote, hakuna ujuzi wa kina wa uchambuzi tuli unaohitajika:

slither project_paths

Mbali na vitambuzi, Slither ina uwezo wa kukagua msimbo kupitia printers (opens in a new tab) na zana (opens in a new tab) zake.

Tumia crytic.io (opens in a new tab) ili kupata ufikiaji wa vitambuzi vya faragha na muunganisho wa GitHub.

Uchambuzi tuli

Uwezo na muundo wa mfumo wa uchambuzi tuli wa Slither umeelezewa katika machapisho ya blogu (1 (opens in a new tab), 2 (opens in a new tab)) na karatasi ya kitaaluma (opens in a new tab).

Uchambuzi tuli upo katika aina tofauti. Pengine unagundua kwamba vikompilaji kama clang (opens in a new tab) na gcc (opens in a new tab) hutegemea mbinu hizi za utafiti, lakini pia inasaidia (Infer (opens in a new tab), CodeClimate (opens in a new tab), FindBugs (opens in a new tab) na zana zinazotegemea mbinu rasmi kama vile Frama-C (opens in a new tab) na Polyspace (opens in a new tab).

Hatutakuwa tukikagua kwa kina mbinu za uchambuzi tuli na watafiti hapa. Badala yake, tutazingatia kile kinachohitajika kuelewa jinsi Slither inavyofanya kazi ili uweze kuitumia kwa ufanisi zaidi kupata hitilafu na kuelewa msimbo.

Uwakilishi wa msimbo

Tofauti na uchambuzi wenye mabadiliko, unaozingatia njia moja ya utekelezaji, uchambuzi tuli huzingatia njia zote kwa wakati mmoja. Ili kufanya hivyo, inategemea uwakilishi tofauti wa msimbo. Mbili za kawaida zaidi ni mti wa sintaksia dhahania (AST) na grafu ya mtiririko wa udhibiti (CFG).

Miti ya Sintaksia Dhahania (AST)

AST hutumika kila wakati kikompilaji kinapochanganua msimbo. Pengine ndiyo muundo wa msingi zaidi ambao uchambuzi tuli unaweza kufanywa.

Kwa ufupi, AST ni mti uliopangiliwa ambapo, kwa kawaida, kila jani lina kigezo au thamani isiyobadilika na nodi za ndani ni viendeshaji au shughuli za mtiririko wa udhibiti. Zingatia msimbo ufuatao:

1function safeAdd(uint a, uint b) pure internal returns(uint){
2 if(a + b <= a){
3 revert();
4 }
5 return a + b;
6}

AST inayolingana inaonyeshwa katika:

AST

Slither hutumia AST inayosafirishwa na solc.

Ingawa ni rahisi kuunda, AST ni muundo uliowekwa ndani. Wakati mwingine, hii siyo njia rahisi zaidi ya kuchambua. Kwa mfano, ili kubaini shughuli zinazotumiwa na usemi a + b <= a, lazima kwanza uchanganue <= na kisha +. Njia ya kawaida ni kutumia kinachoitwa muundo wa mtembeleaji, ambao hupitia mti kwa kujirudia. Slither ina mtembeleaji wa jumla katika ExpressionVisitor (opens in a new tab).

Msimbo ufuatao unatumia ExpressionVisitor kugundua kama usemi una nyongeza:

1from slither.visitors.expression.expression import ExpressionVisitor
2from slither.core.expressions.binary_operation import BinaryOperationType
3
4class HasAddition(ExpressionVisitor):
5
6 def result(self):
7 return self._result
8
9 def _post_binary_operation(self, expression):
10 if expression.type == BinaryOperationType.ADDITION:
11 self._result = True
12
13visitor = HasAddition(expression) # expression is the expression to be tested
14print(f'The expression {expression} has a addition: {visitor.result()}')
Onyesha yote

Grafu ya Mtiririko wa Udhibiti (CFG)

Uwakilishi wa pili wa kawaida wa msimbo ni grafu ya mtiririko wa udhibiti (CFG). Kama jina lake linavyopendekeza, ni uwakilishi unaotegemea grafu unaoonyesha njia zote za utekelezaji. Kila nodi ina maagizo moja au zaidi. Pande katika grafu zinawakilisha shughuli za mtiririko wa udhibiti (kama/basi/vinginevyo, kitanzi, n.k). CFG ya mfano wetu uliopita ni:

CFG

CFG ndio uwakilishi ambao juu yake uchambuzi mwingi hujengwa.

Uwakilishi mwingine mwingi wa msimbo upo. Kila uwakilishi una faida na hasara kulingana na uchambuzi unaotaka kufanya.

Uchambuzi

Aina rahisi zaidi ya uchambuzi unaweza kufanya na Slither ni uchambuzi wa sintaksia.

Uchambuzi wa sintaksia

Slither inaweza kupitia vipengele tofauti vya msimbo na uwakilishi wao ili kupata kutofautiana na kasoro kwa kutumia mbinu inayofanana na ulinganishaji wa muundo.

Kwa mfano, vitambuzi vifuatavyo hutafuta masuala yanayohusiana na sintaksia:

Uchambuzi wa maana

Tofauti na uchambuzi wa sintaksia, uchambuzi wa maana utaenda ndani zaidi na kuchambua "maana" ya msimbo. Familia hii inajumuisha aina pana za uchambuzi. Zinapelekea matokeo yenye nguvu zaidi na muhimu, lakini pia ni ngumu zaidi kuandika.

Uchambuzi wa maana hutumika kwa utambuzi wa hali ya juu zaidi ya udhaifu.

Uchambuzi wa utegemezi wa data

Kigezo variable_a kinasemekana kuwa kinategemea data ya variable_b ikiwa kuna njia ambayo thamani ya variable_a inaathiriwa na variable_b.

Katika msimbo ufuatao, variable_a inategemea variable_b:

1// ...
2variable_a = variable_b + 1;

Slither inakuja na uwezo uliojengewa ndani wa utegemezi wa data (opens in a new tab), shukrani kwa uwakilishi wake wa kati (utakaoshughulikiwa katika sehemu ya baadaye).

Mfano wa matumizi ya utegemezi wa data unaweza kupatikana katika kitambuzi hatari cha usawa mkali (opens in a new tab). Hapa Slither itatafuta ulinganisho wa usawa mkali na thamani hatari (incorrect_strict_equality.py#L86-L87 (opens in a new tab)), na itamjulisha mtumiaji kwamba anapaswa kutumia >= au <= badala ya ==, ili kumzuia mshambulizi asitege mkataba. Miongoni mwa mambo mengine, kitambuzi kitazingatia thamani ya kurejesha ya mwito kwa balanceOf(address) kuwa hatari (incorrect_strict_equality.py#L63-L64 (opens in a new tab)), na itatumia injini ya utegemezi wa data kufuatilia matumizi yake.

Hesabu ya nukta isiyobadilika

Ikiwa uchambuzi wako unapitia CFG na kufuata pande, kuna uwezekano wa kuona nodi ambazo tayari zimetembelewa. Kwa mfano, ikiwa kitanzi kinaonyeshwa kama ilivyo hapo chini:

1for(uint i; i < range; ++){
2 variable_a += 1
3}

Uchambuzi wako utahitaji kujua wakati wa kusimama. Kuna mikakati miwili mikuu hapa: (1) kurudia kwenye kila nodi idadi maalum ya mara, (2) kuhesabu kinachoitwa nukta isiyobadilika. Nukta isiyobadilika kimsingi inamaanisha kuwa kuchambua nodi hii hakutoi taarifa yoyote ya maana.

Mfano wa nukta isiyobadilika iliyotumiwa unaweza kupatikana katika vitambuzi vya uingiaji tena: Slither inachunguza nodi, na kutafuta miito ya nje, kuandika na kusoma kwenye ghala. Mara tu inapofikia nukta isiyobadilika (reentrancy.py#L125-L131 (opens in a new tab)), inasitisha uchunguzi, na kuchambua matokeo ili kuona kama kuna uingiaji tena, kupitia miundo tofauti ya uingiaji tena (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)).

Kuandika uchambuzi kwa kutumia hesabu ya nukta isiyobadilika inayofaa kunahitaji uelewa mzuri wa jinsi uchambuzi unavyoeneza taarifa zake.

Uwakilishi wa kati

Uwakilishi wa kati (IR) ni lugha inayokusudiwa kuwa rahisi zaidi kwa uchambuzi tuli kuliko ile ya asili. Slither hutafsiri Solidity kuwa IR yake mwenyewe: SlithIR (opens in a new tab).

Kuelewa SlithIR si lazima ikiwa unataka tu kuandika ukaguzi wa msingi. Hata hivyo, itakuwa muhimu ikiwa unapanga kuandika uchambuzi wa maana wa hali ya juu. Vichapishi vya SlithIR (opens in a new tab) na SSA (opens in a new tab) vitakusaidia kuelewa jinsi msimbo unavyotafsiriwa.

Misingi ya API

Slither ina API inayokuruhusu kuchunguza sifa za msingi za mkataba na chaguo zake za kukokotoa.

Ili kupakia codebase:

1from slither import Slither
2slither = Slither('/path/to/project')
3

Kuchunguza mikataba na chaguo za kukokotoa

Kitu cha Slither kina:

  • contracts (orodha(Mkataba): orodha ya mikataba
  • contracts_derived (orodha(Mkataba): orodha ya mikataba ambayo haijarithiwa na mkataba mwingine (sehemu ndogo ya mikataba)
  • get_contract_from_name (str): Rudisha mkataba kutoka kwa jina lake

Kitu cha Mkataba kina:

  • name (str): Jina la mkataba
  • functions (orodha(Chaguo la Kukokotoa)): Orodha ya chaguo za kukokotoa
  • modifiers (orodha(Kibadilishi)): Orodha ya vibadilishi
  • all_functions_called (orodha(Chaguo la Kukokotoa/Kibadilishi)): Orodha ya chaguo zote za kukokotoa za ndani zinazoweza kufikiwa na mkataba
  • inheritance (orodha(Mkataba)): Orodha ya mikataba iliyorithiwa
  • get_function_from_signature (str): Rudisha Chaguo la Kukokotoa kutoka kwa saini yake
  • get_modifier_from_signature (str): Rudisha Kibadilishi kutoka kwa saini yake
  • get_state_variable_from_name (str): Rudisha Kigezo cha Hali kutoka kwa jina lake

Kitu cha Chaguo la Kukokotoa au Kibadilishi kina:

  • name (str): Jina la chaguo la kukokotoa
  • contract (mkataba): mkataba ambapo chaguo la kukokotoa linatangazwa
  • nodes (orodha(Nodi)): Orodha ya nodi zinazounda CFG ya chaguo la kukokotoa/kibadilishi
  • entry_point (Nodi): Sehemu ya kuingilia ya CFG
  • variables_read (orodha(Kigezo)): Orodha ya vigezo vilivyosomwa
  • variables_written (orodha(Kigezo)): Orodha ya vigezo vilivyoandikwa
  • state_variables_read (orodha(KigezoChaHali)): Orodha ya vigezo vya hali vilivyosomwa (sehemu ndogo ya vigezo vilivyosomwa)
  • state_variables_written (orodha(KigezoChaHali)): Orodha ya vigezo vya hali vilivyoandikwa (sehemu ndogo ya vigezo vilivyoandikwa)

Ukurasa ulihaririwa mwisho: 3 Februari 2025

Umesaidika na mafunzo haya?