Program Analysis for High-Value Smart Contract Vulnerabilities: Techniques and Insights at SBC 2023 (สรุป)

Nattawat Songsom
5 min readSep 27, 2023

--

มาดู tool ที่ Dedaub (บริษัท audit smart contract) ใช้กัน

โอเค session แบ่งเป็น 2 ช่วง

  • Technique
  • Insight

Techniques

Dedaub ใช้ tool 2 ตัวในการหาช่องโหว่มูลค่าสูง (*ช่องโหว่มูลค่าสูงที่ Dedaub หมายถึงนั้น เค้าเข้าร่วม 10 bug bounties และได้รางวัลมากว่า $3M) ใน smart contract

โดยทั้ง 2 tool ประกอบด้วย

  • Symvalic Analysis (Symbolic Value-Flow Static Analysis)
  • Corpus analysis

โอเค มาดูทีละตัวกัน

Symvalic Analysis ?

Symvalic analysis ย่อมาจาก SYMBOLIC-VALUE-FLOW STATIC ANALYSIS

จากชื่อจะเห็นได้ว่า Symvalic analysis = SYMBOLIC analysis (เป็นหนึ่งใน dynamic analysis) + Static analysis

โอเค Symvalic Analysis = symbolic analysis กับ static analysis ผสมกัน

งั้นก่อนจะเข้าใจ Symvalic Analysis เรามาทำความเข้าใจ symbolic analysis กับ static analysis กันก่อน

Symbolic analysis (Symbolic execution)

คือการที่เราพยายามวิเคราะห์โปรแกรม โดยคำนวณค่าที่เป็นไปได้ของตัวแปรทั้งหมด และกรองค่าที่เป็นไปไม่ได้ออก โดยดูว่าที่บรรทัดนั้น มี logic ยังไง

เช่นจากรูป

เราจะเห็นได้ว่าเมื่อเราใช้ symbolic execution

ในตอนแรกค่าของตัวแปร x และ y จะเป็นไปได้ทุกๆค่า int เลย

แต่พอมีการรัน code ไปเรื่อยๆ

เราจะพบว่า ใน if (x > y) assert false; นั้น เป็นไปไม่ได้ที่ if นั้นจะเป็นจริง

เนื่องจากพอเราลองทดค่าดู จะพบว่าถ้า if (x > y) assert false; เป็นจริง แสดงว่า ในบรรทัด int x,y; นั้น จะต้องมี x > y และ y < x ซึ่งเป็นไปไม่ได้

จะเห็นได้ว่าการใช้ symbolic execution จะเป็นการนำค่าแต่ละตัวแปร มาอ้างอิงถึงกัน (คล้ายๆ โซ่) เพื่อกรองค่าที่เป็นไปได้ของตัวแปรๆหนึ่ง ออกไปเรื่อยๆ ตามรูป

จากเทคนิคนี้ทำให้ symbolic execution มีความแม่นยำ (precision) สูง

แต่การที่ต้องทำการ execute code เพื่อคำนวณค่าที่เป็นไปได้ ก็ทำให้ symbolic execution มีโอกาสที่จะรัน code บางชุดไม่ไหว เช่น code ที่มี loop ใหญ่ๆ แล้วต้องทำการคำนวณค่าที่เป็นไปได้ทั้งหมด

หรือก็คือ symbolic execution มี completeness ที่ต่ำ นั่นเอง

โอเค ต่อมาคือ

Static analysis

static analysis คือการที่เราทำการ analysis โดยไม่ได้ทำการ execute code ตรงๆ แต่ใช้เทคนิคอื่นๆ ที่ทำการจำลองการ execute code แบบคร่าวๆ แทน

โอเค มายกตัวอย่างกัน

เช่น การทำ taint analysis โดยใช้ static analysis

โอเค ก่อนอื่นการทำ taint analysis คืออะไร ?

taint analysis คือการหาว่า มีค่าไหนบ้าง ที่ user ไม่ควรที่จะแก้ไขเองได้ (ถ้า user แก้ไขได้ จะกลายเป็นช่องโหว่ของระบบ)

