![](/img/bg-single.png)
Bal Küpü'ndeki gizli tuzaklar
![](https://lotusmarket.io/storage/files/hidden-traps-in-honeypot/cover.png)
Honeypot akıllı sözleşmeleri, kullanıcılar için cazip görünen ve finansal faydalar vaat eden bir tür hileli akıllı sözleşmedir. Bununla birlikte, bu tür sözleşmeler gizli tuzaklar veya kötü amaçlı kodlar içerir ve kullanıcıların aksine fonlarını kaybetmelerine neden olur.
Kendinizi Honeypot akıllı sözleşmelerinden korumak için, sözleşme ile etkileşime girmeden önce sözleşme kodunu iyice araştırmanız ve doğrulamanız gerekir. Akıllı sözleşmeler ve blok zinciri dünyası, düzenli olarak ortaya çıkan yeni güvenlik açıkları ve aldatma yöntemleri ile sürekli olarak gelişmektedir, bu nedenle geliştiricilerin, denetçilerin ve kullanıcıların bu alandaki en son trendleri ve gelişmeleri takip etmeleri çok önemlidir.
Bal Küpü akıllı sözleşmelerin birçok örneği vardır. Bu makalede bazı örneklere bakacağız.
1. Geri alma fonksiyonu balküpü
Bu tür balküpünde, sözleşme, görünüşte herkesin sözleşmeye sahip olmasına ve bakiyesini kaldırmasına izin veren savunmasız bir "geri alma" özelliğine sahiptir. Ancak, böyle bir özellik başarılı bir yürütmeyi engelleyen gizli bir koşul içerir.
Örnek kod:
pragma solidity 0.4.18
contract FallbackHoneypot {
address public owner;
function() public payable {
if (owner == 0) {
owner = msg.sender;
} else {
revert();
}
}
function withdraw() public {
require(msg.sender == owner);
msg.sender.transfer(this.balance);
}
}
Bu örnekte, fallback fonksiyonu herhangi bir kullanıcının sahip olmasına izin verir. Ancak, revert() operatörü sahiplik değişikliğinin asla gerçekleşmemesini sağlayarak saldırganın fonlarının sözleşmede sıkışıp kalmasına neden olur.
2. Gizli koşullu bal küpü
Bu tür sözleşmeler, görünüşte savunmasız olan işlevin başarılı olması için yerine getirilmesi gereken gizli bir koşul veya gereksinim içerir. Kullanıcılar sözleşmeyi kullanabileceklerini düşünebilir, ancak gizli koşul kullanamayacaklarını garanti eder.
Örnek kod:
pragma solidity 0.4.18
contract HiddenConditionHoneypot {
uint256 public counter = 0;
function deposit() public payable {
require(msg.value == 1 ether);
counter++;
}
function withdraw() public {
require(counter > 100);
msg.sender.transfer(this.balance);
}
}
Bu sözleşmede, kullanıcı 1 ether yatırabilir ve 100 para yatırma işleminden sonra kullanıcı tüm sözleşme bakiyesini çekebilir gibi görünür. Ancak counter > 100 koşulu, para çekme işleminin yalnızca 101 para yatırma işleminden sonra mümkün olmasını sağlar ve bu da sözleşmedeki fonları geciktirir.
3. Reentrancy honeypot
Bu tür bir honeypotta sözleşme, bir saldırganın para çekme işlemi sırasında bir sözleşme işlevini tekrar tekrar çağırabileceği bir reentrancy saldırısına karşı savunmasızdır. Bununla birlikte, sözleşme başarılı bir istismarı önleyen gizli bir mekanizma içerir.
Örnek kod:
pragma solidity 0.4.18
contract ReentrancyHoneypot {
mapping(address => uint256) public balances;
function deposit() public payable {
balances[msg.sender] += msg.value;
}
function withdraw(uint256 _amount) public {
require(balances[msg.sender] >= _amount);
if (msg.sender.call.value(_amount)()) {
balances[msg.sender] -= _amount;
}
}
}
Bu örnekte, msg.sender.call.value(_amount)() kullanımı nedeniyle sözleşme yeniden merkezlenme saldırısına karşı savunmasızdır. Bununla birlikte, sözleşme kullanıcıların ilk bakiyeden daha fazla para yatırmasına izin vermeyerek fonlarını etkili bir şekilde geciktirir.
4. Gaz limiti bal küpü
Bu tür bal küpünde, sözleşme kullanıcının para çekmesine izin veriyor gibi görünür, ancak para çekme işlevini gerçekleştirmek için gereken gaz miktarı gaz blok limitini aşarak işlemi imkansız hale getirir.
Örnek kod:
pragma solidity 0.4.18
contract GasLimitHoneypot {
uint256 constant public numArrayElements = 1000;
uint256[numArrayElements] public someArray;
function deposit() public payable {
for (uint256 i = 0; i < numArrayElements; i++) {
someArray[i] = 0;
}
}
function withdraw() public {
uint256 balance = address(this).balance;
for (uint256 i = 0; i < numArrayElements; i++) {
someArray[i] = 1;
}
msg.sender.transfer(balance);
}
}
Bu örnekte, deposit fonksiyonu 1000 elemanlı bir diziyi başlatır. Para çekme fonksiyonu sözleşme bakiyesini gönderene aktarır, ancak dizi elemanlarını değiştirir. Döngüyü yürütmek için gereken gaz, gaz bloğu sınırını aşar, bu da para çekmeyi önler ve sözleşmede geciktirir.
5. Zaman damgası manipülasyonu bal küpü
Bu tür bir bal küpünde, sözleşme Ethereum blok zinciri zaman damgasını yürütme koşulu olarak kullanır. Ancak madenciler blok zaman damgasını manipüle edebildiği için sözleşme savunmasız hale gelir.
Örnek kod:
pragma solidity 0.4.18
contract TimestampHoneypot {
uint256 public lastInteraction;
uint256 public prize;
function deposit() public payable {
lastInteraction = now;
prize += msg.value;
}
function withdraw() public {
require(now >= lastInteraction + 1 hours);
msg.sender.transfer(prize);
prize = 0;
}
}
Bu sözleşmede kullanıcılar fon yatırabilir ve son etkileşimden 1 saat sonra tüm sözleşme bakiyesini çekebilir. Ancak madenciler blok zaman damgasını manipüle edebildiğinden, para çekme işlevini beklenenden daha erken tetikleyebilir ve böylece aslında fonları çalabilirler.
6. Gizli transfer bal küpü
Bu tür bir bal küpünde, sözleşme saldırganın adresine gizli bir fon transferi içerir, bu da meşru bir sözleşme görünümü verir, ancak gerçekte fon kaybına neden olur.
Örnek kod:
pragma solidity 0.4.18
contract HiddenTransferHoneypot {
address public owner;
constructor() public {
owner = msg.sender;
}
function deposit() public payable {
if (msg.value >= 1 ether) {
owner.transfer(msg.value);
}
}
function withdraw() public {
require(msg.sender == owner);
owner.transfer(address(this).balance);
}
}
Bu örnekte, sözleşme para yatırma ve çekme işlemlerine izin veriyor gibi görünüyor. Bununla birlikte, para yatırma işlevi, para yatırma miktarı 1 etere eşit veya daha büyükse, sahibine (saldırgan) gizli bir para transferi içerir. Para yatıran şüphelenmeyen kullanıcılar, saldırganın adresine aktarılacağı için etherlerini kaybedecektir.
7. Yeniden merkezlilik bal küpü
Yeniden merkezlilik bal küpü, bir sözleşme işlevinin durumu güncellenmeden önce özyinelemeli olarak çağrılabildiği sözleşmedeki yeniden merkezlilik güvenlik açığından yararlanmaya dayanır.
Örnek kod:
pragma solidity 0.4.18
contract ReentrancyHoneypot {
mapping(address => uint256) public balances;
function deposit() public payable {
balances[msg.sender] += msg.value;
}
function withdraw() public {
uint256 amount = balances[msg.sender];
(bool success,) = msg.sender.call.value(amount)("");
require(success, "Withdrawal failed.");
balances[msg.sender] = 0;
}
}
Bu örnekte, sözleşme para yatırma ve çekme işlemlerini yetkilendirir. Ancak, yeniden merkezleme saldırılarına karşı savunmasızdır. Bir saldırgan, bakiye sıfıra ayarlanmadan önce para çekme işlevini özyinelemeli olarak çağıran ve tüm sözleşme bakiyesini tüketen kötü amaçlı bir sözleşme oluşturabilir.
8. Tür dönüştürme ve taşma bal küpü
Bu tür bir bal küpünde saldırgan, kullanıcıları sözleşmenin güvenli olduğuna inandırmak için tür dönüştürme ve tamsayı taşmaları kullanır, ancak aslında gizli tuzaklar içerir.
Örnek kod:
pragma solidity 0.4.18
contract TypeCastingHoneypot {
uint8 public count = 0;
uint256 public reward = 1 ether;
function increment() public payable {
require(msg.value >= reward);
uint8 prevCount = count;
count++;
if (count < prevCount) {
msg.sender.transfer(address(this).balance);
}
}
}
Bu örnekte, sözleşme, ödül tutarına eşit veya daha büyük bir tutar gönderdiklerinde count değişkenini artıran kullanıcıları ödüllendirir. Ancak, count değişkeni için uint8 kullanılması nedeniyle, değer 255'e ulaştığında bir tamsayı taşması meydana gelir. Taşmadan sonra sayım 0'a sıfırlanır ve bir saldırgan sözleşmenin tüm bakiyesini elde edebilir.
9. Delegatecall honeypot
Bu tür bir honeypot'ta saldırgan, görünüşte güvenli bir sözleşme adına kötü amaçlı kod çalıştırmak için delegatecall işlevini kullanır.
Örnek kod:
pragma solidity 0.4.18
contract DelegateCallHoneypot {
address public owner;
constructor() public {
owner = msg.sender;
}
function() external payable {}
function withdraw() public {
require(msg.sender == owner);
owner.transfer(address(this).balance);
}
function execute(address _target, bytes memory _data) public {
require(msg.sender == owner);
(bool success,) = _target.delegatecall(_data);
require(success, "Execution failed.");
}
}
Bu örnekte, sözleşme execute işlevi aracılığıyla para yatırma, para çekme ve kod yürütme işlemlerine izin verir. Ancak bir saldırgan, delegatecall işlevini çalıştırarak sahip değişkeni de dahil olmak üzere sözleşmenin durumunu değiştirebilen kötü amaçlı bir kod oluşturabilir. Saldırgan, sahibi değiştirerek sözleşmenin kontrolünü ele geçirebilir ve bakiyesini boşaltabilir.
10. Gizli depolama manipülasyonu bal küpü
Bu tür bir bal küpünde saldırgan, kullanıcıları kandırarak sözleşmenin kontrolünü ele geçirmek için depolama değişkenlerini gizlice manipüle eder.
Örnek kod:
pragma solidity 0.4.18
contract HiddenStorageManipulation {
mapping(address => uint256) public balances;
uint256 public totalSupply;
address public owner;
constructor() public {
owner = msg.sender;
balances[owner] = 1000;
totalSupply = 1000;
}
function transfer(address _to, uint256 _value) public {
require(balances[msg.sender] >= _value);
balances[msg.sender] -= _value;
balances[_to] += _value;
if (totalSupply - balances[owner] >= 1000) {
owner = _to;
}
}
}
Bu örnekte, sözleşme basit bir token sözleşmesi gibi görünür. Kullanıcılar birbirlerine token aktarabilir ve sahip başlangıçta sözleşmenin yaratıcısı olarak ayarlanır. Ancak bir saldırgan, sözleşmenin kontrolünü yeniden ele geçirmek için totalSupply ve balances değişkenlerini gizlice manipüle edebilir. totalSupply ve balances[owner] arasındaki fark 1000'e ulaştığında, owner değişkeni güncellenerek saldırganın sözleşmenin kontrolünü yeniden ele geçirmesi sağlanır.
11. İşlev adı çarpışması bal küpü
Bu tür bal küpünde saldırgan, kullanıcıları yanlış işlevi çağırmaları için kandırmak için işlev adı çarpışmalarını kullanır.
Örnek kod:
pragma solidity 0.4.18
contract FunctionNameCollision {
address public owner;
constructor() public {
owner = msg.sender;
}
function withdraw() external {
require(msg.sender == owner);
msg.sender.transfer(address(this).balance);
}
function withdraw(uint256 amount) external {
require(msg.sender == owner);
owner.transfer(amount);
}
function() external payable {}
}
Bu örnekte, sözleşmenin iki para çekme işlevi vardır. Bunlardan biri sahibinin tüm bakiyeyi çekmesine izin verirken diğeri sahibinin belirli bir miktarı çekmesine izin verir. Ancak, kullanıcı withdraw(uint256) işlevini çağırarak belirli bir tutarı çekmeye çalışırsa, bir işlev adı çakışması nedeniyle, kullanıcı yanlışlıkla argüman olmadan withdraw() işlevini çağıracak ve bu da tüm sözleşme bakiyesinin çekilmesine neden olacaktır.
12. Delegatecall güvenlik açığı bal küpü
Bu tür bir bal küpünde, saldırgan başka bir sözleşmede kötü amaçlı bir işlevi yürütmek için delegatecall kullanır ve bu da kullanıcıların fonlarının çalınmasına yol açabilir.
Örnek kod:
pragma solidity 0.4.18
contract DelegatecallVulnerability {
address public owner;
constructor() public {
owner = msg.sender;
}
function withdraw() external {
require(msg.sender == owner);
msg.sender.transfer(address(this).balance);
}
function () external payable {
if (msg.value > 1 ether) {
this.delegatecall(msg.data);
}
}
}
contract Malicious {
function withdraw() external {
msg.sender.transfer(address(this).balance);
}
}
Bu örnekte sözleşme, sahibinin sözleşmenin bakiyesini çekmesine olanak tanıyan basit bir withdraw() fonksiyonu ile zararsız görünmektedir. Bununla birlikte, sözleşme aynı zamanda 1'den fazla ether alırken msg.data kullanarak başka bir sözleşmenin delegatecall'unu gerçekleştiren bir geri dönüş işlevi de içerir. Bir saldırgan withdraw() ile sözleşme bakiyesini çalan kötü niyetli bir sözleşme oluşturur ve kurban sözleşmeye 1'den fazla ether gönderirse, delegatecall kötü niyetli withdraw() işlevini çalıştırarak sözleşme bakiyesini çalar.
13. Pseudo-integers overflow honeypot
Bu tür bir honeypot, Solidity'nin kayan noktalı sayılar için yerleşik desteğe sahip olmadığı gerçeğine dayanır. Saldırganlar dışarıdan ondalık sayıları kullanan ancak aslında tam sayıları hileli bir şekilde manipüle eden sözleşmeler oluşturabilir.
Örnek kod:
pragma solidity 0.4.18
contract PseudoIntegersOverflow {
mapping(address => uint256) public balances;
function deposit() external payable {
require(msg.value > 0);
uint256 pseudoValue = msg.value * 100;
balances[msg.sender] += pseudoValue;
}
function withdraw(uint256 amount) external {
uint256 pseudoAmount = amount * 100;
require(balances[msg.sender] >= pseudoAmount);
balances[msg.sender] -= pseudoAmount;
msg.sender.transfer(amount);
}
}
Bu örnek, sözleşmenin değerleri kaydetmeden önce 100 ile çarparak kullanıcının bakiyesini ondalık hassasiyetle yönettiği izlenimini verir. Ancak, Solidity kayan nokta sayılarını desteklemediği için bu yaklaşım yanıltıcıdır. Kullanıcı fonlarını çekmeye çalıştığında, sözleşme tamsayı kesme nedeniyle sözde toplamı yanlış hesaplar ve kullanıcı tüm bakiyesini çekemeyebilir.
Bu tür bal küplerine karşı korunmak için Solidity dilinin sınırlamalarını ve sayısal işlemleri nasıl ele aldığını anlamanız gerekir. Ondalık hassasiyeti desteklediğini iddia eden sözleşmelerle çalışırken dikkatli olun ve olası sorunlara karşı sözleşme kodunu her zaman kontrol edin.
14. Akıllı sözleşmelerdeki gizli ücretler
Bazı kötü niyetli akıllı sözleşmeler kullanıcılara bilgileri olmadan gizli ödemeler dayatabilir. Bu tür ödemeler sözleşme kodunda gizlenebilir veya yalnızca belirli koşullar altında tetiklenebilir.
Örnek kod:
pragma solidity 0.4.18
contract HiddenFees {
address public owner;
uint256 public feePercentage;
constructor(uint256 _feePercentage) public {
owner = msg.sender;
feePercentage = _feePercentage;
}
function withdraw(uint256 amount) external {
uint256 fee = amount * feePercentage / 100;
uint256 netAmount = amount - fee;
require(address(this).balance >= netAmount);
msg.sender.transfer(netAmount);
owner.transfer(fee);
}
}
Bu örnekte, sözleşme oluşturucu sözleşmeyi dağıtırken bir ücret (feePercentage) belirler. Kullanıcılar sözleşme ile etkileşim kurarken bu ücretin farkında olmayabilir. Bir kullanıcı fonlarını çektiğinde, sözleşme ücreti hesaplar, para çekme tutarından çıkarır ve kalanı kullanıcıya gönderir. Komisyon daha sonra sözleşme sahibine aktarılır.
Bu tuzağa düşmekten kaçınmak için sözleşme kodunu dikkatlice inceleyin ve ilgili tüm ücretleri anladığınızdan emin olun. Gizli veya gizlenmiş anlaşmaları arayın.
15. Gizli durum manipülasyonu
Bazı durumlarda, kötü niyetli sözleşmeler, sözleşme sahibinin veya bir saldırganın sözleşmenin dahili durumunu manipüle etmesine izin vererek diğer kullanıcılar için beklenmedik sonuçlara yol açabilir.
Örnek kod:
pragma solidity 0.4.18
contract HiddenStateManipulation {
address public owner;
mapping(address => uint256) public balances;
constructor() public {
owner = msg.sender;
}
function deposit() external payable {
balances[msg.sender] += msg.value;
}
function withdraw(uint256 amount) external {
require(balances[msg.sender] >= amount);
msg.sender.transfer(amount);
balances[msg.sender] -= amount;
}
function manipulateBalance(address user, uint256 newBalance) external {
require(msg.sender == owner);
balances[user] = newBalance;
}
}
Bu örnekte, sözleşme kullanıcıların para yatırmasına ve çekmesine izin verir. Ancak manipulateBalance işlevi, sözleşme sahibinin herhangi bir kullanıcının bakiyesini keyfi olarak değiştirmesine izin verir. Bu durum kullanıcıların beklenmedik kayıplar yaşamasına ya da sözleşme sahibinin fon çalmasına neden olabilir.
Sözleşme kodu, özellikle yalnızca sözleşme sahibinin ya da belirli adreslerin erişimi varsa, durum manipülasyonuna izin veren özellikler açısından incelenmelidir.
16. Gizli token çalma
Bazı durumlarda, kötü niyetli sözleşmeler, sözleşme sahibinin veya saldırganın şüphelenmeyen kullanıcılardan token çalmasına olanak tanıyan gizli özellikler içerebilir.
Örnek kod:
pragma solidity 0.4.18
contract HiddenTokenStealing {
address public owner;
mapping(address => uint256) public balances;
constructor() public {
owner = msg.sender;
}
function deposit(IERC20 token, uint256 amount) external {
require(token.transferFrom(msg.sender, address(this), amount));
balances[msg.sender] += amount;
}
function withdraw(IERC20 token, uint256 amount) external {
require(balances[msg.sender] >= amount);
require(token.transfer(msg.sender, amount));
balances[msg.sender] -= amount;
}
function stealTokens(IERC20 token, address user, uint256 amount) external {
require(msg.sender == owner);
require(token.transfer(owner, amount));
balances[user] -= amount;
}
}
Bu örnekte, sözleşme kullanıcıların ERC20 tokenlarını yatırmasına ve çekmesine izin vermektedir. Ancak stealTokens fonksiyonu, sözleşme sahibinin herhangi bir kullanıcıdan token çalmasına olanak tanır.
Sonuç:
Honeypot, DeFi'de yalnızca para çekme kısıtlamasını değil, aynı zamanda yukarıda açıklanan çeşitli gizli tuzakları da kullanan birçok dolandırıcılık planından yalnızca biridir.
Yemi yutmamak için dolandırıcılık planının özelliklerini, Solidity programlama dilinin inceliklerini anlamanız ve akıllı sözleşmelerle etkileşime girmeden önce bunları iyice incelemeniz gerekir.
Bilgili kalarak ve kapsamlı bir durum tespiti yaparak, akıllı sözleşmelerin kullanımıyla ilgili riskleri en aza indirebilirsiniz.
Akıllı bir sözleşmenin güvenliği veya işlevselliği hakkında herhangi bir şüpheniz varsa Lotus Market platformumuzu kullanın.
Lotus Market platformu, deneyimli geliştiriciler ve profesyonel denetçilerden oluşan bir ekip tarafından oluşturulmuştur. Projenin amacı, hileli tokenlere yatırım yapma risklerini en aza indirmek ve kripto para birimlerinin güvenli ve rahat bir şekilde ticaretine yardımcı olmaktır.
Saygılar, Lotus Market ekibi.