Selamat datang di panduan Pemula untuk audit kontrak pintar! Salah satu cara terbaik untuk memulai audit kontrak pintar adalah dengan masuk dan melihat beberapa jenis kerentanan umum dalam kontrak pintar.
Akan sangat membantu jika Anda sudah memiliki pemahaman dasar tentang bahasa pemrograman Soliditas Ethereum. Seperti yang akan kita lihat beberapa kode yang ditulis oleh programmer soliditas Noob.
Serangan Masuk Kembali
Skenario Dunia Nyata:
Bayangkan Anda memiliki 50 cokelat. Anda memiliki adik perempuan nakal yang Anda izinkan untuk mengambil hanya 2 cokelat dari Anda setiap saat. Anda juga tidak ingin memberikan lebih dari 10 cokelat padanya dalam sehari, karena khawatir dia akan mengalami kerusakan gigi. Untuk memastikannya, setiap malam Anda menghitung berapa banyak cokelat yang tersisa. Apakah menurut Anda ini akan berhasil? Atau apakah Anda akan diretas oleh adik perempuan Anda?
Sayangnya, itu tidak akan berhasil! Kakakmu mengetahui bahwa kamu tidak menyadari berapa banyak cokelat yang kamu miliki sampai malam tiba. Jadi keesokan harinya, adik perempuan Anda mengunjungi Anda 6 kali sebelum malam dan mengambil 2 cokelat setiap kali! Inilah yang kami sebut serangan Re-entrancy.
Di sini Anda memperbarui jumlah cokelat yang Anda miliki di malam hari alih-alih memperbarui jumlah setiap kali saudara perempuan Anda mengambil 2 cokelat dari Anda. Ini juga yang terjadi dengan kontrak pintar. Kontrak pintar mengasumsikan keseimbangan tertentu sementara penyerang sebenarnya sibuk menarik sejumlah crypto dari kontrak beberapa kali.
Contoh Kode Dunia Nyata:
Kode ini milik kontrak pintar yang disebut Tidak memiliki rekening bank. Siapapun dapat menarik ether dari kontrak Unbanked selama saldo msg.sender (yaitu pemanggil dari withdraw
function ) lebih besar dari atau sama dengan jumlah yang diminta untuk ditarik.
function withdraw(uint _amount) { require(balances[msg.sender] >= _amount); msg.sender.call.value(_amount)(); balances[msg.sender] -= _amount;
}
Perhatikan bahwa ada kata kunci panggilan yang digunakan untuk mengirim jumlah eter yang diperlukan ke msg.sender
. Seorang penyerang dapat mengeksploitasi ini dengan membuat kontrak yang disebut Pencuri di mana ia memanggil fungsi penarikan di a fallback()
fungsi. SEBUAH fallback()
function di Solidity adalah fungsi khusus yang dieksekusi saat ether dikirim ke smart contract.
Ini berarti bahwa penyerang dapat memanggil fungsi penarikan secara rekursif. Jadi, sebelum kontrak pintar diperbarui, saldo msg.sender
pada baris kode terakhir, penyerang telah menarik eter beberapa kali. Ini dapat dihindari jika saldo diperbarui sebelum menggunakan kata kunci panggilan, sehingga mengikuti a cek-efek-interaksi pola.
Dampak:
Grafik Serangan Masuk Kembali pertama kalinya terjadi pada tahun 2016 pada DAO (Organisasi Otonomi Terdesentralisasi) yang menghasilkan sekitar $50 Juta peretasan. Untuk membalikkan peretasan ini, komunitas Ethereum membagi blockchain Ethereum yang memunculkan ETC (Ethereum Classic) dan ETH (Ethereum).
Overflow dan Underflow Aritmatika
Skenario Dunia Nyata:
Ayo mainkan permainan pikiran. Ini terdiri dari Spin-the wheel, dan pemenangnya ditentukan berdasarkan jumlah terbesar yang bisa dia dapatkan saat memutar roda. Roda ditandai dari 256 hingga -256.
Aturan untuk permainan ini adalah bahwa penunjuk untuk semua pemain bertumpu pada 0 di awal setiap putaran. Dan seorang pemain hanya diperbolehkan berputar ke arah angka negatif. Bagaimana Anda akan memenangkan permainan ini?
Strategi yang baik untuk memenangkan permainan ini setiap saat adalah memutar roda dengan kekuatan sedemikian rupa sehingga roda berputar hingga -256 dan kemudian berubah menjadi 256 sekaligus. Ini dimungkinkan karena 256 datang tepat setelah -256 di atas kemudi. Inilah yang kami sebut underflow aritmatika. Dan luapan aritmatika hanyalah kebalikan dari ini.
Contoh Kode Dunia Nyata:
An aliran bawah atau overflow terjadi ketika operasi aritmatika mencapai minimum atau maksimum.
function withdraw(uint _amount) public { require(balances[msg.sender] - _amount > 0); address payable to = payable(msg.sender); to.transfer(_amount); balances[msg.sender] -= _amount;
}
Grafik _amount
parameter fungsi penarikan adalah bilangan bulat yang tidak ditandatangani. Nilai pemetaan saldo (yang seperti kamus di python atau pasangan nilai kunci di C++ atau Java) juga merupakan bilangan bulat yang tidak ditandatangani.
mapping(address => uint256) public balances
Pernyataan yang diperlukan memeriksa apakah saldo msg.sender
itu positif atau tidak. Tetapi pernyataan ini akan selalu benar bahkan jika jumlahnya lebih besar dari saldo msg.sender
. Hal ini karena keduanya balances
dan _amount
variabel bertipe unsigned integer dan hasil aritmatikanya (setelah underflow) juga akan menjadi unsigned integer!
Dan seperti yang Anda ingat, bilangan bulat yang tidak ditandatangani selalu positif. Ini berarti penyerang dapat menarik Eter dalam jumlah tak terbatas dari kontrak pintar! Anda dapat menemukan contoh terperinci dan kode implementasi untuk kerentanan ini di sini.
Hal penting lainnya yang perlu diperhatikan di sini adalah bahwa operasi aritmatika antara katakanlah dua bilangan bulat tidak bertanda juga merupakan bilangan bulat tidak bertanda. Ini bisa berbahaya jika diabaikan dalam kontrak pintar, karena dapat mengakibatkan pelanggaran keamanan yang tidak diinginkan!
function votes(uint postId, uint upvote, uint downvotes) { if (upvote - downvote < 0) { deletePost(postId) }
}
Seperti yang mungkin Anda perhatikan dalam contoh di atas, pernyataan if tidak ada gunanya karena upvote - downvote
akan selalu positif. Dan postingan akan dihapus meskipun downvotes
lebih besar dari upvotes
. Untuk menghindari serangan seperti itu, disarankan untuk menggunakan versi kompiler Solidity yang lebih besar dari 0.8.0.
Dampak:
Sebuah koin yang disebut Koin PoWH diluncurkan pada tahun 2017. Meskipun itu adalah permainan Ponzi, itu sendiri diretas karena bug aritmatika overflow yang mengakibatkan kerugian sekitar 866 ETH atau $ 950,000 pada waktu itu. Anda dapat membaca tentang ini secara detail di sini.
Harus baca: Pelajaran Dari Serangan Terhadap Tinyman, DEX Terbesar Di Algorand
Serangan Denial of Service
Skenario Dunia Nyata:
Bayangkan Anda berada di Universitas Teknologi Bitcoin. Semuanya tampak baik-baik saja kecuali bahwa ada meja makan umum untuk semua orang. Dan sayangnya, ada beberapa orang dari kelas lain yang selalu berhasil menempati meja makan sebelum siapa pun dari kelas Anda.
Dalam skenario praktis, mereka menolak layanan penting untuk semua orang yang mengakibatkan hilangnya waktu yang berharga. Inilah yang kami sebut 'serangan Denial of Service'.
Contoh Kode Dunia Nyata:
Dalam permainan yang disebut Raja Eter, siapa pun bisa menjadi raja. Tetapi aturan untuk menjadi raja adalah seseorang harus menyetor lebih banyak eter daripada raja saat ini. Ini dapat dilakukan dengan menelepon claimThrone()
fungsi dari kontrak Raja Eter di mana orang tersebut mengirimkan eter langsung ke raja sebelumnya dan menjadi raja baru.
function claimThrone() external payable { require(msg.value > balance, "Need to pay more to become the king"); (bool sent, ) = king.call{value: balance}(""); require(sent, "Failed to send Ether"); balance = msg.value; king = msg.sender; }
Seperti yang mungkin sudah Anda duga, kode ini rentan terhadap Serangan DoS, tetapi bagaimana caranya? Untuk ini, Anda harus memahami bahwa ada dua jenis alamat di Ethereum- pertama adalah alamat eksternal akun yang dimiliki atau hanya alamat dompet, dan yang kedua adalah alamat kontrak. Sekarang eter dapat dikirim dari salah satu jenis alamat ini.
Jika ini, eter dikirim melalui alamat kontrak, maka kontrak akan menjadi raja. Tapi mari kita asumsikan bahwa kontrak baru ini tidak memiliki fallback()
fungsi yang diperlukan jika kontrak ingin menerima ether. Kemudian jika orang baru datang dan mencoba menelepon claimThrone()
fungsi, itu akan selalu gagal!
Perhatikan bahwa ini juga terjadi sebagian karena claimThrone()
fungsi secara eksplisit memeriksa apakah transfer eter berhasil atau tidak dalam pernyataan kedua yang diperlukan. Anda dapat menemukan kode lengkap dan melakukan serangan DoS padanya di sini.
Kode juga mungkin rentan terhadap serangan DoS jika kode tersebut memiliki loop pada array ukuran besar. Hal ini terjadi karena batas gas dapat dilampaui dalam kasus seperti itu. Anda dapat membaca tentang itu di sini.
Dampak:
Sebuah permainan yang disebut PemerintahMental, yang tampaknya merupakan skema Ponzi, terjebak dengan 1100 eter karena sejumlah besar gas diperlukan untuk memproses pembayaran.
Keacakan yang Tidak Aman
Skenario Dunia Nyata:
Alkisah ada seorang laki-laki bernama Hesky yang selalu ditemani oleh monyet sialnya. Hesky melakukan permainan lotere dan mendapat untung besar. Suatu hari Alice memperhatikan Hesky menatap tajam ke arah monyetnya, Pesky. Kemudian dia melihat dia menulis sesuatu di secarik kertas dan menyegelnya di dalam amplop. Karena penasaran, dia memutuskan untuk menyelidiki lebih lanjut.
Malamnya, Alice melihat bahwa pemenang lotere ditentukan dengan membuka secara terbuka amplop tertutup itu. Setelah mengamatinya selama beberapa hari, Alice menemukan bahwa Hesky memutuskan nomor lotre yang menang dengan melihat gerakan Pesky (misalnya jika monyet menggaruk kepalanya, Hesky menulis 10)! Sekarang Alice memiliki formula untuk memenangkan setiap lotere dan hanya perlu membeli tiket lotre dengan nomor yang tepat!
Hesky berasumsi bahwa cara "acak" dalam menentukan pemenang lotre tidak akan pernah bisa diketahui, tetapi dia memang salah.
Contoh Kode Dunia Nyata:
Dalam contoh ini, nomor acak dihasilkan berdasarkan hash dari kombinasi nomor blok dan stempel waktu bloknya. hash ini kemudian ditugaskan ke variabel jawaban. Sekarang siapa pun yang menebak (tampaknya) angka acak ini, diberi hadiah 1 Eter. Apakah menurut Anda ini tidak dapat diretas?
function guess(uint _guess) public { uint answer = uint( keccak256(abi.encodePacked(blockhash(block.number - 1), block.timestamp)) ); if (_guess == answer) { (bool sent, ) = msg.sender.call{value: 1 ether}(""); require(sent, "Failed to send Ether"); } }
Tidak! Penyerang masih dapat menebak nomor acak ini hanya dengan menyalin kode untuk menghasilkan nilai yang ditetapkan ke variabel jawaban, dan meneruskan variabel jawaban yang sama ke guess()
fungsi!
guessTheRandomNumber.guess(answer);
Anda dapat menemukan kode lengkap di sini. Untuk menghindari serangan ini, disarankan untuk menggunakan Fungsi Acak yang Dapat Diverifikasi seperti Rantai Tautan VRF.
Dampak:
Sekitar 400 ETH hilang karena serangan terhadap Lotere Miliaran Cerdas kontrak. Anehnya, bahkan lotere kontrak itu sendiri adalah skema Ponzi (aduh!).
Manipulasi waktu
Skenario Dunia Nyata:
Satoshi suka makan kue. Dia menyukai semua jenis kue yang dibuat ibunya. Tetapi ibunya sangat ketat dan merasa bahwa makan terlalu banyak kue tidak baik untuknya. Jadi ibunya membuat aturan bahwa dia akan mendapatkan kue hanya pada jam 8 malam.
Hari itu juga pukul 7:45, Satoshi berlari ke ibunya dan meminta kue. Ibunya bertanya- "Jam berapa sekarang?"
“Ini jam 8!” - dia menjawab.
"Oke. Kemudian ambil kue dari lemari saya. ”
Dan dengan demikian, Satoshi berhasil memanipulasi waktu selama 15 menit sehingga dia bisa mendapatkan kuenya! Sungguh pria yang haus kue!
Contoh Kode Dunia Nyata:
Stempel waktu sebuah blok dapat dimanipulasi oleh sekitar 15 detik oleh seorang penambang. Dengan cara ini, seorang penambang dapat mengatur stempel waktu yang menguntungkan dan memasukkan transaksinya di blok yang sama yang dia tambang. Fungsinya play()
milik kontrak Game yang disebut G-Dot.
function play() public { require(now > 1640392200 && neverPlayed == true); neverPlayed = false; msg.sender.transfer(1500 ether);
}
Kontrak ini memberikan hadiah 1500 eter kepada pemain yang pertama kali memanggil fungsi putar. Tapi seperti yang Anda lihat, fungsi play hanya bisa dipanggil jika sekarang atau block.timestamp dari transaksi yang berisi panggilan ke play()
fungsi, lebih besar dari waktu zaman 1640392200.
Seorang penambang dapat dengan mudah memanipulasi stempel waktu ini dan memasukkan transaksinya untuk memanggil play()
berfungsi di blok yang sama sehingga dia sendiri adalah pemain pertama. Dengan cara ini dijamin penambang akan memenangkan permainan!
Dampak:
Block.timestamp digunakan untuk menghasilkan angka acak di Pemerintah dan dengan demikian rentan terhadap serangan manipulasi waktu.
Hubungi QuillAudits
QuillAudits adalah platform audit kontrak pintar yang aman yang dirancang oleh QuillHash
Teknologi.
Ini adalah platform audit yang menganalisis dan memverifikasi kontrak cerdas secara ketat untuk memeriksa kerentanan keamanan melalui tinjauan manual yang efektif dengan alat analisis statis dan dinamis, penganalisis gas, serta simulator. Selain itu, proses audit juga mencakup pengujian unit ekstensif serta analisis struktural.
Kami melakukan audit kontrak pintar dan tes penetrasi untuk menemukan potensi
kerentanan keamanan yang dapat membahayakan integritas platform.
Jika Anda memerlukan bantuan dalam audit kontrak pintar, jangan ragu untuk menghubungi pakar kami di sini!
Untuk mengetahui pekerjaan kami, Bergabunglah dengan Komunitas Kami:-
Twitter | LinkedIn | Facebook | Telegram
Pos Panduan Pemula untuk Audit Kontrak Cerdas: Bagian 1 muncul pertama pada Blog Quillhash.
Sumber: https://blog.quillhash.com/2022/01/19/beginners-guide-to-smart-contract-auditing-part-1/
- "
- &
- 000
- 2016
- 7
- Tentang Kami
- Akun
- alamat
- Semua
- sudah
- Meskipun
- analisis
- Audit
- otonom
- Awal
- TERBAIK
- Bitcoin
- blockchain
- Bug
- membeli
- panggilan
- kasus
- Cek
- klasik
- kode
- Koin
- kombinasi
- Umum
- masyarakat
- mengandung
- kontrak
- kontrak
- kue
- bisa
- membuat
- kripto
- terbaru
- DAO
- hari
- Terdesentralisasi
- Denial of Service
- rinci
- dex
- turun
- mudah
- makan
- ETH
- Eter
- ethereum
- Blockchain Ethereum
- Ethereum Klasik
- contoh
- Mengeksploitasi
- akhir
- Pertama
- Gratis
- fungsi
- permainan
- Games
- GAS
- menghasilkan
- GitHub
- akan
- baik
- membimbing
- terjangan
- hacks
- hash
- kepala
- di sini
- Seterpercayaapakah Olymp Trade? Kesimpulan
- HTTPS
- menyelidiki
- IT
- Jawa
- ikut
- melompat
- King
- bahasa
- besar
- baris
- Panjang
- mencari
- lotere
- pria
- juta
- ibu
- nomor
- organisasi
- kertas
- pola
- Membayar
- Konsultan Ahli
- bagian
- Platform
- Bermain
- pemain
- ponzi
- Skema Ponzi
- kekuasaan
- proses
- Programmer
- Pemrograman
- publik
- membalikkan
- ulasan
- Hadiah
- aturan
- Satoshi
- keamanan
- set
- pintar
- kontrak pintar
- Kontrak Cerdas
- So
- soliditas
- sesuatu
- Berputar
- membagi
- mulai
- Pernyataan
- Penyelarasan
- sukses
- berhasil
- tech
- tes
- Melalui
- waktu
- alat
- .
- tak memiliki rekening bank
- universitas
- Pembaruan
- nilai
- Kerentanan
- kerentanan
- Rentan
- dompet
- Apa
- Roda
- SIAPA
- menang
- Kerja
- penulisan