เช่นจากรูป

เราตั้งว่า owner เป็น untainted value (ค่าที่ user ไม่ควรจะแก้เองได้)

จากนั้นเราจะนำ code ไปเข้า static analysis framework ที่จะทำการจำลองการทำงานของ code ทั้งหมด

เช่น ทำการแปลง code Solidity เป็น code Datalog ตามรูป

โดย code ใน version Datalog จะทำการสรุป logic ของ code Solidity

เพื่อที่สุดท้าย เราจะมาดูกันว่า สรุปแล้ว user สามารถแก้ไขค่า owner เป็นค่าที่ตัวเองต้องการได้มั้ย

ถ้าใช่ แสดงว่า code Solidity นี้ พอทำ taint analysis แล้วพบว่า มีช่องโหว่ที่ user สามารถแก้ค่า owner เป็นค่าที่ตัวเองต้องการได้

ซึ่งจะนำไปสู่การ attacker ด้วยการ withdraw ต่อไป

โอเค พอเราทำการจำลอง (หรือสรุป) การทำงานของ code มาคร่าวๆ แล้ว

เราจะต้องทำการ input ค่าของแต่ละตัวแปรเข้าไป ในแบบจำลอง code นั้น

โดย static analysis มักจะทำการประกาศ set ของค่าที่เป็นไปได้ของตัวแปรแต่ละประเภทไว้เลย ตามรูป

โดยเราจะไม่สามารถ กรอง ค่าที่เป็นไปไม่ได้ออก เหมือนใน symbolic execution

เช่นจากรูป ในบรรทัด token.transfer(sendTo, adjusted) นั้น

ตัว static analysis อาจจะสรุปออกมาว่า

adjusted = 31, amount = 10,000

ซึ่งจริงๆแล้วเป็นไปไม่ได้

เพราะ บรรทัด uint256 adjusted = amount * 103 / 100

แต่ static analysis ไม่สน

เนื่องจาก adjusted

  • ไม่ได้ใช้ใน if, require ใดๆ
  • ไม่ได้มีการเปลี่ยนค่าหลังจาก initial
  • ไม่ได้เอาไปคิดค่าอื่นๆใน contract ต่อ

จะเห็นได้ว่า static analysis จะมี completeness ที่สูง (สามารถวิเคราะห์ code ได้ทุกบรรทัด เพื่อหา pattern ช่องโหว่)

ซึ่ง completeness ที่สูงก็มาจากการที่ไม่ได้ทำการ execute / ทด ค่าจากการรันจริงๆ

จึงทำให้มี precision ที่ต่ำ เนื่องจากผลลัพธ์ที่ออกมา อาจจะผิด นั่นเอง

Symvalic Analysis ?

symvalic analysis คือ ผสมกันของ static analysis และ symbolic execution

โดยตัว static analysis จะใช้ symbolic execution (แต่เค้าเรียกว่า symbolic solver แหะ) ในการกรองค่าที่เป็นไปไม่ได้ออก

เช่นจากรูป

เมื่อเรามาถึงบรรทัด token.transfer(sendTo,adjusted)

เราจะได้ว่าจาก set ค่าตัวแปรที่เป็นไปได้

เมื่อทำการใช้ตัว symbolic solver มาช่วย จะเหลือค่าที่เป็นไปได้แค่

adjusted = 1030

เนื่องจาก amount ที่ผ่านเงื่อนไข if(amount ≥ 1,000 && amount < 100,000) มีแค่ amount = 1,000 นั่นเอง

*เราจะสมมติว่า code เขียนว่า if(amount ≥ 1,000 && amount < 100,000) ไม่ใช่ if(amount ≥ 10,000 && amount < 100,000) ละกัน

จะเห็นได้ว่า symvalic analysis ที่ใช้ static analysis เป็น core หลักนั้น

ได้รับ completeness ที่สูงมาจาก static analysis

และยังเพิ่ม precision ด้วยการให้ symbolic solver ช่วย

ดังนั้น

Symvalic analysis มี precision สูงกว่า static analysis แบบปกติ

และมี completeness สูงกว่า symbolic execution แบบปกติ นั่นเอง

โอเค นั่นคือ อาวุธแรกของ Dedaub

มาต่อที่อาวุธที่สองกัน

Corpus analysis

โอเค ก่อนจะพูดถึง Corpus analysis มาลองกลับไปดู code เดิมกัน

จากรูป เราอาจจะใช้ symvalic analysis ในการทำ tool เพื่อหาว่า sendTo เป็น untainted หรือ tainted value (ถ้า user ปกติ สามารถส่ง token ให้ sentTo ใดๆได้ แสดงว่ามีช่องโหว่)

แต่ประเด็นคือ

ถ้าเราจะทำ tool ที่รันอัตโนมัติได้

ตัว tool จะรู้ได้ยังไงว่าตัวแปร sendTo เป็นตัวแปรสำคัญ ที่ห้ามเป็น untainted value

ถ้า sendTo ไม่ได้ชื่อ sendTo ละ ?

ถ้า sendTo ไม่ได้เป็น parameter ตัวที่สามของ withdrawToken ละ ?

ถ้า function ไม่ได้ชื่อว่า withdrawToken ?

ถ้า token.transfer เป็น logic ที่ซับซ้อนขึ้นเช่น pool.swap ?

คำตอบคือ

การใช้ Corpus analysis ซึ่งสามารถ

  • สรุป pattern ของ code ได้ เพื่อทำการหาว่าจะ analysis ยังไงต่อ
  • สรุป pattern การทำงานหลักๆที่ function ใน code นั้นๆ ทำงานได้ เช่น ถึงแม้จะเปลี่ยนชื่อ function จาก swap เป็น trade … ตัว analysis ก็ยังเข้าใจนั่นเอง

Insights

จาก technique ที่ว่ามา

พอลองมารันกับ smart contract (ที่ถูก deploy ไปใช้งานจริงๆ) พบว่า

  1. warning rate อยู่ที่ 0.5% ( tool ทำการ flag 1 / 200 contract)

ซึ่งถ้าในเชิง academic ตัวจำนวนถือว่าน้อยไป

พูดอีกอย่างก็คือ ถ้า มี 99.5% ที่ไม่มีช่องโหว่

ถึงเราหา 0.5% ที่มีช่องโหว่ได้

ก็อาจจะไม่ได้มี impact เยอะขนาดนั้นรึเปล่า

แต่ทาง Dedaub ก็แสดงให้เห็นว่า จำนวน 0.5% นั้น เมื่อถูก attack แล้ว เสียหายเป็นระดับล้าน usd เลย

2. false positive rate อยู่ที่ 98% (จาก 100 warning มีที่เป็นช่องโหว่จริงๆ 2 อัน)

ซึ่ง false positive 98% ในเชิง academic นั้น ถือว่าสูงเกินไป (ปกติแล้วต้อง < 60%)

แต่ทาง Dedaub ก็แสดงให้เห็นว่าถึง false positive สูงขนาดนี้ ก็เพียงพอต่อการที่ Dedaub นำ tool ไปใช้ เพื่อป้องกันความเสียหายในระดับล้าน usd ได้ นั่นเอง

พูดอีกอย่างก็คือ tool ที่มี false positive ต่ำ อาจจะไม่ได้หาช่องโหว่ที่มีมูลค่าสูงเจอ เท่ากับ tool ที่มี false positive สูง

โดย จาก paper นี้ ระบุว่า ในปี 2021 จากการลองรัน tool เพื่อหา ช่องโหว่ของ smart contract ดู มีเพียง 0.27% ของ smart contract ที่ถูกระบุว่ามีช่องโหว่เท่านั้น ที่ถูก hack เพื่อเอาเงินจริงๆ (เพราะ ช่องโหว่มีมูลค่าน้อยเกินไป, ต้องใช้ effort มากเกินไปในการ hack etc. )

โอเค สรุป Program Analysis for High-Value Smart Contract Vulnerabilities: Techniques and Insights ประมาณนี้ครับ

Referrences

https://dl.acm.org/doi/pdf/10.1145/3485540

--

--

No responses yet